summaryrefslogtreecommitdiffstats
path: root/src/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/screen.c b/src/screen.c
index db11c6d..c4de59e 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -25,6 +25,8 @@ typedef struct
/* 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 */
@@ -194,6 +196,8 @@ static int putglyph(VTermGlyphInfo *info, VTermPos pos, void *user)
};
cell->pen.protected_cell = info->protected_cell;
+ cell->pen.dwl = info->dwl;
+ cell->pen.dhl = info->dhl;
damagerect(screen, rect);
@@ -262,7 +266,9 @@ static int erase_internal(VTermRect rect, int selective, void *user)
{
VTermScreen *screen = user;
- for(int row = rect.start_row; row < rect.end_row; row++)
+ for(int row = rect.start_row; row < rect.end_row; row++) {
+ const VTermLineInfo *info = vterm_state_get_lineinfo(screen->state, row);
+
for(int col = rect.start_col; col < rect.end_col; col++) {
ScreenCell *cell = getcell(screen, row, col);
@@ -271,7 +277,10 @@ static int erase_internal(VTermRect rect, int selective, void *user)
cell->chars[0] = 0;
cell->pen = screen->pen;
+ cell->pen.dwl = info->doublewidth;
+ cell->pen.dhl = info->doubleheight;
}
+ }
return 1;
}
@@ -568,6 +577,37 @@ static int resize(int new_rows, int new_cols, VTermPos *delta, void *user)
return 1;
}
+static int setlineinfo(int row, const VTermLineInfo *newinfo, const VTermLineInfo *oldinfo, void *user)
+{
+ VTermScreen *screen = user;
+
+ if(newinfo->doublewidth != oldinfo->doublewidth ||
+ newinfo->doubleheight != oldinfo->doubleheight) {
+ for(int col = 0; col < screen->cols; col++) {
+ ScreenCell *cell = getcell(screen, row, col);
+ cell->pen.dwl = newinfo->doublewidth;
+ cell->pen.dhl = newinfo->doubleheight;
+ }
+
+ VTermRect rect = {
+ .start_row = row,
+ .end_row = row + 1,
+ .start_col = 0,
+ .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,
@@ -578,6 +618,7 @@ static VTermStateCallbacks state_cbs = {
.setmousefunc = &setmousefunc,
.bell = &bell,
.resize = &resize,
+ .setlineinfo = &setlineinfo,
};
static VTermScreen *screen_new(VTerm *vt)
@@ -612,7 +653,7 @@ static VTermScreen *screen_new(VTerm *vt)
return screen;
}
-void vterm_screen_free(VTermScreen *screen)
+INTERNAL void vterm_screen_free(VTermScreen *screen)
{
vterm_allocator_free(screen->vt, screen->buffers[0]);
if(screen->buffers[1])
@@ -712,6 +753,9 @@ int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCe
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;