summaryrefslogtreecommitdiff
path: root/tty-keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'tty-keys.c')
-rw-r--r--tty-keys.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/tty-keys.c b/tty-keys.c
index 3debeea1..3c08db11 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -654,6 +654,74 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
return (-1);
}
+/* Process window size change escape sequences. */
+static int
+tty_keys_winsz(struct tty *tty, const char *buf, size_t len, size_t *size)
+{
+ struct client *c = tty->client;
+ size_t end;
+ char tmp[64];
+ u_int sx, sy, xpixel, ypixel, char_x, char_y;
+
+ *size = 0;
+
+ /* If we did not request this, ignore it. */
+ if (!(tty->flags & TTY_WINSIZEQUERY))
+ return (-1);
+
+ /* First two bytes are always \033[. */
+ if (buf[0] != '\033')
+ return (-1);
+ if (len == 1)
+ return (1);
+ if (buf[1] != '[')
+ return (-1);
+ if (len == 2)
+ return (1);
+
+ /*
+ * Stop at either 't' or anything that isn't a
+ * number or ';'.
+ */
+ for (end = 2; end < len && end != sizeof tmp; end++) {
+ if (buf[end] == 't')
+ break;
+ if (!isdigit((u_char)buf[end]) && buf[end] != ';')
+ break;
+ }
+ if (end == len)
+ return (1);
+ if (end == sizeof tmp || buf[end] != 't')
+ return (-1);
+
+ /* Copy to the buffer. */
+ memcpy(tmp, buf + 2, end - 2);
+ tmp[end - 2] = '\0';
+
+ /* Try to parse the window size sequence. */
+ if (sscanf(tmp, "8;%u;%u", &sy, &sx) == 2) {
+ /* Window size in characters. */
+ tty_set_size(tty, sx, sy, tty->xpixel, tty->ypixel);
+
+ *size = end + 1;
+ return (0);
+ } else if (sscanf(tmp, "4;%u;%u", &ypixel, &xpixel) == 2) {
+ /* Window size in pixels. */
+ char_x = (xpixel && tty->sx) ? xpixel / tty->sx : 0;
+ char_y = (ypixel && tty->sy) ? ypixel / tty->sy : 0;
+ tty_set_size(tty, tty->sx, tty->sy, char_x, char_y);
+ tty_invalidate(tty);
+
+ tty->flags &= ~TTY_WINSIZEQUERY;
+ *size = end + 1;
+ return (0);
+ }
+
+ log_debug("%s: unrecognized window size sequence: %s", c->name, tmp);
+ return (-1);
+}
+
+
/* Process at least one key in the buffer. Return 0 if no keys present. */
int
tty_keys_next(struct tty *tty)
@@ -754,6 +822,17 @@ tty_keys_next(struct tty *tty)
goto partial_key;
}
+ /* Check for window size query */
+ switch (tty_keys_winsz(tty, buf, len, &size)) {
+ case 0: /* yes */
+ key = KEYC_UNKNOWN;
+ goto complete_key;
+ case -1: /* no, or not valid */
+ break;
+ case 1: /* partial */
+ goto partial_key;
+ }
+
first_key:
/* Try to lookup complete key. */
n = tty_keys_next1(tty, buf, len, &key, &size, expired);