1 /************************************************************
2 * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 * Permission to use, copy, modify, and distribute this
5 * software and its documentation for any purpose and without
6 * fee is hereby granted, provided that the above copyright
7 * notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting
9 * documentation, and that the name of Silicon Graphics not be
10 * used in advertising or publicity pertaining to distribution
11 * of the software without specific prior written permission.
12 * Silicon Graphics makes no representation about the suitability
13 * of this software for any purpose. It is provided "as is"
14 * without any express or implied warranty.
16 * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 * THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
30 LookupString(const LookupEntry tab[], const char *string,
31 unsigned int *value_rtrn)
33 const LookupEntry *entry;
38 for (entry = tab; entry->name; entry++) {
39 if (istreq(entry->name, string)) {
40 *value_rtrn = entry->value;
49 LookupValue(const LookupEntry tab[], unsigned int value)
51 const LookupEntry *entry;
53 for (entry = tab; entry->name; entry++)
54 if (entry->value == value)
60 const LookupEntry ctrlMaskNames[] = {
61 { "RepeatKeys", XkbRepeatKeysMask },
62 { "Repeat", XkbRepeatKeysMask },
63 { "AutoRepeat", XkbRepeatKeysMask },
64 { "SlowKeys", XkbSlowKeysMask },
65 { "BounceKeys", XkbBounceKeysMask },
66 { "StickyKeys", XkbStickyKeysMask },
67 { "MouseKeys", XkbMouseKeysMask },
68 { "MouseKeysAccel", XkbMouseKeysAccelMask },
69 { "AccessXKeys", XkbAccessXKeysMask },
70 { "AccessXTimeout", XkbAccessXTimeoutMask },
71 { "AccessXFeedback", XkbAccessXFeedbackMask },
72 { "AudibleBell", XkbAudibleBellMask },
73 { "IgnoreGroupLock", XkbIgnoreGroupLockMask },
74 { "all", XkbAllBooleanCtrlsMask },
81 const LookupEntry modComponentMaskNames[] = {
82 {"base", XkbIM_UseBase},
83 {"latched", XkbIM_UseLatched},
84 {"locked", XkbIM_UseLocked},
85 {"effective", XkbIM_UseEffective},
86 {"compat", XkbIM_UseCompat},
87 {"any", XkbIM_UseAnyMods},
92 const LookupEntry groupComponentMaskNames[] = {
93 {"base", XkbIM_UseBase},
94 {"latched", XkbIM_UseLatched},
95 {"locked", XkbIM_UseLocked},
96 {"effective", XkbIM_UseEffective},
97 {"any", XkbIM_UseAnyGroup},
102 const LookupEntry groupMaskNames[] = {
116 const LookupEntry groupNames[] = {
128 const LookupEntry levelNames[] = {
140 const LookupEntry buttonNames[] = {
150 const LookupEntry useModMapValueNames[] = {
158 const LookupEntry actionTypeNames[] = {
159 { "NoAction", XkbSA_NoAction },
160 { "SetMods", XkbSA_SetMods },
161 { "LatchMods", XkbSA_LatchMods },
162 { "LockMods", XkbSA_LockMods },
163 { "SetGroup", XkbSA_SetGroup },
164 { "LatchGroup", XkbSA_LatchGroup },
165 { "LockGroup", XkbSA_LockGroup },
166 { "MovePtr", XkbSA_MovePtr },
167 { "MovePointer", XkbSA_MovePtr },
168 { "PtrBtn", XkbSA_PtrBtn },
169 { "PointerButton", XkbSA_PtrBtn },
170 { "LockPtrBtn", XkbSA_LockPtrBtn },
171 { "LockPtrButton", XkbSA_LockPtrBtn },
172 { "LockPointerButton", XkbSA_LockPtrBtn },
173 { "LockPointerBtn", XkbSA_LockPtrBtn },
174 { "SetPtrDflt", XkbSA_SetPtrDflt },
175 { "SetPointerDefault", XkbSA_SetPtrDflt },
176 { "ISOLock", XkbSA_ISOLock },
177 { "Terminate", XkbSA_Terminate },
178 { "TerminateServer", XkbSA_Terminate },
179 { "SwitchScreen", XkbSA_SwitchScreen },
180 { "SetControls", XkbSA_SetControls },
181 { "LockControls", XkbSA_LockControls },
182 { "ActionMessage", XkbSA_ActionMessage },
183 { "MessageAction", XkbSA_ActionMessage },
184 { "Message", XkbSA_ActionMessage },
185 { "RedirectKey", XkbSA_RedirectKey },
186 { "Redirect", XkbSA_RedirectKey },
187 { "DeviceBtn", XkbSA_DeviceBtn },
188 { "DevBtn", XkbSA_DeviceBtn },
189 { "DevButton", XkbSA_DeviceBtn },
190 { "DeviceButton", XkbSA_DeviceBtn },
191 { "LockDeviceBtn", XkbSA_LockDeviceBtn },
192 { "LockDevBtn", XkbSA_LockDeviceBtn },
193 { "LockDevButton", XkbSA_LockDeviceBtn },
194 { "LockDeviceButton", XkbSA_LockDeviceBtn },
195 { "DeviceValuator", XkbSA_DeviceValuator },
196 { "DevVal", XkbSA_DeviceValuator },
197 { "DeviceVal", XkbSA_DeviceValuator },
198 { "DevValuator", XkbSA_DeviceValuator },
199 { "Private", PrivateAction },
203 const LookupEntry symInterpretMatchMaskNames[] = {
204 { "NoneOf", XkbSI_NoneOf },
205 { "AnyOfOrNone", XkbSI_AnyOfOrNone },
206 { "AnyOf", XkbSI_AnyOf },
207 { "AllOf", XkbSI_AllOf },
208 { "Exactly", XkbSI_Exactly },
211 #define BUFFER_SIZE 1024
214 GetBuffer(size_t size)
216 static char buffer[BUFFER_SIZE];
220 if (size >= BUFFER_SIZE)
223 if (BUFFER_SIZE - next <= size)
226 rtrn = &buffer[next];
233 * Get a vmod name's text, where the vmod index is zero based
234 * (0..XkbNumVirtualMods-1).
237 VModIndexText(struct xkb_keymap *keymap, xkb_mod_index_t ndx)
241 const char *tmp = NULL;
244 if (ndx >= XkbNumVirtualMods)
247 tmp = xkb_atom_text(keymap->ctx, keymap->vmod_names[ndx]);
250 snprintf(buf, sizeof(buf) - 1, "%d", ndx);
254 len = strlen(tmp) + 1;
255 if (len >= BUFFER_SIZE)
256 len = BUFFER_SIZE - 1;
258 rtrn = GetBuffer(len);
259 strncpy(rtrn, tmp, len);
264 /* Get a mod mask's text, where the mask is in rmods+vmods format. */
266 VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t cmask)
270 xkb_mod_mask_t rmask, vmask;
272 const char *mm = NULL;
274 char buf[BUFFER_SIZE];
276 rmask = cmask & 0xff;
277 vmask = cmask >> XkbNumModifiers;
279 if (rmask == 0 && vmask == 0)
283 mm = ModMaskText(rmask);
290 for (i = 0, bit = 1; i < XkbNumVirtualMods && rem > 1; i++, bit <<=
295 len = snprintf(str, rem, "%s%s",
296 (str != buf) ? "+" : "",
297 VModIndexText(keymap, i));
307 len = (str ? strlen(str) : 0) + (mm ? strlen(mm) : 0) +
309 if (len >= BUFFER_SIZE)
310 len = BUFFER_SIZE - 1;
312 rtrn = GetBuffer(len + 1);
315 snprintf(rtrn, len + 1, "%s%s%s", (mm ? mm : ""),
316 (mm && str ? "+" : ""), (str ? str : ""));
323 * The indices used for the legacy core modifiers is derived from
324 * the order of the names in this table. It matches the values
325 * ShiftMapIndex, LockMapIndex, etc. from X11/X.h. Take note before
328 static const char *modNames[XkbNumModifiers] = {
340 ModNameToIndex(const char *name)
344 for (i = 0; i < XkbNumModifiers; i++)
345 if (istreq(name, modNames[i]))
348 return XKB_MOD_INVALID;
352 ModIndexToName(xkb_mod_index_t ndx)
354 if (ndx < XkbNumModifiers)
355 return modNames[ndx];
360 ModIndexText(xkb_mod_index_t ndx)
365 name = ModIndexToName(ndx);
369 if (ndx == XKB_MOD_INVALID)
373 snprintf(buf, 32, "ILLEGAL_%02x", ndx);
378 /* Gets the text for the real modifiers only. */
380 ModMaskText(xkb_mod_mask_t mask)
386 if ((mask & 0xff) == 0xff)
389 if ((mask & 0xff) == 0)
393 buf = GetBuffer(rem);
396 for (i = 0, bit = 1; i < XkbNumModifiers && rem > 1; i++, bit <<= 1) {
402 len = snprintf(str, rem, "%s%s",
403 (str != buf ? "+" : ""), modNames[i]);
412 ActionTypeText(unsigned type)
414 const char *name = LookupValue(actionTypeNames, type);
415 return name ? name : "Private";
419 KeysymText(xkb_keysym_t sym)
421 static char buffer[64];
423 xkb_keysym_get_name(sym, buffer, sizeof buffer);
429 KeyNameText(const char name[XKB_KEY_NAME_LENGTH])
436 strncpy(&buf[1], name, 4);
446 SIMatchText(unsigned type)
451 type &= XkbSI_OpMask;
453 name = LookupValue(symInterpretMatchMaskNames, type);
458 snprintf(buf, 40, "0x%x", type & XkbSI_OpMask);