comparison src/libvterm/src/screen.c @ 20518:a4652d7ec99f v8.2.0813

patch 8.2.0813: libvterm code is slightly different from upstream Commit: https://github.com/vim/vim/commit/591cec8366e87a172495c362477cbf5de8d399f0 Author: Bram Moolenaar <Bram@vim.org> Date: Fri May 22 22:06:06 2020 +0200 patch 8.2.0813: libvterm code is slightly different from upstream Problem: libvterm code is slightly different from upstream. Solution: Use upstream text to avoid future merge problems. Mainly comment style changes.
author Bram Moolenaar <Bram@vim.org>
date Fri, 22 May 2020 22:15:04 +0200
parents 03826c672315
children 88cec48503b8
comparison
equal deleted inserted replaced
20517:a7c6cd0d7ba0 20518:a4652d7ec99f
8 #include "utf8.h" 8 #include "utf8.h"
9 9
10 #define UNICODE_SPACE 0x20 10 #define UNICODE_SPACE 0x20
11 #define UNICODE_LINEFEED 0x0a 11 #define UNICODE_LINEFEED 0x0a
12 12
13 // State of the pen at some moment in time, also used in a cell 13 /* State of the pen at some moment in time, also used in a cell */
14 typedef struct 14 typedef struct
15 { 15 {
16 // After the bitfield 16 /* After the bitfield */
17 VTermColor fg, bg; 17 VTermColor fg, bg;
18 18
19 unsigned int bold : 1; 19 unsigned int bold : 1;
20 unsigned int underline : 2; 20 unsigned int underline : 2;
21 unsigned int italic : 1; 21 unsigned int italic : 1;
22 unsigned int blink : 1; 22 unsigned int blink : 1;
23 unsigned int reverse : 1; 23 unsigned int reverse : 1;
24 unsigned int conceal : 1; 24 unsigned int conceal : 1;
25 unsigned int strike : 1; 25 unsigned int strike : 1;
26 unsigned int font : 4; // 0 to 9 26 unsigned int font : 4; /* 0 to 9 */
27 27
28 // Extra state storage that isn't strictly pen-related 28 /* Extra state storage that isn't strictly pen-related */
29 unsigned int protected_cell : 1; 29 unsigned int protected_cell : 1;
30 unsigned int dwl : 1; // on a DECDWL or DECDHL line 30 unsigned int dwl : 1; /* on a DECDWL or DECDHL line */
31 unsigned int dhl : 2; // on a DECDHL line (1=top 2=bottom) 31 unsigned int dhl : 2; /* on a DECDHL line (1=top 2=bottom) */
32 } ScreenPen; 32 } ScreenPen;
33 33
34 // Internal representation of a screen cell 34 /* Internal representation of a screen cell */
35 typedef struct 35 typedef struct
36 { 36 {
37 uint32_t chars[VTERM_MAX_CHARS_PER_CELL]; 37 uint32_t chars[VTERM_MAX_CHARS_PER_CELL];
38 ScreenPen pen; 38 ScreenPen pen;
39 } ScreenCell; 39 } ScreenCell;
45 45
46 const VTermScreenCallbacks *callbacks; 46 const VTermScreenCallbacks *callbacks;
47 void *cbdata; 47 void *cbdata;
48 48
49 VTermDamageSize damage_merge; 49 VTermDamageSize damage_merge;
50 // start_row == -1 => no damage 50 /* start_row == -1 => no damage */
51 VTermRect damaged; 51 VTermRect damaged;
52 VTermRect pending_scrollrect; 52 VTermRect pending_scrollrect;
53 int pending_scroll_downward, pending_scroll_rightward; 53 int pending_scroll_downward, pending_scroll_rightward;
54 54
55 int rows; 55 int rows;
56 int cols; 56 int cols;
57 int global_reverse; 57 int global_reverse;
58 58
59 // Primary and Altscreen. buffers[1] is lazily allocated as needed 59 /* Primary and Altscreen. buffers[1] is lazily allocated as needed */
60 ScreenCell *buffers[2]; 60 ScreenCell *buffers[2];
61 61
62 // buffer will == buffers[0] or buffers[1], depending on altscreen 62 /* buffer will == buffers[0] or buffers[1], depending on altscreen */
63 ScreenCell *buffer; 63 ScreenCell *buffer;
64 64
65 // buffer for a single screen row used in scrollback storage callbacks 65 /* buffer for a single screen row used in scrollback storage callbacks */
66 VTermScreenCell *sb_buffer; 66 VTermScreenCell *sb_buffer;
67 67
68 ScreenPen pen; 68 ScreenPen pen;
69 }; 69 };
70 70
104 { 104 {
105 VTermRect emit; 105 VTermRect emit;
106 106
107 switch(screen->damage_merge) { 107 switch(screen->damage_merge) {
108 case VTERM_DAMAGE_CELL: 108 case VTERM_DAMAGE_CELL:
109 // Always emit damage event 109 /* Always emit damage event */
110 emit = rect; 110 emit = rect;
111 break; 111 break;
112 112
113 case VTERM_DAMAGE_ROW: 113 case VTERM_DAMAGE_ROW:
114 // Emit damage longer than one row. Try to merge with existing damage in 114 /* Emit damage longer than one row. Try to merge with existing damage in
115 // the same row 115 * the same row */
116 if(rect.end_row > rect.start_row + 1) { 116 if(rect.end_row > rect.start_row + 1) {
117 // Bigger than 1 line - flush existing, emit this 117 // Bigger than 1 line - flush existing, emit this
118 vterm_screen_flush_damage(screen); 118 vterm_screen_flush_damage(screen);
119 emit = rect; 119 emit = rect;
120 } 120 }
138 } 138 }
139 break; 139 break;
140 140
141 case VTERM_DAMAGE_SCREEN: 141 case VTERM_DAMAGE_SCREEN:
142 case VTERM_DAMAGE_SCROLL: 142 case VTERM_DAMAGE_SCROLL:
143 // Never emit damage event 143 /* Never emit damage event */
144 if(screen->damaged.start_row == -1) 144 if(screen->damaged.start_row == -1)
145 screen->damaged = rect; 145 screen->damaged = rect;
146 else { 146 else {
147 rect_expand(&screen->damaged, &rect); 147 rect_expand(&screen->damaged, &rect);
148 } 148 }
353 353
354 if(screen->damaged.start_row == -1) 354 if(screen->damaged.start_row == -1)
355 return 1; 355 return 1;
356 356
357 if(rect_contains(&rect, &screen->damaged)) { 357 if(rect_contains(&rect, &screen->damaged)) {
358 // Scroll region entirely contains the damage; just move it 358 /* Scroll region entirely contains the damage; just move it */
359 vterm_rect_move(&screen->damaged, -downward, -rightward); 359 vterm_rect_move(&screen->damaged, -downward, -rightward);
360 rect_clip(&screen->damaged, &rect); 360 rect_clip(&screen->damaged, &rect);
361 } 361 }
362 // There are a number of possible cases here, but lets restrict this to only 362 /* There are a number of possible cases here, but lets restrict this to only
363 // the common case where we might actually gain some performance by 363 * the common case where we might actually gain some performance by
364 // optimising it. Namely, a vertical scroll that neatly cuts the damage 364 * optimising it. Namely, a vertical scroll that neatly cuts the damage
365 // region in half. 365 * region in half.
366 */
366 else if(rect.start_col <= screen->damaged.start_col && 367 else if(rect.start_col <= screen->damaged.start_col &&
367 rect.end_col >= screen->damaged.end_col && 368 rect.end_col >= screen->damaged.end_col &&
368 rightward == 0) { 369 rightward == 0) {
369 if(screen->damaged.start_row >= rect.start_row && 370 if(screen->damaged.start_row >= rect.start_row &&
370 screen->damaged.start_row < rect.end_row) { 371 screen->damaged.start_row < rect.end_row) {
452 case VTERM_PROP_ALTSCREEN: 453 case VTERM_PROP_ALTSCREEN:
453 if(val->boolean && !screen->buffers[BUFIDX_ALTSCREEN]) 454 if(val->boolean && !screen->buffers[BUFIDX_ALTSCREEN])
454 return 0; 455 return 0;
455 456
456 screen->buffer = val->boolean ? screen->buffers[BUFIDX_ALTSCREEN] : screen->buffers[BUFIDX_PRIMARY]; 457 screen->buffer = val->boolean ? screen->buffers[BUFIDX_ALTSCREEN] : screen->buffers[BUFIDX_PRIMARY];
457 // only send a damage event on disable; because during enable there's an 458 /* only send a damage event on disable; because during enable there's an
458 // erase that sends a damage anyway 459 * erase that sends a damage anyway
460 */
459 if(!val->boolean) 461 if(!val->boolean)
460 damagescreen(screen); 462 damagescreen(screen);
461 break; 463 break;
462 case VTERM_PROP_REVERSE: 464 case VTERM_PROP_REVERSE:
463 screen->global_reverse = val->boolean; 465 screen->global_reverse = val->boolean;
464 damagescreen(screen); 466 damagescreen(screen);
465 break; 467 break;
466 default: 468 default:
467 ; // ignore 469 ; /* ignore */
468 } 470 }
469 471
470 if(screen->callbacks && screen->callbacks->settermprop) 472 if(screen->callbacks && screen->callbacks->settermprop)
471 return (*screen->callbacks->settermprop)(prop, val, screen->cbdata); 473 return (*screen->callbacks->settermprop)(prop, val, screen->cbdata);
472 474
489 int old_cols = screen->cols; 491 int old_cols = screen->cols;
490 492
491 ScreenCell *old_buffer = screen->buffers[bufidx]; 493 ScreenCell *old_buffer = screen->buffers[bufidx];
492 ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols); 494 ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols);
493 495
494 /* Find the final row of old buffer content */ 496 // Find the final row of old buffer content
495 int old_row = old_rows - 1; 497 int old_row = old_rows - 1;
496 int new_row = new_rows - 1; 498 int new_row = new_rows - 1;
497 int col; 499 int col;
498 500
499 while(new_row >= 0 && old_row >= 0) { 501 while(new_row >= 0 && old_row >= 0) {
571 /* Scroll new rows back up to the top and fill in blanks at the bottom */ 573 /* Scroll new rows back up to the top and fill in blanks at the bottom */
572 int moverows = new_rows - new_row - 1; 574 int moverows = new_rows - new_row - 1;
573 memmove(&new_buffer[0], &new_buffer[(new_row + 1) * new_cols], moverows * new_cols * sizeof(ScreenCell)); 575 memmove(&new_buffer[0], &new_buffer[(new_row + 1) * new_cols], moverows * new_cols * sizeof(ScreenCell));
574 576
575 for(new_row = moverows; new_row < new_rows; new_row++) 577 for(new_row = moverows; new_row < new_rows; new_row++)
576 {
577 for(col = 0; col < new_cols; col++) 578 for(col = 0; col < new_cols; col++)
578 clearcell(screen, &new_buffer[new_row * new_cols + col]); 579 clearcell(screen, &new_buffer[new_row * new_cols + col]);
579 }
580 } 580 }
581 581
582 vterm_allocator_free(screen->vt, old_buffer); 582 vterm_allocator_free(screen->vt, old_buffer);
583 screen->buffers[bufidx] = new_buffer; 583 screen->buffers[bufidx] = new_buffer;
584 584
727 vterm_allocator_free(screen->vt, screen->buffers[BUFIDX_PRIMARY]); 727 vterm_allocator_free(screen->vt, screen->buffers[BUFIDX_PRIMARY]);
728 if(screen->buffers[BUFIDX_ALTSCREEN]) 728 if(screen->buffers[BUFIDX_ALTSCREEN])
729 vterm_allocator_free(screen->vt, screen->buffers[BUFIDX_ALTSCREEN]); 729 vterm_allocator_free(screen->vt, screen->buffers[BUFIDX_ALTSCREEN]);
730 730
731 vterm_allocator_free(screen->vt, screen->sb_buffer); 731 vterm_allocator_free(screen->vt, screen->sb_buffer);
732
732 vterm_allocator_free(screen->vt, screen); 733 vterm_allocator_free(screen->vt, screen);
733 } 734 }
734 735
735 void vterm_screen_reset(VTermScreen *screen, int hard) 736 void vterm_screen_reset(VTermScreen *screen, int hard)
736 { 737 {
800 size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, const VTermRect rect) 801 size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, const VTermRect rect)
801 { 802 {
802 return _get_chars(screen, 1, str, len, rect); 803 return _get_chars(screen, 1, str, len, rect);
803 } 804 }
804 805
805 // Copy internal to external representation of a screen cell 806 /* Copy internal to external representation of a screen cell */
806 int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell) 807 int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell)
807 { 808 {
808 ScreenCell *intcell = getcell(screen, pos.row, pos.col); 809 ScreenCell *intcell = getcell(screen, pos.row, pos.col);
809 int i; 810 int i;
810 811
858 return 1; 859 return 1;
859 } 860 }
860 861
861 int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos) 862 int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos)
862 { 863 {
863 // This cell is EOL if this and every cell to the right is black 864 /* This cell is EOL if this and every cell to the right is black */
864 for(; pos.col < screen->cols; pos.col++) { 865 for(; pos.col < screen->cols; pos.col++) {
865 ScreenCell *cell = getcell(screen, pos.row, pos.col); 866 ScreenCell *cell = getcell(screen, pos.row, pos.col);
866 if(cell->chars[0] != 0) 867 if(cell->chars[0] != 0)
867 return 0; 868 return 0;
868 } 869 }