revamp keycode handling

This commit is contained in:
Florian Stinglmayr 2019-07-05 17:33:42 +02:00
parent a164afe170
commit 7a565e4764
7 changed files with 107 additions and 45 deletions

View File

@ -2,28 +2,17 @@
#define NCDC_INPUT_H
#include <ncdc/ncdc.h>
#include <ncdc/keycodes.h>
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);

View File

@ -0,0 +1,20 @@
#ifndef NCDC_KEYCODES_H
#define NCDC_KEYCODES_H
#include <ncdc/ncdc.h>
#include <ncdc/input.h>
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

View File

@ -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);

View File

@ -1,11 +1,21 @@
#include <ncdc/input.h>
#include <ncdc/keycodes.h>
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)
};

View File

@ -1,5 +1,6 @@
#include <ncdc/input.h>
#include <ncdc/ncdc.h>
#include <ncdc/keycodes.h>
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);
}
}

View File

@ -183,24 +183,44 @@ static void ncdc_mainwindow_update_focus(ncdc_mainwindow_t n)
}
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
{
switch (n->focus) {
case FOCUS_INPUT:
{
wint_t i = 0;
wchar_t *key = NULL;
WINDOW *win = NULL;
if (wget_wch(n->input, &i) == ERR) {
switch (n->focus) {
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);
} else {
ncdc_input_feed(n->in, (wchar_t)i);
return;
}
} break;
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)

View File

@ -1,5 +1,22 @@
#include <ncdc/ncdc.h>
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;