aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul LeoNerd Evans <leonerd@leonerd.org.uk>2009-11-24 01:31:35 +0000
committerPaul LeoNerd Evans <leonerd@leonerd.org.uk>2009-11-24 01:31:35 +0000
commitc9d2bd93fdbe87b6c59d010761a88066fc8a0f4d (patch)
tree84b641f8777743a2ebd11a4b7c40a8611e84ab0a
parent7459a038fbb67922b5143c985b768dc819c1c630 (diff)
downloadtermo-c9d2bd93fdbe87b6c59d010761a88066fc8a0f4d.tar.gz
termo-c9d2bd93fdbe87b6c59d010761a88066fc8a0f4d.tar.xz
termo-c9d2bd93fdbe87b6c59d010761a88066fc8a0f4d.zip
Implement XTerm mouse parsing in terminfo driver
-rw-r--r--driver-ti.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/driver-ti.c b/driver-ti.c
index 7d4c047..c8b1336 100644
--- a/driver-ti.c
+++ b/driver-ti.c
@@ -7,6 +7,9 @@
#include <term.h>
#include <curses.h>
+/* curses.h has just poluted our namespace. We want this back */
+#undef buttons
+
#include <ctype.h>
#include <stdio.h>
#include <string.h>
@@ -20,7 +23,8 @@
typedef enum {
TYPE_KEY,
- TYPE_ARR
+ TYPE_ARR,
+ TYPE_MOUSE,
} trie_nodetype;
struct trie_node {
@@ -48,7 +52,7 @@ typedef struct {
} TermKeyTI;
static int funcname2keysym(const char *funcname, TermKeyType *typep, TermKeySym *symp, int *modmask, int *modsetp);
-static int register_seq(TermKeyTI *ti, const char *seq, TermKeyType type, TermKeySym sym, int modmask, int modset);
+static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node);
static struct trie_node *new_node_key(TermKeyType type, TermKeySym sym, int modmask, int modset)
{
@@ -86,6 +90,7 @@ static struct trie_node *lookup_next(struct trie_node *n, unsigned char b)
{
switch(n->type) {
case TYPE_KEY:
+ case TYPE_MOUSE:
fprintf(stderr, "ABORT: lookup_next within a TYPE_KEY node\n");
abort();
case TYPE_ARR:
@@ -104,6 +109,7 @@ static void free_trie(struct trie_node *n)
{
switch(n->type) {
case TYPE_KEY:
+ case TYPE_MOUSE:
break;
case TYPE_ARR:
{
@@ -126,6 +132,7 @@ static struct trie_node *compress_trie(struct trie_node *n)
switch(n->type) {
case TYPE_KEY:
+ case TYPE_MOUSE:
return n;
case TYPE_ARR:
{
@@ -180,17 +187,35 @@ static void *new_driver(TermKey *tk, const char *term)
if(!value || value == (char*)-1)
continue;
- TermKeyType type;
- TermKeySym sym;
- int mask = 0;
- int set = 0;
+ struct trie_node *node = NULL;
- if(!funcname2keysym(strfnames[i] + 4, &type, &sym, &mask, &set))
- continue;
+ if(strcmp(strfnames[i] + 4, "mouse") == 0) {
+ node = malloc(sizeof(*node));
+ if(!node)
+ goto abort_free_trie;
+
+ node->type = TYPE_MOUSE;
+ }
+ else {
+ TermKeyType type;
+ TermKeySym sym;
+ int mask = 0;
+ int set = 0;
+
+ if(!funcname2keysym(strfnames[i] + 4, &type, &sym, &mask, &set))
+ continue;
- if(sym != TERMKEY_SYM_NONE)
- if(!register_seq(ti, value, type, sym, mask, set))
+ if(sym == TERMKEY_SYM_NONE)
+ continue;
+
+ node = new_node_key(type, sym, mask, set);
+ }
+
+ if(node)
+ if(!insert_seq(ti, value, node)) {
+ free(node);
goto abort_free_trie;
+ }
}
ti->root = compress_trie(ti->root);
@@ -285,6 +310,17 @@ static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force
*nbytep = pos;
return TERMKEY_RES_KEY;
}
+ else if(p->type == TYPE_MOUSE) {
+ if(tk->buffcount - pos < 3)
+ return TERMKEY_RES_AGAIN;
+
+ key->type = TERMKEY_TYPE_MOUSE;
+ key->code.mouse.buttons = CHARAT(pos+0) - 0x20;
+ key->code.mouse.col = CHARAT(pos+1) - 0x20;
+ key->code.mouse.line = CHARAT(pos+2) - 0x20;
+ *nbytep = pos+3;
+ return TERMKEY_RES_KEY;
+ }
}
// If p is not NULL then we hadn't walked off the end yet, so we have a
@@ -395,7 +431,7 @@ static int funcname2keysym(const char *funcname, TermKeyType *typep, TermKeySym
return 0;
}
-static int register_seq(TermKeyTI *ti, const char *seq, TermKeyType type, TermKeySym sym, int modmask, int modset)
+static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node)
{
int pos = 0;
struct trie_node *p = ti->root;
@@ -418,7 +454,7 @@ static int register_seq(TermKeyTI *ti, const char *seq, TermKeyType type, TermKe
next = new_node_arr(0, 0xff);
else
// Final key node
- next = new_node_key(type, sym, modmask, modset);
+ next = node;
if(!next)
return 0;
@@ -437,6 +473,7 @@ static int register_seq(TermKeyTI *ti, const char *seq, TermKeyType type, TermKe
break;
}
case TYPE_KEY:
+ case TYPE_MOUSE:
fprintf(stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n");
abort();
}