allow hotkeys to affect other windows too

This commit is contained in:
Florian Stinglmayr 2019-07-05 18:05:39 +02:00
parent 7a565e4764
commit 82d36c38f1
9 changed files with 97 additions and 54 deletions

View File

@ -15,9 +15,9 @@ SET(SOURCES
"include/ncdc/textview.h"
"src/cmds.c"
"src/config.c"
"src/emacs.c"
"src/friends.c"
"src/input.c"
"src/keycodes.c"
"src/login.c"
"src/mainwindow.c"
"src/msg.c"

View File

@ -2,19 +2,23 @@
#define NCDC_KEYCODES_H
#include <ncdc/ncdc.h>
#include <ncdc/input.h>
typedef void (*ncdc_keybinding_t)(void *p);
typedef void (*ncdc_keyhandler_t)(void *p);
typedef struct {
wchar_t key[10];
wchar_t const *name;
ncdc_keybinding_t handler;
} ncdc_input_keybinding_t;
ncdc_keyhandler_t handler;
} ncdc_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 }
#define NCDC_BINDCUR(k, n, f) { .key = { k, '\0' }, .name = n, .handler = (ncdc_keyhandler_t) f }
#define NCDC_BINDING(k, n, f) { .key = k, .name = n, .handler = (ncdc_keyhandler_t) f }
#define NCDC_BINDEND() { .key = {0}, .name = NULL, .handler = NULL }
extern ncdc_input_keybinding_t emacs[];
extern ncdc_keybinding_t keys_emacs[];
extern ncdc_keybinding_t keys_mainwin[];
ncdc_keybinding_t *ncdc_find_keybinding(ncdc_keybinding_t *keys,
wchar_t const *key, size_t l);
#endif

View File

@ -20,4 +20,7 @@ void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx);
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n);
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n);
void ncdc_mainwindow_rightview(ncdc_mainwindow_t n);
void ncdc_mainwindow_leftview(ncdc_mainwindow_t n);
#endif

View File

@ -1,21 +0,0 @@
#include <ncdc/keycodes.h>
ncdc_input_keybinding_t emacs[] = {
/* 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

@ -8,7 +8,7 @@ struct ncdc_input_
GArray *buffer;
int cursor;
ncdc_input_keybinding_t *keys;
ncdc_keybinding_t *keys;
ncdc_input_callback_t callback;
void *callback_arg;
@ -33,35 +33,20 @@ ncdc_input_t ncdc_input_new(void)
p->buffer = g_array_new(TRUE, TRUE, sizeof(wchar_t));
p->cursor = 0;
p->keys = emacs;
p->keys = keys_emacs;
return p;
}
static ncdc_keybinding_t
has_binding(ncdc_input_t in, wchar_t const *key, size_t l)
{
size_t i = 0;
for (; in->keys[i].name != NULL; i++) {
if ((l == sizeof(wchar_t) && key[0] == in->keys[i].key[0]) ||
wcscmp(key, in->keys[i].key) == 0) {
return in->keys[i].handler;
}
}
return NULL;
}
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;
ncdc_keybinding_t *bind = NULL;
if (c[0] == '\r') {
ncdc_input_enter(input);
} else if ((handler = has_binding(input, c, sz)) != NULL) {
handler(input);
} else if ((bind = ncdc_find_keybinding(input->keys, c, sz)) != NULL) {
bind->handler(input);
} else if (iswprint(c[0])) {
g_array_insert_vals(input->buffer, input->cursor, &c[0], 1);
input->cursor += wcswidth(&c[0], 1);

49
ncdc/src/keycodes.c Normal file
View File

@ -0,0 +1,49 @@
#include <ncdc/keycodes.h>
#include <ncdc/mainwindow.h>
#include <ncdc/input.h>
ncdc_keybinding_t *
ncdc_find_keybinding(ncdc_keybinding_t *keys, wchar_t const *key, size_t l)
{
size_t i = 0;
for (i = 0; keys[i].name != NULL; i++) {
if ((l == sizeof(wchar_t) && key[0] == keys[i].key[0]) ||
wcscmp(key, keys[i].key) == 0) {
return keys+i;
}
}
return NULL;
}
ncdc_keybinding_t keys_mainwin[] = {
/* ALT+KEY_RIGHT
*/
NCDC_BINDING(L"\x1B[1;3C", L"right-window", ncdc_mainwindow_rightview),
/* ALT+KEY_LEFT
*/
NCDC_BINDING(L"\x1B[1;3D", L"left-window", ncdc_mainwindow_leftview),
NCDC_BINDEND()
};
ncdc_keybinding_t keys_emacs[] = {
/* 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_BINDEND()
};

View File

@ -186,7 +186,9 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
{
wint_t i = 0;
wchar_t *key = NULL;
size_t keylen = 0;
WINDOW *win = NULL;
ncdc_keybinding_t *k = NULL;
switch (n->focus) {
case FOCUS_INPUT: win = n->input; break;
@ -203,15 +205,23 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
return;
}
if (i == KEY_ESCAPE &&
(key = util_readkey(i, n->input)) == NULL) {
return;
if (i == KEY_ESCAPE) {
if ((key = util_readkey(i, n->input)) == NULL) {
return;
}
keylen = wcslen(key);
}
FILE *f = fopen("keys.txt", "a+");
fwprintf(f, L"%d - %ls\n", i, (key == NULL ? L"n/a" : key));
fwprintf(f, L"%d - %ls\n", i, (key == NULL ? L"n/a" : &key[1]));
fclose(f);
if (key != NULL &&
(k = ncdc_find_keybinding(keys_mainwin, key, keylen)) != NULL) {
k->handler(n);
return;
}
if (n->focus == FOCUS_INPUT) {
if (key == NULL) {
ncdc_input_feed(n->in, (wchar_t const *)&i, sizeof(wchar_t));
@ -271,3 +281,15 @@ void ncdc_mainwindow_log(ncdc_mainwindow_t w, wchar_t const *fmt, ...)
ncdc_textview_append(w->log, buf);
}
void ncdc_mainwindow_rightview(ncdc_mainwindow_t n)
{
return_if_true(n == NULL,);
n->curview = (n->curview + 1) % n->views->len;
}
void ncdc_mainwindow_leftview(ncdc_mainwindow_t n)
{
return_if_true(n == NULL,);
n->curview = (n->curview - 1) % n->views->len;
}

View File

@ -167,6 +167,7 @@ int main(int ac, char **av)
}
initscr();
cbreak();
noecho();
nonl();
keypad(stdscr, TRUE);

View File

@ -8,7 +8,7 @@ wchar_t *util_readkey(int e, WINDOW *win)
return_if_true(e != KEY_ESCAPE, NULL);
esc[0] = e;
for (i = 1; i < 7; i++) {
for (i = 1; i < 6; i++) {
if (wget_wch(win, esc+i) == ERR) {
return NULL;
}