ltk

Socket-based GUI for X11 (WIP)
git clone git://lumidify.org/ltk.git (fast, but not encrypted)
git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit 7598671835a7421e8415a978cc055a61b5d8588a
parent b610b280bbdbda3dba8f8fc3e67961f26857da43
Author: lumidify <nobody@lumidify.org>
Date:   Thu, 17 Aug 2023 15:38:22 +0200

Add more keysyms

Diffstat:
Msrc/config.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/event_xlib.c | 152++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/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 {