From 2eebf9b8cc1fa384e4972ad470eeca1b6f4c16ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:20:47 +0200 Subject: [PATCH 01/11] csi: break out decset/decrst --- csi.c | 480 +++++++++++++++++++++++++--------------------------------- 1 file changed, 206 insertions(+), 274 deletions(-) diff --git a/csi.c b/csi.c index 21a94625..873d45a7 100644 --- a/csi.c +++ b/csi.c @@ -321,6 +321,204 @@ csi_sgr(struct terminal *term) } } +static void +decset_decrst(struct terminal *term, unsigned param, bool enable) +{ +#if defined(_DEBUG) + /* For UNHANDLED() */ + int UNUSED final = enable ? 'h' : 'l'; +#endif + + switch (param) { + case 1: + term->cursor_keys_mode = + enable ? CURSOR_KEYS_APPLICATION : CURSOR_KEYS_NORMAL; + break; + + case 3: + if (enable) + LOG_WARN("unimplemented: 132 column mode (DECCOLM)"); + + term_erase( + term, + &(struct coord){0, 0}, + &(struct coord){term->cols - 1, term->rows - 1}); + term_cursor_home(term); + break; + + case 4: + /* DECSCLM - Smooth scroll */ + if (enable) + LOG_WARN("unimplemented: Smooth (Slow) Scroll (DECSCLM)"); + break; + + case 5: + term->reverse = enable; + term_damage_all(term); + break; + + case 6: { /* DECOM */ + term->origin = enable ? ORIGIN_RELATIVE : ORIGIN_ABSOLUTE; + term_cursor_home(term); + break; + } + + case 7: + /* DECAWM */ + term->auto_margin = enable; + term->grid->cursor.lcf = false; + break; + + case 9: + if (enable) + LOG_WARN("unimplemented: X10 mouse tracking mode"); + else + term->mouse_tracking = MOUSE_NONE; + break; + + case 12: + if (enable) + term_cursor_blink_enable(term); + else + term_cursor_blink_disable(term); + break; + + case 25: + term->hide_cursor = !enable; + break; + + case 1000: + term->mouse_tracking = enable ? MOUSE_CLICK : MOUSE_NONE; + term_xcursor_update(term); + break; + + case 1001: + if (enable) + LOG_WARN("unimplemented: highlight mouse tracking"); + break; + + case 1002: + term->mouse_tracking = enable ? MOUSE_DRAG : MOUSE_NONE; + term_xcursor_update(term); + break; + + case 1003: + term->mouse_tracking = enable ? MOUSE_MOTION : MOUSE_NONE; + term_xcursor_update(term); + break; + + case 1004: + term->focus_events = enable; + break; + + case 1005: + if (enable) + LOG_WARN("unimplemented: mouse reporting mode: UTF-8"); + else + term->mouse_reporting = MOUSE_NONE; + break; + + case 1006: + if (enable) + LOG_DBG("mouse reporting mode: SGR"); + term->mouse_reporting = enable ? MOUSE_SGR : MOUSE_NORMAL; + break; + + case 1007: + term->alt_scrolling = enable; + break; + + case 1015: + if (enable) + LOG_DBG("mouse reporting mode: urxvt"); + term->mouse_reporting = enable ? MOUSE_URXVT : MOUSE_NORMAL; + break; + + case 1034: + /* smm */ + LOG_DBG("%s 8-bit meta mode", enable ? "enabling" : "disabling"); + term->meta.eight_bit = enable; + break; + + case 1036: + /* metaSendsEscape */ + LOG_DBG("%s meta-sends-escape", enable ? "enabling" : "disabling"); + term->meta.esc_prefix = enable; + break; + +#if 0 + case 1042: + LOG_WARN("unimplemented: 'urgency' window manager hint on ctrl-g"); + break; + + case 1043: + LOG_WARN("unimplemented: raise window on ctrl-g"); + break; +#endif + + case 1049: + if (enable && term->grid != &term->alt) { + selection_cancel(term); + + term->grid = &term->alt; + + term_cursor_to( + term, + min(term->grid->cursor.point.row, term->rows - 1), + min(term->grid->cursor.point.col, term->cols - 1)); + + tll_free(term->alt.scroll_damage); + + term_erase( + term, + &(struct coord){0, 0}, + &(struct coord){term->cols - 1, term->rows - 1}); + } + + else if (!enable && term->grid == &term->alt) { + selection_cancel(term); + + term->grid = &term->normal; + + term_cursor_to( + term, + min(term->grid->cursor.point.row, term->rows - 1), + min(term->grid->cursor.point.col, term->cols - 1)); + + tll_free(term->alt.scroll_damage); + + /* Delete all sixel images on the alt screen */ + tll_foreach(term->alt.sixel_images, it) { + sixel_destroy(&it->item); + tll_remove(term->alt.sixel_images, it); + } + + term_damage_all(term); + } + break; + + case 2004: + term->bracketed_paste = enable; + break; + + default: + UNHANDLED(); + break; + } +} + +static void +decset(struct terminal *term, unsigned param) +{ + decset_decrst(term, param, true); +} + +static void +decrst(struct terminal *term, unsigned param) +{ + deecset_decrst(term, param, false); +} + void csi_dispatch(struct terminal *term, uint8_t final) { @@ -1008,283 +1206,17 @@ csi_dispatch(struct terminal *term, uint8_t final) case '?': { switch (final) { - case 'h': { - for (size_t i = 0; i < term->vt.params.idx; i++) { - switch (term->vt.params.v[i].value) { - case 1: - term->cursor_keys_mode = CURSOR_KEYS_APPLICATION; - break; - - case 3: - LOG_WARN("unimplemented: 132 column mode (DECCOLM, %s)", - csi_as_string(term, final, i)); - term_erase( - term, - &(struct coord){0, 0}, - &(struct coord){term->cols - 1, term->rows - 1}); - term_cursor_home(term); - break; - - case 4: - /* DECSCLM - Smooth scroll */ - LOG_WARN("unimplemented: Smooth (Slow) Scroll (DECSCLM, %s)", - csi_as_string(term, final, i)); - break; - - case 5: - term->reverse = true; - term_damage_all(term); - break; - - case 6: { /* DECOM */ - term->origin = ORIGIN_RELATIVE; - term_cursor_home(term); - break; - } - - case 7: - /* DECAWM */ - term->auto_margin = true; - term->grid->cursor.lcf = false; - break; - - case 9: - LOG_WARN("unimplemented: X10 mouse tracking mode"); - /* term->mouse_tracking = MOUSE_X10; */ - break; - - case 12: - term_cursor_blink_enable(term); - break; - - case 25: - term->hide_cursor = false; - break; - - case 1000: - term->mouse_tracking = MOUSE_CLICK; - term_xcursor_update(term); - break; - - case 1001: - LOG_WARN("unimplemented: highlight mouse tracking"); - break; - - case 1002: - term->mouse_tracking = MOUSE_DRAG; - term_xcursor_update(term); - break; - - case 1003: - term->mouse_tracking = MOUSE_MOTION; - term_xcursor_update(term); - break; - - case 1004: - term->focus_events = true; - break; - - case 1005: - LOG_WARN("unimplemented: mouse reporting mode: UTF-8"); - /* term->mouse_reporting = MOUSE_UTF8; */ - break; - - case 1006: - LOG_DBG("mouse reporting mode: SGR"); - term->mouse_reporting = MOUSE_SGR; - break; - - case 1007: - term->alt_scrolling = true; - break; - - case 1015: - LOG_DBG("mouse reporting mode: urxvt"); - term->mouse_reporting = MOUSE_URXVT; - break; - - case 1034: - /* smm */ - LOG_DBG("enabling 8-bit meta mode"); - term->meta.eight_bit = true; - break; - - case 1036: - /* metaSendsEscape */ - LOG_DBG("enabling meta-sends-escape"); - term->meta.esc_prefix = true; - break; - -#if 0 - case 1042: - LOG_WARN("unimplemented: 'urgency' window manager hint on ctrl-g"); - break; - - case 1043: - LOG_WARN("unimplemented: raise window on ctrl-g"); - break; -#endif - - case 1049: - if (term->grid != &term->alt) { - selection_cancel(term); - - term->grid = &term->alt; - - term_cursor_to( - term, - min(term->grid->cursor.point.row, term->rows - 1), - min(term->grid->cursor.point.col, term->cols - 1)); - - tll_free(term->alt.scroll_damage); - - term_erase( - term, - &(struct coord){0, 0}, - &(struct coord){term->cols - 1, term->rows - 1}); - } - break; - - case 2004: - term->bracketed_paste = true; - break; - - default: - UNHANDLED(); - break; - } - } + case 'h': + /* DECSET - DEC private mode set */ + for (size_t i = 0; i < term->vt.params.idx; i++) + decset(term, term->vt.params.v[i].value); break; - } - case 'l': { - for (size_t i = 0; i < term->vt.params.idx; i++) { - switch (term->vt.params.v[i].value) { - case 1: - term->cursor_keys_mode = CURSOR_KEYS_NORMAL; - break; - - case 3: - /* DECCOLM - 80 column mode */ - term_erase( - term, - &(struct coord){0, 0}, - &(struct coord){term->cols - 1, term->rows - 1}); - term_cursor_home(term); - break; - - case 4: - /* DECSCLM - Jump scroll */ - break; - - case 5: - term->reverse = false; - term_damage_all(term); - break; - - case 6: { /* DECOM */ - term->origin = ORIGIN_ABSOLUTE; - term_cursor_home(term); - break; - } - - case 7: - /* DECAWM */ - term->auto_margin = false; - term->grid->cursor.lcf = false; - break; - - case 12: - term_cursor_blink_disable(term); - break; - - case 25: - term->hide_cursor = true; - break; - - case 1001: - /* Highlight mouse tracking */ - break; - - case 9: /* MOUSE_X10 */ - case 1000: /* MOUSE_NORMAL */ - case 1002: /* MOUSE_BUTTON_EVENT */ - case 1003: /* MOUSE_ANY_EVENT */ - term->mouse_tracking = MOUSE_NONE; - term_xcursor_update(term); - break; - - case 1005: /* MOUSE_UTF8 */ - case 1006: /* MOUSE_SGR */ - case 1015: /* MOUSE_URXVT */ - LOG_DBG("mouse reporting mode: legacy"); - term->mouse_reporting = MOUSE_NORMAL; - break; - - case 1004: - term->focus_events = false; - break; - - case 1007: - term->alt_scrolling = false; - break; - - case 1034: - /* rmm */ - LOG_DBG("disabling 8-bit meta mode"); - term->meta.eight_bit = false; - break; - - case 1036: - /* metaSendsEscape */ - LOG_DBG("disabling meta-sends-escape"); - term->meta.esc_prefix = false; - break; - -#if 0 - case 1042: - /* 'urgency' window manager hint on ctrl-g */ - break; - - case 1043: - /* raise window on ctrl-g */ - break; -#endif - - case 1049: - if (term->grid == &term->alt) { - selection_cancel(term); - - term->grid = &term->normal; - - term_cursor_to( - term, - min(term->grid->cursor.point.row, term->rows - 1), - min(term->grid->cursor.point.col, term->cols - 1)); - - tll_free(term->alt.scroll_damage); - - /* Delete all sixel images on the alt screen */ - tll_foreach(term->alt.sixel_images, it) { - sixel_destroy(&it->item); - tll_remove(term->alt.sixel_images, it); - } - - term_damage_all(term); - } - break; - - case 2004: - term->bracketed_paste = false; - break; - - default: - UNHANDLED(); - break; - } - } + case 'l': + /* DECRST - DEC private mode reset */ + for (size_t i = 0; i < term->vt.params.idx; i++) + decrst(term, term->vt.params.v[i].value); break; - } case 'p': { if (term->vt.private[1] != '$') { From cf315de174ffb851b7d794aae1b38ad5c2467560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:25:52 +0200 Subject: [PATCH 02/11] csi: add DEC names to a couple of DECSET modes --- csi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/csi.c b/csi.c index 873d45a7..e4c3ca9a 100644 --- a/csi.c +++ b/csi.c @@ -331,11 +331,13 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) switch (param) { case 1: + /* DECCKM */ term->cursor_keys_mode = enable ? CURSOR_KEYS_APPLICATION : CURSOR_KEYS_NORMAL; break; case 3: + /* DECCOLM */ if (enable) LOG_WARN("unimplemented: 132 column mode (DECCOLM)"); @@ -353,11 +355,13 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) break; case 5: + /* DECSCNM */ term->reverse = enable; term_damage_all(term); break; - case 6: { /* DECOM */ + case 6: { + /* DECOM */ term->origin = enable ? ORIGIN_RELATIVE : ORIGIN_ABSOLUTE; term_cursor_home(term); break; @@ -384,6 +388,7 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) break; case 25: + /* DECTCEM */ term->hide_cursor = !enable; break; From 07870800230bc3fa82c6540ebdc2d9f0a2204ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:38:30 +0200 Subject: [PATCH 03/11] csi: decrst: spell decset correctly --- csi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csi.c b/csi.c index e4c3ca9a..3337e7fd 100644 --- a/csi.c +++ b/csi.c @@ -521,7 +521,7 @@ decset(struct terminal *term, unsigned param) static void decrst(struct terminal *term, unsigned param) { - deecset_decrst(term, param, false); + decset_decrst(term, param, false); } void From 55938684711fa31d59479a74026f4b36a6b169b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:38:57 +0200 Subject: [PATCH 04/11] csi: add xtsave() This function stores the current state of DECSET private modes. --- csi.c | 31 +++++++++++++++++++++++++++++++ terminal.h | 33 +++++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/csi.c b/csi.c index 3337e7fd..497b82f4 100644 --- a/csi.c +++ b/csi.c @@ -329,6 +329,8 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) int UNUSED final = enable ? 'h' : 'l'; #endif + /* Note: update XTSAVE/XTRESTORE if adding/removing things here */ + switch (param) { case 1: /* DECCKM */ @@ -524,6 +526,35 @@ decrst(struct terminal *term, unsigned param) decset_decrst(term, param, false); } +static void +xtsave(struct terminal *term, unsigned param) +{ + switch (param) { + case 1: term->xtsave.cursor_keys_mode = term->cursor_keys_mode; break; + case 3: break; + case 4: break; + case 5: term->xtsave.reverse = term->reverse; break; + case 6: term->xtsave.origin = term->origin; break; + case 7: term->xtsave.auto_margin = term->auto_margin; break; + case 9: if (term->mouse_tracking == MOUSE_X10) term->xtsave.mouse_tracking = MOUSE_X10; break; + case 12: break; + case 25: term->xtsave.hide_cursor = term->hide_cursor; break; + case 1000: if (term->mouse_tracking == MOUSE_CLICK) term->xtsave.mouse_tracking = MOUSE_CLICK; break; + case 1001: break; + case 1002: if (term->mouse_tracking == MOUSE_DRAG) term->xtsave.mouse_tracking = MOUSE_DRAG; break; + case 1003: if (term->mouse_tracking == MOUSE_MOTION) term->xtsave.mouse_tracking = MOUSE_MOTION; break; + case 1004: term->xtsave.focus_events = term->focus_events; break; + case 1005: /* if (term->mouse_reporting == MOUSE_UTF8) term->xtsave.mouse_reporting = MOUSE_UTF8; break; */ + case 1006: if (term->mouse_reporting == MOUSE_SGR) term->xtsave.mouse_reporting = MOUSE_SGR; break; + case 1007: term->xtsave.alt_scrolling = term->alt_scrolling; break; + case 1015: if (term->mouse_reporting == MOUSE_URXVT) term->xtsave.mouse_reporting = MOUSE_URXVT; break; + case 1034: term->xtsave.meta.eight_bit = term->meta.eight_bit; break; + case 1036: term->xtsave.meta.esc_prefix = term->meta.esc_prefix; break; + case 1049: term->xtsave.alt_screen = term->grid == &term->alt; break; + case 2004: term->xtsave.bracketed_paste = term->bracketed_paste; break; + } +} + void csi_dispatch(struct terminal *term, uint8_t final) { diff --git a/terminal.h b/terminal.h index 983c80a0..22cea4bf 100644 --- a/terminal.h +++ b/terminal.h @@ -228,6 +228,7 @@ struct terminal { tll(struct ptmx_buffer) ptmx_buffer; + enum cursor_origin origin; enum cursor_keys cursor_keys_mode; enum keypad_keys keypad_keys_mode; bool reverse; @@ -240,6 +241,32 @@ struct terminal { enum mouse_tracking mouse_tracking; enum mouse_reporting mouse_reporting; + struct { + bool esc_prefix; + bool eight_bit; + } meta; + + /* Saved DECSET modes */ + struct { + enum cursor_origin origin; + enum cursor_keys cursor_keys_mode; + //enum keypad_keys keypad_keys_mode; + bool reverse; + bool hide_cursor; + bool auto_margin; + bool insert_mode; + bool bracketed_paste; + bool focus_events; + bool alt_scrolling; + enum mouse_tracking mouse_tracking; + enum mouse_reporting mouse_reporting; + struct { + bool esc_prefix; + bool eight_bit; + } meta; + bool alt_screen; + } xtsave; + struct charsets charsets; struct charsets saved_charsets; /* For save/restore cursor + attributes */ @@ -288,7 +315,6 @@ struct terminal { uint32_t default_table[256]; } colors; - enum cursor_origin origin; enum cursor_style default_cursor_style; enum cursor_style cursor_style; struct { @@ -328,11 +354,6 @@ struct terminal { size_t match_len; } search; - struct { - bool esc_prefix; - bool eight_bit; - } meta; - tll(int) tab_stops; struct wayland *wl; From cc48366f02cf371c9e2d6c5c8b661f763742ffcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:47:46 +0200 Subject: [PATCH 05/11] csi: implement CSI ? Pm s - XTSAVE --- csi.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/csi.c b/csi.c index 497b82f4..cd581c19 100644 --- a/csi.c +++ b/csi.c @@ -1278,22 +1278,8 @@ csi_dispatch(struct terminal *term, uint8_t final) } case 's': - for (size_t i = 0; i < term->vt.params.idx; i++) { - switch (term->vt.params.v[i].value) { -#if 0 /* We don't implement "highlight mouse tracking" */ - case 1001: /* save old highlight mouse tracking mode? */ - LOG_WARN( - "unimplemented: %s " - "(save 'highlight mouse tracking' mode)", - csi_as_string(term, final, i)); - break; -#endif - - default: - UNHANDLED(); - break; - } - } + for (size_t i = 0; i < term->vt.params.idx; i++) + xtsave(term, term->vt.params.v[i].value); break; case 'r': From b4f868e566954e6844bd74754782d0aca8bf4631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:57:39 +0200 Subject: [PATCH 06/11] csi: xtsave: store modes' SET state, not the current state --- csi.c | 22 +++++++++++----------- terminal.h | 25 ++++++++++++++----------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/csi.c b/csi.c index cd581c19..20790892 100644 --- a/csi.c +++ b/csi.c @@ -530,26 +530,26 @@ static void xtsave(struct terminal *term, unsigned param) { switch (param) { - case 1: term->xtsave.cursor_keys_mode = term->cursor_keys_mode; break; + case 1: term->xtsave.application_cursor_keys = term->cursor_keys_mode == CURSOR_KEYS_APPLICATION; break; case 3: break; case 4: break; case 5: term->xtsave.reverse = term->reverse; break; case 6: term->xtsave.origin = term->origin; break; case 7: term->xtsave.auto_margin = term->auto_margin; break; - case 9: if (term->mouse_tracking == MOUSE_X10) term->xtsave.mouse_tracking = MOUSE_X10; break; + case 9: /* term->xtsave.mouse_x10 = term->mouse_tracking == MOUSE_X10; */ break; case 12: break; - case 25: term->xtsave.hide_cursor = term->hide_cursor; break; - case 1000: if (term->mouse_tracking == MOUSE_CLICK) term->xtsave.mouse_tracking = MOUSE_CLICK; break; + case 25: term->xtsave.show_cursor = !term->hide_cursor; break; + case 1000: term->xtsave.mouse_click = term->mouse_tracking == MOUSE_CLICK; break; case 1001: break; - case 1002: if (term->mouse_tracking == MOUSE_DRAG) term->xtsave.mouse_tracking = MOUSE_DRAG; break; - case 1003: if (term->mouse_tracking == MOUSE_MOTION) term->xtsave.mouse_tracking = MOUSE_MOTION; break; + case 1002: term->xtsave.mouse_drag = term->mouse_tracking == MOUSE_DRAG; break; + case 1003: term->xtsave.mouse_motion = term->mouse_tracking == MOUSE_MOTION; break; case 1004: term->xtsave.focus_events = term->focus_events; break; - case 1005: /* if (term->mouse_reporting == MOUSE_UTF8) term->xtsave.mouse_reporting = MOUSE_UTF8; break; */ - case 1006: if (term->mouse_reporting == MOUSE_SGR) term->xtsave.mouse_reporting = MOUSE_SGR; break; + case 1005: /* term->xtsave.mouse_utf8 = term->mouse_reporting == MOUSE_UTF8; */ break; + case 1006: term->xtsave.mouse_sgr = term->mouse_reporting == MOUSE_SGR; break; case 1007: term->xtsave.alt_scrolling = term->alt_scrolling; break; - case 1015: if (term->mouse_reporting == MOUSE_URXVT) term->xtsave.mouse_reporting = MOUSE_URXVT; break; - case 1034: term->xtsave.meta.eight_bit = term->meta.eight_bit; break; - case 1036: term->xtsave.meta.esc_prefix = term->meta.esc_prefix; break; + case 1015: term->xtsave.mouse_urxvt = term->mouse_reporting == MOUSE_URXVT; break; + case 1034: term->xtsave.meta_eight_bit = term->meta.eight_bit; break; + case 1036: term->xtsave.meta_esc_prefix = term->meta.esc_prefix; break; case 1049: term->xtsave.alt_screen = term->grid == &term->alt; break; case 2004: term->xtsave.bracketed_paste = term->bracketed_paste; break; } diff --git a/terminal.h b/terminal.h index 22cea4bf..8f3416e6 100644 --- a/terminal.h +++ b/terminal.h @@ -246,24 +246,27 @@ struct terminal { bool eight_bit; } meta; - /* Saved DECSET modes */ + /* Saved DECSET modes - we save the SET state */ struct { - enum cursor_origin origin; - enum cursor_keys cursor_keys_mode; - //enum keypad_keys keypad_keys_mode; + bool origin; + bool application_cursor_keys; bool reverse; - bool hide_cursor; + bool show_cursor; bool auto_margin; + //bool cursor_blink; bool insert_mode; bool bracketed_paste; bool focus_events; bool alt_scrolling; - enum mouse_tracking mouse_tracking; - enum mouse_reporting mouse_reporting; - struct { - bool esc_prefix; - bool eight_bit; - } meta; + //bool mouse_x10; + bool mouse_click; + bool mouse_drag; + bool mouse_motion; + //bool mouse_utf8; + bool mouse_sgr; + bool mouse_urxvt; + bool meta_eight_bit; + bool meta_esc_prefix; bool alt_screen; } xtsave; From d4473c4e67bd10dfb7ee4816d34c50bfb33d0138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 16:58:32 +0200 Subject: [PATCH 07/11] term: xtsave: store state in a bitfield These shouldn't be accessed in any performance critical paths, so lets save some memory and use a bitfield. --- terminal.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/terminal.h b/terminal.h index 8f3416e6..86b5e80b 100644 --- a/terminal.h +++ b/terminal.h @@ -248,26 +248,26 @@ struct terminal { /* Saved DECSET modes - we save the SET state */ struct { - bool origin; - bool application_cursor_keys; - bool reverse; - bool show_cursor; - bool auto_margin; - //bool cursor_blink; - bool insert_mode; - bool bracketed_paste; - bool focus_events; - bool alt_scrolling; - //bool mouse_x10; - bool mouse_click; - bool mouse_drag; - bool mouse_motion; - //bool mouse_utf8; - bool mouse_sgr; - bool mouse_urxvt; - bool meta_eight_bit; - bool meta_esc_prefix; - bool alt_screen; + uint32_t origin:1; + uint32_t application_cursor_keys:1; + uint32_t reverse:1; + uint32_t show_cursor:1; + uint32_t auto_margin:1; + //uint32_t cursor_blink:1; + uint32_t insert_mode:1; + uint32_t bracketed_paste:1; + uint32_t focus_events:1; + uint32_t alt_scrolling:1; + //uint32_t mouse_x10:1; + uint32_t mouse_click:1; + uint32_t mouse_drag:1; + uint32_t mouse_motion:1; + //uint32_t mouse_utf8:1; + uint32_t mouse_sgr:1; + uint32_t mouse_urxvt:1; + uint32_t meta_eight_bit:1; + uint32_t meta_esc_prefix:1; + uint32_t alt_screen:1; } xtsave; struct charsets charsets; From 23a5ff53eb3bbcafb919e24c156d9fecd5710306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 17:02:52 +0200 Subject: [PATCH 08/11] csi: implement XTRESTORE --- csi.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/csi.c b/csi.c index 20790892..28ec3053 100644 --- a/csi.c +++ b/csi.c @@ -555,6 +555,38 @@ xtsave(struct terminal *term, unsigned param) } } +static void +xtrestore(struct terminal *term, unsigned param) +{ + bool enable; + switch (param) { + case 1: enable = term->xtsave.application_cursor_keys; + case 3: return; + case 4: return; + case 5: enable = term->xtsave.reverse; break; + case 6: enable = term->xtsave.origin; break; + case 7: enable = term->xtsave.auto_margin; break; + case 9: /* enable = term->xtsave.mouse_x10; break; */ return; + case 12: return; + case 25: enable = term->xtsave.show_cursor; break; + case 1000: enable = term->xtsave.mouse_click; break; + case 1001: return; + case 1002: enable = term->xtsave.mouse_drag; break; + case 1003: enable = term->xtsave.mouse_motion; break; + case 1004: enable = term->xtsave.focus_events; break; + case 1005: /* enable = term->xtsave.mouse_utf8; break; */ return; + case 1006: enable = term->xtsave.mouse_sgr; break; + case 1007: enable = term->xtsave.alt_scrolling; break; + case 1015: enable = term->xtsave.mouse_urxvt; break; + case 1034: enable = term->xtsave.meta_eight_bit; break; + case 1036: enable = term->xtsave.meta_esc_prefix; break; + case 1049: enable = term->xtsave.alt_screen; break; + case 2004: enable = term->xtsave.bracketed_paste; break; + } + + decset_decrst(term, param, enable); +} + void csi_dispatch(struct terminal *term, uint8_t final) { @@ -1283,22 +1315,8 @@ csi_dispatch(struct terminal *term, uint8_t final) break; case 'r': - for (size_t i = 0; i < term->vt.params.idx; i++) { - switch (term->vt.params.v[i].value) { -#if 0 /* We don't implement "highlight mouse tracking" */ - case 1001: /* restore old highlight mouse tracking mode? */ - LOG_WARN( - "unimplemented: %s " - "(restore 'highlight mouse tracking' mode)", - csi_as_string(term, final, i)); - break; -#endif - - default: - UNHANDLED(); - break; - } - } + for (size_t i = 0; i < term->vt.params.idx; i++) + xtrestore(term, term->vt.params.v[i].value); break; case 'S': { From dfcc4192ce1e48dceecc5b57527f4148c8a00214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 16 Aug 2020 17:03:58 +0200 Subject: [PATCH 09/11] changelog: xtsave/xtrestore --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f625a1..336bf8d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ **select-word-whitespace** and **select-row** options in the **mouse-bindings** section in `footrc` (https://codeberg.org/dnkl/foot/issues/79). +* Implement XTSAVE/XTRESTORE escape sequences, `CSI ? Ps s` and `CSI ? + Ps r` (https://codeberg.org/dnkl/foot/issues/91). ### Deprecated From 15ae82e62e2cd753e96c2a6878016a9f41360086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 18 Aug 2020 06:53:47 +0200 Subject: [PATCH 10/11] csi: decset/decrst: only clear mouse tracking/reporting if mode matches E.g. only set mouse reporting to NONE, if mouse reporting mode is SGR and an DECRST SGR is issued. Do *not* reset the mouse mode if e.g. mouse reporting mode is SGR and an DECRST URXVT is issued. --- csi.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/csi.c b/csi.c index 28ec3053..fe5460e3 100644 --- a/csi.c +++ b/csi.c @@ -378,8 +378,10 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) case 9: if (enable) LOG_WARN("unimplemented: X10 mouse tracking mode"); - else +#if 0 + else if (term->mouse_tracking == MOUSE_X10) term->mouse_tracking = MOUSE_NONE; +#endif break; case 12: @@ -395,7 +397,10 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) break; case 1000: - term->mouse_tracking = enable ? MOUSE_CLICK : MOUSE_NONE; + if (enable) + term->mouse_tracking = MOUSE_CLICK; + else if (term->mouse_tracking == MOUSE_CLICK) + term->mouse_tracking = MOUSE_NONE; term_xcursor_update(term); break; @@ -405,12 +410,18 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) break; case 1002: - term->mouse_tracking = enable ? MOUSE_DRAG : MOUSE_NONE; + if (enable) + term->mouse_tracking = MOUSE_DRAG; + else if (term->mouse_tracking == MOUSE_DRAG) + term->mouse_tracking = MOUSE_NONE; term_xcursor_update(term); break; case 1003: - term->mouse_tracking = enable ? MOUSE_MOTION : MOUSE_NONE; + if (enable) + term->mouse_tracking = MOUSE_MOTION; + else if (term->mouse_tracking == MOUSE_MOTION) + term->mouse_tracking = MOUSE_NONE; term_xcursor_update(term); break; @@ -421,14 +432,17 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) case 1005: if (enable) LOG_WARN("unimplemented: mouse reporting mode: UTF-8"); - else +#if 0 + else if (term->mouse_reporting == MOUSE_UTF8) term->mouse_reporting = MOUSE_NONE; +#endif break; case 1006: if (enable) - LOG_DBG("mouse reporting mode: SGR"); - term->mouse_reporting = enable ? MOUSE_SGR : MOUSE_NORMAL; + term->mouse_reporting = MOUSE_SGR; + else if (term->mouse_reporting == MOUSE_SGR) + term->mouse_reporting = MOUSE_NORMAL; break; case 1007: @@ -437,8 +451,9 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) case 1015: if (enable) - LOG_DBG("mouse reporting mode: urxvt"); - term->mouse_reporting = enable ? MOUSE_URXVT : MOUSE_NORMAL; + term->mouse_reporting = MOUSE_URXVT; + else if (term->mouse_reporting == MOUSE_URXVT) + term->mouse_reporting = MOUSE_NORMAL; break; case 1034: From 22dcbeacb702fd3600a4644996f1420cd778db3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 18 Aug 2020 07:00:26 +0200 Subject: [PATCH 11/11] csi: xtsave/xtrestore: implement \E[?12s and \E[?12r I.e. save/restore cursor-blink state. --- csi.c | 20 ++++++++++++++++++-- terminal.h | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/csi.c b/csi.c index fe5460e3..9c998cb4 100644 --- a/csi.c +++ b/csi.c @@ -4,11 +4,14 @@ #include #include #include +#include #if defined(_DEBUG) #include #endif +#include + #define LOG_MODULE "csi" #define LOG_ENABLE_DBG 0 #include "log.h" @@ -552,7 +555,20 @@ xtsave(struct terminal *term, unsigned param) case 6: term->xtsave.origin = term->origin; break; case 7: term->xtsave.auto_margin = term->auto_margin; break; case 9: /* term->xtsave.mouse_x10 = term->mouse_tracking == MOUSE_X10; */ break; - case 12: break; + + case 12: { + struct itimerspec current_value; + if (timerfd_gettime(term->cursor_blink.fd, ¤t_value) < 0) + LOG_WARN("xtsave: failed to read cursor blink timer: %s", strerror(errno)); + else { + const struct timespec zero = {}; + term->xtsave.cursor_blink = + !(memcmp(¤t_value.it_interval, &zero, sizeof(zero)) == 0 && + memcmp(¤t_value.it_value, &zero, sizeof(zero)) == 0); + } + break; + } + case 25: term->xtsave.show_cursor = !term->hide_cursor; break; case 1000: term->xtsave.mouse_click = term->mouse_tracking == MOUSE_CLICK; break; case 1001: break; @@ -582,7 +598,7 @@ xtrestore(struct terminal *term, unsigned param) case 6: enable = term->xtsave.origin; break; case 7: enable = term->xtsave.auto_margin; break; case 9: /* enable = term->xtsave.mouse_x10; break; */ return; - case 12: return; + case 12: enable = term->xtsave.cursor_blink; break; case 25: enable = term->xtsave.show_cursor; break; case 1000: enable = term->xtsave.mouse_click; break; case 1001: return; diff --git a/terminal.h b/terminal.h index 86b5e80b..d1235c2f 100644 --- a/terminal.h +++ b/terminal.h @@ -253,7 +253,7 @@ struct terminal { uint32_t reverse:1; uint32_t show_cursor:1; uint32_t auto_margin:1; - //uint32_t cursor_blink:1; + uint32_t cursor_blink:1; uint32_t insert_mode:1; uint32_t bracketed_paste:1; uint32_t focus_events:1;