From 978bc64580742087bf5becd4a3802bc9f12ce70b Mon Sep 17 00:00:00 2001 From: Zdenek Dohnal Date: Sep 19 2018 07:47:26 +0000 Subject: - src/libvterm/src/termscreen.c is missing --- diff --git a/.gitignore b/.gitignore index a503f66..4b29608 100644 --- a/.gitignore +++ b/.gitignore @@ -226,3 +226,4 @@ /vim-8.1-287.tar.bz2 /vim-8.1-328.tar.bz2 /vim-8.1-351.tar.bz2 +/vim-8.1-408.tar.bz2 diff --git a/sources b/sources index b52cb66..f1ccb20 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (vim-8.1-351.tar.bz2) = 320c91eb7eab8d87c45fa9843e31d058a424ad5ad4685cdf419b7e268bad35451881f2d94f3cfb9999a560fd21cc63a8c5416362e6fabaac23d2f3a6a7daf6bf +SHA512 (vim-8.1-408.tar.bz2) = b2f90aa2b6463d1a0ff21294a26ea93c142190cc2376e562ba99a32b4dafe166648a6bf10f63ac7335d601d74259ea48b3f723da91bf735c20ec20190468e399 diff --git a/vim-missing-file.patch b/vim-missing-file.patch new file mode 100644 index 0000000..4634fa0 --- /dev/null +++ b/vim-missing-file.patch @@ -0,0 +1,939 @@ +diff -up vim81/src/libvterm/src/termscreen.c.missing-file vim81/src/libvterm/src/termscreen.c +--- vim81/src/libvterm/src/termscreen.c.missing-file 2018-09-19 09:26:00.601523830 +0200 ++++ vim81/src/libvterm/src/termscreen.c 2018-09-19 09:26:56.448031158 +0200 +@@ -0,0 +1,935 @@ ++#include "vterm_internal.h" ++ ++#include ++#include ++ ++#include "rect.h" ++#include "utf8.h" ++ ++#define UNICODE_SPACE 0x20 ++#define UNICODE_LINEFEED 0x0a ++ ++/* State of the pen at some moment in time, also used in a cell */ ++typedef struct ++{ ++ /* After the bitfield */ ++ VTermColor fg, bg; ++ ++ unsigned int bold : 1; ++ unsigned int underline : 2; ++ unsigned int italic : 1; ++ unsigned int blink : 1; ++ unsigned int reverse : 1; ++ unsigned int strike : 1; ++ unsigned int font : 4; /* 0 to 9 */ ++ ++ /* Extra state storage that isn't strictly pen-related */ ++ unsigned int protected_cell : 1; ++ unsigned int dwl : 1; /* on a DECDWL or DECDHL line */ ++ unsigned int dhl : 2; /* on a DECDHL line (1=top 2=bottom) */ ++} ScreenPen; ++ ++/* Internal representation of a screen cell */ ++typedef struct ++{ ++ uint32_t chars[VTERM_MAX_CHARS_PER_CELL]; ++ ScreenPen pen; ++} ScreenCell; ++ ++static int vterm_screen_set_cell(VTermScreen *screen, VTermPos pos, const VTermScreenCell *cell); ++ ++struct VTermScreen ++{ ++ VTerm *vt; ++ VTermState *state; ++ ++ const VTermScreenCallbacks *callbacks; ++ void *cbdata; ++ ++ VTermDamageSize damage_merge; ++ /* start_row == -1 => no damage */ ++ VTermRect damaged; ++ VTermRect pending_scrollrect; ++ int pending_scroll_downward, pending_scroll_rightward; ++ ++ int rows; ++ int cols; ++ int global_reverse; ++ ++ /* Primary and Altscreen. buffers[1] is lazily allocated as needed */ ++ ScreenCell *buffers[2]; ++ ++ /* buffer will == buffers[0] or buffers[1], depending on altscreen */ ++ ScreenCell *buffer; ++ ++ /* buffer for a single screen row used in scrollback storage callbacks */ ++ VTermScreenCell *sb_buffer; ++ ++ ScreenPen pen; ++}; ++ ++static ScreenCell *getcell(const VTermScreen *screen, int row, int col) ++{ ++ if(row < 0 || row >= screen->rows) ++ return NULL; ++ if(col < 0 || col >= screen->cols) ++ return NULL; ++ return screen->buffer + (screen->cols * row) + col; ++} ++ ++static ScreenCell *realloc_buffer(VTermScreen *screen, ScreenCell *buffer, int new_rows, int new_cols) ++{ ++ ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols); ++ int row, col; ++ ++ for(row = 0; row < new_rows; row++) { ++ for(col = 0; col < new_cols; col++) { ++ ScreenCell *new_cell = new_buffer + row*new_cols + col; ++ ++ if(buffer && row < screen->rows && col < screen->cols) ++ *new_cell = buffer[row * screen->cols + col]; ++ else { ++ new_cell->chars[0] = 0; ++ new_cell->pen = screen->pen; ++ } ++ } ++ } ++ ++ if(buffer) ++ vterm_allocator_free(screen->vt, buffer); ++ ++ return new_buffer; ++} ++ ++static void damagerect(VTermScreen *screen, VTermRect rect) ++{ ++ VTermRect emit; ++ ++ switch(screen->damage_merge) { ++ case VTERM_DAMAGE_CELL: ++ /* Always emit damage event */ ++ emit = rect; ++ break; ++ ++ case VTERM_DAMAGE_ROW: ++ /* Emit damage longer than one row. Try to merge with existing damage in ++ * the same row */ ++ if(rect.end_row > rect.start_row + 1) { ++ // Bigger than 1 line - flush existing, emit this ++ vterm_screen_flush_damage(screen); ++ emit = rect; ++ } ++ else if(screen->damaged.start_row == -1) { ++ // None stored yet ++ screen->damaged = rect; ++ return; ++ } ++ else if(rect.start_row == screen->damaged.start_row) { ++ // Merge with the stored line ++ if(screen->damaged.start_col > rect.start_col) ++ screen->damaged.start_col = rect.start_col; ++ if(screen->damaged.end_col < rect.end_col) ++ screen->damaged.end_col = rect.end_col; ++ return; ++ } ++ else { ++ // Emit the currently stored line, store a new one ++ emit = screen->damaged; ++ screen->damaged = rect; ++ } ++ break; ++ ++ case VTERM_DAMAGE_SCREEN: ++ case VTERM_DAMAGE_SCROLL: ++ /* Never emit damage event */ ++ if(screen->damaged.start_row == -1) ++ screen->damaged = rect; ++ else { ++ rect_expand(&screen->damaged, &rect); ++ } ++ return; ++ ++ default: ++ DEBUG_LOG1("TODO: Maybe merge damage for level %d\n", screen->damage_merge); ++ return; ++ } ++ ++ if(screen->callbacks && screen->callbacks->damage) ++ (*screen->callbacks->damage)(emit, screen->cbdata); ++} ++ ++static void damagescreen(VTermScreen *screen) ++{ ++ VTermRect rect = {0,0,0,0}; ++ rect.end_row = screen->rows; ++ rect.end_col = screen->cols; ++ ++ damagerect(screen, rect); ++} ++ ++static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user) ++{ ++ int i; ++ int col; ++ VTermRect rect; ++ ++ VTermScreen *screen = user; ++ ScreenCell *cell = getcell(screen, pos.row, pos.col); ++ ++ if(!cell) ++ return 0; ++ ++ for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++) { ++ cell->chars[i] = info->chars[i]; ++ cell->pen = screen->pen; ++ } ++ if(i < VTERM_MAX_CHARS_PER_CELL) ++ cell->chars[i] = 0; ++ ++ for(col = 1; col < info->width; col++) ++ getcell(screen, pos.row, pos.col + col)->chars[0] = (uint32_t)-1; ++ ++ rect.start_row = pos.row; ++ rect.end_row = pos.row+1; ++ rect.start_col = pos.col; ++ rect.end_col = pos.col+info->width; ++ ++ cell->pen.protected_cell = info->protected_cell; ++ cell->pen.dwl = info->dwl; ++ cell->pen.dhl = info->dhl; ++ ++ damagerect(screen, rect); ++ ++ return 1; ++} ++ ++static int moverect_internal(VTermRect dest, VTermRect src, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ if(screen->callbacks && screen->callbacks->sb_pushline && ++ dest.start_row == 0 && dest.start_col == 0 && // starts top-left corner ++ dest.end_col == screen->cols && // full width ++ screen->buffer == screen->buffers[0]) { // not altscreen ++ VTermPos pos; ++ for(pos.row = 0; pos.row < src.start_row; pos.row++) { ++ for(pos.col = 0; pos.col < screen->cols; pos.col++) ++ (void)vterm_screen_get_cell(screen, pos, screen->sb_buffer + pos.col); ++ ++ (screen->callbacks->sb_pushline)(screen->cols, screen->sb_buffer, screen->cbdata); ++ } ++ } ++ ++ { ++ int cols = src.end_col - src.start_col; ++ int downward = src.start_row - dest.start_row; ++ int init_row, test_row, inc_row; ++ int row; ++ ++ if(downward < 0) { ++ init_row = dest.end_row - 1; ++ test_row = dest.start_row - 1; ++ inc_row = -1; ++ } ++ else { ++ init_row = dest.start_row; ++ test_row = dest.end_row; ++ inc_row = +1; ++ } ++ ++ for(row = init_row; row != test_row; row += inc_row) ++ memmove(getcell(screen, row, dest.start_col), ++ getcell(screen, row + downward, src.start_col), ++ cols * sizeof(ScreenCell)); ++ } ++ ++ return 1; ++} ++ ++static int moverect_user(VTermRect dest, VTermRect src, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ if(screen->callbacks && screen->callbacks->moverect) { ++ if(screen->damage_merge != VTERM_DAMAGE_SCROLL) ++ // Avoid an infinite loop ++ vterm_screen_flush_damage(screen); ++ ++ if((*screen->callbacks->moverect)(dest, src, screen->cbdata)) ++ return 1; ++ } ++ ++ damagerect(screen, dest); ++ ++ return 1; ++} ++ ++static int erase_internal(VTermRect rect, int selective, void *user) ++{ ++ VTermScreen *screen = user; ++ int row, col; ++ ++ for(row = rect.start_row; row < screen->state->rows && row < rect.end_row; row++) { ++ const VTermLineInfo *info = vterm_state_get_lineinfo(screen->state, row); ++ ++ for(col = rect.start_col; col < rect.end_col; col++) { ++ ScreenCell *cell = getcell(screen, row, col); ++ ++ if(selective && cell->pen.protected_cell) ++ continue; ++ ++ cell->chars[0] = 0; ++ cell->pen = screen->pen; ++ cell->pen.dwl = info->doublewidth; ++ cell->pen.dhl = info->doubleheight; ++ } ++ } ++ ++ return 1; ++} ++ ++static int erase_user(VTermRect rect, int selective UNUSED, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ damagerect(screen, rect); ++ ++ return 1; ++} ++ ++static int erase(VTermRect rect, int selective, void *user) ++{ ++ erase_internal(rect, selective, user); ++ return erase_user(rect, 0, user); ++} ++ ++static int scrollrect(VTermRect rect, int downward, int rightward, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ if(screen->damage_merge != VTERM_DAMAGE_SCROLL) { ++ vterm_scroll_rect(rect, downward, rightward, ++ moverect_internal, erase_internal, screen); ++ ++ vterm_screen_flush_damage(screen); ++ ++ vterm_scroll_rect(rect, downward, rightward, ++ moverect_user, erase_user, screen); ++ ++ return 1; ++ } ++ ++ if(screen->damaged.start_row != -1 && ++ !rect_intersects(&rect, &screen->damaged)) { ++ vterm_screen_flush_damage(screen); ++ } ++ ++ if(screen->pending_scrollrect.start_row == -1) { ++ screen->pending_scrollrect = rect; ++ screen->pending_scroll_downward = downward; ++ screen->pending_scroll_rightward = rightward; ++ } ++ else if(rect_equal(&screen->pending_scrollrect, &rect) && ++ ((screen->pending_scroll_downward == 0 && downward == 0) || ++ (screen->pending_scroll_rightward == 0 && rightward == 0))) { ++ screen->pending_scroll_downward += downward; ++ screen->pending_scroll_rightward += rightward; ++ } ++ else { ++ vterm_screen_flush_damage(screen); ++ ++ screen->pending_scrollrect = rect; ++ screen->pending_scroll_downward = downward; ++ screen->pending_scroll_rightward = rightward; ++ } ++ ++ vterm_scroll_rect(rect, downward, rightward, ++ moverect_internal, erase_internal, screen); ++ ++ if(screen->damaged.start_row == -1) ++ return 1; ++ ++ if(rect_contains(&rect, &screen->damaged)) { ++ /* Scroll region entirely contains the damage; just move it */ ++ vterm_rect_move(&screen->damaged, -downward, -rightward); ++ rect_clip(&screen->damaged, &rect); ++ } ++ /* There are a number of possible cases here, but lets restrict this to only ++ * the common case where we might actually gain some performance by ++ * optimising it. Namely, a vertical scroll that neatly cuts the damage ++ * region in half. ++ */ ++ else if(rect.start_col <= screen->damaged.start_col && ++ rect.end_col >= screen->damaged.end_col && ++ rightward == 0) { ++ if(screen->damaged.start_row >= rect.start_row && ++ screen->damaged.start_row < rect.end_row) { ++ screen->damaged.start_row -= downward; ++ if(screen->damaged.start_row < rect.start_row) ++ screen->damaged.start_row = rect.start_row; ++ if(screen->damaged.start_row > rect.end_row) ++ screen->damaged.start_row = rect.end_row; ++ } ++ if(screen->damaged.end_row >= rect.start_row && ++ screen->damaged.end_row < rect.end_row) { ++ screen->damaged.end_row -= downward; ++ if(screen->damaged.end_row < rect.start_row) ++ screen->damaged.end_row = rect.start_row; ++ if(screen->damaged.end_row > rect.end_row) ++ screen->damaged.end_row = rect.end_row; ++ } ++ } ++ else { ++ DEBUG_LOG2("TODO: Just flush and redo damaged=" STRFrect " rect=" STRFrect "\n", ++ ARGSrect(screen->damaged), ARGSrect(rect)); ++ } ++ ++ return 1; ++} ++ ++static int movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ if(screen->callbacks && screen->callbacks->movecursor) ++ return (*screen->callbacks->movecursor)(pos, oldpos, visible, screen->cbdata); ++ ++ return 0; ++} ++ ++static int setpenattr(VTermAttr attr, VTermValue *val, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ switch(attr) { ++ case VTERM_ATTR_BOLD: ++ screen->pen.bold = val->boolean; ++ return 1; ++ case VTERM_ATTR_UNDERLINE: ++ screen->pen.underline = val->number; ++ return 1; ++ case VTERM_ATTR_ITALIC: ++ screen->pen.italic = val->boolean; ++ return 1; ++ case VTERM_ATTR_BLINK: ++ screen->pen.blink = val->boolean; ++ return 1; ++ case VTERM_ATTR_REVERSE: ++ screen->pen.reverse = val->boolean; ++ return 1; ++ case VTERM_ATTR_STRIKE: ++ screen->pen.strike = val->boolean; ++ return 1; ++ case VTERM_ATTR_FONT: ++ screen->pen.font = val->number; ++ return 1; ++ case VTERM_ATTR_FOREGROUND: ++ screen->pen.fg = val->color; ++ return 1; ++ case VTERM_ATTR_BACKGROUND: ++ screen->pen.bg = val->color; ++ return 1; ++ ++ case VTERM_N_ATTRS: ++ return 0; ++ } ++ ++ return 0; ++} ++ ++static int settermprop(VTermProp prop, VTermValue *val, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ switch(prop) { ++ case VTERM_PROP_ALTSCREEN: ++ if(val->boolean && !screen->buffers[1]) ++ return 0; ++ ++ screen->buffer = val->boolean ? screen->buffers[1] : screen->buffers[0]; ++ /* only send a damage event on disable; because during enable there's an ++ * erase that sends a damage anyway ++ */ ++ if(!val->boolean) ++ damagescreen(screen); ++ break; ++ case VTERM_PROP_REVERSE: ++ screen->global_reverse = val->boolean; ++ damagescreen(screen); ++ break; ++ default: ++ ; /* ignore */ ++ } ++ ++ if(screen->callbacks && screen->callbacks->settermprop) ++ return (*screen->callbacks->settermprop)(prop, val, screen->cbdata); ++ ++ return 1; ++} ++ ++static int bell(void *user) ++{ ++ VTermScreen *screen = user; ++ ++ if(screen->callbacks && screen->callbacks->bell) ++ return (*screen->callbacks->bell)(screen->cbdata); ++ ++ return 0; ++} ++ ++static int resize(int new_rows, int new_cols, VTermPos *delta, void *user) ++{ ++ VTermScreen *screen = user; ++ ++ int is_altscreen = (screen->buffers[1] && screen->buffer == screen->buffers[1]); ++ ++ int old_rows = screen->rows; ++ int old_cols = screen->cols; ++ int first_blank_row; ++ ++ if(!is_altscreen && new_rows < old_rows) { ++ // Fewer rows - determine if we're going to scroll at all, and if so, push ++ // those lines to scrollback ++ VTermPos pos = { 0, 0 }; ++ VTermPos cursor = screen->state->pos; ++ // Find the first blank row after the cursor. ++ for(pos.row = old_rows - 1; pos.row >= new_rows; pos.row--) ++ if(!vterm_screen_is_eol(screen, pos) || cursor.row == pos.row) ++ break; ++ ++ first_blank_row = pos.row + 1; ++ if(first_blank_row > new_rows) { ++ VTermRect rect = {0,0,0,0}; ++ rect.end_row = old_rows; ++ rect.end_col = old_cols; ++ scrollrect(rect, first_blank_row - new_rows, 0, user); ++ vterm_screen_flush_damage(screen); ++ ++ delta->row -= first_blank_row - new_rows; ++ } ++ } ++ ++ screen->buffers[0] = realloc_buffer(screen, screen->buffers[0], new_rows, new_cols); ++ if(screen->buffers[1]) ++ screen->buffers[1] = realloc_buffer(screen, screen->buffers[1], new_rows, new_cols); ++ ++ screen->buffer = is_altscreen ? screen->buffers[1] : screen->buffers[0]; ++ ++ screen->rows = new_rows; ++ screen->cols = new_cols; ++ ++ if(screen->sb_buffer) ++ vterm_allocator_free(screen->vt, screen->sb_buffer); ++ ++ screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * new_cols); ++ ++ if(new_cols > old_cols) { ++ VTermRect rect; ++ rect.start_row = 0; ++ rect.end_row = old_rows; ++ rect.start_col = old_cols; ++ rect.end_col = new_cols; ++ damagerect(screen, rect); ++ } ++ ++ if(new_rows > old_rows) { ++ if(!is_altscreen && screen->callbacks && screen->callbacks->sb_popline) { ++ int rows = new_rows - old_rows; ++ while(rows) { ++ VTermRect rect = {0,0,0,0}; ++ VTermPos pos = { 0, 0 }; ++ if(!(screen->callbacks->sb_popline(screen->cols, screen->sb_buffer, screen->cbdata))) ++ break; ++ ++ rect.end_row = screen->rows; ++ rect.end_col = screen->cols; ++ scrollrect(rect, -1, 0, user); ++ ++ for(pos.col = 0; pos.col < screen->cols; pos.col += screen->sb_buffer[pos.col].width) ++ vterm_screen_set_cell(screen, pos, screen->sb_buffer + pos.col); ++ ++ rect.end_row = 1; ++ damagerect(screen, rect); ++ ++ vterm_screen_flush_damage(screen); ++ ++ rows--; ++ delta->row++; ++ } ++ } ++ ++ { ++ VTermRect rect; ++ rect.start_row = old_rows; ++ rect.end_row = new_rows; ++ rect.start_col = 0; ++ rect.end_col = new_cols; ++ damagerect(screen, rect); ++ } ++ } ++ ++ if(screen->callbacks && screen->callbacks->resize) ++ return (*screen->callbacks->resize)(new_rows, new_cols, screen->cbdata); ++ ++ return 1; ++} ++ ++static int setlineinfo(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user) ++{ ++ VTermScreen *screen = user; ++ int col; ++ VTermRect rect; ++ ++ if(newinfo->doublewidth != oldinfo->doublewidth || ++ newinfo->doubleheight != oldinfo->doubleheight) { ++ for(col = 0; col < screen->cols; col++) { ++ ScreenCell *cell = getcell(screen, row, col); ++ cell->pen.dwl = newinfo->doublewidth; ++ cell->pen.dhl = newinfo->doubleheight; ++ } ++ ++ rect.start_row = row; ++ rect.end_row = row + 1; ++ rect.start_col = 0; ++ rect.end_col = newinfo->doublewidth ? screen->cols / 2 : screen->cols; ++ damagerect(screen, rect); ++ ++ if(newinfo->doublewidth) { ++ rect.start_col = screen->cols / 2; ++ rect.end_col = screen->cols; ++ ++ erase_internal(rect, 0, user); ++ } ++ } ++ ++ return 1; ++} ++ ++static VTermStateCallbacks state_cbs = { ++ &putglyph, /* putglyph */ ++ &movecursor, /* movecursor */ ++ &scrollrect, /* scrollrect */ ++ NULL, /* moverect */ ++ &erase, /* erase */ ++ NULL, /* initpen */ ++ &setpenattr, /* setpenattr */ ++ &settermprop, /* settermprop */ ++ &bell, /* bell */ ++ &resize, /* resize */ ++ &setlineinfo /* setlineinfo */ ++}; ++ ++static VTermScreen *screen_new(VTerm *vt) ++{ ++ VTermState *state = vterm_obtain_state(vt); ++ VTermScreen *screen; ++ int rows, cols; ++ ++ if(!state) ++ return NULL; ++ ++ screen = vterm_allocator_malloc(vt, sizeof(VTermScreen)); ++ ++ vterm_get_size(vt, &rows, &cols); ++ ++ screen->vt = vt; ++ screen->state = state; ++ ++ screen->damage_merge = VTERM_DAMAGE_CELL; ++ screen->damaged.start_row = -1; ++ screen->pending_scrollrect.start_row = -1; ++ ++ screen->rows = rows; ++ screen->cols = cols; ++ ++ screen->callbacks = NULL; ++ screen->cbdata = NULL; ++ ++ screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols); ++ ++ screen->buffer = screen->buffers[0]; ++ ++ screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * cols); ++ ++ vterm_state_set_callbacks(screen->state, &state_cbs, screen); ++ ++ return screen; ++} ++ ++INTERNAL void vterm_screen_free(VTermScreen *screen) ++{ ++ vterm_allocator_free(screen->vt, screen->buffers[0]); ++ if(screen->buffers[1]) ++ vterm_allocator_free(screen->vt, screen->buffers[1]); ++ ++ vterm_allocator_free(screen->vt, screen->sb_buffer); ++ ++ vterm_allocator_free(screen->vt, screen); ++} ++ ++void vterm_screen_reset(VTermScreen *screen, int hard) ++{ ++ screen->damaged.start_row = -1; ++ screen->pending_scrollrect.start_row = -1; ++ vterm_state_reset(screen->state, hard); ++ vterm_screen_flush_damage(screen); ++} ++ ++static size_t _get_chars(const VTermScreen *screen, const int utf8, void *buffer, size_t len, const VTermRect rect) ++{ ++ size_t outpos = 0; ++ int padding = 0; ++ int row, col; ++ ++#define PUT(c) \ ++ if(utf8) { \ ++ size_t thislen = utf8_seqlen(c); \ ++ if(buffer && outpos + thislen <= len) \ ++ outpos += fill_utf8((c), (char *)buffer + outpos); \ ++ else \ ++ outpos += thislen; \ ++ } \ ++ else { \ ++ if(buffer && outpos + 1 <= len) \ ++ ((uint32_t*)buffer)[outpos++] = (c); \ ++ else \ ++ outpos++; \ ++ } ++ ++ for(row = rect.start_row; row < rect.end_row; row++) { ++ for(col = rect.start_col; col < rect.end_col; col++) { ++ ScreenCell *cell = getcell(screen, row, col); ++ int i; ++ ++ if(cell->chars[0] == 0) ++ // Erased cell, might need a space ++ padding++; ++ else if(cell->chars[0] == (uint32_t)-1) ++ // Gap behind a double-width char, do nothing ++ ; ++ else { ++ while(padding) { ++ PUT(UNICODE_SPACE); ++ padding--; ++ } ++ for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && cell->chars[i]; i++) { ++ PUT(cell->chars[i]); ++ } ++ } ++ } ++ ++ if(row < rect.end_row - 1) { ++ PUT(UNICODE_LINEFEED); ++ padding = 0; ++ } ++ } ++ ++ return outpos; ++} ++ ++size_t vterm_screen_get_chars(const VTermScreen *screen, uint32_t *chars, size_t len, const VTermRect rect) ++{ ++ return _get_chars(screen, 0, chars, len, rect); ++} ++ ++size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, const VTermRect rect) ++{ ++ return _get_chars(screen, 1, str, len, rect); ++} ++ ++/* Copy internal to external representation of a screen cell */ ++int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell) ++{ ++ ScreenCell *intcell = getcell(screen, pos.row, pos.col); ++ int i; ++ ++ if(!intcell) ++ return 0; ++ ++ for(i = 0; ; i++) { ++ cell->chars[i] = intcell->chars[i]; ++ if(!intcell->chars[i]) ++ break; ++ } ++ ++ cell->attrs.bold = intcell->pen.bold; ++ cell->attrs.underline = intcell->pen.underline; ++ cell->attrs.italic = intcell->pen.italic; ++ cell->attrs.blink = intcell->pen.blink; ++ cell->attrs.reverse = intcell->pen.reverse ^ screen->global_reverse; ++ cell->attrs.strike = intcell->pen.strike; ++ cell->attrs.font = intcell->pen.font; ++ ++ cell->attrs.dwl = intcell->pen.dwl; ++ cell->attrs.dhl = intcell->pen.dhl; ++ ++ cell->fg = intcell->pen.fg; ++ cell->bg = intcell->pen.bg; ++ ++ if(pos.col < (screen->cols - 1) && ++ getcell(screen, pos.row, pos.col + 1)->chars[0] == (uint32_t)-1) ++ cell->width = 2; ++ else ++ cell->width = 1; ++ ++ return 1; ++} ++ ++/* Copy external to internal representation of a screen cell */ ++/* static because it's only used internally for sb_popline during resize */ ++static int vterm_screen_set_cell(VTermScreen *screen, VTermPos pos, const VTermScreenCell *cell) ++{ ++ ScreenCell *intcell = getcell(screen, pos.row, pos.col); ++ int i; ++ ++ if(!intcell) ++ return 0; ++ ++ for(i = 0; ; i++) { ++ intcell->chars[i] = cell->chars[i]; ++ if(!cell->chars[i]) ++ break; ++ } ++ ++ intcell->pen.bold = cell->attrs.bold; ++ intcell->pen.underline = cell->attrs.underline; ++ intcell->pen.italic = cell->attrs.italic; ++ intcell->pen.blink = cell->attrs.blink; ++ intcell->pen.reverse = cell->attrs.reverse ^ screen->global_reverse; ++ intcell->pen.strike = cell->attrs.strike; ++ intcell->pen.font = cell->attrs.font; ++ ++ intcell->pen.fg = cell->fg; ++ intcell->pen.bg = cell->bg; ++ ++ if(cell->width == 2) ++ getcell(screen, pos.row, pos.col + 1)->chars[0] = (uint32_t)-1; ++ ++ return 1; ++} ++ ++int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos) ++{ ++ /* This cell is EOL if this and every cell to the right is black */ ++ for(; pos.col < screen->cols; pos.col++) { ++ ScreenCell *cell = getcell(screen, pos.row, pos.col); ++ if(cell->chars[0] != 0) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++VTermScreen *vterm_obtain_screen(VTerm *vt) ++{ ++ if(!vt->screen) ++ vt->screen = screen_new(vt); ++ return vt->screen; ++} ++ ++void vterm_screen_enable_altscreen(VTermScreen *screen, int altscreen) ++{ ++ ++ if(!screen->buffers[1] && altscreen) { ++ int rows, cols; ++ vterm_get_size(screen->vt, &rows, &cols); ++ ++ screen->buffers[1] = realloc_buffer(screen, NULL, rows, cols); ++ } ++} ++ ++void vterm_screen_set_callbacks(VTermScreen *screen, const VTermScreenCallbacks *callbacks, void *user) ++{ ++ screen->callbacks = callbacks; ++ screen->cbdata = user; ++} ++ ++void *vterm_screen_get_cbdata(VTermScreen *screen) ++{ ++ return screen->cbdata; ++} ++ ++void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermParserCallbacks *fallbacks, void *user) ++{ ++ vterm_state_set_unrecognised_fallbacks(screen->state, fallbacks, user); ++} ++ ++void *vterm_screen_get_unrecognised_fbdata(VTermScreen *screen) ++{ ++ return vterm_state_get_unrecognised_fbdata(screen->state); ++} ++ ++void vterm_screen_flush_damage(VTermScreen *screen) ++{ ++ if(screen->pending_scrollrect.start_row != -1) { ++ vterm_scroll_rect(screen->pending_scrollrect, screen->pending_scroll_downward, screen->pending_scroll_rightward, ++ moverect_user, erase_user, screen); ++ ++ screen->pending_scrollrect.start_row = -1; ++ } ++ ++ if(screen->damaged.start_row != -1) { ++ if(screen->callbacks && screen->callbacks->damage) ++ (*screen->callbacks->damage)(screen->damaged, screen->cbdata); ++ ++ screen->damaged.start_row = -1; ++ } ++} ++ ++void vterm_screen_set_damage_merge(VTermScreen *screen, VTermDamageSize size) ++{ ++ vterm_screen_flush_damage(screen); ++ screen->damage_merge = size; ++} ++ ++static int attrs_differ(VTermAttrMask attrs, ScreenCell *a, ScreenCell *b) ++{ ++ if((attrs & VTERM_ATTR_BOLD_MASK) && (a->pen.bold != b->pen.bold)) ++ return 1; ++ if((attrs & VTERM_ATTR_UNDERLINE_MASK) && (a->pen.underline != b->pen.underline)) ++ return 1; ++ if((attrs & VTERM_ATTR_ITALIC_MASK) && (a->pen.italic != b->pen.italic)) ++ return 1; ++ if((attrs & VTERM_ATTR_BLINK_MASK) && (a->pen.blink != b->pen.blink)) ++ return 1; ++ if((attrs & VTERM_ATTR_REVERSE_MASK) && (a->pen.reverse != b->pen.reverse)) ++ return 1; ++ if((attrs & VTERM_ATTR_STRIKE_MASK) && (a->pen.strike != b->pen.strike)) ++ return 1; ++ if((attrs & VTERM_ATTR_FONT_MASK) && (a->pen.font != b->pen.font)) ++ return 1; ++ if((attrs & VTERM_ATTR_FOREGROUND_MASK) && !vterm_color_equal(a->pen.fg, b->pen.fg)) ++ return 1; ++ if((attrs & VTERM_ATTR_BACKGROUND_MASK) && !vterm_color_equal(a->pen.bg, b->pen.bg)) ++ return 1; ++ ++ return 0; ++} ++ ++int vterm_screen_get_attrs_extent(const VTermScreen *screen, VTermRect *extent, VTermPos pos, VTermAttrMask attrs) ++{ ++ int col; ++ ++ ScreenCell *target = getcell(screen, pos.row, pos.col); ++ ++ // TODO: bounds check ++ extent->start_row = pos.row; ++ extent->end_row = pos.row + 1; ++ ++ if(extent->start_col < 0) ++ extent->start_col = 0; ++ if(extent->end_col < 0) ++ extent->end_col = screen->cols; ++ ++ for(col = pos.col - 1; col >= extent->start_col; col--) ++ if(attrs_differ(attrs, target, getcell(screen, pos.row, col))) ++ break; ++ extent->start_col = col + 1; ++ ++ for(col = pos.col + 1; col < extent->end_col; col++) ++ if(attrs_differ(attrs, target, getcell(screen, pos.row, col))) ++ break; ++ extent->end_col = col - 1; ++ ++ return 1; ++} diff --git a/vim.spec b/vim.spec index 508ef4a..ed0c794 100644 --- a/vim.spec +++ b/vim.spec @@ -1,4 +1,4 @@ -%define patchlevel 351 +%define patchlevel 408 %if %{?WITH_SELINUX:0}%{!?WITH_SELINUX:1} %define WITH_SELINUX 1 %endif @@ -67,6 +67,8 @@ Patch3014: vim-7.4-releasestring-1318991.patch Patch3016: vim-8.0-copy-paste.patch # migrate shebangs in script to /usr/bin/python3 and use python2 when necessary Patch3017: vim-python3-tests.patch +# reported upstream https://github.com/vim/vim/pull/3449 - missing file +Patch3018: vim-missing-file.patch # gcc is no longer in buildroot by default BuildRequires: gcc @@ -257,6 +259,7 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk %patch3014 -p1 %patch3016 -p1 %patch3017 -p1 +%patch3018 -p1 %build %if 0%{?rhel} > 7 @@ -795,6 +798,10 @@ touch %{buildroot}/%{_datadir}/%{name}/vimfiles/doc/tags %{_datadir}/icons/locolor/*/apps/* %changelog +* Wed Sep 19 2018 Zdenek Dohnal - 2:8.1.408-1 +- patchlevel 408 +- src/libvterm/src/termscreen.c is missing + * Fri Sep 07 2018 Zdenek Dohnal - 2:8.1.351-1 - patchlevel 351