From fa8b0cbd80c5473e648c5fa1a71b0f74537d1af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 17 Apr 2020 23:03:20 +0200 Subject: [PATCH] csi: implement CSI Ps ; Ps ; Ps t reporting escape sequences A lot of the escape sequences on the "CSI Ps ; Ps ; Ps t" form are expected to return a reply. Thus, not having these implemented means we will hang if the client sends these escapes. Not all of these escapes can be meaningfully implemented on Wayland, and thus this implementation is best effort. We now support the following escapes: * 11t - report if window is iconified (always replies "no") * 13t - report window position (always replies 0,0) * 13;2t - report text area position (replies with margins, since we cannot get the window's position) * 14t - report text area size, in pixels * 14;2t - report window size, in pixels * 15t - report screen size, in pixels * 16t - report cell size, in pixels * 18t - report text area size, in cells * 19t - report screen size, in cells --- CHANGELOG.md | 2 + csi.c | 105 +++++++++++++++++++++++++++++++++++++++++++++------ render.c | 2 +- 3 files changed, 97 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13805227..f495f562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ * **title** option to `footrc`, that sets the initial window title. * `--title` command line option, that sets the initial window title. * Right mouse button extends the current selection. +* Implemented 'CSI Ps ; Ps ; Ps t' escape sequences for the following + parameters: `11t`, `13t`, `14;2t`, `15t`, `19t`. ### Changed diff --git a/csi.c b/csi.c index 40526518..8e6dba1c 100644 --- a/csi.c +++ b/csi.c @@ -782,23 +782,91 @@ csi_dispatch(struct terminal *term, uint8_t final) case 8: LOG_WARN("unimplemented: resize window in chars"); break; case 9: LOG_WARN("unimplemented: maximize/unmaximize window"); break; case 10: LOG_WARN("unimplemented: to/from full screen"); break; - case 11: LOG_WARN("unimplemented: report if window is iconified"); break; - case 13: LOG_WARN("unimplemented: report window position"); break; - case 15: LOG_WARN("unimplemented: report screen size in pixels"); break; - case 19: LOG_WARN("unimplemented: report screen size in chars"); break; case 20: LOG_WARN("unimplemented: report icon label"); break; case 21: LOG_WARN("unimplemented: report window title"); break; case 24: LOG_WARN("unimplemented: resize window (DECSLPP)"); break; - case 14: { /* report window size in pixels */ - char reply[64]; - snprintf(reply, sizeof(reply), "\033[4;%d;%dt", - term->height - term->margins.top - term->margins.bottom, - term->width - term->margins.left - term->margins.right); - term_to_slave(term, reply, strlen(reply)); + case 11: /* report if window is iconified */ + /* We don't know - always report *not* iconified */ + /* 1=not iconified, 2=iconified */ + term_to_slave(term, "\033[1t", 4); + break; + + case 13: { /* report window position */ + + /* We don't know our position - always report (0,0) */ + int x = -1; + int y = -1; + + switch (vt_param_get(term, 1, 0)) { + case 0: + /* window position */ + x = y = 0; + break; + + case 2: + /* text area position */ + x = term->margins.left; + y = term->margins.top; + break; + + default: + UNHANDLED(); + break; + } + + if (x >= 0 && y >= 0) { + char reply[64]; + snprintf(reply, sizeof(reply), "\033[3;%d;%dt", x, y); + term_to_slave(term, reply, strlen(reply)); + } break; } + case 14: { /* report window size in pixels */ + int width = -1; + int height = -1; + + switch (vt_param_get(term, 1, 0)) { + case 0: + /* text area size */ + width = term->width - term->margins.left - term->margins.right; + height = term->height - term->margins.top - term->margins.bottom; + break; + + case 2: + /* window size */ + width = term->width; + height = term->height; + break; + + default: + UNHANDLED(); + break; + } + + if (width >= 0 && height >= 0) { + char reply[64]; + snprintf(reply, sizeof(reply), "\033[4;%d;%dt", height, width); + term_to_slave(term, reply, strlen(reply)); + } + break; + } + + case 15: /* report screen size in pixels */ + tll_foreach(term->window->on_outputs, it) { + char reply[64]; + snprintf(reply, sizeof(reply), "\033[5;%d;%dt", + it->item->dim.px_scaled.height, + it->item->dim.px_scaled.width); + term_to_slave(term, reply, strlen(reply)); + break; + } + + if (tll_length(term->window->on_outputs) == 0) + term_to_slave(term, "\033[5;0;0t", 8); + break; + case 16: { /* report cell size in pixels */ char reply[64]; snprintf(reply, sizeof(reply), "\033[6;%d;%dt", @@ -807,7 +875,7 @@ csi_dispatch(struct terminal *term, uint8_t final) break; } - case 18: { /* window size in chars */ + case 18: { /* text area size in chars */ char reply[64]; snprintf(reply, sizeof(reply), "\033[8;%d;%dt", term->rows, term->cols); @@ -815,6 +883,21 @@ csi_dispatch(struct terminal *term, uint8_t final) break; } + case 19: { /* report screen size in chars */ + tll_foreach(term->window->on_outputs, it) { + char reply[64]; + snprintf(reply, sizeof(reply), "\033[9;%d;%dt", + it->item->dim.px_scaled.height / term->cell_height, + it->item->dim.px_scaled.width / term->cell_width); + term_to_slave(term, reply, strlen(reply)); + break; + } + + if (tll_length(term->window->on_outputs) == 0) + term_to_slave(term, "\033[9;0;0t", 8); + break; + } + case 22: { /* push window title */ /* 0 - icon + title, 1 - icon, 2 - title */ unsigned what = vt_param_get(term, 1, 0); diff --git a/render.c b/render.c index 8c4f55db..a9508f9c 100644 --- a/render.c +++ b/render.c @@ -626,7 +626,7 @@ grid_render_scroll_reverse(struct terminal *term, struct buffer *buf, int height = (dmg->scroll.region.end - dmg->scroll.region.start - dmg->scroll.lines) * term->cell_height; LOG_DBG( - "damage: SCROLL REVERSE: %d-%d by %d lines"m + "damage: SCROLL REVERSE: %d-%d by %d lines", dmg->scroll.region.start, dmg->scroll.region.end, dmg->scroll.lines); if (height <= 0)