[PATCH 3/4] xkbsupport: Extract translation table
Alexey Gladkov <[email protected]> Thu, 4 Jan 2024 18:15:17 +0000
| Newsgroups | dev.linux.lists.kbd |
|---|---|
| Message-ID | <4dce50945ea36445d676780e785fba67ce47921c.1704392039.git.legion@kernel.org> |
This will allow us to expand the xkb to kbd keys translation table. Signed-off-by: Alexey Gladkov <[email protected]> --- data/xkbtrans/names | 154 ++++++++++++++++++++++++++++++++++++++ src/xkbsupport.c | 176 ++++++++++++++++++++++++-------------------- 2 files changed, 251 insertions(+), 79 deletions(-) create mode 100644 data/xkbtrans/names diff --git a/data/xkbtrans/names b/data/xkbtrans/names new file mode 100644 index 00000000..f39e8456 --- /dev/null +++ b/data/xkbtrans/names @@ -0,0 +1,154 @@ +0 zero +1 one +2 two +3 three +4 four +5 five +6 six +7 seven +8 eight +9 nine +Alt_L Alt +Alt_R Alt +Begin Begin +Break Break +Control_L Control +Control_R Control +Down Down +End End +F1 F1 +F10 F10 +F11 F11 +F12 F12 +F13 F13 +F14 F14 +F15 F15 +F16 F16 +F17 F17 +F18 F18 +F19 F19 +F2 F2 +F20 F20 +F21 F21 +F22 F22 +F23 F23 +F24 F24 +F25 F25 +F26 F26 +F27 F27 +F28 F28 +F29 F29 +F3 F3 +F30 F30 +F31 F31 +F32 F32 +F33 F33 +F34 F34 +F35 F35 +F4 F4 +F5 F5 +F6 F6 +F7 F7 +F8 F8 +F9 F9 +Find Find +Help Help +Home Home +Hyper_L Alt +Hyper_R Alt +ISO_First_Group AltGr_Lock +ISO_First_Group_Lock AltGr_Lock +ISO_Group_Latch AltGr +ISO_Group_Lock AltGr_Lock +ISO_Group_Shift AltGr +ISO_Last_Group AltGr_Lock +ISO_Last_Group_Lock AltGr_Lock +ISO_Left_Tab Meta_Tab +ISO_Level2_Latch Shift +ISO_Level3_Latch AltGr +ISO_Level3_Lock AltGr_Lock +ISO_Level3_Shift AltGr +ISO_Level5_Latch AltGr +ISO_Level5_Lock AltGr_Lock +ISO_Level5_Shift AltGr +ISO_Lock Caps_Lock +ISO_Next_Group AltGr_Lock +ISO_Next_Group_Lock AltGr_Lock +ISO_Prev_Group AltGr_Lock +ISO_Prev_Group_Lock AltGr_Lock +Insert Insert +KP_Down KP_2 +KP_End KP_1 +KP_Home KP_7 +KP_Insert KP_0 +KP_Left KP_4 +KP_Next KP_3 +KP_Prior KP_9 +KP_Right KP_6 +KP_Up KP_8 +L1 F11 +L10 F20 +L2 F12 +L3 F13 +L4 F14 +L5 F15 +L6 F16 +L7 F17 +L8 F18 +L9 F19 +Left Left +Meta_L Alt +Meta_R Alt +Mode_switch AltGr +Multi_key Compose +Next Next +Num_Lock Num_Lock +Pause Pause +Print Control_backslash +Prior Prior +R1 F21 +R10 F30 +R11 F31 +R12 F32 +R13 F33 +R14 F34 +R15 F35 +R2 F22 +R3 F23 +R4 F24 +R5 F25 +R6 F26 +R7 F27 +R8 F28 +R9 F29 +Right Right +Scroll_Lock Scroll_Lock +Shift_L Shift +Shift_R Shift +Super_L Alt +Super_R Alt +Sys_Req Last_Console +Up Up +XF86Switch_VT_1 Console_1 +XF86Switch_VT_10 Console_10 +XF86Switch_VT_11 Console_11 +XF86Switch_VT_12 Console_12 +XF86Switch_VT_2 Console_2 +XF86Switch_VT_3 Console_3 +XF86Switch_VT_4 Console_4 +XF86Switch_VT_5 Console_5 +XF86Switch_VT_6 Console_6 +XF86Switch_VT_7 Console_7 +XF86Switch_VT_8 Console_8 +XF86Switch_VT_9 Console_9 +dead_V dead_caron +dead_acute dead_acute +dead_breve dead_breve +dead_caron dead_caron +dead_cedilla dead_cedilla +dead_circumflex dead_circumflex +dead_diaeresis dead_diaeresis +dead_doubleacute dead_doubleacute +dead_grave dead_grave +dead_ogonek dead_ogonek +dead_tilde dead_tilde diff --git a/src/xkbsupport.c b/src/xkbsupport.c index 3caf8465..77abada0 100644 --- a/src/xkbsupport.c +++ b/src/xkbsupport.c @@ -36,11 +36,17 @@ static const unsigned int layouts[4][4] = { { 0, 1, 3, 2 }, }; +struct sym_pair { + char *xkb_sym; + char *krn_sym; +}; + struct xkeymap { struct xkb_context *xkb; struct xkb_keymap *keymap; struct lk_ctx *ctx; void *used_codes; + void *syms_map; }; /* @@ -83,6 +89,7 @@ static struct modifier_mapping modifier_mapping[] = { { NULL, NULL, 0 }, }; + static struct modifier_mapping *convert_modifier(const char *xkb_name) { struct modifier_mapping *map = modifier_mapping; @@ -96,82 +103,32 @@ static struct modifier_mapping *convert_modifier(const char *xkb_name) return NULL; } -struct symbols_mapping { - const char *xkb_sym; - const char *krn_sym; -}; - -static struct symbols_mapping symbols_mapping[] = { - { "0", "zero" }, - { "1", "one" }, - { "2", "two" }, - { "3", "three" }, - { "4", "four" }, - { "5", "five" }, - { "6", "six" }, - { "7", "seven" }, - { "8", "eight" }, - { "9", "nine" }, - { "KP_Insert", "KP_0" }, - { "KP_End", "KP_1" }, - { "KP_Down", "KP_2" }, - { "KP_Next", "KP_3" }, - { "KP_Left", "KP_4" }, - { "KP_Right", "KP_6" }, - { "KP_Home", "KP_7" }, - { "KP_Up", "KP_8" }, - { "KP_Prior", "KP_9" }, - { "KP_Begin", "VoidSymbol" }, - { "KP_Delete", "VoidSymbol" }, - { "Alt_R", "Alt" }, - { "Alt_L", "Alt" }, - { "Control_R", "Control" }, - { "Control_L", "Control" }, - { "Super_R", "Alt" }, - { "Super_L", "Alt" }, - { "Hyper_R", "Alt" }, - { "Hyper_L", "Alt" }, - { "Mode_switch", "AltGr" }, - { "ISO_Group_Shift", "AltGr" }, - { "ISO_Group_Latch", "AltGr" }, - { "ISO_Group_Lock", "AltGr_Lock" }, - { "ISO_Next_Group", "AltGr_Lock" }, - { "ISO_Next_Group_Lock", "AltGr_Lock" }, - { "ISO_Prev_Group", "AltGr_Lock" }, - { "ISO_Prev_Group_Lock", "AltGr_Lock" }, - { "ISO_First_Group", "AltGr_Lock" }, - { "ISO_First_Group_Lock", "AltGr_Lock" }, - { "ISO_Last_Group", "AltGr_Lock" }, - { "ISO_Last_Group_Lock", "AltGr_Lock" }, - { "ISO_Level3_Shift", "AltGr" }, - { "ISO_Left_Tab", "Meta_Tab" }, - { "XF86Switch_VT_1", "Console_1" }, - { "XF86Switch_VT_2", "Console_2" }, - { "XF86Switch_VT_3", "Console_3" }, - { "XF86Switch_VT_4", "Console_4" }, - { "XF86Switch_VT_5", "Console_5" }, - { "XF86Switch_VT_6", "Console_6" }, - { "XF86Switch_VT_7", "Console_7" }, - { "XF86Switch_VT_8", "Console_8" }, - { "XF86Switch_VT_9", "Console_9" }, - { "XF86Switch_VT_10", "Console_10" }, - { "XF86Switch_VT_11", "Console_11" }, - { "XF86Switch_VT_12", "Console_12" }, - { "Sys_Req", "Last_Console" }, - { "Print", "Control_backslash" }, - { NULL, NULL }, -}; +static void xkeymap_pair_free(void *pa) +{ + struct sym_pair *pair = pa; + if (!pair) + return; + free(pair->xkb_sym); + free(pair->krn_sym); + free(pair); +} -static const char *map_xkbsym_to_ksym(const char *xkb_sym) +static int compare_by_xkbsym(const void *pa, const void *pb) { - struct symbols_mapping *map = symbols_mapping; + return strcmp(((struct sym_pair *)pa)->xkb_sym, + ((struct sym_pair *)pb)->xkb_sym); +} - while (map->xkb_sym) { - if (!strcmp(map->xkb_sym, xkb_sym)) - return map->krn_sym; - map++; - } +static const char *map_xkbsym_to_ksym(struct xkeymap *xkeymap, char *xkb_sym) +{ + struct sym_pair **val; + struct sym_pair pair = { + .xkb_sym = xkb_sym, + }; + val = tfind(&pair, &xkeymap->syms_map, compare_by_xkbsym); + if (val) + return ((struct sym_pair *) *val)->krn_sym; return NULL; } @@ -236,7 +193,7 @@ static void xkeymap_walk_printer(struct xkeymap *xkeymap, return; } - if (!(symname = map_xkbsym_to_ksym(s))) + if (!(symname = map_xkbsym_to_ksym(xkeymap, s))) symname = s; if (unicode == 0) { @@ -303,7 +260,7 @@ static int parse_hexcode(const char *symname) return 0; } -static int xkeymap_get_code(struct lk_ctx *ctx, xkb_keysym_t symbol) +static int xkeymap_get_code(struct xkeymap *xkeymap, xkb_keysym_t symbol) { uint32_t xkb_unicode; int ret, unicode; @@ -321,10 +278,10 @@ static int xkeymap_get_code(struct lk_ctx *ctx, xkb_keysym_t symbol) if ((unicode = parse_hexcode(symbuf)) != 0) { ; - } else if ((symname = map_xkbsym_to_ksym(symbuf)) != NULL) { + } else if ((symname = map_xkbsym_to_ksym(xkeymap, symbuf)) != NULL) { unicode = parse_hexcode(symname); if (!unicode) - unicode = lk_ksym_to_unicode(ctx, symname); + unicode = lk_ksym_to_unicode(xkeymap->ctx, symname); } else if ((xkb_unicode = xkb_keysym_to_utf32(symbol)) > 0) { unicode = (int) xkb_unicode; @@ -335,7 +292,7 @@ static int xkeymap_get_code(struct lk_ctx *ctx, xkb_keysym_t symbol) ret = CODE_FOR_UNKNOWN_KSYM; if (unicode > 0) - ret = lk_convert_code(ctx, unicode, TO_AUTO); + ret = lk_convert_code(xkeymap->ctx, unicode, TO_AUTO); if (ret == CODE_FOR_UNKNOWN_KSYM) { kbd_warning(0, "unable to convert code <%s> and replace it with VoidSymbol", symbuf); @@ -451,7 +408,7 @@ static int xkeymap_walk(struct xkeymap *xkeymap) goto process_keycode; } - if ((value = xkeymap_get_code(xkeymap->ctx, sym)) < 0) + if ((value = xkeymap_get_code(xkeymap, sym)) < 0) continue; xkeymap_keycode_mask(xkeymap->keymap, layout, level, keycode, &keycode_mask); @@ -506,10 +463,60 @@ err: return -1; } +static int parsemap(struct xkeymap *xkeymap, FILE *fp) +{ + char buffer[BUFSIZ]; + char *p, *q, *xkb_sym = NULL, *krn_sym = NULL; + struct sym_pair **val, *pair = NULL; + + while (fgets(buffer, sizeof(buffer) - 1, fp)) { + for (p = buffer; isspace(*p); p++); + + if (*p == '#' || *p == '\0') + continue; + + for (q = p; *q != '\0' && !isspace(*q); q++); + *q = '\0'; + + xkb_sym = p; + + if (p != q) + for(p = ++q; isspace(*p); p++); + + for (q = p; *q != '\0' && !isspace(*q); q++); + *q = '\0'; + + krn_sym = p; + + pair = calloc(1, sizeof(*pair)); + if (!pair) + goto err; + + pair->xkb_sym = strdup(xkb_sym); + pair->krn_sym = strdup(krn_sym); + + if (!pair->xkb_sym || !pair->krn_sym) + goto err; + + val = tsearch(pair, &xkeymap->syms_map, compare_by_xkbsym); + if (!val) + goto err; + + if (*val != pair) + xkeymap_pair_free(pair); + + pair = NULL; + } + return 0; +err: + xkeymap_pair_free(pair); + return -1; +} int convert_xkb_keymap(struct lk_ctx *ctx, struct xkeymap_params *params, int options) { - struct xkeymap xkeymap; + FILE *fp; + struct xkeymap xkeymap = { 0 }; int ret = -1; struct xkb_rule_names names = { @@ -541,6 +548,14 @@ int convert_xkb_keymap(struct lk_ctx *ctx, struct xkeymap_params *params, int op goto end; } + if ((fp = fopen(DATADIR "/xkbtrans/names", "r")) != NULL) { + if (parsemap(&xkeymap, fp) < 0) { + kbd_warning(0, "unable to parse xkb translation names"); + goto end; + } + fclose(fp); + } + if (!(ret = xkeymap_walk(&xkeymap))) { if (options & OPT_P) lk_dump_keymap(ctx, stdout, LK_SHAPE_SEPARATE_LINES, 0); @@ -550,6 +565,9 @@ end: if (xkeymap.used_codes) tdestroy(xkeymap.used_codes, free); + if (xkeymap.syms_map) + tdestroy(xkeymap.syms_map, xkeymap_pair_free); + xkb_keymap_unref(xkeymap.keymap); xkb_context_unref(xkeymap.xkb); -- 2.43.0