aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul LeoNerd Evans <leonerd@leonerd.org.uk>2012-04-24 17:27:48 +0100
committerPaul LeoNerd Evans <leonerd@leonerd.org.uk>2012-04-24 17:27:48 +0100
commitf5cbf9eb57b0dd38ed8054eff02defec1602f57a (patch)
tree8f5d412e6ce36cd3639600d1b6aa92b819bf07f4
parent6645ee971807c5257ca50b073d1dee4af0630fc7 (diff)
downloadtermo-f5cbf9eb57b0dd38ed8054eff02defec1602f57a.tar.gz
termo-f5cbf9eb57b0dd38ed8054eff02defec1602f57a.tar.xz
termo-f5cbf9eb57b0dd38ed8054eff02defec1602f57a.zip
Also handle CSI R; position report replies to CSI 6n
-rw-r--r--driver-csi.c17
-rw-r--r--t/31position.c28
-rw-r--r--termkey.c27
-rw-r--r--termkey.h.in5
4 files changed, 76 insertions, 1 deletions
diff --git a/driver-csi.c b/driver-csi.c
index 1719e70..d305356 100644
--- a/driver-csi.c
+++ b/driver-csi.c
@@ -187,6 +187,21 @@ static TermKeyResult handle_csi_mouse(TermKey *tk, TermKeyKey *key, int cmd, lon
return TERMKEY_RES_NONE;
}
+/*
+ * Handler for CSI R position reports
+ */
+
+static TermKeyResult handle_csi_position(TermKey *tk, TermKeyKey *key, int cmd, long *arg, int args)
+{
+ if(args < 2)
+ return TERMKEY_RES_NONE;
+
+ key->type = TERMKEY_TYPE_POSITION;
+ termkey_key_set_linecol(key, arg[0], arg[1]);
+
+ return TERMKEY_RES_KEY;
+}
+
static int register_keys(void)
{
int i;
@@ -268,6 +283,8 @@ static int register_keys(void)
csi_handlers['M' - 0x40] = &handle_csi_mouse;
csi_handlers['m' - 0x40] = &handle_csi_mouse;
+ csi_handlers['R' - 0x40] = &handle_csi_position;
+
keyinfo_initialised = 1;
return 1;
}
diff --git a/t/31position.c b/t/31position.c
new file mode 100644
index 0000000..baefb8b
--- /dev/null
+++ b/t/31position.c
@@ -0,0 +1,28 @@
+#include "../termkey.h"
+#include "taplib.h"
+
+int main(int argc, char *argv[])
+{
+ TermKey *tk;
+ TermKeyKey key;
+ int line, col;
+
+ plan_tests(5);
+
+ tk = termkey_new_abstract("vt100", 0);
+
+ termkey_push_bytes(tk, "\e[15;7R", 7);
+
+ is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for position report");
+
+ is_int(key.type, TERMKEY_TYPE_POSITION, "key.type for position report");
+
+ is_int(termkey_interpret_position(tk, &key, &line, &col), TERMKEY_RES_KEY, "interpret_position yields RES_KEY");
+
+ is_int(line, 7, "line for position report");
+ is_int(col, 15, "column for position report");
+
+ termkey_destroy(tk);
+
+ return exit_status();
+}
diff --git a/termkey.c b/termkey.c
index ade90a8..e080fec 100644
--- a/termkey.c
+++ b/termkey.c
@@ -956,6 +956,16 @@ TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKe
return TERMKEY_RES_KEY;
}
+TermKeyResult termkey_interpret_position(TermKey *tk, const TermKeyKey *key, int *line, int *col)
+{
+ if(key->type != TERMKEY_TYPE_POSITION)
+ return TERMKEY_RES_NONE;
+
+ termkey_key_get_linecol(key, line, col);
+
+ return TERMKEY_RES_KEY;
+}
+
TermKeyResult termkey_getkey(TermKey *tk, TermKeyKey *key)
{
size_t nbytes = 0;
@@ -1297,6 +1307,9 @@ size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, T
}
}
break;
+ case TERMKEY_TYPE_POSITION:
+ l = snprintf(buffer + pos, len - pos, "Position");
+ break;
}
if(l <= 0) return pos;
@@ -1394,18 +1407,32 @@ int termkey_keycmp(TermKey *tk, const TermKeyKey *key1p, const TermKeyKey *key2p
case TERMKEY_TYPE_UNICODE:
if(key1.code.codepoint != key2.code.codepoint)
return key1.code.codepoint - key2.code.codepoint;
+ break;
case TERMKEY_TYPE_KEYSYM:
if(key1.code.sym != key2.code.sym)
return key1.code.sym - key2.code.sym;
+ break;
case TERMKEY_TYPE_FUNCTION:
if(key1.code.number != key2.code.number)
return key1.code.number - key2.code.number;
+ break;
case TERMKEY_TYPE_MOUSE:
{
int cmp = strncmp(key1.code.mouse, key2.code.mouse, 4);
if(cmp != 0)
return cmp;
}
+ break;
+ case TERMKEY_TYPE_POSITION:
+ {
+ int line1, col1, line2, col2;
+ termkey_interpret_position(tk, &key1, &line1, &col1);
+ termkey_interpret_position(tk, &key2, &line2, &col2);
+ if(line1 != line2)
+ return line1 - line2;
+ return col1 - col2;
+ }
+ break;
}
return key1.modifiers - key2.modifiers;
diff --git a/termkey.h.in b/termkey.h.in
index 6c91b09..bd5187c 100644
--- a/termkey.h.in
+++ b/termkey.h.in
@@ -95,7 +95,8 @@ typedef enum {
TERMKEY_TYPE_UNICODE,
TERMKEY_TYPE_FUNCTION,
TERMKEY_TYPE_KEYSYM,
- TERMKEY_TYPE_MOUSE
+ TERMKEY_TYPE_MOUSE,
+ TERMKEY_TYPE_POSITION
} TermKeyType;
typedef enum {
@@ -199,6 +200,8 @@ TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname);
TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col);
+TermKeyResult termkey_interpret_position(TermKey *tk, const TermKeyKey *key, int *line, int *col);
+
typedef enum {
TERMKEY_FORMAT_LONGMOD = 1 << 0, /* Shift-... instead of S-... */
TERMKEY_FORMAT_CARETCTRL = 1 << 1, /* ^X instead of C-X */