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 {