xref: /aosp_15_r20/external/libxkbcommon/src/text.c (revision 2b949d0487e80d67f1fda82db69e101e761f8064)
1*2b949d04SAndroid Build Coastguard Worker /************************************************************
2*2b949d04SAndroid Build Coastguard Worker  * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3*2b949d04SAndroid Build Coastguard Worker  *
4*2b949d04SAndroid Build Coastguard Worker  * Permission to use, copy, modify, and distribute this
5*2b949d04SAndroid Build Coastguard Worker  * software and its documentation for any purpose and without
6*2b949d04SAndroid Build Coastguard Worker  * fee is hereby granted, provided that the above copyright
7*2b949d04SAndroid Build Coastguard Worker  * notice appear in all copies and that both that copyright
8*2b949d04SAndroid Build Coastguard Worker  * notice and this permission notice appear in supporting
9*2b949d04SAndroid Build Coastguard Worker  * documentation, and that the name of Silicon Graphics not be
10*2b949d04SAndroid Build Coastguard Worker  * used in advertising or publicity pertaining to distribution
11*2b949d04SAndroid Build Coastguard Worker  * of the software without specific prior written permission.
12*2b949d04SAndroid Build Coastguard Worker  * Silicon Graphics makes no representation about the suitability
13*2b949d04SAndroid Build Coastguard Worker  * of this software for any purpose. It is provided "as is"
14*2b949d04SAndroid Build Coastguard Worker  * without any express or implied warranty.
15*2b949d04SAndroid Build Coastguard Worker  *
16*2b949d04SAndroid Build Coastguard Worker  * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17*2b949d04SAndroid Build Coastguard Worker  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18*2b949d04SAndroid Build Coastguard Worker  * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19*2b949d04SAndroid Build Coastguard Worker  * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20*2b949d04SAndroid Build Coastguard Worker  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21*2b949d04SAndroid Build Coastguard Worker  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22*2b949d04SAndroid Build Coastguard Worker  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23*2b949d04SAndroid Build Coastguard Worker  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*2b949d04SAndroid Build Coastguard Worker  *
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 #include "text.h"
31*2b949d04SAndroid Build Coastguard Worker 
32*2b949d04SAndroid Build Coastguard Worker bool
LookupString(const LookupEntry tab[],const char * string,unsigned int * value_rtrn)33*2b949d04SAndroid Build Coastguard Worker LookupString(const LookupEntry tab[], const char *string,
34*2b949d04SAndroid Build Coastguard Worker               unsigned int *value_rtrn)
35*2b949d04SAndroid Build Coastguard Worker {
36*2b949d04SAndroid Build Coastguard Worker     if (!string)
37*2b949d04SAndroid Build Coastguard Worker         return false;
38*2b949d04SAndroid Build Coastguard Worker 
39*2b949d04SAndroid Build Coastguard Worker     for (const LookupEntry *entry = tab; entry->name; entry++) {
40*2b949d04SAndroid Build Coastguard Worker         if (istreq(entry->name, string)) {
41*2b949d04SAndroid Build Coastguard Worker             *value_rtrn = entry->value;
42*2b949d04SAndroid Build Coastguard Worker             return true;
43*2b949d04SAndroid Build Coastguard Worker         }
44*2b949d04SAndroid Build Coastguard Worker     }
45*2b949d04SAndroid Build Coastguard Worker 
46*2b949d04SAndroid Build Coastguard Worker     return false;
47*2b949d04SAndroid Build Coastguard Worker }
48*2b949d04SAndroid Build Coastguard Worker 
49*2b949d04SAndroid Build Coastguard Worker const char *
LookupValue(const LookupEntry tab[],unsigned int value)50*2b949d04SAndroid Build Coastguard Worker LookupValue(const LookupEntry tab[], unsigned int value)
51*2b949d04SAndroid Build Coastguard Worker {
52*2b949d04SAndroid Build Coastguard Worker     for (const LookupEntry *entry = tab; entry->name; entry++)
53*2b949d04SAndroid Build Coastguard Worker         if (entry->value == value)
54*2b949d04SAndroid Build Coastguard Worker             return entry->name;
55*2b949d04SAndroid Build Coastguard Worker 
56*2b949d04SAndroid Build Coastguard Worker     return NULL;
57*2b949d04SAndroid Build Coastguard Worker }
58*2b949d04SAndroid Build Coastguard Worker 
59*2b949d04SAndroid Build Coastguard Worker const LookupEntry ctrlMaskNames[] = {
60*2b949d04SAndroid Build Coastguard Worker     { "RepeatKeys", CONTROL_REPEAT },
61*2b949d04SAndroid Build Coastguard Worker     { "Repeat", CONTROL_REPEAT },
62*2b949d04SAndroid Build Coastguard Worker     { "AutoRepeat", CONTROL_REPEAT },
63*2b949d04SAndroid Build Coastguard Worker     { "SlowKeys", CONTROL_SLOW },
64*2b949d04SAndroid Build Coastguard Worker     { "BounceKeys", CONTROL_DEBOUNCE },
65*2b949d04SAndroid Build Coastguard Worker     { "StickyKeys", CONTROL_STICKY },
66*2b949d04SAndroid Build Coastguard Worker     { "MouseKeys", CONTROL_MOUSEKEYS },
67*2b949d04SAndroid Build Coastguard Worker     { "MouseKeysAccel", CONTROL_MOUSEKEYS_ACCEL },
68*2b949d04SAndroid Build Coastguard Worker     { "AccessXKeys", CONTROL_AX },
69*2b949d04SAndroid Build Coastguard Worker     { "AccessXTimeout", CONTROL_AX_TIMEOUT },
70*2b949d04SAndroid Build Coastguard Worker     { "AccessXFeedback", CONTROL_AX_FEEDBACK },
71*2b949d04SAndroid Build Coastguard Worker     { "AudibleBell", CONTROL_BELL },
72*2b949d04SAndroid Build Coastguard Worker     { "IgnoreGroupLock", CONTROL_IGNORE_GROUP_LOCK },
73*2b949d04SAndroid Build Coastguard Worker     { "all", CONTROL_ALL },
74*2b949d04SAndroid Build Coastguard Worker     { "none", 0 },
75*2b949d04SAndroid Build Coastguard Worker     { "Overlay1", 0 },
76*2b949d04SAndroid Build Coastguard Worker     { "Overlay2", 0 },
77*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
78*2b949d04SAndroid Build Coastguard Worker };
79*2b949d04SAndroid Build Coastguard Worker 
80*2b949d04SAndroid Build Coastguard Worker const LookupEntry modComponentMaskNames[] = {
81*2b949d04SAndroid Build Coastguard Worker     { "base", XKB_STATE_MODS_DEPRESSED },
82*2b949d04SAndroid Build Coastguard Worker     { "latched", XKB_STATE_MODS_LATCHED },
83*2b949d04SAndroid Build Coastguard Worker     { "locked", XKB_STATE_MODS_LOCKED },
84*2b949d04SAndroid Build Coastguard Worker     { "effective", XKB_STATE_MODS_EFFECTIVE },
85*2b949d04SAndroid Build Coastguard Worker     { "compat", XKB_STATE_MODS_EFFECTIVE },
86*2b949d04SAndroid Build Coastguard Worker     { "any", XKB_STATE_MODS_EFFECTIVE },
87*2b949d04SAndroid Build Coastguard Worker     { "none", 0 },
88*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
89*2b949d04SAndroid Build Coastguard Worker };
90*2b949d04SAndroid Build Coastguard Worker 
91*2b949d04SAndroid Build Coastguard Worker const LookupEntry groupComponentMaskNames[] = {
92*2b949d04SAndroid Build Coastguard Worker     { "base", XKB_STATE_LAYOUT_DEPRESSED },
93*2b949d04SAndroid Build Coastguard Worker     { "latched", XKB_STATE_LAYOUT_LATCHED },
94*2b949d04SAndroid Build Coastguard Worker     { "locked", XKB_STATE_LAYOUT_LOCKED },
95*2b949d04SAndroid Build Coastguard Worker     { "effective", XKB_STATE_LAYOUT_EFFECTIVE },
96*2b949d04SAndroid Build Coastguard Worker     { "any", XKB_STATE_LAYOUT_EFFECTIVE },
97*2b949d04SAndroid Build Coastguard Worker     { "none", 0 },
98*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
99*2b949d04SAndroid Build Coastguard Worker };
100*2b949d04SAndroid Build Coastguard Worker 
101*2b949d04SAndroid Build Coastguard Worker const LookupEntry groupMaskNames[] = {
102*2b949d04SAndroid Build Coastguard Worker     { "Group1", 0x01 },
103*2b949d04SAndroid Build Coastguard Worker     { "Group2", 0x02 },
104*2b949d04SAndroid Build Coastguard Worker     { "Group3", 0x04 },
105*2b949d04SAndroid Build Coastguard Worker     { "Group4", 0x08 },
106*2b949d04SAndroid Build Coastguard Worker     { "Group5", 0x10 },
107*2b949d04SAndroid Build Coastguard Worker     { "Group6", 0x20 },
108*2b949d04SAndroid Build Coastguard Worker     { "Group7", 0x40 },
109*2b949d04SAndroid Build Coastguard Worker     { "Group8", 0x80 },
110*2b949d04SAndroid Build Coastguard Worker     { "none", 0x00 },
111*2b949d04SAndroid Build Coastguard Worker     { "all", 0xff },
112*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
113*2b949d04SAndroid Build Coastguard Worker };
114*2b949d04SAndroid Build Coastguard Worker 
115*2b949d04SAndroid Build Coastguard Worker const LookupEntry groupNames[] = {
116*2b949d04SAndroid Build Coastguard Worker     { "Group1", 1 },
117*2b949d04SAndroid Build Coastguard Worker     { "Group2", 2 },
118*2b949d04SAndroid Build Coastguard Worker     { "Group3", 3 },
119*2b949d04SAndroid Build Coastguard Worker     { "Group4", 4 },
120*2b949d04SAndroid Build Coastguard Worker     { "Group5", 5 },
121*2b949d04SAndroid Build Coastguard Worker     { "Group6", 6 },
122*2b949d04SAndroid Build Coastguard Worker     { "Group7", 7 },
123*2b949d04SAndroid Build Coastguard Worker     { "Group8", 8 },
124*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
125*2b949d04SAndroid Build Coastguard Worker };
126*2b949d04SAndroid Build Coastguard Worker 
127*2b949d04SAndroid Build Coastguard Worker const LookupEntry levelNames[] = {
128*2b949d04SAndroid Build Coastguard Worker     { "Level1", 1 },
129*2b949d04SAndroid Build Coastguard Worker     { "Level2", 2 },
130*2b949d04SAndroid Build Coastguard Worker     { "Level3", 3 },
131*2b949d04SAndroid Build Coastguard Worker     { "Level4", 4 },
132*2b949d04SAndroid Build Coastguard Worker     { "Level5", 5 },
133*2b949d04SAndroid Build Coastguard Worker     { "Level6", 6 },
134*2b949d04SAndroid Build Coastguard Worker     { "Level7", 7 },
135*2b949d04SAndroid Build Coastguard Worker     { "Level8", 8 },
136*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
137*2b949d04SAndroid Build Coastguard Worker };
138*2b949d04SAndroid Build Coastguard Worker 
139*2b949d04SAndroid Build Coastguard Worker const LookupEntry buttonNames[] = {
140*2b949d04SAndroid Build Coastguard Worker     { "Button1", 1 },
141*2b949d04SAndroid Build Coastguard Worker     { "Button2", 2 },
142*2b949d04SAndroid Build Coastguard Worker     { "Button3", 3 },
143*2b949d04SAndroid Build Coastguard Worker     { "Button4", 4 },
144*2b949d04SAndroid Build Coastguard Worker     { "Button5", 5 },
145*2b949d04SAndroid Build Coastguard Worker     { "default", 0 },
146*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
147*2b949d04SAndroid Build Coastguard Worker };
148*2b949d04SAndroid Build Coastguard Worker 
149*2b949d04SAndroid Build Coastguard Worker const LookupEntry useModMapValueNames[] = {
150*2b949d04SAndroid Build Coastguard Worker     { "LevelOne", 1 },
151*2b949d04SAndroid Build Coastguard Worker     { "Level1", 1 },
152*2b949d04SAndroid Build Coastguard Worker     { "AnyLevel", 0 },
153*2b949d04SAndroid Build Coastguard Worker     { "any", 0 },
154*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 }
155*2b949d04SAndroid Build Coastguard Worker };
156*2b949d04SAndroid Build Coastguard Worker 
157*2b949d04SAndroid Build Coastguard Worker const LookupEntry actionTypeNames[] = {
158*2b949d04SAndroid Build Coastguard Worker     { "NoAction", ACTION_TYPE_NONE },
159*2b949d04SAndroid Build Coastguard Worker     { "SetMods", ACTION_TYPE_MOD_SET },
160*2b949d04SAndroid Build Coastguard Worker     { "LatchMods", ACTION_TYPE_MOD_LATCH },
161*2b949d04SAndroid Build Coastguard Worker     { "LockMods", ACTION_TYPE_MOD_LOCK },
162*2b949d04SAndroid Build Coastguard Worker     { "SetGroup", ACTION_TYPE_GROUP_SET },
163*2b949d04SAndroid Build Coastguard Worker     { "LatchGroup", ACTION_TYPE_GROUP_LATCH },
164*2b949d04SAndroid Build Coastguard Worker     { "LockGroup", ACTION_TYPE_GROUP_LOCK },
165*2b949d04SAndroid Build Coastguard Worker     { "MovePtr", ACTION_TYPE_PTR_MOVE },
166*2b949d04SAndroid Build Coastguard Worker     { "MovePointer", ACTION_TYPE_PTR_MOVE },
167*2b949d04SAndroid Build Coastguard Worker     { "PtrBtn", ACTION_TYPE_PTR_BUTTON },
168*2b949d04SAndroid Build Coastguard Worker     { "PointerButton", ACTION_TYPE_PTR_BUTTON },
169*2b949d04SAndroid Build Coastguard Worker     { "LockPtrBtn", ACTION_TYPE_PTR_LOCK },
170*2b949d04SAndroid Build Coastguard Worker     { "LockPtrButton", ACTION_TYPE_PTR_LOCK },
171*2b949d04SAndroid Build Coastguard Worker     { "LockPointerButton", ACTION_TYPE_PTR_LOCK },
172*2b949d04SAndroid Build Coastguard Worker     { "LockPointerBtn", ACTION_TYPE_PTR_LOCK },
173*2b949d04SAndroid Build Coastguard Worker     { "SetPtrDflt", ACTION_TYPE_PTR_DEFAULT },
174*2b949d04SAndroid Build Coastguard Worker     { "SetPointerDefault", ACTION_TYPE_PTR_DEFAULT },
175*2b949d04SAndroid Build Coastguard Worker     { "Terminate", ACTION_TYPE_TERMINATE },
176*2b949d04SAndroid Build Coastguard Worker     { "TerminateServer", ACTION_TYPE_TERMINATE },
177*2b949d04SAndroid Build Coastguard Worker     { "SwitchScreen", ACTION_TYPE_SWITCH_VT },
178*2b949d04SAndroid Build Coastguard Worker     { "SetControls", ACTION_TYPE_CTRL_SET },
179*2b949d04SAndroid Build Coastguard Worker     { "LockControls", ACTION_TYPE_CTRL_LOCK },
180*2b949d04SAndroid Build Coastguard Worker     { "Private", ACTION_TYPE_PRIVATE },
181*2b949d04SAndroid Build Coastguard Worker     /* deprecated actions below here - unused */
182*2b949d04SAndroid Build Coastguard Worker     { "RedirectKey", ACTION_TYPE_NONE },
183*2b949d04SAndroid Build Coastguard Worker     { "Redirect", ACTION_TYPE_NONE },
184*2b949d04SAndroid Build Coastguard Worker     { "ISOLock", ACTION_TYPE_NONE },
185*2b949d04SAndroid Build Coastguard Worker     { "ActionMessage", ACTION_TYPE_NONE },
186*2b949d04SAndroid Build Coastguard Worker     { "MessageAction", ACTION_TYPE_NONE },
187*2b949d04SAndroid Build Coastguard Worker     { "Message", ACTION_TYPE_NONE },
188*2b949d04SAndroid Build Coastguard Worker     { "DeviceBtn", ACTION_TYPE_NONE },
189*2b949d04SAndroid Build Coastguard Worker     { "DevBtn", ACTION_TYPE_NONE },
190*2b949d04SAndroid Build Coastguard Worker     { "DevButton", ACTION_TYPE_NONE },
191*2b949d04SAndroid Build Coastguard Worker     { "DeviceButton", ACTION_TYPE_NONE },
192*2b949d04SAndroid Build Coastguard Worker     { "LockDeviceBtn", ACTION_TYPE_NONE },
193*2b949d04SAndroid Build Coastguard Worker     { "LockDevBtn", ACTION_TYPE_NONE },
194*2b949d04SAndroid Build Coastguard Worker     { "LockDevButton", ACTION_TYPE_NONE },
195*2b949d04SAndroid Build Coastguard Worker     { "LockDeviceButton", ACTION_TYPE_NONE },
196*2b949d04SAndroid Build Coastguard Worker     { "DeviceValuator", ACTION_TYPE_NONE },
197*2b949d04SAndroid Build Coastguard Worker     { "DevVal", ACTION_TYPE_NONE },
198*2b949d04SAndroid Build Coastguard Worker     { "DeviceVal", ACTION_TYPE_NONE },
199*2b949d04SAndroid Build Coastguard Worker     { "DevValuator", ACTION_TYPE_NONE },
200*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 },
201*2b949d04SAndroid Build Coastguard Worker };
202*2b949d04SAndroid Build Coastguard Worker 
203*2b949d04SAndroid Build Coastguard Worker const LookupEntry symInterpretMatchMaskNames[] = {
204*2b949d04SAndroid Build Coastguard Worker     { "NoneOf", MATCH_NONE },
205*2b949d04SAndroid Build Coastguard Worker     { "AnyOfOrNone", MATCH_ANY_OR_NONE },
206*2b949d04SAndroid Build Coastguard Worker     { "AnyOf", MATCH_ANY },
207*2b949d04SAndroid Build Coastguard Worker     { "AllOf", MATCH_ALL },
208*2b949d04SAndroid Build Coastguard Worker     { "Exactly", MATCH_EXACTLY },
209*2b949d04SAndroid Build Coastguard Worker     { NULL, 0 },
210*2b949d04SAndroid Build Coastguard Worker };
211*2b949d04SAndroid Build Coastguard Worker 
212*2b949d04SAndroid Build Coastguard Worker const char *
ModIndexText(struct xkb_context * ctx,const struct xkb_mod_set * mods,xkb_mod_index_t ndx)213*2b949d04SAndroid Build Coastguard Worker ModIndexText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
214*2b949d04SAndroid Build Coastguard Worker              xkb_mod_index_t ndx)
215*2b949d04SAndroid Build Coastguard Worker {
216*2b949d04SAndroid Build Coastguard Worker     if (ndx == XKB_MOD_INVALID)
217*2b949d04SAndroid Build Coastguard Worker         return "none";
218*2b949d04SAndroid Build Coastguard Worker 
219*2b949d04SAndroid Build Coastguard Worker     if (ndx >= mods->num_mods)
220*2b949d04SAndroid Build Coastguard Worker         return NULL;
221*2b949d04SAndroid Build Coastguard Worker 
222*2b949d04SAndroid Build Coastguard Worker     return xkb_atom_text(ctx, mods->mods[ndx].name);
223*2b949d04SAndroid Build Coastguard Worker }
224*2b949d04SAndroid Build Coastguard Worker 
225*2b949d04SAndroid Build Coastguard Worker const char *
ActionTypeText(enum xkb_action_type type)226*2b949d04SAndroid Build Coastguard Worker ActionTypeText(enum xkb_action_type type)
227*2b949d04SAndroid Build Coastguard Worker {
228*2b949d04SAndroid Build Coastguard Worker     const char *name = LookupValue(actionTypeNames, type);
229*2b949d04SAndroid Build Coastguard Worker     return name ? name : "Private";
230*2b949d04SAndroid Build Coastguard Worker }
231*2b949d04SAndroid Build Coastguard Worker 
232*2b949d04SAndroid Build Coastguard Worker const char *
KeysymText(struct xkb_context * ctx,xkb_keysym_t sym)233*2b949d04SAndroid Build Coastguard Worker KeysymText(struct xkb_context *ctx, xkb_keysym_t sym)
234*2b949d04SAndroid Build Coastguard Worker {
235*2b949d04SAndroid Build Coastguard Worker     char *buffer = xkb_context_get_buffer(ctx, 64);
236*2b949d04SAndroid Build Coastguard Worker     xkb_keysym_get_name(sym, buffer, 64);
237*2b949d04SAndroid Build Coastguard Worker     return buffer;
238*2b949d04SAndroid Build Coastguard Worker }
239*2b949d04SAndroid Build Coastguard Worker 
240*2b949d04SAndroid Build Coastguard Worker const char *
KeyNameText(struct xkb_context * ctx,xkb_atom_t name)241*2b949d04SAndroid Build Coastguard Worker KeyNameText(struct xkb_context *ctx, xkb_atom_t name)
242*2b949d04SAndroid Build Coastguard Worker {
243*2b949d04SAndroid Build Coastguard Worker     const char *sname = xkb_atom_text(ctx, name);
244*2b949d04SAndroid Build Coastguard Worker     size_t len = strlen_safe(sname) + 3;
245*2b949d04SAndroid Build Coastguard Worker     char *buf = xkb_context_get_buffer(ctx, len);
246*2b949d04SAndroid Build Coastguard Worker     snprintf(buf, len, "<%s>", strempty(sname));
247*2b949d04SAndroid Build Coastguard Worker     return buf;
248*2b949d04SAndroid Build Coastguard Worker }
249*2b949d04SAndroid Build Coastguard Worker 
250*2b949d04SAndroid Build Coastguard Worker const char *
SIMatchText(enum xkb_match_operation type)251*2b949d04SAndroid Build Coastguard Worker SIMatchText(enum xkb_match_operation type)
252*2b949d04SAndroid Build Coastguard Worker {
253*2b949d04SAndroid Build Coastguard Worker     return LookupValue(symInterpretMatchMaskNames, type);
254*2b949d04SAndroid Build Coastguard Worker }
255*2b949d04SAndroid Build Coastguard Worker 
256*2b949d04SAndroid Build Coastguard Worker const char *
ModMaskText(struct xkb_context * ctx,const struct xkb_mod_set * mods,xkb_mod_mask_t mask)257*2b949d04SAndroid Build Coastguard Worker ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods,
258*2b949d04SAndroid Build Coastguard Worker             xkb_mod_mask_t mask)
259*2b949d04SAndroid Build Coastguard Worker {
260*2b949d04SAndroid Build Coastguard Worker     char buf[1024] = {0};
261*2b949d04SAndroid Build Coastguard Worker     size_t pos = 0;
262*2b949d04SAndroid Build Coastguard Worker     xkb_mod_index_t i;
263*2b949d04SAndroid Build Coastguard Worker     const struct xkb_mod *mod;
264*2b949d04SAndroid Build Coastguard Worker 
265*2b949d04SAndroid Build Coastguard Worker     if (mask == 0)
266*2b949d04SAndroid Build Coastguard Worker         return "none";
267*2b949d04SAndroid Build Coastguard Worker 
268*2b949d04SAndroid Build Coastguard Worker     if (mask == MOD_REAL_MASK_ALL)
269*2b949d04SAndroid Build Coastguard Worker         return "all";
270*2b949d04SAndroid Build Coastguard Worker 
271*2b949d04SAndroid Build Coastguard Worker     xkb_mods_enumerate(i, mod, mods) {
272*2b949d04SAndroid Build Coastguard Worker         int ret;
273*2b949d04SAndroid Build Coastguard Worker 
274*2b949d04SAndroid Build Coastguard Worker         if (!(mask & (1u << i)))
275*2b949d04SAndroid Build Coastguard Worker             continue;
276*2b949d04SAndroid Build Coastguard Worker 
277*2b949d04SAndroid Build Coastguard Worker         ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
278*2b949d04SAndroid Build Coastguard Worker                        pos == 0 ? "" : "+",
279*2b949d04SAndroid Build Coastguard Worker                        xkb_atom_text(ctx, mod->name));
280*2b949d04SAndroid Build Coastguard Worker         if (ret <= 0 || pos + ret >= sizeof(buf))
281*2b949d04SAndroid Build Coastguard Worker             break;
282*2b949d04SAndroid Build Coastguard Worker         else
283*2b949d04SAndroid Build Coastguard Worker             pos += ret;
284*2b949d04SAndroid Build Coastguard Worker     }
285*2b949d04SAndroid Build Coastguard Worker 
286*2b949d04SAndroid Build Coastguard Worker     return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
287*2b949d04SAndroid Build Coastguard Worker }
288*2b949d04SAndroid Build Coastguard Worker 
289*2b949d04SAndroid Build Coastguard Worker const char *
LedStateMaskText(struct xkb_context * ctx,enum xkb_state_component mask)290*2b949d04SAndroid Build Coastguard Worker LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask)
291*2b949d04SAndroid Build Coastguard Worker {
292*2b949d04SAndroid Build Coastguard Worker     char buf[1024];
293*2b949d04SAndroid Build Coastguard Worker     size_t pos = 0;
294*2b949d04SAndroid Build Coastguard Worker 
295*2b949d04SAndroid Build Coastguard Worker     if (mask == 0)
296*2b949d04SAndroid Build Coastguard Worker         return "0";
297*2b949d04SAndroid Build Coastguard Worker 
298*2b949d04SAndroid Build Coastguard Worker     for (unsigned i = 0; mask; i++) {
299*2b949d04SAndroid Build Coastguard Worker         int ret;
300*2b949d04SAndroid Build Coastguard Worker 
301*2b949d04SAndroid Build Coastguard Worker         if (!(mask & (1u << i)))
302*2b949d04SAndroid Build Coastguard Worker             continue;
303*2b949d04SAndroid Build Coastguard Worker 
304*2b949d04SAndroid Build Coastguard Worker         mask &= ~(1u << i);
305*2b949d04SAndroid Build Coastguard Worker 
306*2b949d04SAndroid Build Coastguard Worker         ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
307*2b949d04SAndroid Build Coastguard Worker                        pos == 0 ? "" : "+",
308*2b949d04SAndroid Build Coastguard Worker                        LookupValue(modComponentMaskNames, 1u << i));
309*2b949d04SAndroid Build Coastguard Worker         if (ret <= 0 || pos + ret >= sizeof(buf))
310*2b949d04SAndroid Build Coastguard Worker             break;
311*2b949d04SAndroid Build Coastguard Worker         else
312*2b949d04SAndroid Build Coastguard Worker             pos += ret;
313*2b949d04SAndroid Build Coastguard Worker     }
314*2b949d04SAndroid Build Coastguard Worker 
315*2b949d04SAndroid Build Coastguard Worker     return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
316*2b949d04SAndroid Build Coastguard Worker }
317*2b949d04SAndroid Build Coastguard Worker 
318*2b949d04SAndroid Build Coastguard Worker const char *
ControlMaskText(struct xkb_context * ctx,enum xkb_action_controls mask)319*2b949d04SAndroid Build Coastguard Worker ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask)
320*2b949d04SAndroid Build Coastguard Worker {
321*2b949d04SAndroid Build Coastguard Worker     char buf[1024];
322*2b949d04SAndroid Build Coastguard Worker     size_t pos = 0;
323*2b949d04SAndroid Build Coastguard Worker 
324*2b949d04SAndroid Build Coastguard Worker     if (mask == 0)
325*2b949d04SAndroid Build Coastguard Worker         return "none";
326*2b949d04SAndroid Build Coastguard Worker 
327*2b949d04SAndroid Build Coastguard Worker     if (mask == CONTROL_ALL)
328*2b949d04SAndroid Build Coastguard Worker         return "all";
329*2b949d04SAndroid Build Coastguard Worker 
330*2b949d04SAndroid Build Coastguard Worker     for (unsigned i = 0; mask; i++) {
331*2b949d04SAndroid Build Coastguard Worker         int ret;
332*2b949d04SAndroid Build Coastguard Worker 
333*2b949d04SAndroid Build Coastguard Worker         if (!(mask & (1u << i)))
334*2b949d04SAndroid Build Coastguard Worker             continue;
335*2b949d04SAndroid Build Coastguard Worker 
336*2b949d04SAndroid Build Coastguard Worker         mask &= ~(1u << i);
337*2b949d04SAndroid Build Coastguard Worker 
338*2b949d04SAndroid Build Coastguard Worker         ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
339*2b949d04SAndroid Build Coastguard Worker                        pos == 0 ? "" : "+",
340*2b949d04SAndroid Build Coastguard Worker                        LookupValue(ctrlMaskNames, 1u << i));
341*2b949d04SAndroid Build Coastguard Worker         if (ret <= 0 || pos + ret >= sizeof(buf))
342*2b949d04SAndroid Build Coastguard Worker             break;
343*2b949d04SAndroid Build Coastguard Worker         else
344*2b949d04SAndroid Build Coastguard Worker             pos += ret;
345*2b949d04SAndroid Build Coastguard Worker     }
346*2b949d04SAndroid Build Coastguard Worker 
347*2b949d04SAndroid Build Coastguard Worker     return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf);
348*2b949d04SAndroid Build Coastguard Worker }
349