Hello community, here is the log from the commit of package libtermkey for openSUSE:Factory checked in at 2020-10-29 09:22:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libtermkey (Old) and /work/SRC/openSUSE:Factory/.libtermkey.new.3463 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libtermkey" Thu Oct 29 09:22:51 2020 rev:4 rq:844623 version:0.22 Changes: -------- --- /work/SRC/openSUSE:Factory/libtermkey/libtermkey.changes 2018-11-09 07:54:50.183682492 +0100 +++ /work/SRC/openSUSE:Factory/.libtermkey.new.3463/libtermkey.changes 2020-10-29 09:22:56.746724543 +0100 @@ -1,0 +2,7 @@ +Thu Oct 22 14:47:38 UTC 2020 - Dirk Stoecker <[email protected]> 0.22 + +- update to 0.22 + 0.22 - changes: bugfixes for unit tests on BSD platforms + 0.21.1 - changes: internal bugfixes, valgrind neatness + +------------------------------------------------------------------- Old: ---- libtermkey-0.20.tar.gz New: ---- libtermkey-0.22.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libtermkey.spec ++++++ --- /var/tmp/diff_new_pack.JneClt/_old 2020-10-29 09:22:57.298725072 +0100 +++ /var/tmp/diff_new_pack.JneClt/_new 2020-10-29 09:22:57.302725076 +0100 @@ -1,7 +1,7 @@ # # spec file for package libtermkey # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,12 +18,12 @@ %define sover 1 Name: libtermkey -Version: 0.20 +Version: 0.22 Release: 0 Summary: Library for processing of keyboard entry from terminal-based programs License: MIT Group: Development/Libraries/C and C++ -Url: http://www.leonerd.org.uk/code/libtermkey/ +URL: http://www.leonerd.org.uk/code/libtermkey/ Source: http://www.leonerd.org.uk/code/libtermkey/libtermkey-%{version}.tar.gz Patch0: fix-syntax.patch BuildRequires: gcc @@ -91,7 +91,7 @@ %files -n %{name}%{sover} %defattr(-,root,root) -%doc LICENSE +%license LICENSE %{_libdir}/libtermkey.so.%{sover} %{_libdir}/libtermkey.so.%{sover}.* ++++++ libtermkey-0.20.tar.gz -> libtermkey-0.22.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/Makefile new/libtermkey-0.22/Makefile --- old/libtermkey-0.20/Makefile 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/Makefile 2019-03-14 14:47:10.000000000 +0100 @@ -49,10 +49,12 @@ TESTFILES=$(TESTSOURCES:.c=.t) VERSION_MAJOR=0 -VERSION_MINOR=20 +VERSION_MINOR=22 + +VERSION=$(VERSION_MAJOR).$(VERSION_MINOR) VERSION_CURRENT=15 -VERSION_REVISION=0 +VERSION_REVISION=2 VERSION_AGE=14 PREFIX=/usr/local @@ -110,7 +112,7 @@ install -d $(DESTDIR)$(INCDIR) install -m644 termkey.h $(DESTDIR)$(INCDIR) install -d $(DESTDIR)$(LIBDIR)/pkgconfig - sed "s,@LIBDIR@,$(LIBDIR),;s,@INCDIR@,$(INCDIR)," <termkey.pc.in >$(DESTDIR)$(LIBDIR)/pkgconfig/termkey.pc + LIBDIR=$(LIBDIR) INCDIR=$(INCDIR) VERSION=$(VERSION) sh termkey.pc.sh >$(DESTDIR)$(LIBDIR)/pkgconfig/termkey.pc install-lib: $(LIBRARY) install -d $(DESTDIR)$(LIBDIR) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/driver-csi.c new/libtermkey-0.22/driver-csi.c --- old/libtermkey-0.20/driver-csi.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/driver-csi.c 2019-03-14 14:47:10.000000000 +0100 @@ -158,7 +158,7 @@ } /* - * Handler for CSI M / CSI m mouse events in SRG and rxvt encodings + * Handler for CSI M / CSI m mouse events in SGR and rxvt encodings * Note: This does not handle X10 encoding */ @@ -569,6 +569,9 @@ if(result == TERMKEY_RES_NONE) { #ifdef DEBUG switch(args) { + case 0: + fprintf(stderr, "CSI: Unknown cmd=%c\n", (char)cmd); + break; case 1: fprintf(stderr, "CSI: Unknown arg1=%ld cmd=%c\n", arg[0], (char)cmd); break; @@ -585,6 +588,7 @@ #endif key->type = TERMKEY_TYPE_UNKNOWN_CSI; key->code.number = cmd; + key->modifiers = 0; tk->hightide = csi_len - introlen; *nbytep = introlen; // Do not yet eat the data bytes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/driver-ti.c new/libtermkey-0.22/driver-ti.c --- old/libtermkey-0.20/driver-ti.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/driver-ti.c 2019-03-14 14:47:10.000000000 +0100 @@ -10,17 +10,97 @@ # include <curses.h> # include <term.h> -/* curses.h has just poluted our namespace. We want this back */ +/* curses.h has just polluted our namespace. We want this back */ # undef buttons #endif #include <ctype.h> +#include <errno.h> +#include <stdbool.h> #include <stdio.h> #include <string.h> -#include <unistd.h> +#ifndef _WIN32 +# include <unistd.h> +#endif #include <sys/types.h> #include <sys/stat.h> +#define streq(a,b) (!strcmp(a,b)) + +#define MAX_FUNCNAME 9 + +static struct { + const char *funcname; + TermKeyType type; + TermKeySym 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 }, + { "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 }, +}; + +#ifdef HAVE_UNIBILIUM +static enum unibi_string unibi_lookup_str(const char *name) +{ + for(enum unibi_string ret = unibi_string_begin_+1; ret < unibi_string_end_; ret++) + if(streq(unibi_name_str(ret), name)) + return ret; + + return -1; +} + +static const char *unibi_get_str_by_name(const unibi_term *ut, const char *name) +{ + enum unibi_string idx = unibi_lookup_str(name); + if(idx == (enum unibi_string)-1) + return NULL; + + return unibi_get_str(ut, idx); +} +#endif + /* To be efficient at lookups, we store the byte sequence => keyinfo mapping * in a trie. This avoids a slow linear search through a flat list of * sequences. Because it is likely most nodes will be very sparse, we optimise @@ -30,7 +110,6 @@ typedef enum { TYPE_KEY, TYPE_ARR, - TYPE_MOUSE, } trie_nodetype; struct trie_node { @@ -63,7 +142,6 @@ char *stop_string; } TermKeyTI; -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); static struct trie_node *new_node_key(TermKeyType type, TermKeySym sym, int modmask, int modset) @@ -102,7 +180,6 @@ { switch(n->type) { case TYPE_KEY: - case TYPE_MOUSE: fprintf(stderr, "ABORT: lookup_next within a TYPE_KEY node\n"); abort(); case TYPE_ARR: @@ -121,7 +198,6 @@ { switch(n->type) { case TYPE_KEY: - case TYPE_MOUSE: break; case TYPE_ARR: { @@ -144,7 +220,6 @@ switch(n->type) { case TYPE_KEY: - case TYPE_MOUSE: return n; case TYPE_ARR: { @@ -152,7 +227,11 @@ unsigned char min, max; // Find the real bounds for(min = 0; !nar->arr[min]; min++) - ; + if(min == 255 && !nar->arr[min]) { + free(nar); + return new_node_arr(1, 0); + } + for(max = 0xff; !nar->arr[max]; max--) ; @@ -169,6 +248,30 @@ return n; } +static bool try_load_terminfo_key(TermKeyTI *ti, const char *name, struct keyinfo *info) +{ + const char *value = NULL; + +#ifdef HAVE_UNIBILIUM + if(ti->unibi) + value = unibi_get_str_by_name(ti->unibi, name); +#else + if(ti->term) + value = tigetstr(name); +#endif + + if(ti->tk->ti_getstr_hook) + value = (ti->tk->ti_getstr_hook)(name, value, ti->tk->ti_getstr_hook_data); + + if(!value || value == (char*)-1 || !value[0]) + return false; + + struct trie_node *node = new_node_key(info->type, info->sym, info->modifier_mask, info->modifier_set); + insert_seq(ti, value, node); + + return true; +} + static int load_terminfo(TermKeyTI *ti) { int i; @@ -190,70 +293,57 @@ if(!ti->root) return 0; -#ifdef HAVE_UNIBILIUM - for(i = unibi_string_begin_+1; i < unibi_string_end_; i++) -#else - for(i = 0; strfnames[i]; i++) -#endif - { - // Only care about the key_* constants -#ifdef HAVE_UNIBILIUM - const char *name = unibi_name_str(i); -#else - const char *name = strfnames[i]; -#endif - if(strncmp(name, "key_", 4) != 0) - continue; - -#ifdef HAVE_UNIBILIUM - const char *value = unibi_get_str(unibi, i); -#else - const char *value = tigetstr(strnames[i]); -#endif - - if(ti->tk->ti_getstr_hook) - value = (ti->tk->ti_getstr_hook)(name, value, ti->tk->ti_getstr_hook_data); + /* First the regular key strings + */ + for(i = 0; funcs[i].funcname; i++) { + char name[MAX_FUNCNAME + 5 + 1]; - if(!value || value == (char*)-1) + sprintf(name, "key_%s", funcs[i].funcname); + if(!try_load_terminfo_key(ti, name, &(struct keyinfo){ + .type = funcs[i].type, + .sym = funcs[i].sym, + .modifier_mask = funcs[i].mods, + .modifier_set = funcs[i].mods, + })) 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); - } + /* Maybe it has a shifted version */ + sprintf(name, "key_s%s", funcs[i].funcname); + try_load_terminfo_key(ti, name, &(struct keyinfo){ + .type = funcs[i].type, + .sym = funcs[i].sym, + .modifier_mask = funcs[i].mods | TERMKEY_KEYMOD_SHIFT, + .modifier_set = funcs[i].mods | TERMKEY_KEYMOD_SHIFT, + }); + } - if(node) - if(!insert_seq(ti, value, node)) { - free(node); - return 0; - } + /* Now the F<digit> keys + */ + for(i = 1; i < 255; i++) { + char name[9]; + sprintf(name, "key_f%d", i); + if(!try_load_terminfo_key(ti, name, &(struct keyinfo){ + .type = TERMKEY_TYPE_FUNCTION, + .sym = i, + .modifier_mask = 0, + .modifier_set = 0, + })) + break; } + /* Finally mouse mode */ + try_load_terminfo_key(ti, "key_mouse", &(struct keyinfo){ + .type = TERMKEY_TYPE_MOUSE, + }); + /* 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_keypad_xmit); + const char *keypad_xmit = unibi ? + unibi_get_str(unibi, unibi_keypad_xmit) : + NULL; #endif if(keypad_xmit) @@ -262,7 +352,9 @@ ti->start_string = NULL; #ifdef HAVE_UNIBILIUM - const char *keypad_local = unibi_get_str(unibi, unibi_keypad_local); + const char *keypad_local = unibi ? + unibi_get_str(unibi, unibi_keypad_local) : + NULL; #endif if(keypad_local) @@ -271,9 +363,15 @@ ti->stop_string = NULL; #ifdef HAVE_UNIBILIUM - unibi_destroy(unibi); + if(unibi) + unibi_destroy(unibi); + + ti->unibi = NULL; #else - free(ti->term); + if(ti->term) + free(ti->term); + + ti->term = NULL; #endif ti->root = compress_trie(ti->root); @@ -289,30 +387,34 @@ ti->tk = tk; ti->root = NULL; + ti->start_string = NULL; + ti->stop_string = NULL; #ifdef HAVE_UNIBILIUM ti->unibi = unibi_from_term(term); - if(!ti->unibi) - goto abort_free; + int saved_errno = errno; + if(!ti->unibi && saved_errno != ENOENT) { + free(ti); + return NULL; + } + /* ti->unibi may be NULL if errno == ENOENT. That means the terminal wasn't + * known. Lets keep going because if we get getstr hook that might invent + * new strings for us + */ #else { int err; + ti->term = NULL; + /* 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) - goto abort_free; - - ti->term = strdup(term); + if(setupterm((char*)term, 1, &err) == OK) + ti->term = strdup(term); } #endif return ti; - -abort_free: - free(ti); - - return NULL; } static int start_driver(TermKey *tk, void *info) @@ -338,8 +440,10 @@ if(fstat(tk->fd, &statbuf) == -1) return 0; +#ifndef _WIN32 if(S_ISFIFO(statbuf.st_mode)) return 1; +#endif // Can't call putp or tputs because they suck and don't give us fd control len = strlen(start_string); @@ -367,8 +471,10 @@ if(fstat(tk->fd, &statbuf) == -1) return 0; +#ifndef _WIN32 if(S_ISFIFO(statbuf.st_mode)) return 1; +#endif /* The terminfo database will contain keys in application cursor key mode. * We may need to enable that mode @@ -398,6 +504,14 @@ if(ti->stop_string) free(ti->stop_string); +#ifdef HAVE_UNIBILIUM + if(ti->unibi) + unibi_destroy(ti->unibi); +#else + if(ti->term) + free(ti->term); +#endif + free(ti); } @@ -420,15 +534,11 @@ 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) { + if(p->type != TYPE_KEY) + continue; + + struct trie_node_key *nk = (struct trie_node_key*)p; + if(nk->key.type == TERMKEY_TYPE_MOUSE) { tk->buffstart += pos; tk->buffcount -= pos; @@ -442,6 +552,12 @@ return mouse_result; } + + key->type = nk->key.type; + key->code.sym = nk->key.sym; + key->modifiers = nk->key.modifier_set; + *nbytep = pos; + return TERMKEY_RES_KEY; } // If p is not NULL then we hadn't walked off the end yet, so we have a @@ -452,106 +568,6 @@ return TERMKEY_RES_NONE; } -static struct { - const char *funcname; - TermKeyType type; - TermKeySym 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 }, -}; - -static int funcname2keysym(const char *funcname, TermKeyType *typep, TermKeySym *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; - } - -#ifdef DEBUG - fprintf(stderr, "TODO: Need to convert funcname %s to a type/sym\n", funcname); -#endif - - return 0; -} - static int insert_seq(TermKeyTI *ti, const char *seq, struct trie_node *node) { int pos = 0; @@ -594,7 +610,6 @@ break; } case TYPE_KEY: - case TYPE_MOUSE: fprintf(stderr, "ASSERT FAIL: Tried to insert child node in TYPE_KEY\n"); abort(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/man/termkey.7 new/libtermkey-0.22/man/termkey.7 --- old/libtermkey-0.20/man/termkey.7 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/man/termkey.7 2019-03-14 14:47:10.000000000 +0100 @@ -72,7 +72,7 @@ .PP A pair of functions are also provided to convert between key events and strings. \fBtermkey_strfkey\fP(3) converts a key event into a string, and \fBtermkey_strpkey\fP(3) parses a string turning it into a key event. .PP -Key events may be compared for equallity or ordering by using \fBtermkey_keycmp\fP(3). +Key events may be compared for equality or ordering by using \fBtermkey_keycmp\fP(3). .SS Control Flags Details of the behaviour of a \fBtermkey\fP instance are controlled by two bitmasks of flags. \fBtermkey_set_flags\fP(3) and \fBtermkey_get_flags\fP(3) set or return the flags used to control the general behaviour, and \fBtermkey_set_canonflags\fP(3) and \fBtermkey_get_canonflags\fP(3) set or return the flags that control the key value canonicalisation behaviour performed by \fBtermkey_canonicalise\fP(3). .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/man/termkey_advisereadable.3 new/libtermkey-0.22/man/termkey_advisereadable.3 --- old/libtermkey-0.20/man/termkey_advisereadable.3 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/man/termkey_advisereadable.3 2019-03-14 14:47:10.000000000 +0100 @@ -25,7 +25,7 @@ No nore bytes were read. .TP .B TERMKEY_RES_ERROR -An IO error occured. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead. +An IO error occurred. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead. .SH "SEE ALSO" .BR termkey_getkey (3), .BR termkey_waitkey (3), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/man/termkey_set_waittime.3 new/libtermkey-0.22/man/termkey_set_waittime.3 --- old/libtermkey-0.20/man/termkey_set_waittime.3 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/man/termkey_set_waittime.3 2019-03-14 14:47:10.000000000 +0100 @@ -11,11 +11,11 @@ .sp Link with \fI-ltermkey\fP. .SH DESCRIPTION -\fBtermkey_set_waittime\fP() sets the number of miliseconds that \fBtermkey_waitkey\fP(3) will wait for the remaining bytes of a multibyte sequence if it detects the start of a partially-complete one. +\fBtermkey_set_waittime\fP() sets the number of milliseconds that \fBtermkey_waitkey\fP(3) will wait for the remaining bytes of a multibyte sequence if it detects the start of a partially-complete one. .PP \fBtermkey_get_waittime\fP() returns the value set by the last call to \fBtermkey_set_waittime\fP(), or the default value if a different has not been set. .SH "RETURN VALUE" -\fBtermkey_set_waittime\fP() returns no value. \fBtermkey_get_waittime\fP() returns the current wait time in miliseconds. +\fBtermkey_set_waittime\fP() returns no value. \fBtermkey_get_waittime\fP() returns the current wait time in milliseconds. .SH "SEE ALSO" .BR termkey_getkey (3), .BR termkey_waitkey (3), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/man/termkey_strfkey.3 new/libtermkey-0.22/man/termkey_strfkey.3 --- old/libtermkey-0.20/man/termkey_strfkey.3 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/man/termkey_strfkey.3 2019-03-14 14:47:10.000000000 +0100 @@ -47,7 +47,7 @@ .B TERMKEY_FORMAT_URWID Shortcut to set \fBALTISMETA\fP, \fBLONGMOD\fP, \fBLOWERMOD\fP, \fBSPACEMOD\fP and \fBLOWERSPACE\fP, to give an output close to the format the \fIurwid\fP python library uses. .PP -When formatting a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function uses the \fIutf8\fP member. If this member contains an empty string (i.e. its first character is 0) then this member will be prefilled by the function from the \fIcode.number\fP member. This can be convenient when the key structure is being constructed programatically by user code. +When formatting a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function uses the \fIutf8\fP member. If this member contains an empty string (i.e. its first character is 0) then this member will be prefilled by the function from the \fIcode.number\fP member. This can be convenient when the key structure is being constructed programmatically by user code. .SH "RETURN VALUE" \fBtermkey_strfkey\fP() returns the number of characters written to \fIbuffer\fP. .SH "SEE ALSO" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/man/termkey_strpkey.3 new/libtermkey-0.22/man/termkey_strpkey.3 --- old/libtermkey-0.20/man/termkey_strpkey.3 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/man/termkey_strpkey.3 2019-03-14 14:47:10.000000000 +0100 @@ -25,17 +25,20 @@ Expect the name "\f(CWMeta\fP" or the letter "\f(CWM\fP" instead of "\f(CWAlt\fP" or "\f(CWA\fP". .TP .B TERMKEY_FORMAT_SPACEMOD -Expect spaces instead of hyphens to separate the modifer name(s) from the base key name. +Expect spaces instead of hyphens to separate the modifier name(s) from the base key name. .TP .B TERMKEY_FORMAT_LOWERMOD Expect lowercase for the modifier name. .TP .B TERMKEY_FORMAT_LOWERSPACE Expect lowercase with spaces in for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP"). +.TP +.B TERMKEY_FORMAT_MOUSE_POS +Expect a mouse event to be followed by its position rendered as "\f(CW@ (col,line)\fP". .PP Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3). .PP -The \fBTERMKEY_FORMAT_WRAPBRACKET\fP and \fBTERMKEY_FORMAT_MOUSE_POS\fP options are currently not supported by \fBtermkey_strpkey\fP(). When returning a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function will fill in the \fIutf8\fP member. +The \fBTERMKEY_FORMAT_WRAPBRACKET\fP option is currently not supported by \fBtermkey_strpkey\fP(). When returning a \fBTERMKEY_TYPE_UNICODE\fP key structure, this function will fill in the \fIutf8\fP member. .SH "RETURN VALUE" After a successful parse, \fBtermkey_strpkey\fP() returns a pointer to the first character of the input it did not consume. If the input string contains more characters then this will point at the first character beyond. If the entire input string was consumed, then this will point at a null byte. If \fBtermkey_strpkey\fP() fails to parse, it returns \fBNULL\fP. After a failed parse, the \fIkey\fP structure may contain partial or invalid results. The structure will only be valid if the function returns a non-\fBNULL\fP result. .SH "SEE ALSO" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/man/termkey_waitkey.3 new/libtermkey-0.22/man/termkey_waitkey.3 --- old/libtermkey-0.20/man/termkey_waitkey.3 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/man/termkey_waitkey.3 2019-03-14 14:47:10.000000000 +0100 @@ -25,7 +25,7 @@ No key events are ready and the terminal has been closed, so no more will arrive. .TP .B TERMKEY_RES_ERROR -An IO error occured. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead. If this is called with terminal IO stopped, due to \fBtermkey_stop\fP(3) then \fIerrno\fP will be set to \fBEINVAL\fP. +An IO error occurred. \fIerrno\fP will be preserved. If the error is \fBEINTR\fP then this will only be returned if \fBTERMKEY_FLAG_EINTR\fP flag is not set; if it is then the IO operation will be retried instead. If this is called with terminal IO stopped, due to \fBtermkey_stop\fP(3) then \fIerrno\fP will be set to \fBEINVAL\fP. .SH EXAMPLE The following example program prints details of every keypress until the user presses \fICtrl-C\fP. .PP @@ -151,6 +151,8 @@ } .in .fi +.SH COMPATIBILITY +This function is not available on Windows. .SH "SEE ALSO" .BR termkey_getkey (3), .BR termkey_set_waittime (3), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/12strpkey.c new/libtermkey-0.22/t/12strpkey.c --- old/libtermkey-0.20/t/12strpkey.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/12strpkey.c 2019-03-14 14:47:10.000000000 +0100 @@ -5,11 +5,14 @@ { TermKey *tk; TermKeyKey key; + TermKeyMouseEvent mouse; + int button, line, col; const char *endp; #define CLEAR_KEY do { key.type = -1; key.code.codepoint = -1; key.modifiers = -1; key.utf8[0] = 0; } while(0) +#define CLEAR_MOUSE do { CLEAR_KEY; mouse = -1; button = -1, line = -1; col = -1; } while(0) - plan_tests(62); + plan_tests(84); tk = termkey_new_abstract("vt100", 0); @@ -115,6 +118,48 @@ is_int(key.modifiers, 0, "key.modifiers for func/5/0"); is_str(endp, "", "consumed entire input for func/5/0"); + CLEAR_MOUSE; + endp = termkey_strpkey(tk, "MousePress(1)", &key, 0); + termkey_interpret_mouse(tk, &key, &mouse, &button, &line, &col); + is_int(key.type, TERMKEY_TYPE_MOUSE, "key.type for mouse"); + is_int(mouse, TERMKEY_MOUSE_PRESS, "mouse press event"); + is_int(button, 1, "mouse button 1"); + is_str(endp, "", "consumed entire input for MousePress(1)"); + + CLEAR_MOUSE; + endp = termkey_strpkey(tk, "MousePress(2) @ (3, 5)", &key, TERMKEY_FORMAT_MOUSE_POS); + termkey_interpret_mouse(tk, &key, &mouse, &button, &line, &col); + is_int(key.type, TERMKEY_TYPE_MOUSE, "key.type for mouse"); + is_int(mouse, TERMKEY_MOUSE_PRESS, "mouse press event"); + is_int(button, 2, "mouse button 2"); + is_int(col, 3, "mouse column 3"); + is_int(line, 5, "mouse line 5"); + is_str(endp, "", "consumed entire input for MousePress(2) @ (3, 5)"); + + CLEAR_MOUSE; + endp = termkey_strpkey(tk, "MouseRelease(1)", &key, 0); + termkey_interpret_mouse(tk, &key, &mouse, &button, &line, &col); + is_int(key.type, TERMKEY_TYPE_MOUSE, "key.type for mouse"); + is_int(mouse, TERMKEY_MOUSE_RELEASE, "mouse release event"); + is_int(button, 0, "mouse button 1 lost"); // TODO: can we recover it? + is_str(endp, "", "consumed entire input for MouseRelease(1)"); + + CLEAR_MOUSE; + endp = termkey_strpkey(tk, "MouseDrag(1)", &key, 0); + termkey_interpret_mouse(tk, &key, &mouse, &button, &line, &col); + is_int(key.type, TERMKEY_TYPE_MOUSE, "key.type for mouse"); + is_int(mouse, TERMKEY_MOUSE_DRAG, "mouse drap event"); + is_int(button, 1, "mouse button 1"); + is_str(endp, "", "consumed entire input for MouseDrag(1)"); + + CLEAR_MOUSE; + endp = termkey_strpkey(tk, "MouseUnknown(1)", &key, 0); + termkey_interpret_mouse(tk, &key, &mouse, &button, &line, &col); + is_int(key.type, TERMKEY_TYPE_MOUSE, "key.type for mouse"); + is_int(mouse, TERMKEY_MOUSE_UNKNOWN, "mouse unknown event"); + is_int(button, 0, "mouse button 1 lost"); + is_str(endp, "", "consumed entire input for MouseUnknown(1)"); + termkey_destroy(tk); return exit_status(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/30mouse.c new/libtermkey-0.22/t/30mouse.c --- old/libtermkey-0.20/t/30mouse.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/30mouse.c 2019-03-14 14:47:10.000000000 +0100 @@ -14,7 +14,7 @@ tk = termkey_new_abstract("vt100", 0); - termkey_push_bytes(tk, "\e[M !!", 6); + termkey_push_bytes(tk, "\x1b[M !!", 6); key.type = -1; is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse press"); @@ -38,7 +38,7 @@ is_int(len, 21, "string length for press"); is_str(buffer, "MousePress(1) @ (1,1)", "string buffer for press"); - termkey_push_bytes(tk, "\e[M@\"!", 6); + termkey_push_bytes(tk, "\x1b[M@\"!", 6); key.type = -1; ev = -1; button = -1; line = -1; col = -1; @@ -51,7 +51,7 @@ is_int(col, 2, "mouse column for drag"); is_int(key.modifiers, 0, "modifiers for press"); - termkey_push_bytes(tk, "\e[M##!", 6); + termkey_push_bytes(tk, "\x1b[M##!", 6); key.type = -1; ev = -1; button = -1; line = -1; col = -1; @@ -63,7 +63,7 @@ is_int(col, 3, "mouse column for release"); is_int(key.modifiers, 0, "modifiers for press"); - termkey_push_bytes(tk, "\e[M0++", 6); + termkey_push_bytes(tk, "\x1b[M0++", 6); key.type = -1; ev = -1; button = -1; line = -1; col = -1; @@ -81,7 +81,7 @@ is_str(buffer, "C-MousePress(1)", "string buffer for Ctrl-press"); // rxvt protocol - termkey_push_bytes(tk, "\e[0;20;20M", 10); + termkey_push_bytes(tk, "\x1b[0;20;20M", 10); key.type = -1; is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse press rxvt protocol"); @@ -96,7 +96,7 @@ is_int(col, 20, "mouse column for press rxvt protocol"); is_int(key.modifiers, 0, "modifiers for press rxvt protocol"); - termkey_push_bytes(tk, "\e[3;20;20M", 10); + termkey_push_bytes(tk, "\x1b[3;20;20M", 10); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse release rxvt protocol"); @@ -111,7 +111,7 @@ is_int(key.modifiers, 0, "modifiers for release rxvt protocol"); // SGR protocol - termkey_push_bytes(tk, "\e[<0;30;30M", 11); + termkey_push_bytes(tk, "\x1b[<0;30;30M", 11); key.type = -1; is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse press SGR encoding"); @@ -127,7 +127,7 @@ is_int(col, 30, "mouse column for press SGR"); is_int(key.modifiers, 0, "modifiers for press SGR"); - termkey_push_bytes(tk, "\e[<0;30;30m", 11); + termkey_push_bytes(tk, "\x1b[<0;30;30m", 11); key.type = -1; is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mouse release SGR encoding"); @@ -139,7 +139,7 @@ is_int(ev, TERMKEY_MOUSE_RELEASE, "mouse event for release SGR"); - termkey_push_bytes(tk, "\e[<0;500;300M", 13); + termkey_push_bytes(tk, "\x1b[<0;500;300M", 13); key.type = -1; ev = -1; button = -1; line = -1; col = -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/31position.c new/libtermkey-0.22/t/31position.c --- old/libtermkey-0.20/t/31position.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/31position.c 2019-03-14 14:47:10.000000000 +0100 @@ -11,7 +11,7 @@ tk = termkey_new_abstract("vt100", 0); - termkey_push_bytes(tk, "\e[?15;7R", 8); + termkey_push_bytes(tk, "\x1b[?15;7R", 8); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for position report"); @@ -25,7 +25,7 @@ /* A plain CSI R is likely to be <F3> though. * This is tricky :/ */ - termkey_push_bytes(tk, "\e[R", 3); + termkey_push_bytes(tk, "\x1b[R", 3); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for <F3>"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/32modereport.c new/libtermkey-0.22/t/32modereport.c --- old/libtermkey-0.20/t/32modereport.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/32modereport.c 2019-03-14 14:47:10.000000000 +0100 @@ -11,7 +11,7 @@ tk = termkey_new_abstract("vt100", 0); - termkey_push_bytes(tk, "\e[?1;2$y", 8); + termkey_push_bytes(tk, "\x1b[?1;2$y", 8); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mode report"); @@ -23,7 +23,7 @@ is_int(mode, 1, "mode number from mode report"); is_int(value, 2, "mode value from mode report"); - termkey_push_bytes(tk, "\e[4;1$y", 7); + termkey_push_bytes(tk, "\x1b[4;1$y", 7); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for mode report"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/38csi.c new/libtermkey-0.22/t/38csi.c --- old/libtermkey-0.20/t/38csi.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/38csi.c 2019-03-14 14:47:10.000000000 +0100 @@ -13,7 +13,7 @@ tk = termkey_new_abstract("vt100", 0); - termkey_push_bytes(tk, "\e[5;25v", 7); + termkey_push_bytes(tk, "\x1b[5;25v", 7); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for CSI v"); @@ -26,14 +26,14 @@ is_int(args[1], 25, "args[1] for unknown CSI"); is_int(command, 'v', "command for unknown CSI"); - termkey_push_bytes(tk, "\e[?w", 4); + termkey_push_bytes(tk, "\x1b[?w", 4); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for CSI ? w"); is_int(key.type, TERMKEY_TYPE_UNKNOWN_CSI, "key.type for unknown CSI"); is_int(termkey_interpret_csi(tk, &key, args, &nargs, &command), TERMKEY_RES_KEY, "interpret_csi yields RES_KEY"); is_int(command, '?'<<8 | 'w', "command for unknown CSI"); - termkey_push_bytes(tk, "\e[?$x", 5); + termkey_push_bytes(tk, "\x1b[?$x", 5); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for CSI ? $x"); is_int(key.type, TERMKEY_TYPE_UNKNOWN_CSI, "key.type for unknown CSI"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/39dcs.c new/libtermkey-0.22/t/39dcs.c --- old/libtermkey-0.20/t/39dcs.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/39dcs.c 2019-03-14 14:47:10.000000000 +0100 @@ -12,7 +12,7 @@ tk = termkey_new_abstract("xterm", 0); // 7bit DCS - termkey_push_bytes(tk, "\eP1$r1 q\e\\", 10); + termkey_push_bytes(tk, "\x1bP1$r1 q\x1b\\", 10); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for DCS"); @@ -38,7 +38,7 @@ is_int(termkey_getkey(tk, &key), TERMKEY_RES_NONE, "getkey again yields RES_NONE"); // 7bit OSC - termkey_push_bytes(tk, "\e]15;abc\e\\", 10); + termkey_push_bytes(tk, "\x1b]15;abc\x1b\\", 10); is_int(termkey_getkey(tk, &key), TERMKEY_RES_KEY, "getkey yields RES_KEY for OSC"); @@ -51,11 +51,11 @@ is_int(termkey_getkey(tk, &key), TERMKEY_RES_NONE, "getkey again yields RES_NONE"); // False alarm - termkey_push_bytes(tk, "\eP", 2); + termkey_push_bytes(tk, "\x1bP", 2); is_int(termkey_getkey(tk, &key), TERMKEY_RES_AGAIN, "getkey yields RES_AGAIN for false alarm"); - is_int(termkey_getkey_force(tk, &key), TERMKEY_RES_KEY, "getkey_forvce yields RES_KEY for false alarm"); + is_int(termkey_getkey_force(tk, &key), TERMKEY_RES_KEY, "getkey_force yields RES_KEY for false alarm"); is_int(key.type, TERMKEY_TYPE_UNICODE, "key.type for false alarm"); is_int(key.code.codepoint, 'P', "key.code.codepoint for false alarm"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/t/40ti-override.c new/libtermkey-0.22/t/40ti-override.c --- old/libtermkey-0.20/t/40ti-override.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/t/40ti-override.c 2019-03-14 14:47:10.000000000 +0100 @@ -22,7 +22,11 @@ plan_tests(3); - tk = termkey_new_abstract("vt100", TERMKEY_FLAG_NOSTART); + /* There was never a VT750. We've just made this string up. + * This test ensures that the hooked function can invent TI strings for new + * terminal types that don't exist in the TI database yet. + */ + tk = termkey_new_abstract("vt750", TERMKEY_FLAG_NOSTART); termkey_hook_terminfo_getstr(tk, &backspace_is_X, NULL); termkey_start(tk); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/termkey-internal.h new/libtermkey-0.22/termkey-internal.h --- old/libtermkey-0.20/termkey-internal.h 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/termkey-internal.h 2019-03-14 14:47:10.000000000 +0100 @@ -1,10 +1,23 @@ #ifndef GUARD_TERMKEY_INTERNAL_H_ #define GUARD_TERMKEY_INTERNAL_H_ +#define HAVE_TERMIOS + +#ifdef _WIN32 +# undef HAVE_TERMIOS +#endif + #include "termkey.h" #include <stdint.h> -#include <termios.h> +#ifdef HAVE_TERMIOS +# include <termios.h> +#endif + +#ifdef _MSC_VER +#include <BaseTsd.h> +typedef SSIZE_T ssize_t; +#endif struct TermKeyDriver { @@ -41,8 +54,10 @@ size_t hightide; /* Position beyond buffstart at which peekkey() should next start * normally 0, but see also termkey_interpret_csi */ +#ifdef HAVE_TERMIOS struct termios restore_termios; char restore_termios_valid; +#endif TermKey_Terminfo_Getstr_Hook *ti_getstr_hook; void *ti_getstr_hook_data; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/termkey.c new/libtermkey-0.22/termkey.c --- old/libtermkey-0.20/termkey.c 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/termkey.c 2019-03-14 14:47:10.000000000 +0100 @@ -3,14 +3,20 @@ #include <ctype.h> #include <errno.h> -#include <poll.h> -#include <unistd.h> +#ifndef _WIN32 +# include <poll.h> +# include <unistd.h> +# include <strings.h> +#endif #include <string.h> -#include <strings.h> #include <stdio.h> -#define strcaseeq(a,b) (strcasecmp(a,b) == 0) +#ifdef _MSC_VER +# define strcaseeq(a,b) (_stricmp(a,b) == 0) +#else +# define strcaseeq(a,b) (strcasecmp(a,b) == 0) +#endif void termkey_check_version(int major, int minor) { @@ -111,10 +117,13 @@ { 0, NULL }, }; +// Mouse event names +static const char *evnames[] = { "Unknown", "Press", "Drag", "Release" }; + #define CHARAT(i) (tk->buffer[tk->buffstart + (i)]) #ifdef DEBUG -/* Some internal deubgging functions */ +/* Some internal debugging functions */ static void print_buffer(TermKey *tk) { @@ -282,7 +291,9 @@ tk->buffsize = 256; /* bytes */ tk->hightide = 0; +#ifdef HAVE_TERMIOS tk->restore_termios_valid = 0; +#endif tk->ti_getstr_hook = NULL; tk->ti_getstr_hook_data = NULL; @@ -483,6 +494,7 @@ if(tk->is_started) return 1; +#ifdef HAVE_TERMIOS if(tk->fd != -1 && !(tk->flags & TERMKEY_FLAG_NOTERMIOS)) { struct termios termios; if(tcgetattr(tk->fd, &termios) == 0) { @@ -517,6 +529,7 @@ tcsetattr(tk->fd, TCSANOW, &termios); } } +#endif struct TermKeyDriverNode *p; for(p = tk->drivers; p; p = p->next) @@ -542,8 +555,10 @@ if(p->driver->stop_driver) (*p->driver->stop_driver)(tk, p->info); +#ifdef HAVE_TERMIOS if(tk->restore_termios_valid) tcsetattr(tk->fd, TCSANOW, &tk->restore_termios); +#endif tk->is_started = 0; @@ -768,12 +783,12 @@ if(!key->code.sym) { key->type = TERMKEY_TYPE_UNICODE; /* Generically modified Unicode ought not report the SHIFT state, or else - * we get into complicationg trying to report Shift-; vs : and so on... + * we get into complications trying to report Shift-; vs : and so on... * In order to be able to represent Ctrl-Shift-A as CTRL modified * unicode A, we need to call Ctrl-A simply 'a', lowercase */ if(codepoint+0x40 >= 'A' && codepoint+0x40 <= 'Z') - // it's a letter - use lowecase instead + // it's a letter - use lowercase instead key->code.codepoint = codepoint + 0x60; else key->code.codepoint = codepoint + 0x40; @@ -1046,6 +1061,7 @@ return ret; } +#ifndef _WIN32 TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key) { if(tk->fd == -1) { @@ -1105,6 +1121,7 @@ /* UNREACHABLE */ } +#endif TermKeyResult termkey_advisereadable(TermKey *tk) { @@ -1307,7 +1324,7 @@ key->modifiers == TERMKEY_KEYMOD_CTRL) { long codepoint = key->code.codepoint; - // Handle some of the special casesfirst + // Handle some of the special cases first if(codepoint >= 'a' && codepoint <= 'z') { l = snprintf(buffer + pos, len - pos, wrapbracket ? "<^%c>" : "^%c", (char)codepoint - 0x20); if(l <= 0) return pos; @@ -1373,8 +1390,6 @@ int line, col; termkey_interpret_mouse(tk, key, &ev, &button, &line, &col); - static const char *evnames[] = { "Unknown", "Press", "Drag", "Release" }; - l = snprintf(buffer + pos, len - pos, "Mouse%s(%d)", evnames[ev], button); @@ -1466,6 +1481,8 @@ size_t nbytes; ssize_t snbytes; const char *endstr; + int button; + char event_name[32]; if((endstr = termkey_lookup_keyname_format(tk, str, &key->code.sym, format))) { key->type = TERMKEY_TYPE_KEYSYM; @@ -1475,13 +1492,48 @@ key->type = TERMKEY_TYPE_FUNCTION; str += snbytes; } + else if(sscanf(str, "Mouse%31[^(](%d)%zn", event_name, &button, &snbytes) == 2) { + str += snbytes; + key->type = TERMKEY_TYPE_MOUSE; + + TermKeyMouseEvent ev = TERMKEY_MOUSE_UNKNOWN; + for(size_t i = 0; i < sizeof(evnames)/sizeof(evnames[0]); i++) { + if(strcmp(evnames[i], event_name) == 0) { + ev = TERMKEY_MOUSE_UNKNOWN + i; + break; + } + } + + int code; + switch(ev) { + case TERMKEY_MOUSE_PRESS: + case TERMKEY_MOUSE_DRAG: + code = button - 1; + if(ev == TERMKEY_MOUSE_DRAG) { + code |= 0x20; + } + break; + case TERMKEY_MOUSE_RELEASE: + code = 3; + break; + default: + code = 128; + break; + } + key->code.mouse[0] = code; + + unsigned int line = 0, col = 0; + if((format & TERMKEY_FORMAT_MOUSE_POS) && sscanf(str, " @ (%u,%u)%zn", &col, &line, &snbytes) == 2) { + str += snbytes; + } + termkey_key_set_linecol(key, col, line); + } // Unicode must be last else if(parse_utf8((unsigned const char *)str, strlen(str), &key->code.codepoint, &nbytes) == TERMKEY_RES_KEY) { key->type = TERMKEY_TYPE_UNICODE; fill_utf8(key); str += nbytes; } - // TODO: Consider mouse events? else return NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/termkey.h new/libtermkey-0.22/termkey.h --- old/libtermkey-0.20/termkey.h 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/termkey.h 2019-03-14 14:47:10.000000000 +0100 @@ -9,7 +9,7 @@ #include <stdlib.h> #define TERMKEY_VERSION_MAJOR 0 -#define TERMKEY_VERSION_MINOR 20 +#define TERMKEY_VERSION_MINOR 22 #define TERMKEY_CHECK_VERSION \ termkey_check_version(TERMKEY_VERSION_MAJOR, TERMKEY_VERSION_MINOR) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/termkey.pc.in new/libtermkey-0.22/termkey.pc.in --- old/libtermkey-0.20/termkey.pc.in 2017-03-30 15:17:09.000000000 +0200 +++ new/libtermkey-0.22/termkey.pc.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,8 +0,0 @@ -libdir=@LIBDIR@ -includedir=@INCDIR@ - -Name: termkey -Description: Abstract terminal key input library -Version: 0.20 -Libs: -L${libdir} -ltermkey -Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libtermkey-0.20/termkey.pc.sh new/libtermkey-0.22/termkey.pc.sh --- old/libtermkey-0.20/termkey.pc.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/libtermkey-0.22/termkey.pc.sh 2019-03-14 14:47:10.000000000 +0100 @@ -0,0 +1,10 @@ +cat <<EOF +libdir=$LIBDIR +includedir=$INCDIR + +Name: termkey +Description: Abstract terminal key input library +Version: $VERSION +Libs: -L\${libdir} -ltermkey +Cflags: -I\${includedir} +EOF
