Implement XTerm mouse parsing in terminfo driver
This commit is contained in:
parent
7459a038fb
commit
c9d2bd93fd
49
driver-ti.c
49
driver-ti.c
|
@ -7,6 +7,9 @@
|
||||||
#include <term.h>
|
#include <term.h>
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
|
|
||||||
|
/* curses.h has just poluted our namespace. We want this back */
|
||||||
|
#undef buttons
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -20,7 +23,8 @@
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TYPE_KEY,
|
TYPE_KEY,
|
||||||
TYPE_ARR
|
TYPE_ARR,
|
||||||
|
TYPE_MOUSE,
|
||||||
} trie_nodetype;
|
} trie_nodetype;
|
||||||
|
|
||||||
struct trie_node {
|
struct trie_node {
|
||||||
|
@ -48,7 +52,7 @@ typedef struct {
|
||||||
} TermKeyTI;
|
} TermKeyTI;
|
||||||
|
|
||||||
static int funcname2keysym(const char *funcname, TermKeyType *typep, TermKeySym *symp, int *modmask, int *modsetp);
|
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)
|
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) {
|
switch(n->type) {
|
||||||
case TYPE_KEY:
|
case TYPE_KEY:
|
||||||
|
case TYPE_MOUSE:
|
||||||
fprintf(stderr, "ABORT: lookup_next within a TYPE_KEY node\n");
|
fprintf(stderr, "ABORT: lookup_next within a TYPE_KEY node\n");
|
||||||
abort();
|
abort();
|
||||||
case TYPE_ARR:
|
case TYPE_ARR:
|
||||||
|
@ -104,6 +109,7 @@ static void free_trie(struct trie_node *n)
|
||||||
{
|
{
|
||||||
switch(n->type) {
|
switch(n->type) {
|
||||||
case TYPE_KEY:
|
case TYPE_KEY:
|
||||||
|
case TYPE_MOUSE:
|
||||||
break;
|
break;
|
||||||
case TYPE_ARR:
|
case TYPE_ARR:
|
||||||
{
|
{
|
||||||
|
@ -126,6 +132,7 @@ static struct trie_node *compress_trie(struct trie_node *n)
|
||||||
|
|
||||||
switch(n->type) {
|
switch(n->type) {
|
||||||
case TYPE_KEY:
|
case TYPE_KEY:
|
||||||
|
case TYPE_MOUSE:
|
||||||
return n;
|
return n;
|
||||||
case TYPE_ARR:
|
case TYPE_ARR:
|
||||||
{
|
{
|
||||||
|
@ -180,6 +187,16 @@ static void *new_driver(TermKey *tk, const char *term)
|
||||||
if(!value || value == (char*)-1)
|
if(!value || value == (char*)-1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
struct trie_node *node = NULL;
|
||||||
|
|
||||||
|
if(strcmp(strfnames[i] + 4, "mouse") == 0) {
|
||||||
|
node = malloc(sizeof(*node));
|
||||||
|
if(!node)
|
||||||
|
goto abort_free_trie;
|
||||||
|
|
||||||
|
node->type = TYPE_MOUSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
TermKeyType type;
|
TermKeyType type;
|
||||||
TermKeySym sym;
|
TermKeySym sym;
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
|
@ -188,10 +205,18 @@ static void *new_driver(TermKey *tk, const char *term)
|
||||||
if(!funcname2keysym(strfnames[i] + 4, &type, &sym, &mask, &set))
|
if(!funcname2keysym(strfnames[i] + 4, &type, &sym, &mask, &set))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(sym != TERMKEY_SYM_NONE)
|
if(sym == TERMKEY_SYM_NONE)
|
||||||
if(!register_seq(ti, value, type, sym, mask, set))
|
continue;
|
||||||
|
|
||||||
|
node = new_node_key(type, sym, mask, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(node)
|
||||||
|
if(!insert_seq(ti, value, node)) {
|
||||||
|
free(node);
|
||||||
goto abort_free_trie;
|
goto abort_free_trie;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ti->root = compress_trie(ti->root);
|
ti->root = compress_trie(ti->root);
|
||||||
|
|
||||||
|
@ -285,6 +310,17 @@ static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force
|
||||||
*nbytep = pos;
|
*nbytep = pos;
|
||||||
return TERMKEY_RES_KEY;
|
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
|
// 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;
|
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;
|
int pos = 0;
|
||||||
struct trie_node *p = ti->root;
|
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);
|
next = new_node_arr(0, 0xff);
|
||||||
else
|
else
|
||||||
// Final key node
|
// Final key node
|
||||||
next = new_node_key(type, sym, modmask, modset);
|
next = node;
|
||||||
|
|
||||||
if(!next)
|
if(!next)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -437,6 +473,7 @@ static int register_seq(TermKeyTI *ti, const char *seq, TermKeyType type, TermKe
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_KEY:
|
case TYPE_KEY:
|
||||||
|
case TYPE_MOUSE:
|
||||||
fprintf(stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n");
|
fprintf(stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue