// // Created by MightyPork on 2017/08/20. // // Handle DCS sequences (Device Control String) // DCS Pt ST // (DCS = ESC P) // // Those are used for terminal status queries. // // Pt = // $ q " p .... read conformance level // $ q " q .... read character protection attribute // $ q r ...... read scrolling region extents // $ q s ...... read horizontal margins extents // $ q m ...... read SGR in a format that would restore them exactly when run as a CSI Pm m // $ q SP q ... read cursor style // // For details, see // http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Device-Control-functions // #include #include "apars_dcs.h" #include "ansi_parser_callbacks.h" #include "screen.h" #include "apars_logging.h" /** * Helper function to parse incoming DCS (Device Control String) * @param buffer - the DCS body (after DCS and before ST) */ void ICACHE_FLASH_ATTR apars_handle_dcs(char *buffer) { char buf[64]; // just about big enough for full-house SGR size_t len = strlen(buffer); if ((len == 3 || len == 4) && strneq(buffer, "$q", 2)) { // DECRQSS - Request Status String if (strneq(buffer+2, "\"p", 2)) { // DECSCL - Select Conformance Level apars_respond("\033P1$r64;1\"p\033\\"); // 64;1 - Pretend we are VT400 with 7-bit characters } else if (strneq(buffer+2, "\"q", 2)) { // DECSCA - Select character protection attribute sprintf(buf, "\033P1$r%d\"q\033\\", 0); // 0 - Can erase - TODO real protection status if implemented apars_respond(buf); } else if (buffer[2] == 'r') { // DECSTBM - Query scrolling region int v0, v1; screen_region_get(&v0, &v1); sprintf(buf, "\033P1$r%d;%dr\033\\", v0+1, v1+1); apars_respond(buf); } else if (buffer[2] == 's') { // DECSLRM - Query horizontal margins sprintf(buf, "\033P1$r%d;%ds\033\\", 1, termconf_live.width); // Can erase - TODO real extent of horiz margins if implemented apars_respond(buf); } else if (buffer[2] == 'm') { // SGR - query SGR apars_respond("\033P1$r"); screen_report_sgr(buf); apars_respond(buf); apars_respond("m\033\\"); } else if (strneq(buffer+2, " q", 2)) { // DECSCUSR - Query cursor style sprintf(buf, "\033P1$r%d q\033\\", termconf_live.cursor_shape); /* Ps = 0 -> blinking block. Ps = 1 -> blinking block (default). Ps = 2 -> steady block. Ps = 3 -> blinking underline. Ps = 4 -> steady underline. Ps = 5 -> blinking bar (xterm). Ps = 6 -> steady bar (xterm). */ apars_respond(buf); } else { // invalid query ansi_noimpl("DCS %s ST", buffer); sprintf(buf, "\033P0$r%s\033\\", buffer+2); } } else { ansi_warn("Bad DCS: %s", buffer); apars_show_context(); } }