From bb7edb5f8fbdeb32f3cd6f1ba82f93a18de68636 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 5 Feb 2017 16:20:50 +0530 Subject: [PATCH] Implement DECRQM Also add tests for DECRQM and DECCKM --- kitty/data-types.h | 1 + kitty/parser.c | 11 ++++++++++- kitty/screen.c | 25 +++++++++++++++++++++++++ kitty_tests/parser.py | 7 +++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/kitty/data-types.h b/kitty/data-types.h index aac1f4032..236638710 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -406,6 +406,7 @@ void screen_request_capabilities(Screen *, PyObject *); void report_device_attributes(Screen *self, unsigned int UNUSED mode, bool UNUSED secondary); void select_graphic_rendition(Screen *self, unsigned int *params, unsigned int count); void report_device_status(Screen *self, unsigned int which, bool UNUSED); +void report_mode_status(Screen *self, unsigned int which, bool); #define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen); DECLARE_CH_SCREEN_HANDLER(bell) DECLARE_CH_SCREEN_HANDLER(backspace) diff --git a/kitty/parser.c b/kitty/parser.c index 99fbf0067..53ac0c6fe 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -314,7 +314,8 @@ dispatch_osc(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { case '"': \ case '*': \ case '\'': \ - case ' ': + case ' ': \ + case '$': static inline void @@ -472,6 +473,14 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { CALL_CSI_HANDLER1(screen_indexn, 1); case SD: CALL_CSI_HANDLER1(screen_reverse_indexn, 1); + case DECSTR: + if (end_modifier == '$') { + // DECRQM + CALL_CSI_HANDLER1P(report_mode_status, 0, '?'); + } else { + REPORT_ERROR("Unknown DECSTR CSI sequence with start and end modifiers: 0x%x 0x%x", start_modifier, end_modifier); + } + break; default: REPORT_ERROR("Unknown CSI code: 0x%x", code); } diff --git a/kitty/screen.c b/kitty/screen.c index 30399f324..a5cf96558 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -900,6 +900,31 @@ report_device_status(Screen *self, unsigned int which, bool private) { } } +void +report_mode_status(Screen *self, unsigned int which, bool private) { + unsigned int q = private ? which << 5 : which; + unsigned int ans = 0; + char buf[50] = {0}; + switch(q) { +#define KNOWN_MODE(x) \ + case x: \ + ans = self->modes.m##x ? 1 : 2; break; + KNOWN_MODE(LNM); + KNOWN_MODE(IRM); + KNOWN_MODE(DECTCEM); + KNOWN_MODE(DECSCNM); + KNOWN_MODE(DECOM); + KNOWN_MODE(DECAWM); + KNOWN_MODE(DECCOLM); + KNOWN_MODE(DECARM); + KNOWN_MODE(DECCKM); + KNOWN_MODE(BRACKETED_PASTE); + KNOWN_MODE(FOCUS_TRACKING); +#undef KNOWN_MODE + } + if (snprintf(buf, sizeof(buf) - 1, "\x1b[%s%u;%u$y", (private ? "?" : ""), which, ans)) callback("write_to_child", self, buf, 0); +} + void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom) { if (!top) top = 1; diff --git a/kitty_tests/parser.py b/kitty_tests/parser.py index 03bb0a2e2..2839ba24d 100644 --- a/kitty_tests/parser.py +++ b/kitty_tests/parser.py @@ -132,6 +132,13 @@ class TestParser(BaseTest): c.clear() pb('\033[6n', ('report_device_status', 6, 0)) self.ae(c.wtcbuf, b'\033[2;1R') + c.clear() + pb('\033[?1$p', ('report_mode_status', 1, 1)) + self.ae(c.wtcbuf, b'\033[?1;1$y') + pb('\033[?1l', ('screen_reset_mode', 1, 1)) + c.clear() + pb('\033[?1$p', ('report_mode_status', 1, 1)) + self.ae(c.wtcbuf, b'\033[?1;2$y') pb('\033[2;4r', ('screen_set_margins', 2, 4)) self.ae(s.margin_top, 1), self.ae(s.margin_bottom, 3) pb('\033[r', ('screen_set_margins', 0, 0))