[PATCH 2/4] xkbsupport: Create a list of used codes
Alexey Gladkov <[email protected]> Thu, 4 Jan 2024 18:15:16 +0000
| Newsgroups | dev.linux.lists.kbd |
|---|---|
| Message-ID | <65b88d9b5ca46b6c6b9d2b13936c62b9060215e4.1704392039.git.legion@kernel.org> |
This is preparation with the following changes. We create a binary search tree with all the unicodes that are used in the generated keymap so that we can later check whether the unicode symbol is used or not. Signed-off-by: Alexey Gladkov <[email protected]> --- src/xkbsupport.c | 50 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/xkbsupport.c b/src/xkbsupport.c index 694d516f..3caf8465 100644 --- a/src/xkbsupport.c +++ b/src/xkbsupport.c @@ -1,3 +1,6 @@ +#define _GNU_SOURCE +#include <search.h> + #include <stdlib.h> #include <string.h> #include <errno.h> @@ -37,6 +40,7 @@ struct xkeymap { struct xkb_context *xkb; struct xkb_keymap *keymap; struct lk_ctx *ctx; + void *used_codes; }; /* @@ -171,6 +175,15 @@ static const char *map_xkbsym_to_ksym(const char *xkb_sym) return NULL; } +static int compare_codes(const void *pa, const void *pb) +{ + if (*(int *) pa < *(int *) pb) + return -1; + if (*(int *) pa > *(int *) pb) + return 1; + return 0; +} + static void print_modifiers(struct xkb_keymap *keymap, struct xkb_mask *mask) { xkb_mod_index_t num_mods = xkb_keymap_num_mods(keymap); @@ -351,6 +364,32 @@ static int xkeymap_get_symbol(struct xkb_keymap *keymap, return 1; } +static int used_code(struct xkeymap *xkeymap, int code) +{ + return tfind(&code, &xkeymap->used_codes, compare_codes) != NULL; +} + +static void remember_code(struct xkeymap *xkeymap, int code) +{ + int *ptr, **val; + + if (used_code(xkeymap, code)) + return; + + ptr = malloc(sizeof(code)); + if (!ptr) + kbd_error(1, errno, "out of memory"); + + *ptr = code; + + val = tsearch(ptr, &xkeymap->used_codes, compare_codes); + if (!val) + kbd_error(1, errno, "out of memory"); + + if (*val != ptr) + free(ptr); +} + static void xkeymap_add_value(struct xkeymap *xkeymap, int modifier, int code, int keyvalue[MAX_NR_KEYMAPS]) { if (!modifier || (modifier & (1 << KG_SHIFT))) @@ -438,9 +477,6 @@ static int xkeymap_walk(struct xkeymap *xkeymap) } } - if (getenv("LK_XKB_DEBUG")) - continue; - process_keycode: unsigned short layout = 0; @@ -455,6 +491,11 @@ process_keycode: keyvalue[i] = keyvalue[layout_switch[layout]]; } + remember_code(xkeymap, keyvalue[i]); + + if (getenv("LK_XKB_DEBUG")) + continue; + if (lk_add_key(xkeymap->ctx, i, (int) KERN_KEYCODE(keycode), keyvalue[i]) < 0) goto err; } @@ -506,6 +547,9 @@ int convert_xkb_keymap(struct lk_ctx *ctx, struct xkeymap_params *params, int op } end: + if (xkeymap.used_codes) + tdestroy(xkeymap.used_codes, free); + xkb_keymap_unref(xkeymap.keymap); xkb_context_unref(xkeymap.xkb); -- 2.43.0