Mercurial > vim
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 } |