From c9d2bd93fdbe87b6c59d010761a88066fc8a0f4d Mon Sep 17 00:00:00 2001 From: Paul LeoNerd Evans Date: Tue, 24 Nov 2009 01:31:35 +0000 Subject: Implement XTerm mouse parsing in terminfo driver --- driver-ti.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file 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 #include +/* curses.h has just poluted our namespace. We want this back */ +#undef buttons + #include #include #include @@ -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(); } -- cgit v1.2.3-70-g09d2