diff options
Diffstat (limited to 'src/nvim/tui/termkey')
-rw-r--r-- | src/nvim/tui/termkey/driver-csi.c | 57 | ||||
-rw-r--r-- | src/nvim/tui/termkey/driver-csi.h | 2 | ||||
-rw-r--r-- | src/nvim/tui/termkey/driver-ti.c | 6 | ||||
-rw-r--r-- | src/nvim/tui/termkey/driver-ti.h | 2 | ||||
-rw-r--r-- | src/nvim/tui/termkey/termkey-internal.h | 2 | ||||
-rw-r--r-- | src/nvim/tui/termkey/termkey.c | 55 | ||||
-rw-r--r-- | src/nvim/tui/termkey/termkey.h | 6 | ||||
-rw-r--r-- | src/nvim/tui/termkey/termkey_defs.h | 9 |
8 files changed, 82 insertions, 57 deletions
diff --git a/src/nvim/tui/termkey/driver-csi.c b/src/nvim/tui/termkey/driver-csi.c index 28c7eaccfd..d427be50ff 100644 --- a/src/nvim/tui/termkey/driver-csi.c +++ b/src/nvim/tui/termkey/driver-csi.c @@ -1,11 +1,10 @@ #include <assert.h> -#include <stdio.h> +#include <stdint.h> #include <string.h> #include "nvim/memory.h" #include "nvim/tui/termkey/driver-csi.h" #include "nvim/tui/termkey/termkey-internal.h" -#include "nvim/tui/termkey/termkey.h" #include "nvim/tui/termkey/termkey_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -32,11 +31,20 @@ static TermKeyResult handle_csi_ss3_full(TermKey *tk, TermKeyKey *key, int cmd, if (nparams > 1 && params[1].param != NULL) { int arg = 0; - result = termkey_interpret_csi_param(params[1], &arg, NULL, NULL); + int subparam = 0; + size_t nsubparams = 1; + result = termkey_interpret_csi_param(params[1], &arg, &subparam, &nsubparams); if (result != TERMKEY_RES_KEY) { return result; } + if (nsubparams > 0) { + key->event = parse_key_event(subparam); + if (key->event == TERMKEY_EVENT_UNKNOWN) { + return TERMKEY_RES_NONE; + } + } + key->modifiers = arg - 1; } else { key->modifiers = 0; @@ -104,11 +112,20 @@ static TermKeyResult handle_csifunc(TermKey *tk, TermKeyKey *key, int cmd, TermK int args[3]; if (nparams > 1 && params[1].param != NULL) { - result = termkey_interpret_csi_param(params[1], &args[1], NULL, NULL); + int subparam = 0; + size_t nsubparams = 1; + result = termkey_interpret_csi_param(params[1], &args[1], &subparam, &nsubparams); if (result != TERMKEY_RES_KEY) { return result; } + if (nsubparams > 0) { + key->event = parse_key_event(subparam); + if (key->event == TERMKEY_EVENT_UNKNOWN) { + return TERMKEY_RES_NONE; + } + } + key->modifiers = args[1] - 1; } else { key->modifiers = 0; @@ -178,9 +195,11 @@ static TermKeyResult handle_csi_u(TermKey *tk, TermKeyKey *key, int cmd, TermKey return TERMKEY_RES_ERROR; } - if (nsubparams > 0 && subparam != 1) { - // Not a press event. Ignore for now - return TERMKEY_RES_NONE; + if (nsubparams > 0) { + key->event = parse_key_event(subparam); + if (key->event == TERMKEY_EVENT_UNKNOWN) { + return TERMKEY_RES_NONE; + } } key->modifiers = args[1] - 1; @@ -308,6 +327,12 @@ TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKe btn = code + 4 - 64; break; + case 128: + case 129: + *event = drag ? TERMKEY_MOUSE_DRAG : TERMKEY_MOUSE_PRESS; + btn = code + 8 - 128; + break; + default: *event = TERMKEY_MOUSE_UNKNOWN; } @@ -419,6 +444,20 @@ TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, i #define CHARAT(i) (tk->buffer[tk->buffstart + (i)]) +static TermKeyEvent parse_key_event(int n) +{ + switch (n) { + case 1: + return TERMKEY_EVENT_PRESS; + case 2: + return TERMKEY_EVENT_REPEAT; + case 3: + return TERMKEY_EVENT_RELEASE; + default: + return TERMKEY_EVENT_UNKNOWN; + } +} + static TermKeyResult parse_csi(TermKey *tk, size_t introlen, size_t *csi_len, TermKeyCsiParam params[], size_t *nargs, unsigned *commandp) { @@ -529,7 +568,7 @@ TermKeyResult termkey_interpret_csi_param(TermKeyCsiParam param, int *paramp, in if (c == ':') { if (length == 0) { *paramp = arg; - } else { + } else if (subparams != NULL) { subparams[length - 1] = arg; } @@ -544,7 +583,7 @@ TermKeyResult termkey_interpret_csi_param(TermKeyCsiParam param, int *paramp, in if (length == 0) { *paramp = arg; - } else { + } else if (subparams != NULL) { subparams[length - 1] = arg; } diff --git a/src/nvim/tui/termkey/driver-csi.h b/src/nvim/tui/termkey/driver-csi.h index 0abd8b5c2e..644cc9d58b 100644 --- a/src/nvim/tui/termkey/driver-csi.h +++ b/src/nvim/tui/termkey/driver-csi.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/tui/termkey/termkey_defs.h" +#include "nvim/tui/termkey/termkey_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/termkey/driver-csi.h.generated.h" diff --git a/src/nvim/tui/termkey/driver-ti.c b/src/nvim/tui/termkey/driver-ti.c index 745ee9902f..e402f93e93 100644 --- a/src/nvim/tui/termkey/driver-ti.c +++ b/src/nvim/tui/termkey/driver-ti.c @@ -1,16 +1,16 @@ -#include <ctype.h> #include <errno.h> #include <stdbool.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/stat.h> -#include <sys/types.h> #include <unibilium.h> +#include <uv.h> #include "nvim/memory.h" #include "nvim/tui/termkey/driver-ti.h" #include "nvim/tui/termkey/termkey-internal.h" -#include "nvim/tui/termkey/termkey.h" +#include "nvim/tui/termkey/termkey_defs.h" #ifndef _WIN32 # include <unistd.h> diff --git a/src/nvim/tui/termkey/driver-ti.h b/src/nvim/tui/termkey/driver-ti.h index df9bd72d5b..6dbcb11344 100644 --- a/src/nvim/tui/termkey/driver-ti.h +++ b/src/nvim/tui/termkey/driver-ti.h @@ -1,6 +1,6 @@ #pragma once -#include "nvim/tui/termkey/termkey_defs.h" +#include "nvim/tui/termkey/termkey_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/termkey/driver-ti.h.generated.h" diff --git a/src/nvim/tui/termkey/termkey-internal.h b/src/nvim/tui/termkey/termkey-internal.h index 107591f950..97fae939c5 100644 --- a/src/nvim/tui/termkey/termkey-internal.h +++ b/src/nvim/tui/termkey/termkey-internal.h @@ -47,7 +47,7 @@ struct TermKey { int canonflags; unsigned char *buffer; size_t buffstart; // First offset in buffer - size_t buffcount; // NUMBER of entires valid in buffer + size_t buffcount; // NUMBER of entries valid in buffer size_t buffsize; // Total malloc'ed size size_t hightide; // Position beyond buffstart at which peekkey() should next start // normally 0, but see also termkey_interpret_csi diff --git a/src/nvim/tui/termkey/termkey.c b/src/nvim/tui/termkey/termkey.c index e6440118f3..eabde2f9f7 100644 --- a/src/nvim/tui/termkey/termkey.c +++ b/src/nvim/tui/termkey/termkey.c @@ -1,9 +1,9 @@ #include <ctype.h> #include <errno.h> -#include <stdbool.h> #include <stdio.h> #include <string.h> +#include "nvim/macros_defs.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/tui/termkey/driver-csi.h" @@ -13,9 +13,10 @@ #include "nvim/tui/termkey/termkey_defs.h" #ifndef _WIN32 -# include <poll.h> -# include <strings.h> -# include <unistd.h> +// Include these directly instead of <termios.h> which is system-dependent. #31704 +# include <poll.h> // IWYU pragma: keep +# include <strings.h> // IWYU pragma: keep +# include <unistd.h> // IWYU pragma: keep #else # include <io.h> #endif @@ -633,40 +634,13 @@ static void eat_bytes(TermKey *tk, size_t count) tk->buffcount -= count; } -// TODO(dundargoc): we should be able to replace this with utf_char2bytes from mbyte.c int fill_utf8(int codepoint, char *str) { - int nbytes = utf_char2len(codepoint); - + int nbytes = utf_char2bytes(codepoint, str); str[nbytes] = 0; - - // This is easier done backwards - int b = nbytes; - while (b > 1) { - b--; - str[b] = (char)0x80 | (codepoint & 0x3f); - codepoint >>= 6; - } - - switch (nbytes) { - case 1: - str[0] = (codepoint & 0x7f); break; - case 2: - str[0] = (char)0xc0 | (codepoint & 0x1f); break; - case 3: - str[0] = (char)0xe0 | (codepoint & 0x0f); break; - case 4: - str[0] = (char)0xf0 | (codepoint & 0x07); break; - case 5: - str[0] = (char)0xf8 | (codepoint & 0x03); break; - case 6: - str[0] = (char)0xfc | (codepoint & 0x01); break; - } - return nbytes; } -#define UTF8_INVALID 0xFFFD static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp, size_t *nbytep) { unsigned nbytes; @@ -680,7 +654,7 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp, return TERMKEY_RES_KEY; } else if (b0 < 0xc0) { // Starts with a continuation byte - that's not right - *cp = UTF8_INVALID; + *cp = UNICODE_INVALID; *nbytep = 1; return TERMKEY_RES_KEY; } else if (b0 < 0xe0) { @@ -699,7 +673,7 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp, nbytes = 6; *cp = b0 & 0x01; } else { - *cp = UTF8_INVALID; + *cp = UNICODE_INVALID; *nbytep = 1; return TERMKEY_RES_KEY; } @@ -713,7 +687,7 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp, cb = bytes[b]; if (cb < 0x80 || cb >= 0xc0) { - *cp = UTF8_INVALID; + *cp = UNICODE_INVALID; *nbytep = b; return TERMKEY_RES_KEY; } @@ -724,14 +698,14 @@ static TermKeyResult parse_utf8(const unsigned char *bytes, size_t len, int *cp, // Check for overlong sequences if ((int)nbytes > utf_char2len(*cp)) { - *cp = UTF8_INVALID; + *cp = UNICODE_INVALID; } // Check for UTF-16 surrogates or invalid *cps if ((*cp >= 0xD800 && *cp <= 0xDFFF) || *cp == 0xFFFE || *cp == 0xFFFF) { - *cp = UTF8_INVALID; + *cp = UNICODE_INVALID; } *nbytep = nbytes; @@ -833,6 +807,9 @@ static TermKeyResult peekkey(TermKey *tk, TermKeyKey *key, int force, size_t *nb return TERMKEY_RES_ERROR; } + // Press is the default event type. + key->event = TERMKEY_EVENT_PRESS; + #ifdef DEBUG fprintf(stderr, "getkey(force=%d): buffer ", force); print_buffer(tk); @@ -958,9 +935,9 @@ static TermKeyResult peekkey_simple(TermKey *tk, TermKeyKey *key, int force, siz if (res == TERMKEY_RES_AGAIN && force) { // There weren't enough bytes for a complete UTF-8 sequence but caller // demands an answer. About the best thing we can do here is eat as many - // bytes as we have, and emit a UTF8_INVALID. If the remaining bytes + // bytes as we have, and emit a UNICODE_INVALID. If the remaining bytes // arrive later, they'll be invalid too. - codepoint = UTF8_INVALID; + codepoint = UNICODE_INVALID; *nbytep = tk->buffcount; res = TERMKEY_RES_KEY; } diff --git a/src/nvim/tui/termkey/termkey.h b/src/nvim/tui/termkey/termkey.h index 21ed141346..5cf9894cac 100644 --- a/src/nvim/tui/termkey/termkey.h +++ b/src/nvim/tui/termkey/termkey.h @@ -1,9 +1,9 @@ #pragma once -#include <stdint.h> -#include <stdlib.h> +#include <stdint.h> // IWYU pragma: keep +#include <stdlib.h> // IWYU pragma: keep -#include "nvim/tui/termkey/termkey_defs.h" +#include "nvim/tui/termkey/termkey_defs.h" // IWYU pragma: keep #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/termkey/termkey.h.generated.h" diff --git a/src/nvim/tui/termkey/termkey_defs.h b/src/nvim/tui/termkey/termkey_defs.h index 7c218ba7c2..87d3f63447 100644 --- a/src/nvim/tui/termkey/termkey_defs.h +++ b/src/nvim/tui/termkey/termkey_defs.h @@ -123,6 +123,13 @@ typedef enum { TERMKEY_MOUSE_RELEASE, } TermKeyMouseEvent; +typedef enum { + TERMKEY_EVENT_UNKNOWN, + TERMKEY_EVENT_PRESS, + TERMKEY_EVENT_REPEAT, + TERMKEY_EVENT_RELEASE, +} TermKeyEvent; + enum { TERMKEY_KEYMOD_SHIFT = 1 << 0, TERMKEY_KEYMOD_ALT = 1 << 1, @@ -163,6 +170,8 @@ typedef struct { int modifiers; + TermKeyEvent event; + // Any Unicode character can be UTF-8 encoded in no more than 6 bytes, plus // terminating NUL char utf8[7]; |