From 7a565e4764ffd43d9ac8d96e7af88dd747ffb094 Mon Sep 17 00:00:00 2001 From: Florian Stinglmayr Date: Fri, 5 Jul 2019 17:33:42 +0200 Subject: [PATCH] revamp keycode handling --- ncdc/include/ncdc/input.h | 15 ++--------- ncdc/include/ncdc/keycodes.h | 20 +++++++++++++++ ncdc/include/ncdc/ncdc.h | 4 +++ ncdc/src/emacs.c | 26 +++++++++++++------ ncdc/src/input.c | 20 ++++++++------- ncdc/src/mainwindow.c | 50 +++++++++++++++++++++++++----------- ncdc/src/util.c | 17 ++++++++++++ 7 files changed, 107 insertions(+), 45 deletions(-) create mode 100644 ncdc/include/ncdc/keycodes.h diff --git a/ncdc/include/ncdc/input.h b/ncdc/include/ncdc/input.h index 766956d..5e273e4 100644 --- a/ncdc/include/ncdc/input.h +++ b/ncdc/include/ncdc/input.h @@ -2,28 +2,17 @@ #define NCDC_INPUT_H #include +#include struct ncdc_input_; typedef struct ncdc_input_ *ncdc_input_t; -typedef void (*ncdc_keybinding_t)(ncdc_input_t p); - typedef bool (*ncdc_input_callback_t)(ncdc_input_t p, wchar_t const *str, size_t len, void *data); -typedef struct { - char const *key; - char const *name; - ncdc_keybinding_t handler; -} ncdc_input_keybinding_t; - -#define NCDC_BINDING(k, n, f) { k, n, f } - -extern ncdc_input_keybinding_t emacs[]; - ncdc_input_t ncdc_input_new(void); -void ncdc_input_feed(ncdc_input_t input, wchar_t c); +void ncdc_input_feed(ncdc_input_t input, wchar_t const *c, size_t sz); int ncdc_input_cursor(ncdc_input_t input); char const *ncdc_input_buffer(ncdc_input_t input); void ncdc_input_draw(ncdc_input_t input, WINDOW *win); diff --git a/ncdc/include/ncdc/keycodes.h b/ncdc/include/ncdc/keycodes.h new file mode 100644 index 0000000..0191549 --- /dev/null +++ b/ncdc/include/ncdc/keycodes.h @@ -0,0 +1,20 @@ +#ifndef NCDC_KEYCODES_H +#define NCDC_KEYCODES_H + +#include +#include + +typedef void (*ncdc_keybinding_t)(void *p); + +typedef struct { + wchar_t key[10]; + wchar_t const *name; + ncdc_keybinding_t handler; +} ncdc_input_keybinding_t; + +#define NCDC_BINDCUR(k, n, f) { .key = { k, '\0' }, .name = n, .handler = (ncdc_keybinding_t) f } +#define NCDC_BINDING(k, n, f) { .key = k, .name = n, .handler = (ncdc_keybinding_t) f } + +extern ncdc_input_keybinding_t emacs[]; + +#endif diff --git a/ncdc/include/ncdc/ncdc.h b/ncdc/include/ncdc/ncdc.h index 4921563..4eea444 100644 --- a/ncdc/include/ncdc/ncdc.h +++ b/ncdc/include/ncdc/ncdc.h @@ -52,6 +52,10 @@ extern char *ncdc_private_dir; extern void *config; extern void *mainwindow; +#define KEY_ESCAPE 27 + +wchar_t *util_readkey(int esc, WINDOW *win); + void exit_main(void); int strwidth(char const *string); diff --git a/ncdc/src/emacs.c b/ncdc/src/emacs.c index 334a9a0..281d27f 100644 --- a/ncdc/src/emacs.c +++ b/ncdc/src/emacs.c @@ -1,11 +1,21 @@ -#include +#include ncdc_input_keybinding_t emacs[] = { - NCDC_BINDING("KEY_RIGHT", "forward", ncdc_input_forward), - NCDC_BINDING("KEY_LEFT", "backward", ncdc_input_backward), - NCDC_BINDING("^F", "forward", ncdc_input_forward), - NCDC_BINDING("^B", "backward", ncdc_input_backward), - NCDC_BINDING("^D", "delete", ncdc_input_delete), - NCDC_BINDING("KEY_BACKSPACE", "delete", ncdc_input_delete_backward), - NCDC_BINDING(NULL, NULL, NULL) + /* key left + */ + NCDC_BINDCUR(KEY_LEFT, L"backward", ncdc_input_backward), + /* key right + */ + NCDC_BINDCUR(KEY_RIGHT, L"forward", ncdc_input_forward), + /* CTRL+F + */ + NCDC_BINDING(L"\x06", L"forward", ncdc_input_forward), + /* CTRL+B + */ + NCDC_BINDING(L"\x02", L"backward", ncdc_input_backward), + /* CTRL+D + */ + NCDC_BINDING(L"\x04", L"delete", ncdc_input_delete), + NCDC_BINDCUR(KEY_BACKSPACE, L"delete", ncdc_input_delete_backward), + NCDC_BINDING({0}, NULL, NULL) }; diff --git a/ncdc/src/input.c b/ncdc/src/input.c index c7030ab..5e2dc5f 100644 --- a/ncdc/src/input.c +++ b/ncdc/src/input.c @@ -1,5 +1,6 @@ #include #include +#include struct ncdc_input_ { @@ -37,13 +38,14 @@ ncdc_input_t ncdc_input_new(void) return p; } -static ncdc_keybinding_t has_binding(ncdc_input_t in, wchar_t key) +static ncdc_keybinding_t +has_binding(ncdc_input_t in, wchar_t const *key, size_t l) { - char const *k = keyname(key); size_t i = 0; for (; in->keys[i].name != NULL; i++) { - if (strcmp(k, in->keys[i].key) == 0) { + if ((l == sizeof(wchar_t) && key[0] == in->keys[i].key[0]) || + wcscmp(key, in->keys[i].key) == 0) { return in->keys[i].handler; } } @@ -51,18 +53,18 @@ static ncdc_keybinding_t has_binding(ncdc_input_t in, wchar_t key) return NULL; } -void ncdc_input_feed(ncdc_input_t input, wchar_t c) +void ncdc_input_feed(ncdc_input_t input, wchar_t const *c, size_t sz) { return_if_true(input == NULL,); ncdc_keybinding_t handler = NULL; - if (c == '\r') { + if (c[0] == '\r') { ncdc_input_enter(input); - } else if ((handler = has_binding(input, c)) != NULL) { + } else if ((handler = has_binding(input, c, sz)) != NULL) { handler(input); - } else if (iswprint(c)) { - g_array_insert_vals(input->buffer, input->cursor, &c, 1); - input->cursor += wcswidth(&c, 1); + } else if (iswprint(c[0])) { + g_array_insert_vals(input->buffer, input->cursor, &c[0], 1); + input->cursor += wcswidth(&c[0], 1); } } diff --git a/ncdc/src/mainwindow.c b/ncdc/src/mainwindow.c index f44ff24..57bcc3c 100644 --- a/ncdc/src/mainwindow.c +++ b/ncdc/src/mainwindow.c @@ -184,23 +184,43 @@ static void ncdc_mainwindow_update_focus(ncdc_mainwindow_t n) void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n) { + wint_t i = 0; + wchar_t *key = NULL; + WINDOW *win = NULL; + switch (n->focus) { - case FOCUS_INPUT: - { - wint_t i = 0; - - if (wget_wch(n->input, &i) == ERR) { - return; - } - - if (i == KEY_RESIZE) { - ncdc_mainwindow_resize(n); - } else { - ncdc_input_feed(n->in, (wchar_t)i); - } - } break; - + case FOCUS_INPUT: win = n->input; break; + case FOCUS_CHAT: win = n->chat; break; + case FOCUS_GUILDS: win = n->guilds; break; } + + if (wget_wch(win, &i) == ERR) { + return; + } + + if (i == KEY_RESIZE) { + ncdc_mainwindow_resize(n); + return; + } + + if (i == KEY_ESCAPE && + (key = util_readkey(i, n->input)) == NULL) { + return; + } + + FILE *f = fopen("keys.txt", "a+"); + fwprintf(f, L"%d - %ls\n", i, (key == NULL ? L"n/a" : key)); + fclose(f); + + if (n->focus == FOCUS_INPUT) { + if (key == NULL) { + ncdc_input_feed(n->in, (wchar_t const *)&i, sizeof(wchar_t)); + } else { + ncdc_input_feed(n->in, key, wcslen(key)); + } + } + + free(key); } GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n) diff --git a/ncdc/src/util.c b/ncdc/src/util.c index d1d6ef6..9ce4cb1 100644 --- a/ncdc/src/util.c +++ b/ncdc/src/util.c @@ -1,5 +1,22 @@ #include +wchar_t *util_readkey(int e, WINDOW *win) +{ + wint_t esc[7] = {0}; + int i = 0; + + return_if_true(e != KEY_ESCAPE, NULL); + + esc[0] = e; + for (i = 1; i < 7; i++) { + if (wget_wch(win, esc+i) == ERR) { + return NULL; + } + } + + return wcsdup((wchar_t const *)esc); +} + wchar_t const *w_next_word(wchar_t const *w, ssize_t len) { size_t i = 0;