From 98884e21a60cfc669268444a02a738d31644322b Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 9 Oct 2021 09:41:00 -0400 Subject: [PATCH] [automaton] fold down DA1 rules, extract attrs #2229 --- src/lib/in.c | 88 ++++++++++++++++++++++++++++++++++------------------ src/lib/in.h | 2 +- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/lib/in.c b/src/lib/in.c index 90d264431..c9cb3ee0f 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -354,6 +354,36 @@ prep_special_keys(inputctx* ictx){ return 0; } +// starting from the current amata match point, match any necessary prefix, then +// extract the (possibly empty) content, then match the follow. as we are only +// called from a callback context, and know we've been properly matched, there +// is no error-checking per se (we do require prefix/follow matches, but if +// missed, we just return NULL). indicate empty prefix with "", not NULL. +// updates ictx->amata.matchstart to be pointing past the follow. follow ought +// not be NUL. +static char* +amata_next_kleene(automaton* amata, const char* prefix, char follow){ + char c; + while( (c = *prefix++) ){ + if(*amata->matchstart != c){ + logerror("matchstart didn't match prefix (%c vs %c)\n", c, *amata->matchstart); + return NULL; + } + ++amata->matchstart; + } + // prefix has been matched. mark start of string and find follow. + const unsigned char* start = amata->matchstart; + while(*amata->matchstart != follow){ + ++amata->matchstart; + } + char* ret = malloc(amata->matchstart - start + 1); + if(ret){ + memcpy(ret, start, amata->matchstart - start); + ret[amata->matchstart - start] = '\0'; + } + return ret; +} + // starting from the current amata match point, match any necessary prefix, then // extract the numeric (possibly empty), then match the follow. as we are only // called from a callback context, and know we've been properly matched, there @@ -395,25 +425,7 @@ amata_next_numeric(automaton* amata, const char* prefix, char follow){ // either a match failure or an alloc failure. static char* amata_next_string(automaton* amata, const char* prefix){ - char c; - while( (c = *prefix++) ){ - if(*amata->matchstart != c){ - logerror("matchstart didn't match prefix (%c vs %c)\n", c, *amata->matchstart); - return NULL; - } - ++amata->matchstart; - } - // prefix has been matched. mark start of string and find follow. - const unsigned char* start = amata->matchstart; - while(*amata->matchstart != '\x1b'){ - ++amata->matchstart; - } - char* ret = malloc(amata->matchstart - start + 1); - if(ret){ - memcpy(ret, start, amata->matchstart - start); - ret[amata->matchstart - start] = '\0'; - } - return ret; + return amata_next_kleene(amata, prefix, '\x1b'); } static inline void @@ -901,6 +913,19 @@ da1_cb(inputctx* ictx){ return 1; } +static int +da1_attrs_cb(inputctx* ictx){ + loginfo("read primary device attributes\n"); + unsigned val = amata_next_numeric(&ictx->amata, "\x1b[?", ';'); + char* attrlist = amata_next_kleene(&ictx->amata, "", 'c'); + logdebug("DA1: %u [%s]\n", val, attrlist); + if(ictx->initdata){ + handoff_initial_responses(ictx); + } + free(attrlist); + return 1; +} + static int da2_cb(inputctx* ictx){ loginfo("read secondary device attributes\n"); @@ -1151,24 +1176,25 @@ build_cflow_automaton(inputctx* ictx){ { "[1;\\N:\\NF", kitty_cb_end, }, { "[1;\\N:\\NH", kitty_cb_home, }, { "[?\\Nu", kitty_keyboard_cb, }, - { "[?1;2c", da1_cb, }, // CSI ? 1 ; 2 c ("VT100 with Advanced Video Option") - { "[?1;0c", da1_cb, }, // CSI ? 1 ; 0 c ("VT101 with No Options") - { "[?4;6c", da1_cb, }, // CSI ? 4 ; 6 c ("VT132 with Advanced Video and Graphics") - { "[?6c", da1_cb, }, // CSI ? 6 c ("VT102") - { "[?7c", da1_cb, }, // CSI ? 7 c ("VT131") - { "[?12;\\Dc", da1_cb, }, // CSI ? 1 2 ; Ps c ("VT125") - { "[?60;\\Dc", da1_cb, }, // CSI ? 6 0 ; Ps c (kmscon) - { "[?62;\\Dc", da1_cb, }, // CSI ? 6 2 ; Ps c ("VT220") - { "[?63;\\Dc", da1_cb, }, // CSI ? 6 3 ; Ps c ("VT320") - { "[?64;\\Dc", da1_cb, }, // CSI ? 6 4 ; Ps c ("VT420") - { "[?65;\\Dc", da1_cb, }, // CSI ? 6 5 ; Ps c (WezTerm, VT5xx?) + { "[?2026;\\N$y", decrpm_asu_cb, }, { "[?1;1S", NULL, }, // negative cregs XTSMGRAPHICS { "[?1;2S", NULL, }, // negative cregs XTSMGRAPHICS { "[?1;3;0S", NULL, }, // negative cregs XTSMGRAPHICS - { "[?2026;\\N$y", decrpm_asu_cb, }, { "[?2;1S", NULL, }, // negative pixels XTSMGRAPHICS { "[?2;2S", NULL, }, // negative pixels XTSMGRAPHICS { "[?2;3;0S", NULL, }, // negative pixels XTSMGRAPHICS + { "[?1;2c", da1_cb, }, // CSI ? 1 ; 2 c ("VT100 with Advanced Video Option") + { "[?1;0c", da1_cb, }, // CSI ? 1 ; 0 c ("VT101 with No Options") + { "[?4;6c", da1_cb, }, // CSI ? 4 ; 6 c ("VT132 with Advanced Video and Graphics") + { "[?6c", da1_cb, }, // CSI ? 6 c ("VT102") + { "[?7c", da1_cb, }, // CSI ? 7 c ("VT131") + // CSI ? 1 2 ; Ps c ("VT125") + // CSI ? 6 0 ; Ps c (kmscon) + // CSI ? 6 2 ; Ps c ("VT220") + // CSI ? 6 3 ; Ps c ("VT320") + // CSI ? 6 4 ; Ps c ("VT420") + // CSI ? 6 5 ; Ps c (WezTerm, VT5xx?) + { "[?\\N;\\Dc", da1_attrs_cb, }, { "[?1;0;\\NS", xtsmgraphics_cregs_cb, }, { "[?2;0;\\N;\\NS", xtsmgraphics_sixel_cb, }, { "[>\\N;\\N;\\Nc", da2_cb, }, diff --git a/src/lib/in.h b/src/lib/in.h index 15dcd3983..dc992d748 100644 --- a/src/lib/in.h +++ b/src/lib/in.h @@ -69,7 +69,7 @@ struct initial_responses { int sixely; // maximum sixel height int sixelx; // maximum sixel width char* version; // version string, heap-allocated - unsigned kbdlevel; // kitty keyboard protocol level + unsigned kbdlevel; // enabled kitty keyboard functions }; // Blocking call. Waits until the input thread has processed all responses to