diff options
Diffstat (limited to 'driver-ti.c')
-rw-r--r-- | driver-ti.c | 973 |
1 files changed, 507 insertions, 466 deletions
diff --git a/driver-ti.c b/driver-ti.c index d827bdf..ab76c25 100644 --- a/driver-ti.c +++ b/driver-ti.c @@ -9,9 +9,6 @@ #else # include <curses.h> # include <term.h> - -/* curses.h has just poluted our namespace. We want this back */ -# undef buttons #endif #include <ctype.h> @@ -27,563 +24,607 @@ * vector to store an extent map after the database is loaded. */ -typedef enum { - TYPE_KEY, - TYPE_ARR, - TYPE_MOUSE, -} trie_nodetype; - -struct trie_node { - trie_nodetype type; -}; - -struct trie_node_key { - trie_nodetype type; - struct keyinfo key; -}; - -struct trie_node_arr { - trie_nodetype type; - unsigned char min, max; /* INCLUSIVE endpoints of the extent range */ - struct trie_node *arr[]; /* dynamic size at allocation time */ -}; - -typedef struct { - TermKey *tk; +typedef enum +{ + TYPE_KEY, + TYPE_ARRAY, + TYPE_MOUSE, +} +trie_nodetype_t; - struct trie_node *root; +typedef struct trie_node +{ + trie_nodetype_t type; +} +trie_node_t; - char *start_string; - char *stop_string; -} TermKeyTI; +typedef struct trie_node_key +{ + trie_nodetype_t type; + keyinfo_t key; +} +trie_node_key_t; -static int funcname2keysym(const char *funcname, TermKeyType *typep, TermKeySym *symp, int *modmask, int *modsetp); -static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node); +typedef struct trie_node_array +{ + trie_nodetype_t type; + unsigned char min, max; /* INCLUSIVE endpoints of the extent range */ + trie_node_t *arr[]; /* dynamic size at allocation time */ +} +trie_node_array_t; -static struct trie_node *new_node_key(TermKeyType type, TermKeySym sym, int modmask, int modset) +typedef struct { - struct trie_node_key *n = malloc(sizeof(*n)); - if(!n) - return NULL; + termkey_t *tk; + trie_node_t *root; - n->type = TYPE_KEY; + char *start_string; + char *stop_string; +} +termkey_ti_t; - n->key.type = type; - n->key.sym = sym; - n->key.modifier_mask = modmask; - n->key.modifier_set = modset; +static int funcname2keysym (const char *funcname, termkey_type_t *typep, + termkey_sym_t *symp, int *modmask, int *modsetp); +static int insert_seq (termkey_ti_t *ti, const char *seq, trie_node_t *node); - return (struct trie_node*)n; +static trie_node_t * +new_node_key (termkey_type_t type, termkey_sym_t sym, int modmask, int modset) +{ + trie_node_key_t *n = malloc (sizeof *n); + if (!n) + return NULL; + + n->type = TYPE_KEY; + n->key.type = type; + n->key.sym = sym; + n->key.modifier_mask = modmask; + n->key.modifier_set = modset; + return (trie_node_t *) n; } -static struct trie_node *new_node_arr(unsigned char min, unsigned char max) +static trie_node_t * +new_node_arr (unsigned char min, unsigned char max) { - struct trie_node_arr *n = malloc(sizeof(*n) + ((int)max-min+1) * sizeof(n->arr[0])); - if(!n) - return NULL; + trie_node_array_t *n = malloc (sizeof *n + + ((int) max - min + 1) * sizeof n->arr[0]); + if (!n) + return NULL; - n->type = TYPE_ARR; - n->min = min; n->max = max; + n->type = TYPE_ARRAY; + n->min = min; + n->max = max; - int i; - for(i = min; i <= max; i++) - n->arr[i-min] = NULL; + int i; + for (i = min; i <= max; i++) + n->arr[i - min] = NULL; - return (struct trie_node*)n; + return (trie_node_t *) n; } -static struct trie_node *lookup_next(struct trie_node *n, unsigned char b) +static trie_node_t * +lookup_next (trie_node_t *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: - { - struct trie_node_arr *nar = (struct trie_node_arr*)n; - if(b < nar->min || b > nar->max) - return NULL; - return nar->arr[b - nar->min]; - } - } - - return NULL; // Never reached but keeps compiler happy + switch (n->type) + { + case TYPE_KEY: + case TYPE_MOUSE: + // FIXME + fprintf (stderr, "ABORT: lookup_next within a TYPE_KEY node\n"); + abort (); + case TYPE_ARRAY: + { + trie_node_array_t *nar = (trie_node_array_t *) n; + if (b < nar->min || b > nar->max) + return NULL; + return nar->arr[b - nar->min]; + } + } + + return NULL; // Never reached but keeps compiler happy } -static void free_trie(struct trie_node *n) +static void +free_trie (trie_node_t *n) { - switch(n->type) { - case TYPE_KEY: - case TYPE_MOUSE: - break; - case TYPE_ARR: - { - struct trie_node_arr *nar = (struct trie_node_arr*)n; - int i; - for(i = nar->min; i <= nar->max; i++) - if(nar->arr[i - nar->min]) - free_trie(nar->arr[i - nar->min]); - break; - } - } - - free(n); + switch (n->type) + { + case TYPE_KEY: + case TYPE_MOUSE: + break; + case TYPE_ARRAY: + { + trie_node_array_t *nar = (trie_node_array_t *) n; + int i; + for (i = nar->min; i <= nar->max; i++) + if (nar->arr[i - nar->min]) + free_trie (nar->arr[i - nar->min]); + } + } + free (n); } -static struct trie_node *compress_trie(struct trie_node *n) +static trie_node_t * +compress_trie (struct trie_node *n) { - if(!n) - return NULL; - - switch(n->type) { - case TYPE_KEY: - case TYPE_MOUSE: - return n; - case TYPE_ARR: - { - struct trie_node_arr *nar = (struct trie_node_arr*)n; - unsigned char min, max; - // Find the real bounds - for(min = 0; !nar->arr[min]; min++) - ; - for(max = 0xff; !nar->arr[max]; max--) - ; - - struct trie_node_arr *new = (struct trie_node_arr*)new_node_arr(min, max); - int i; - for(i = min; i <= max; i++) - new->arr[i - min] = compress_trie(nar->arr[i]); - - free(nar); - return (struct trie_node*)new; - } - } - - return n; + if (!n) + return NULL; + + switch (n->type) + { + case TYPE_KEY: + case TYPE_MOUSE: + return n; + case TYPE_ARRAY: + { + trie_node_array_t *nar = (trie_node_array_t *) n; + // Find the real bounds + unsigned char min, max; + for (min = 0; !nar->arr[min]; min++) + ; + for (max = 0xff; !nar->arr[max]; max--) + ; + + trie_node_array_t *new = (trie_node_array_t *) new_node_arr (min, max); + int i; + for (i = min; i <= max; i++) + new->arr[i - min] = compress_trie (nar->arr[i]); + + free (nar); + return (trie_node_t *) new; + } + } + return n; } -static int load_terminfo(TermKeyTI *ti, const char *term) +static int +load_terminfo (termkey_ti_t *ti, const char *term) { - int i; + int i; #ifdef HAVE_UNIBILIUM - unibi_term *unibi = unibi_from_term(term); - if(!unibi) - return 0; + unibi_term *unibi = unibi_from_term (term); + if (!unibi) + return 0; #else - int err; + int err; - /* Have to cast away the const. But it's OK - we know terminfo won't really - * modify term */ - if(setupterm((char*)term, 1, &err) != OK) - return 0; + /* Have to cast away the const. But it's OK - we know terminfo won't really + * modify term */ + if (setupterm ((char *) term, 1, &err) != OK) + return 0; #endif #ifdef HAVE_UNIBILIUM - for(i = unibi_string_begin_+1; i < unibi_string_end_; i++) + for (i = unibi_string_begin_ + 1; i < unibi_string_end_; i++) #else - for(i = 0; strfnames[i]; i++) + for (i = 0; strfnames[i]; i++) #endif - { - // Only care about the key_* constants + { + // Only care about the key_* constants #ifdef HAVE_UNIBILIUM - const char *name = unibi_name_str(i); + const char *name = unibi_name_str (i); #else - const char *name = strfnames[i]; + const char *name = strfnames[i]; #endif - if(strncmp(name, "key_", 4) != 0) - continue; + if (strncmp (name, "key_", 4) != 0) + continue; #ifdef HAVE_UNIBILIUM - const char *value = unibi_get_str(unibi, i); + const char *value = unibi_get_str (unibi, i); #else - const char *value = tigetstr(strnames[i]); + const char *value = tigetstr (strnames[i]); #endif - if(!value || value == (char*)-1) - continue; - - struct trie_node *node = NULL; - - if(strcmp(name + 4, "mouse") == 0) { - node = malloc(sizeof(*node)); - if(!node) - return 0; - - node->type = TYPE_MOUSE; - } - else { - TermKeyType type; - TermKeySym sym; - int mask = 0; - int set = 0; - - if(!funcname2keysym(name + 4, &type, &sym, &mask, &set)) - continue; - - if(sym == TERMKEY_SYM_NONE) - continue; - - node = new_node_key(type, sym, mask, set); - } - - if(node) - if(!insert_seq(ti, value, node)) { - free(node); - return 0; - } - } - - /* Take copies of these terminfo strings, in case we build multiple termkey - * instances for multiple different termtypes, and it's different by the - * time we want to use it - */ + if (!value || value == (char*) -1) + continue; + + struct trie_node *node = NULL; + if (strcmp (name + 4, "mouse") == 0) + { + node = malloc (sizeof *node); + if (!node) + return 0; + + node->type = TYPE_MOUSE; + } + else + { + termkey_type_t type; + termkey_sym_t sym; + int mask = 0; + int set = 0; + + if (!funcname2keysym (name + 4, &type, &sym, &mask, &set)) + continue; + + if (sym == TERMKEY_SYM_NONE) + continue; + + node = new_node_key (type, sym, mask, set); + } + + if (node && !insert_seq (ti, value, node)) + { + free(node); + return 0; + } + } + + /* Take copies of these terminfo strings, in case we build multiple termkey + * instances for multiple different termtypes, and it's different by the + * time we want to use it + */ #ifdef HAVE_UNIBILIUM - const char *keypad_xmit = unibi_get_str(unibi, unibi_pkey_xmit); + const char *keypad_xmit = unibi_get_str (unibi, unibi_pkey_xmit); #endif - if(keypad_xmit) - ti->start_string = strdup(keypad_xmit); - else - ti->start_string = NULL; + if (keypad_xmit) + ti->start_string = strdup (keypad_xmit); + else + ti->start_string = NULL; #ifdef HAVE_UNIBILIUM - const char *keypad_local = unibi_get_str(unibi, unibi_pkey_local); + const char *keypad_local = unibi_get_str (unibi, unibi_pkey_local); #endif - if(keypad_local) - ti->stop_string = strdup(keypad_local); - else - ti->stop_string = NULL; + if (keypad_local) + ti->stop_string = strdup (keypad_local); + else + ti->stop_string = NULL; #ifdef HAVE_UNIBILIUM - unibi_destroy(unibi); + unibi_destroy (unibi); #endif - return 1; + return 1; } -static void *new_driver(TermKey *tk, const char *term) +static void * +new_driver (termkey_t *tk, const char *term) { - TermKeyTI *ti = malloc(sizeof *ti); - if(!ti) - return NULL; - - ti->tk = tk; + termkey_ti_t *ti = malloc (sizeof *ti); + if (!ti) + return NULL; - ti->root = new_node_arr(0, 0xff); - if(!ti->root) - goto abort_free_ti; + ti->tk = tk; + ti->root = new_node_arr (0, 0xff); + if (!ti->root) + goto abort_free_ti; - if(!load_terminfo(ti, term)) - goto abort_free_trie; + if (!load_terminfo (ti, term)) + goto abort_free_trie; - ti->root = compress_trie(ti->root); - - return ti; + ti->root = compress_trie (ti->root); + return ti; abort_free_trie: - free_trie(ti->root); + free_trie(ti->root); abort_free_ti: - free(ti); + free(ti); - return NULL; + return NULL; } -static int start_driver(TermKey *tk, void *info) +static int +start_driver (termkey_t *tk, void *info) { - TermKeyTI *ti = info; - struct stat statbuf; - char *start_string = ti->start_string; - size_t len; - - if(tk->fd == -1 || !start_string) - return 1; - - /* The terminfo database will contain keys in application cursor key mode. - * We may need to enable that mode - */ - - /* There's no point trying to write() to a pipe */ - if(fstat(tk->fd, &statbuf) == -1) - return 0; - - if(S_ISFIFO(statbuf.st_mode)) - return 1; - - // Can't call putp or tputs because they suck and don't give us fd control - len = strlen(start_string); - while(len) { - size_t written = write(tk->fd, start_string, len); - if(written == -1) - return 0; - start_string += written; - len -= written; - } - return 1; + termkey_ti_t *ti = info; + struct stat statbuf; + char *start_string = ti->start_string; + size_t len; + + if (tk->fd == -1 || !start_string) + return 1; + + /* The terminfo database will contain keys in application cursor key mode. + * We may need to enable that mode + */ + + // FIXME: isatty() should suffice + /* There's no point trying to write() to a pipe */ + if (fstat (tk->fd, &statbuf) == -1) + return 0; + + if (S_ISFIFO (statbuf.st_mode)) + return 1; + + // Can't call putp or tputs because they suck and don't give us fd control + len = strlen (start_string); + while (len) + { + size_t written = write (tk->fd, start_string, len); + if (written == -1) + return 0; + start_string += written; + len -= written; + } + return 1; } -static int stop_driver(TermKey *tk, void *info) +// XXX: this is the same as above only with a different string +static int +stop_driver (termkey_t *tk, void *info) { - TermKeyTI *ti = info; - struct stat statbuf; - char *stop_string = ti->stop_string; - size_t len; - - if(tk->fd == -1 || !stop_string) - return 1; - - /* There's no point trying to write() to a pipe */ - if(fstat(tk->fd, &statbuf) == -1) - return 0; - - if(S_ISFIFO(statbuf.st_mode)) - return 1; - - /* The terminfo database will contain keys in application cursor key mode. - * We may need to enable that mode - */ - - // Can't call putp or tputs because they suck and don't give us fd control - len = strlen(stop_string); - while(len) { - size_t written = write(tk->fd, stop_string, len); - if(written == -1) - return 0; - stop_string += written; - len -= written; - } - return 1; + termkey_ti_t *ti = info; + struct stat statbuf; + char *stop_string = ti->stop_string; + size_t len; + + if (tk->fd == -1 || !stop_string) + return 1; + + /* There's no point trying to write() to a pipe */ + if (fstat (tk->fd, &statbuf) == -1) + return 0; + + if (S_ISFIFO (statbuf.st_mode)) + return 1; + + /* The terminfo database will contain keys in application cursor key mode. + * We may need to enable that mode + */ + + // Can't call putp or tputs because they suck and don't give us fd control + len = strlen (stop_string); + while (len) + { + size_t written = write (tk->fd, stop_string, len); + if (written == -1) + return 0; + stop_string += written; + len -= written; + } + return 1; } -static void free_driver(void *info) +static void +free_driver (void *info) { - TermKeyTI *ti = info; - - free_trie(ti->root); - - if(ti->start_string) - free(ti->start_string); - - if(ti->stop_string) - free(ti->stop_string); - - free(ti); + termkey_ti_t *ti = info; + free_trie (ti->root); + free (ti->start_string); + free (ti->stop_string); + free (ti); } #define CHARAT(i) (tk->buffer[tk->buffstart + (i)]) -static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep) +static termkey_result_t +peekkey (termkey_t *tk, void *info, + termkey_key_t *key, int force, size_t *nbytep) { - TermKeyTI *ti = info; - - if(tk->buffcount == 0) - return tk->is_closed ? TERMKEY_RES_EOF : TERMKEY_RES_NONE; - - struct trie_node *p = ti->root; - - unsigned int pos = 0; - while(pos < tk->buffcount) { - p = lookup_next(p, CHARAT(pos)); - if(!p) - break; - - pos++; - - if(p->type == TYPE_KEY) { - struct trie_node_key *nk = (struct trie_node_key*)p; - key->type = nk->key.type; - key->code.sym = nk->key.sym; - key->modifiers = nk->key.modifier_set; - *nbytep = pos; - return TERMKEY_RES_KEY; - } - else if(p->type == TYPE_MOUSE) { - tk->buffstart += pos; - tk->buffcount -= pos; - - TermKeyResult mouse_result = (*tk->method.peekkey_mouse)(tk, key, nbytep); - - tk->buffstart -= pos; - tk->buffcount += pos; - - if(mouse_result == TERMKEY_RES_KEY) - *nbytep += pos; - - return mouse_result; - } - } - - // If p is not NULL then we hadn't walked off the end yet, so we have a - // partial match - if(p && !force) - return TERMKEY_RES_AGAIN; - - return TERMKEY_RES_NONE; + termkey_ti_t *ti = info; + + if (tk->buffcount == 0) + return tk->is_closed ? TERMKEY_RES_EOF : TERMKEY_RES_NONE; + + trie_node_t *p = ti->root; + unsigned int pos = 0; + while (pos < tk->buffcount) + { + p = lookup_next (p, CHARAT (pos)); + if (!p) + break; + + pos++; + + if (p->type == TYPE_KEY) + { + trie_node_key_t *nk = (trie_node_key_t *) p; + key->type = nk->key.type; + key->code.sym = nk->key.sym; + key->modifiers = nk->key.modifier_set; + *nbytep = pos; + return TERMKEY_RES_KEY; + } + else if (p->type == TYPE_MOUSE) + { + tk->buffstart += pos; + tk->buffcount -= pos; + + termkey_result_t mouse_result = + (*tk->method.peekkey_mouse) (tk, key, nbytep); + + tk->buffstart -= pos; + tk->buffcount += pos; + + if (mouse_result == TERMKEY_RES_KEY) + *nbytep += pos; + + return mouse_result; + } + } + + // If p is not NULL then we hadn't walked off the end yet, so we have a + // partial match + if (p && !force) + return TERMKEY_RES_AGAIN; + + return TERMKEY_RES_NONE; } -static struct { - const char *funcname; - TermKeyType type; - TermKeySym sym; - int mods; -} funcs[] = +static struct +{ + const char *funcname; + termkey_type_t type; + termkey_sym_t sym; + int mods; +} +funcs[] = { - /* THIS LIST MUST REMAIN SORTED! */ - { "backspace", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BACKSPACE, 0 }, - { "begin", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 0 }, - { "beg", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 0 }, - { "btab", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_TAB, TERMKEY_KEYMOD_SHIFT }, - { "cancel", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CANCEL, 0 }, - { "clear", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CLEAR, 0 }, - { "close", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CLOSE, 0 }, - { "command", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_COMMAND, 0 }, - { "copy", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_COPY, 0 }, - { "dc", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DELETE, 0 }, - { "down", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DOWN, 0 }, - { "end", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_END, 0 }, - { "enter", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_ENTER, 0 }, - { "exit", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_EXIT, 0 }, - { "find", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_FIND, 0 }, - { "help", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HELP, 0 }, - { "home", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HOME, 0 }, - { "ic", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_INSERT, 0 }, - { "left", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_LEFT, 0 }, - { "mark", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MARK, 0 }, - { "message", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MESSAGE, 0 }, - { "mouse", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_NONE, 0 }, - { "move", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MOVE, 0 }, - { "next", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 0 }, // Not quite, but it's the best we can do - { "npage", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 0 }, - { "open", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_OPEN, 0 }, - { "options", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_OPTIONS, 0 }, - { "ppage", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 0 }, - { "previous", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 0 }, // Not quite, but it's the best we can do - { "print", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PRINT, 0 }, - { "redo", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REDO, 0 }, - { "reference", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REFERENCE, 0 }, - { "refresh", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REFRESH, 0 }, - { "replace", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REPLACE, 0 }, - { "restart", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RESTART, 0 }, - { "resume", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RESUME, 0 }, - { "right", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RIGHT, 0 }, - { "save", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SAVE, 0 }, - { "select", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SELECT, 0 }, - { "suspend", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SUSPEND, 0 }, - { "undo", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UNDO, 0 }, - { "up", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UP, 0 }, - { NULL }, + /* THIS LIST MUST REMAIN SORTED! */ + { "backspace", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BACKSPACE, 0 }, + { "begin", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 0 }, + { "beg", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_BEGIN, 0 }, + { "btab", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_TAB, TERMKEY_KEYMOD_SHIFT }, + { "cancel", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CANCEL, 0 }, + { "clear", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CLEAR, 0 }, + { "close", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_CLOSE, 0 }, + { "command", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_COMMAND, 0 }, + { "copy", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_COPY, 0 }, + { "dc", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DELETE, 0 }, + { "down", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_DOWN, 0 }, + { "end", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_END, 0 }, + { "enter", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_ENTER, 0 }, + { "exit", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_EXIT, 0 }, + { "find", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_FIND, 0 }, + { "help", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HELP, 0 }, + { "home", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_HOME, 0 }, + { "ic", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_INSERT, 0 }, + { "left", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_LEFT, 0 }, + { "mark", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MARK, 0 }, + { "message", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MESSAGE, 0 }, + { "mouse", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_NONE, 0 }, + { "move", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_MOVE, 0 }, + // Not quite, but it's the best we can do + { "next", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 0 }, + { "npage", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEDOWN, 0 }, + { "open", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_OPEN, 0 }, + { "options", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_OPTIONS, 0 }, + { "ppage", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 0 }, + // Not quite, but it's the best we can do + { "previous", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PAGEUP, 0 }, + { "print", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_PRINT, 0 }, + { "redo", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REDO, 0 }, + { "reference", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REFERENCE, 0 }, + { "refresh", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REFRESH, 0 }, + { "replace", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_REPLACE, 0 }, + { "restart", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RESTART, 0 }, + { "resume", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RESUME, 0 }, + { "right", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_RIGHT, 0 }, + { "save", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SAVE, 0 }, + { "select", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SELECT, 0 }, + { "suspend", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_SUSPEND, 0 }, + { "undo", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UNDO, 0 }, + { "up", TERMKEY_TYPE_KEYSYM, TERMKEY_SYM_UP, 0 }, + { NULL }, }; -static int funcname2keysym(const char *funcname, TermKeyType *typep, TermKeySym *symp, int *modmaskp, int *modsetp) +static int +funcname2keysym (const char *funcname, + termkey_type_t *typep, termkey_sym_t *symp, int *modmaskp, int *modsetp) { - // Binary search - - int start = 0; - int end = sizeof(funcs)/sizeof(funcs[0]); // is "one past" the end of the range - - while(1) { - int i = (start+end) / 2; - int cmp = strcmp(funcname, funcs[i].funcname); - - if(cmp == 0) { - *typep = funcs[i].type; - *symp = funcs[i].sym; - *modmaskp = funcs[i].mods; - *modsetp = funcs[i].mods; - return 1; - } - else if(end == start + 1) - // That was our last choice and it wasn't it - not found - break; - else if(cmp > 0) - start = i; - else - end = i; - } - - if(funcname[0] == 'f' && isdigit(funcname[1])) { - *typep = TERMKEY_TYPE_FUNCTION; - *symp = atoi(funcname + 1); - return 1; - } - - // Last-ditch attempt; maybe it's a shift key? - if(funcname[0] == 's' && funcname2keysym(funcname + 1, typep, symp, modmaskp, modsetp)) { - *modmaskp |= TERMKEY_KEYMOD_SHIFT; - *modsetp |= TERMKEY_KEYMOD_SHIFT; - return 1; - } + // Binary search + + int start = 0; + int end = sizeof funcs / sizeof funcs[0]; + // is "one past" the end of the range + + // XXX: bsearch()? + while (1) + { + int i = (start + end) / 2; + int cmp = strcmp (funcname, funcs[i].funcname); + + if (cmp == 0) + { + *typep = funcs[i].type; + *symp = funcs[i].sym; + *modmaskp = funcs[i].mods; + *modsetp = funcs[i].mods; + return 1; + } + else if (end == start + 1) + // That was our last choice and it wasn't it - not found + break; + else if (cmp > 0) + start = i; + else + end = i; + } + + if (funcname[0] == 'f' && isdigit (funcname[1])) + { + *typep = TERMKEY_TYPE_FUNCTION; + // FIXME + *symp = atoi (funcname + 1); + return 1; + } + + // Last-ditch attempt; maybe it's a shift key? + if (funcname[0] == 's' && funcname2keysym + (funcname + 1, typep, symp, modmaskp, modsetp)) + { + *modmaskp |= TERMKEY_KEYMOD_SHIFT; + *modsetp |= TERMKEY_KEYMOD_SHIFT; + return 1; + } #ifdef DEBUG - fprintf(stderr, "TODO: Need to convert funcname %s to a type/sym\n", funcname); + fprintf (stderr, "TODO: Need to convert funcname %s to a type/sym\n", funcname); #endif - return 0; + return 0; } -static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node) +static int +insert_seq (termkey_ti_t *ti, const char *seq, trie_node_t *node) { - int pos = 0; - struct trie_node *p = ti->root; - - // Unsigned because we'll be using it as an array subscript - unsigned char b; - - while((b = seq[pos])) { - struct trie_node *next = lookup_next(p, b); - if(!next) - break; - p = next; - pos++; - } - - while((b = seq[pos])) { - struct trie_node *next; - if(seq[pos+1]) - // Intermediate node - next = new_node_arr(0, 0xff); - else - // Final key node - next = node; - - if(!next) - return 0; - - switch(p->type) { - case TYPE_ARR: - { - struct trie_node_arr *nar = (struct trie_node_arr*)p; - if(b < nar->min || b > nar->max) { - fprintf(stderr, "ASSERT FAIL: Trie insert at 0x%02x is outside of extent bounds (0x%02x..0x%02x)\n", - b, nar->min, nar->max); - abort(); - } - nar->arr[b - nar->min] = next; - p = next; - break; - } - case TYPE_KEY: - case TYPE_MOUSE: - fprintf(stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n"); - abort(); - } - - pos++; - } - - return 1; + int pos = 0; + trie_node_t *p = ti->root; + + // Unsigned because we'll be using it as an array subscript + unsigned char b; + + while ((b = seq[pos])) + { + trie_node_t *next = lookup_next (p, b); + if (!next) + break; + p = next; + pos++; + } + + while ((b = seq[pos])) + { + trie_node_t *next; + if (seq[pos+1]) + // Intermediate node + next = new_node_arr (0, 0xff); + else + // Final key node + next = node; + + if (!next) + return 0; + + switch (p->type) + { + case TYPE_ARRAY: + { + trie_node_array_t *nar = (trie_node_array_t *) p; + if (b < nar->min || b > nar->max) + { + // FIXME + fprintf (stderr, "ASSERT FAIL: Trie insert at 0x%02x is outside of extent bounds (0x%02x..0x%02x)\n", + b, nar->min, nar->max); + abort (); + } + nar->arr[b - nar->min] = next; + p = next; + break; + } + case TYPE_KEY: + case TYPE_MOUSE: + // FIXME + fprintf (stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n"); + abort (); + } + + pos++; + } + return 1; } -struct TermKeyDriver termkey_driver_ti = { - .name = "terminfo", +termkey_driver_t termkey_driver_ti = +{ + .name = "terminfo", - .new_driver = new_driver, - .free_driver = free_driver, + .new_driver = new_driver, + .free_driver = free_driver, - .start_driver = start_driver, - .stop_driver = stop_driver, + .start_driver = start_driver, + .stop_driver = stop_driver, - .peekkey = peekkey, + .peekkey = peekkey, }; |