xref: /aosp_15_r20/external/libxkbcommon/src/keymap-priv.c (revision 2b949d0487e80d67f1fda82db69e101e761f8064)
1*2b949d04SAndroid Build Coastguard Worker /**
2*2b949d04SAndroid Build Coastguard Worker  * Copyright © 2012 Intel Corporation
3*2b949d04SAndroid Build Coastguard Worker  * Copyright © 2012 Ran Benita <[email protected]>
4*2b949d04SAndroid Build Coastguard Worker  *
5*2b949d04SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
6*2b949d04SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
7*2b949d04SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
8*2b949d04SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*2b949d04SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
10*2b949d04SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
11*2b949d04SAndroid Build Coastguard Worker  *
12*2b949d04SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
13*2b949d04SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
14*2b949d04SAndroid Build Coastguard Worker  * Software.
15*2b949d04SAndroid Build Coastguard Worker  *
16*2b949d04SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*2b949d04SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*2b949d04SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19*2b949d04SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*2b949d04SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*2b949d04SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22*2b949d04SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
23*2b949d04SAndroid Build Coastguard Worker  *
24*2b949d04SAndroid Build Coastguard Worker  * Author: Daniel Stone <[email protected]>
25*2b949d04SAndroid Build Coastguard Worker  */
26*2b949d04SAndroid Build Coastguard Worker 
27*2b949d04SAndroid Build Coastguard Worker #include "config.h"
28*2b949d04SAndroid Build Coastguard Worker 
29*2b949d04SAndroid Build Coastguard Worker #include "keymap.h"
30*2b949d04SAndroid Build Coastguard Worker 
31*2b949d04SAndroid Build Coastguard Worker static void
update_builtin_keymap_fields(struct xkb_keymap * keymap)32*2b949d04SAndroid Build Coastguard Worker update_builtin_keymap_fields(struct xkb_keymap *keymap)
33*2b949d04SAndroid Build Coastguard Worker {
34*2b949d04SAndroid Build Coastguard Worker     /* Predefined (AKA real, core, X11) modifiers. The order is important! */
35*2b949d04SAndroid Build Coastguard Worker     static const char *const builtin_mods[] = {
36*2b949d04SAndroid Build Coastguard Worker         [0] = "Shift",
37*2b949d04SAndroid Build Coastguard Worker         [1] = "Lock",
38*2b949d04SAndroid Build Coastguard Worker         [2] = "Control",
39*2b949d04SAndroid Build Coastguard Worker         [3] = "Mod1",
40*2b949d04SAndroid Build Coastguard Worker         [4] = "Mod2",
41*2b949d04SAndroid Build Coastguard Worker         [5] = "Mod3",
42*2b949d04SAndroid Build Coastguard Worker         [6] = "Mod4",
43*2b949d04SAndroid Build Coastguard Worker         [7] = "Mod5"
44*2b949d04SAndroid Build Coastguard Worker     };
45*2b949d04SAndroid Build Coastguard Worker 
46*2b949d04SAndroid Build Coastguard Worker     for (unsigned i = 0; i < ARRAY_SIZE(builtin_mods); i++) {
47*2b949d04SAndroid Build Coastguard Worker         keymap->mods.mods[i].name = xkb_atom_intern(keymap->ctx,
48*2b949d04SAndroid Build Coastguard Worker                                                     builtin_mods[i],
49*2b949d04SAndroid Build Coastguard Worker                                                     strlen(builtin_mods[i]));
50*2b949d04SAndroid Build Coastguard Worker         keymap->mods.mods[i].type = MOD_REAL;
51*2b949d04SAndroid Build Coastguard Worker     }
52*2b949d04SAndroid Build Coastguard Worker     keymap->mods.num_mods = ARRAY_SIZE(builtin_mods);
53*2b949d04SAndroid Build Coastguard Worker }
54*2b949d04SAndroid Build Coastguard Worker 
55*2b949d04SAndroid Build Coastguard Worker struct xkb_keymap *
xkb_keymap_new(struct xkb_context * ctx,enum xkb_keymap_format format,enum xkb_keymap_compile_flags flags)56*2b949d04SAndroid Build Coastguard Worker xkb_keymap_new(struct xkb_context *ctx,
57*2b949d04SAndroid Build Coastguard Worker                enum xkb_keymap_format format,
58*2b949d04SAndroid Build Coastguard Worker                enum xkb_keymap_compile_flags flags)
59*2b949d04SAndroid Build Coastguard Worker {
60*2b949d04SAndroid Build Coastguard Worker     struct xkb_keymap *keymap;
61*2b949d04SAndroid Build Coastguard Worker 
62*2b949d04SAndroid Build Coastguard Worker     keymap = calloc(1, sizeof(*keymap));
63*2b949d04SAndroid Build Coastguard Worker     if (!keymap)
64*2b949d04SAndroid Build Coastguard Worker         return NULL;
65*2b949d04SAndroid Build Coastguard Worker 
66*2b949d04SAndroid Build Coastguard Worker     keymap->refcnt = 1;
67*2b949d04SAndroid Build Coastguard Worker     keymap->ctx = xkb_context_ref(ctx);
68*2b949d04SAndroid Build Coastguard Worker 
69*2b949d04SAndroid Build Coastguard Worker     keymap->format = format;
70*2b949d04SAndroid Build Coastguard Worker     keymap->flags = flags;
71*2b949d04SAndroid Build Coastguard Worker 
72*2b949d04SAndroid Build Coastguard Worker     update_builtin_keymap_fields(keymap);
73*2b949d04SAndroid Build Coastguard Worker 
74*2b949d04SAndroid Build Coastguard Worker     return keymap;
75*2b949d04SAndroid Build Coastguard Worker }
76*2b949d04SAndroid Build Coastguard Worker 
77*2b949d04SAndroid Build Coastguard Worker struct xkb_key *
XkbKeyByName(struct xkb_keymap * keymap,xkb_atom_t name,bool use_aliases)78*2b949d04SAndroid Build Coastguard Worker XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
79*2b949d04SAndroid Build Coastguard Worker {
80*2b949d04SAndroid Build Coastguard Worker     struct xkb_key *key;
81*2b949d04SAndroid Build Coastguard Worker 
82*2b949d04SAndroid Build Coastguard Worker     xkb_keys_foreach(key, keymap)
83*2b949d04SAndroid Build Coastguard Worker         if (key->name == name)
84*2b949d04SAndroid Build Coastguard Worker             return key;
85*2b949d04SAndroid Build Coastguard Worker 
86*2b949d04SAndroid Build Coastguard Worker     if (use_aliases) {
87*2b949d04SAndroid Build Coastguard Worker         xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
88*2b949d04SAndroid Build Coastguard Worker         if (new_name != XKB_ATOM_NONE)
89*2b949d04SAndroid Build Coastguard Worker             return XkbKeyByName(keymap, new_name, false);
90*2b949d04SAndroid Build Coastguard Worker     }
91*2b949d04SAndroid Build Coastguard Worker 
92*2b949d04SAndroid Build Coastguard Worker     return NULL;
93*2b949d04SAndroid Build Coastguard Worker }
94*2b949d04SAndroid Build Coastguard Worker 
95*2b949d04SAndroid Build Coastguard Worker xkb_atom_t
XkbResolveKeyAlias(const struct xkb_keymap * keymap,xkb_atom_t name)96*2b949d04SAndroid Build Coastguard Worker XkbResolveKeyAlias(const struct xkb_keymap *keymap, xkb_atom_t name)
97*2b949d04SAndroid Build Coastguard Worker {
98*2b949d04SAndroid Build Coastguard Worker     for (unsigned i = 0; i < keymap->num_key_aliases; i++)
99*2b949d04SAndroid Build Coastguard Worker         if (keymap->key_aliases[i].alias == name)
100*2b949d04SAndroid Build Coastguard Worker             return keymap->key_aliases[i].real;
101*2b949d04SAndroid Build Coastguard Worker 
102*2b949d04SAndroid Build Coastguard Worker     return XKB_ATOM_NONE;
103*2b949d04SAndroid Build Coastguard Worker }
104*2b949d04SAndroid Build Coastguard Worker 
105*2b949d04SAndroid Build Coastguard Worker void
XkbEscapeMapName(char * name)106*2b949d04SAndroid Build Coastguard Worker XkbEscapeMapName(char *name)
107*2b949d04SAndroid Build Coastguard Worker {
108*2b949d04SAndroid Build Coastguard Worker     /*
109*2b949d04SAndroid Build Coastguard Worker      * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
110*2b949d04SAndroid Build Coastguard Worker      * wildcards.
111*2b949d04SAndroid Build Coastguard Worker      */
112*2b949d04SAndroid Build Coastguard Worker     static const unsigned char legal[] = {
113*2b949d04SAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
114*2b949d04SAndroid Build Coastguard Worker         0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
115*2b949d04SAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116*2b949d04SAndroid Build Coastguard Worker         0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
117*2b949d04SAndroid Build Coastguard Worker     };
118*2b949d04SAndroid Build Coastguard Worker 
119*2b949d04SAndroid Build Coastguard Worker     if (!name)
120*2b949d04SAndroid Build Coastguard Worker         return;
121*2b949d04SAndroid Build Coastguard Worker 
122*2b949d04SAndroid Build Coastguard Worker     while (*name) {
123*2b949d04SAndroid Build Coastguard Worker         unsigned char c = *name;
124*2b949d04SAndroid Build Coastguard Worker         if (!(legal[c / 8] & (1 << (c % 8))))
125*2b949d04SAndroid Build Coastguard Worker             *name = '_';
126*2b949d04SAndroid Build Coastguard Worker         name++;
127*2b949d04SAndroid Build Coastguard Worker     }
128*2b949d04SAndroid Build Coastguard Worker }
129*2b949d04SAndroid Build Coastguard Worker 
130*2b949d04SAndroid Build Coastguard Worker xkb_mod_index_t
XkbModNameToIndex(const struct xkb_mod_set * mods,xkb_atom_t name,enum mod_type type)131*2b949d04SAndroid Build Coastguard Worker XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name,
132*2b949d04SAndroid Build Coastguard Worker                   enum mod_type type)
133*2b949d04SAndroid Build Coastguard Worker {
134*2b949d04SAndroid Build Coastguard Worker     xkb_mod_index_t i;
135*2b949d04SAndroid Build Coastguard Worker     const struct xkb_mod *mod;
136*2b949d04SAndroid Build Coastguard Worker 
137*2b949d04SAndroid Build Coastguard Worker     xkb_mods_enumerate(i, mod, mods)
138*2b949d04SAndroid Build Coastguard Worker         if ((mod->type & type) && name == mod->name)
139*2b949d04SAndroid Build Coastguard Worker             return i;
140*2b949d04SAndroid Build Coastguard Worker 
141*2b949d04SAndroid Build Coastguard Worker     return XKB_MOD_INVALID;
142*2b949d04SAndroid Build Coastguard Worker }
143*2b949d04SAndroid Build Coastguard Worker 
144*2b949d04SAndroid Build Coastguard Worker bool
XkbLevelsSameSyms(const struct xkb_level * a,const struct xkb_level * b)145*2b949d04SAndroid Build Coastguard Worker XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b)
146*2b949d04SAndroid Build Coastguard Worker {
147*2b949d04SAndroid Build Coastguard Worker     if (a->num_syms != b->num_syms)
148*2b949d04SAndroid Build Coastguard Worker         return false;
149*2b949d04SAndroid Build Coastguard Worker     if (a->num_syms <= 1)
150*2b949d04SAndroid Build Coastguard Worker         return a->u.sym == b->u.sym;
151*2b949d04SAndroid Build Coastguard Worker     return memcmp(a->u.syms, b->u.syms, sizeof(*a->u.syms) * a->num_syms) == 0;
152*2b949d04SAndroid Build Coastguard Worker }
153