input: add NCKEY_MOUSEEVENT, match against CSI prefix #165

This commit is contained in:
nick black 2019-12-23 15:36:35 -05:00 committed by Nick Black
parent b4b4b3684a
commit aceda89261
3 changed files with 23 additions and 4 deletions

View File

@ -228,6 +228,7 @@ wchar_supppuab_p(char32_t w){
#define NCKEY_EXIT suppuabize(133)
#define NCKEY_PRINT suppuabize(134)
#define NCKEY_REFRESH suppuabize(135)
#define NCKEY_MOUSEEVENT suppuabize(200)
// See ppoll(2) for more detail. Provide a NULL 'ts' to block at length, a 'ts'
// of 0 for non-blocking operation, and otherwise a timespec to bound blocking.

View File

@ -73,6 +73,7 @@ const char* nckeystr(wchar_t spkey){
case NCKEY_EXIT: return "exit";
case NCKEY_PRINT: return "print";
case NCKEY_REFRESH: return "refresh";
case NCKEY_MOUSEEVENT: return "mouseevent";
default: return "unknown";
}
}

View File

@ -3,6 +3,12 @@
#include <sys/poll.h>
#include "internal.h"
// CSI (Control Sequence Indicators) originate in the terminal itself, and are
// not reported in their bare form to the user. For our purposes, these usually
// indicate a mouse event.
#define CSIPREFIX "\x1b[<"
static const char32_t NCKEY_CSI = 1;
static const unsigned char ESC = 0x1b; // 27
sig_atomic_t resize_seen = 0;
@ -30,7 +36,7 @@ unpop_keypress(notcurses* nc, int kpress){
// we assumed escapes can only be composed of 7-bit chars
typedef struct esctrie {
int special; // composed key terminating here
char32_t special; // composed key terminating here
struct esctrie** trie; // if non-NULL, next level of radix-128 trie
} esctrie;
@ -66,7 +72,7 @@ notcurses_add_input_escape(notcurses* nc, const char* esc, char32_t special){
fprintf(stderr, "Not an escape: %s (0x%x)\n", esc, special);
return -1;
}
if(!wchar_supppuab_p(special)){
if(!wchar_supppuab_p(special) && special != NCKEY_CSI){
fprintf(stderr, "Not a supplementary-b PUA char: %lc (0x%x)\n", special, special);
return -1;
}
@ -102,6 +108,12 @@ notcurses_add_input_escape(notcurses* nc, const char* esc, char32_t special){
return 0;
}
// We received the CSI prefix. Extract the data payload.
static char32_t
handle_csi(notcurses* nc){
return NCKEY_MOUSEEVENT;
}
// add the keypress we just read to our input queue (assuming there is room).
// if there is a full UTF8 codepoint or keystroke (composed or otherwise),
// return it, and pop it from the queue.
@ -115,7 +127,6 @@ handle_getc(notcurses* nc, int kpress){
const esctrie* esc = nc->inputescapes;
while(esc && esc->special == NCKEY_INVALID && nc->inputbuf_occupied){
int candidate = pop_input_keypress(nc);
fprintf(stderr, "CANDIDATE: 0x%02x %d '%c'\n", candidate, candidate, candidate);
if(esc->trie == NULL){
esc = NULL;
}else if(candidate >= 0x80 || candidate < 0){
@ -124,8 +135,10 @@ fprintf(stderr, "CANDIDATE: 0x%02x %d '%c'\n", candidate, candidate, candidate);
esc = esc->trie[candidate];
}
}
//fprintf(stderr, "esc? %c special: %d\n", esc ? 'y' : 'n', esc ? esc->special : NCKEY_INVALID);
if(esc && esc->special != NCKEY_INVALID){
if(esc->special == NCKEY_CSI){
return handle_csi(nc);
}
return esc->special;
}
// FIXME ungetc on failure! walk trie backwards or something
@ -301,5 +314,9 @@ int prep_special_keys(notcurses* nc){
return -1;
}
}
if(notcurses_add_input_escape(nc, CSIPREFIX, NCKEY_CSI)){
fprintf(stderr, "Couldn't add support for %s\n", k->tinfo);
return -1;
}
return 0;
}