commit 7598671835a7421e8415a978cc055a61b5d8588a
parent b610b280bbdbda3dba8f8fc3e67961f26857da43
Author: lumidify <nobody@lumidify.org>
Date: Thu, 17 Aug 2023 15:38:22 +0200
Add more keysyms
Diffstat:
M | src/config.c | | | 139 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
M | src/event_xlib.c | | | 152 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
M | src/eventdefs.h | | | 93 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
3 files changed, 319 insertions(+), 65 deletions(-)
diff --git a/src/config.c b/src/config.c
@@ -6,9 +6,12 @@
#include <limits.h>
#include "util.h"
+#include "keys.h"
#include "memory.h"
#include "config.h"
+static int parse_keysym(char *text, size_t len, ltk_keysym *sym_ret);
+
ltk_config *global_config = NULL;
enum toktype {
@@ -180,38 +183,6 @@ next_token(struct lexstate *s) {
}
}
-/* FIXME: optimize - just copy from ledit; actually support all keysyms */
-static int
-parse_keysym(char *text, size_t len, ltk_keysym *sym_ret) {
- if (str_array_equal("left", text, len))
- *sym_ret = LTK_KEY_LEFT;
- else if (str_array_equal("right", text, len))
- *sym_ret = LTK_KEY_RIGHT;
- else if (str_array_equal("up", text, len))
- *sym_ret = LTK_KEY_UP;
- else if (str_array_equal("down", text, len))
- *sym_ret = LTK_KEY_DOWN;
- else if (str_array_equal("backspace", text, len))
- *sym_ret = LTK_KEY_BACKSPACE;
- else if (str_array_equal("delete", text, len))
- *sym_ret = LTK_KEY_DELETE;
- else if (str_array_equal("space", text, len))
- *sym_ret = LTK_KEY_SPACE;
- else if (str_array_equal("return", text, len))
- *sym_ret = LTK_KEY_RETURN;
- else if (str_array_equal("tab", text, len))
- *sym_ret = LTK_KEY_TAB;
- else if (str_array_equal("escape", text, len))
- *sym_ret = LTK_KEY_ESCAPE;
- else if (str_array_equal("end", text, len))
- *sym_ret = LTK_KEY_END;
- else if (str_array_equal("home", text, len))
- *sym_ret = LTK_KEY_HOME;
- else
- return 1;
- return 0;
-}
-
#undef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -729,3 +700,107 @@ ltk_keypress_binding_destroy(ltk_keypress_binding b) {
ltk_free(b.text);
ltk_free(b.rawtext);
}
+
+/* FIXME: which additional ones are needed here? */
+static struct keysym_mapping {
+ char *name;
+ ltk_keysym keysym;
+} keysym_map[] = {
+ {"backspace", LTK_KEY_BACKSPACE},
+ {"begin", LTK_KEY_BEGIN},
+ {"break", LTK_KEY_BREAK},
+ {"cancel", LTK_KEY_CANCEL},
+ {"clear", LTK_KEY_CLEAR},
+ {"delete", LTK_KEY_DELETE},
+ {"down", LTK_KEY_DOWN},
+ {"end", LTK_KEY_END},
+ {"escape", LTK_KEY_ESCAPE},
+ {"execute", LTK_KEY_EXECUTE},
+
+ {"f1", LTK_KEY_F1},
+ {"f10", LTK_KEY_F10},
+ {"f11", LTK_KEY_F11},
+ {"f12", LTK_KEY_F12},
+ {"f2", LTK_KEY_F2},
+ {"f3", LTK_KEY_F3},
+ {"f4", LTK_KEY_F4},
+ {"f5", LTK_KEY_F5},
+ {"f6", LTK_KEY_F6},
+ {"f7", LTK_KEY_F7},
+ {"f8", LTK_KEY_F8},
+ {"f9", LTK_KEY_F9},
+
+ {"find", LTK_KEY_FIND},
+ {"help", LTK_KEY_HELP},
+ {"home", LTK_KEY_HOME},
+ {"insert", LTK_KEY_INSERT},
+
+ {"kp-0", LTK_KEY_KP_0},
+ {"kp-1", LTK_KEY_KP_1},
+ {"kp-2", LTK_KEY_KP_2},
+ {"kp-3", LTK_KEY_KP_3},
+ {"kp-4", LTK_KEY_KP_4},
+ {"kp-5", LTK_KEY_KP_5},
+ {"kp-6", LTK_KEY_KP_6},
+ {"kp-7", LTK_KEY_KP_7},
+ {"kp-8", LTK_KEY_KP_8},
+ {"kp-9", LTK_KEY_KP_9},
+ {"kp-add", LTK_KEY_KP_ADD},
+ {"kp-begin", LTK_KEY_KP_BEGIN},
+ {"kp-decimal", LTK_KEY_KP_DECIMAL},
+ {"kp-delete", LTK_KEY_KP_DELETE},
+ {"kp-divide", LTK_KEY_KP_DIVIDE},
+ {"kp-down", LTK_KEY_KP_DOWN},
+ {"kp-end", LTK_KEY_KP_END},
+ {"kp-enter", LTK_KEY_KP_ENTER},
+ {"kp-equal", LTK_KEY_KP_EQUAL},
+ {"kp-home", LTK_KEY_KP_HOME},
+ {"kp-insert", LTK_KEY_KP_INSERT},
+ {"kp-left", LTK_KEY_KP_LEFT},
+ {"kp-multiply", LTK_KEY_KP_MULTIPLY},
+ {"kp-next", LTK_KEY_KP_NEXT},
+ {"kp-page-down", LTK_KEY_KP_PAGE_DOWN},
+ {"kp-page-up", LTK_KEY_KP_PAGE_UP},
+ {"kp-prior", LTK_KEY_KP_PRIOR},
+ {"kp-right", LTK_KEY_KP_RIGHT},
+ {"kp-separator", LTK_KEY_KP_SEPARATOR},
+ {"kp-space", LTK_KEY_KP_SPACE},
+ {"kp-subtract", LTK_KEY_KP_SUBTRACT},
+ {"kp-tab", LTK_KEY_KP_TAB},
+ {"kp-up", LTK_KEY_KP_UP},
+
+ {"left", LTK_KEY_LEFT},
+ {"linefeed", LTK_KEY_LINEFEED},
+ {"menu", LTK_KEY_MENU},
+ {"mode-switch", LTK_KEY_MODE_SWITCH},
+ {"next", LTK_KEY_NEXT},
+ {"num-lock", LTK_KEY_NUM_LOCK},
+ {"page-down", LTK_KEY_PAGE_DOWN},
+ {"page-up", LTK_KEY_PAGE_UP},
+ {"pause", LTK_KEY_PAUSE},
+ {"print", LTK_KEY_PRINT},
+ {"prior", LTK_KEY_PRIOR},
+
+ {"redo", LTK_KEY_REDO},
+ {"return", LTK_KEY_RETURN},
+ {"right", LTK_KEY_RIGHT},
+ {"script-switch", LTK_KEY_SCRIPT_SWITCH},
+ {"scroll-lock", LTK_KEY_SCROLL_LOCK},
+ {"select", LTK_KEY_SELECT},
+ {"space", LTK_KEY_SPACE},
+ {"sysreq", LTK_KEY_SYS_REQ},
+ {"tab", LTK_KEY_TAB},
+ {"up", LTK_KEY_UP},
+ {"undo", LTK_KEY_UNDO},
+};
+
+GEN_CB_MAP_HELPERS(keysym_map, struct keysym_mapping, name)
+
+static int
+parse_keysym(char *keysym_str, size_t len, ltk_keysym *sym) {
+ struct keysym_mapping *km = keysym_map_get_entry(keysym_str, len);
+ if (!km)
+ return 1;
+ *sym = km->keysym;
+ return 0;
+}
diff --git a/src/event_xlib.c b/src/event_xlib.c
@@ -3,6 +3,7 @@
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>
+#include "util.h"
#include "memory.h"
#include "graphics.h"
#include "xlib_shared.h"
@@ -43,6 +44,8 @@ static int was_2release[] = {0, 0, 0};
static int next_event_valid = 0;
static ltk_button_event next_event;
+static ltk_keysym get_keysym(KeySym sym);
+
void
ltk_events_cleanup(void) {
ltk_free(text);
@@ -62,30 +65,6 @@ get_button(unsigned int button) {
}
}
-/* FIXME: make an actual exhaustive list here */
-static ltk_keysym
-get_keysym(KeySym sym) {
- switch (sym) {
- case XK_Left: return LTK_KEY_LEFT;
- case XK_Right: return LTK_KEY_RIGHT;
- case XK_Up: return LTK_KEY_UP;
- case XK_Down: return LTK_KEY_DOWN;
- case XK_BackSpace: return LTK_KEY_BACKSPACE;
- case XK_space: return LTK_KEY_SPACE;
- case XK_Return: return LTK_KEY_RETURN;
- case XK_Delete: return LTK_KEY_DELETE;
- /* FIXME: what other weird keys like this exist? */
- /* why is it ISO_Left_Tab when shift is pressed? */
- /* I mean, it makes sense, but I find it to be weird,
- and I'm not sure how standardized it is */
- case XK_ISO_Left_Tab: case XK_Tab: return LTK_KEY_TAB;
- case XK_Escape: return LTK_KEY_ESCAPE;
- case XK_End: return LTK_KEY_END;
- case XK_Home: return LTK_KEY_HOME;
- default: return LTK_KEY_NONE;
- }
-}
-
/* FIXME: properly implement modifiers - see SDL and GTK */
static ltk_mod_type
get_modmask(unsigned int state) {
@@ -363,3 +342,128 @@ ltk_next_event(ltk_renderdata *renderdata, size_t lang_index, ltk_event *event)
}
return ret;
}
+
+/* FIXME: pre-sort array (current sorting is taken from config.c but doesn't make sense here) */
+/* FIXME: can some structure of the X keysyms be abused to make this more efficient */
+static struct keysym_mapping {
+ KeySym xkeysym;
+ ltk_keysym keysym;
+} keysym_map[] = {
+ {XK_BackSpace, LTK_KEY_BACKSPACE},
+ {XK_Begin, LTK_KEY_BEGIN},
+ {XK_Break, LTK_KEY_BREAK},
+ {XK_Cancel, LTK_KEY_CANCEL},
+ {XK_Clear, LTK_KEY_CLEAR},
+ {XK_Delete, LTK_KEY_DELETE},
+ {XK_Down, LTK_KEY_DOWN},
+ {XK_End, LTK_KEY_END},
+ {XK_Escape, LTK_KEY_ESCAPE},
+ {XK_Execute, LTK_KEY_EXECUTE},
+
+ {XK_F1, LTK_KEY_F1},
+ {XK_F10, LTK_KEY_F10},
+ {XK_F11, LTK_KEY_F11},
+ {XK_F12, LTK_KEY_F12},
+ {XK_F2, LTK_KEY_F2},
+ {XK_F3, LTK_KEY_F3},
+ {XK_F4, LTK_KEY_F4},
+ {XK_F5, LTK_KEY_F5},
+ {XK_F6, LTK_KEY_F6},
+ {XK_F7, LTK_KEY_F7},
+ {XK_F8, LTK_KEY_F8},
+ {XK_F9, LTK_KEY_F9},
+
+ {XK_Find, LTK_KEY_FIND},
+ {XK_Help, LTK_KEY_HELP},
+ {XK_Home, LTK_KEY_HOME},
+ {XK_Insert, LTK_KEY_INSERT},
+
+ {XK_KP_0, LTK_KEY_KP_0},
+ {XK_KP_1, LTK_KEY_KP_1},
+ {XK_KP_2, LTK_KEY_KP_2},
+ {XK_KP_3, LTK_KEY_KP_3},
+ {XK_KP_4, LTK_KEY_KP_4},
+ {XK_KP_5, LTK_KEY_KP_5},
+ {XK_KP_6, LTK_KEY_KP_6},
+ {XK_KP_7, LTK_KEY_KP_7},
+ {XK_KP_8, LTK_KEY_KP_8},
+ {XK_KP_9, LTK_KEY_KP_9},
+ {XK_KP_Add, LTK_KEY_KP_ADD},
+ {XK_KP_Begin, LTK_KEY_KP_BEGIN},
+ {XK_KP_Decimal, LTK_KEY_KP_DECIMAL},
+ {XK_KP_Delete, LTK_KEY_KP_DELETE},
+ {XK_KP_Divide, LTK_KEY_KP_DIVIDE},
+ {XK_KP_Down, LTK_KEY_KP_DOWN},
+ {XK_KP_End, LTK_KEY_KP_END},
+ {XK_KP_Enter, LTK_KEY_KP_ENTER},
+ {XK_KP_Equal, LTK_KEY_KP_EQUAL},
+ {XK_KP_Home, LTK_KEY_KP_HOME},
+ {XK_KP_Insert, LTK_KEY_KP_INSERT},
+ {XK_KP_Left, LTK_KEY_KP_LEFT},
+ {XK_KP_Multiply, LTK_KEY_KP_MULTIPLY},
+ {XK_KP_Next, LTK_KEY_KP_NEXT},
+ {XK_KP_Page_Down, LTK_KEY_KP_PAGE_DOWN},
+ {XK_KP_Page_Up, LTK_KEY_KP_PAGE_UP},
+ {XK_KP_Prior, LTK_KEY_KP_PRIOR},
+ {XK_KP_Right, LTK_KEY_KP_RIGHT},
+ {XK_KP_Separator, LTK_KEY_KP_SEPARATOR},
+ {XK_KP_Space, LTK_KEY_KP_SPACE},
+ {XK_KP_Subtract, LTK_KEY_KP_SUBTRACT},
+ {XK_KP_Tab, LTK_KEY_KP_TAB},
+ {XK_KP_Up, LTK_KEY_KP_UP},
+
+ {XK_Left, LTK_KEY_LEFT},
+ {XK_Linefeed, LTK_KEY_LINEFEED},
+ {XK_Menu, LTK_KEY_MENU},
+ {XK_Mode_switch, LTK_KEY_MODE_SWITCH},
+ {XK_Next, LTK_KEY_NEXT},
+ {XK_Num_Lock, LTK_KEY_NUM_LOCK},
+ {XK_Page_Down, LTK_KEY_PAGE_DOWN},
+ {XK_Page_Up, LTK_KEY_PAGE_UP},
+ {XK_Pause, LTK_KEY_PAUSE},
+ {XK_Print, LTK_KEY_PRINT},
+ {XK_Prior, LTK_KEY_PRIOR},
+
+ {XK_Redo, LTK_KEY_REDO},
+ {XK_Return, LTK_KEY_RETURN},
+ {XK_Right, LTK_KEY_RIGHT},
+ {XK_script_switch, LTK_KEY_SCRIPT_SWITCH},
+ {XK_Scroll_Lock, LTK_KEY_SCROLL_LOCK},
+ {XK_Select, LTK_KEY_SELECT},
+ {XK_space, LTK_KEY_SPACE},
+ {XK_Sys_Req, LTK_KEY_SYS_REQ},
+ {XK_Tab, LTK_KEY_TAB},
+ {XK_Up, LTK_KEY_UP},
+ {XK_Undo, LTK_KEY_UNDO},
+};
+
+static int keysym_map_sorted = 0;
+static int
+keysym_map_search_helper(const void *keyv, const void *entryv) {
+ KeySym sym = *((KeySym*)keyv);
+ struct keysym_mapping *m = (struct keysym_mapping *)entryv;
+ /* FIXME: branchless compare version? */
+ return (sym < m->xkeysym) ? -1 : (sym > m->xkeysym);
+}
+static int
+keysym_map_sort_helper(const void *entry1v, const void *entry2v) {
+ struct keysym_mapping *m1 = (struct keysym_mapping *)entry1v;
+ struct keysym_mapping *m2 = (struct keysym_mapping *)entry2v;
+ return (m1->xkeysym < m2->xkeysym) ? -1 : (m1->xkeysym > m2->xkeysym);
+}
+
+static ltk_keysym
+get_keysym(KeySym sym) {
+ if (!keysym_map_sorted) {
+ qsort(
+ keysym_map, LENGTH(keysym_map),
+ sizeof(keysym_map[0]), &keysym_map_sort_helper
+ );
+ keysym_map_sorted = 1;
+ }
+ struct keysym_mapping *m = bsearch(
+ &sym, keysym_map, LENGTH(keysym_map),
+ sizeof(keysym_map[0]), &keysym_map_search_helper
+ );
+ return m ? m->keysym : LTK_KEY_NONE;
+}
diff --git a/src/eventdefs.h b/src/eventdefs.h
@@ -35,21 +35,96 @@ typedef enum {
LTK_BUTTONR,
} ltk_button_type;
-/* FIXME: just steal the definitions from X when using Xlib so no conversion is necessary? */
+/* FIXME: better sorting (the current order is just copied from config.c) */
+/* FIXME: use the Xlib definitions to optimize for the common case? */
typedef enum {
LTK_KEY_NONE = 0,
- LTK_KEY_LEFT,
- LTK_KEY_RIGHT,
- LTK_KEY_UP,
- LTK_KEY_DOWN,
LTK_KEY_BACKSPACE,
+ LTK_KEY_BEGIN,
+ LTK_KEY_BREAK,
+ LTK_KEY_CANCEL,
+ LTK_KEY_CLEAR,
LTK_KEY_DELETE,
- LTK_KEY_SPACE,
- LTK_KEY_RETURN,
- LTK_KEY_TAB,
+ LTK_KEY_DOWN,
+ LTK_KEY_END,
LTK_KEY_ESCAPE,
+ LTK_KEY_EXECUTE,
+
+ LTK_KEY_F1,
+ LTK_KEY_F10,
+ LTK_KEY_F11,
+ LTK_KEY_F12,
+ LTK_KEY_F2,
+ LTK_KEY_F3,
+ LTK_KEY_F4,
+ LTK_KEY_F5,
+ LTK_KEY_F6,
+ LTK_KEY_F7,
+ LTK_KEY_F8,
+ LTK_KEY_F9,
+
+ LTK_KEY_FIND,
+ LTK_KEY_HELP,
LTK_KEY_HOME,
- LTK_KEY_END
+ LTK_KEY_INSERT,
+
+ LTK_KEY_KP_0,
+ LTK_KEY_KP_1,
+ LTK_KEY_KP_2,
+ LTK_KEY_KP_3,
+ LTK_KEY_KP_4,
+ LTK_KEY_KP_5,
+ LTK_KEY_KP_6,
+ LTK_KEY_KP_7,
+ LTK_KEY_KP_8,
+ LTK_KEY_KP_9,
+ LTK_KEY_KP_ADD,
+ LTK_KEY_KP_BEGIN,
+ LTK_KEY_KP_DECIMAL,
+ LTK_KEY_KP_DELETE,
+ LTK_KEY_KP_DIVIDE,
+ LTK_KEY_KP_DOWN,
+ LTK_KEY_KP_END,
+ LTK_KEY_KP_ENTER,
+ LTK_KEY_KP_EQUAL,
+ LTK_KEY_KP_HOME,
+ LTK_KEY_KP_INSERT,
+ LTK_KEY_KP_LEFT,
+ LTK_KEY_KP_MULTIPLY,
+ LTK_KEY_KP_NEXT,
+ LTK_KEY_KP_PAGE_DOWN,
+ LTK_KEY_KP_PAGE_UP,
+ LTK_KEY_KP_PRIOR,
+ LTK_KEY_KP_RIGHT,
+ LTK_KEY_KP_SEPARATOR,
+ LTK_KEY_KP_SPACE,
+ LTK_KEY_KP_SUBTRACT,
+ LTK_KEY_KP_TAB,
+ LTK_KEY_KP_UP,
+
+ LTK_KEY_LEFT,
+ LTK_KEY_LINEFEED,
+ LTK_KEY_MENU,
+ LTK_KEY_MODE_SWITCH,
+ LTK_KEY_NEXT,
+ LTK_KEY_NUM_LOCK,
+ LTK_KEY_PAGE_DOWN,
+ LTK_KEY_PAGE_UP,
+ LTK_KEY_PAUSE,
+ LTK_KEY_PRINT,
+ LTK_KEY_PRIOR,
+
+ LTK_KEY_REDO,
+ LTK_KEY_RETURN,
+ LTK_KEY_RIGHT,
+ LTK_KEY_SCRIPT_SWITCH,
+ LTK_KEY_SCROLL_LOCK,
+ LTK_KEY_SELECT,
+ LTK_KEY_SPACE,
+ LTK_KEY_SYS_REQ,
+ LTK_KEY_TAB,
+ LTK_KEY_UP,
+ LTK_KEY_UNDO
} ltk_keysym;
typedef enum {