/************************************************************ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of Silicon Graphics not be * used in advertising or publicity pertaining to distribution * of the software without specific prior written permission. * Silicon Graphics makes no representation about the suitability * of this software for any purpose. It is provided "as is" * without any express or implied warranty. * * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH * THE USE OR PERFORMANCE OF THIS SOFTWARE. * ********************************************************/ #include "config.h" #include "keymap.h" #include "text.h" bool LookupString(const LookupEntry tab[], const char *string, unsigned int *value_rtrn) { if (!string) return false; for (const LookupEntry *entry = tab; entry->name; entry++) { if (istreq(entry->name, string)) { *value_rtrn = entry->value; return true; } } return false; } const char * LookupValue(const LookupEntry tab[], unsigned int value) { for (const LookupEntry *entry = tab; entry->name; entry++) if (entry->value == value) return entry->name; return NULL; } const LookupEntry ctrlMaskNames[] = { { "RepeatKeys", CONTROL_REPEAT }, { "Repeat", CONTROL_REPEAT }, { "AutoRepeat", CONTROL_REPEAT }, { "SlowKeys", CONTROL_SLOW }, { "BounceKeys", CONTROL_DEBOUNCE }, { "StickyKeys", CONTROL_STICKY }, { "MouseKeys", CONTROL_MOUSEKEYS }, { "MouseKeysAccel", CONTROL_MOUSEKEYS_ACCEL }, { "AccessXKeys", CONTROL_AX }, { "AccessXTimeout", CONTROL_AX_TIMEOUT }, { "AccessXFeedback", CONTROL_AX_FEEDBACK }, { "AudibleBell", CONTROL_BELL }, { "IgnoreGroupLock", CONTROL_IGNORE_GROUP_LOCK }, { "all", CONTROL_ALL }, { "none", 0 }, { "Overlay1", 0 }, { "Overlay2", 0 }, { NULL, 0 } }; const LookupEntry modComponentMaskNames[] = { { "base", XKB_STATE_MODS_DEPRESSED }, { "latched", XKB_STATE_MODS_LATCHED }, { "locked", XKB_STATE_MODS_LOCKED }, { "effective", XKB_STATE_MODS_EFFECTIVE }, { "compat", XKB_STATE_MODS_EFFECTIVE }, { "any", XKB_STATE_MODS_EFFECTIVE }, { "none", 0 }, { NULL, 0 } }; const LookupEntry groupComponentMaskNames[] = { { "base", XKB_STATE_LAYOUT_DEPRESSED }, { "latched", XKB_STATE_LAYOUT_LATCHED }, { "locked", XKB_STATE_LAYOUT_LOCKED }, { "effective", XKB_STATE_LAYOUT_EFFECTIVE }, { "any", XKB_STATE_LAYOUT_EFFECTIVE }, { "none", 0 }, { NULL, 0 } }; const LookupEntry groupMaskNames[] = { { "Group1", 0x01 }, { "Group2", 0x02 }, { "Group3", 0x04 }, { "Group4", 0x08 }, { "Group5", 0x10 }, { "Group6", 0x20 }, { "Group7", 0x40 }, { "Group8", 0x80 }, { "none", 0x00 }, { "all", 0xff }, { NULL, 0 } }; const LookupEntry groupNames[] = { { "Group1", 1 }, { "Group2", 2 }, { "Group3", 3 }, { "Group4", 4 }, { "Group5", 5 }, { "Group6", 6 }, { "Group7", 7 }, { "Group8", 8 }, { NULL, 0 } }; const LookupEntry levelNames[] = { { "Level1", 1 }, { "Level2", 2 }, { "Level3", 3 }, { "Level4", 4 }, { "Level5", 5 }, { "Level6", 6 }, { "Level7", 7 }, { "Level8", 8 }, { NULL, 0 } }; const LookupEntry buttonNames[] = { { "Button1", 1 }, { "Button2", 2 }, { "Button3", 3 }, { "Button4", 4 }, { "Button5", 5 }, { "default", 0 }, { NULL, 0 } }; const LookupEntry useModMapValueNames[] = { { "LevelOne", 1 }, { "Level1", 1 }, { "AnyLevel", 0 }, { "any", 0 }, { NULL, 0 } }; const LookupEntry actionTypeNames[] = { { "NoAction", ACTION_TYPE_NONE }, { "SetMods", ACTION_TYPE_MOD_SET }, { "LatchMods", ACTION_TYPE_MOD_LATCH }, { "LockMods", ACTION_TYPE_MOD_LOCK }, { "SetGroup", ACTION_TYPE_GROUP_SET }, { "LatchGroup", ACTION_TYPE_GROUP_LATCH }, { "LockGroup", ACTION_TYPE_GROUP_LOCK }, { "MovePtr", ACTION_TYPE_PTR_MOVE }, { "MovePointer", ACTION_TYPE_PTR_MOVE }, { "PtrBtn", ACTION_TYPE_PTR_BUTTON }, { "PointerButton", ACTION_TYPE_PTR_BUTTON }, { "LockPtrBtn", ACTION_TYPE_PTR_LOCK }, { "LockPtrButton", ACTION_TYPE_PTR_LOCK }, { "LockPointerButton", ACTION_TYPE_PTR_LOCK }, { "LockPointerBtn", ACTION_TYPE_PTR_LOCK }, { "SetPtrDflt", ACTION_TYPE_PTR_DEFAULT }, { "SetPointerDefault", ACTION_TYPE_PTR_DEFAULT }, { "Terminate", ACTION_TYPE_TERMINATE }, { "TerminateServer", ACTION_TYPE_TERMINATE }, { "SwitchScreen", ACTION_TYPE_SWITCH_VT }, { "SetControls", ACTION_TYPE_CTRL_SET }, { "LockControls", ACTION_TYPE_CTRL_LOCK }, { "Private", ACTION_TYPE_PRIVATE }, /* deprecated actions below here - unused */ { "RedirectKey", ACTION_TYPE_NONE }, { "Redirect", ACTION_TYPE_NONE }, { "ISOLock", ACTION_TYPE_NONE }, { "ActionMessage", ACTION_TYPE_NONE }, { "MessageAction", ACTION_TYPE_NONE }, { "Message", ACTION_TYPE_NONE }, { "DeviceBtn", ACTION_TYPE_NONE }, { "DevBtn", ACTION_TYPE_NONE }, { "DevButton", ACTION_TYPE_NONE }, { "DeviceButton", ACTION_TYPE_NONE }, { "LockDeviceBtn", ACTION_TYPE_NONE }, { "LockDevBtn", ACTION_TYPE_NONE }, { "LockDevButton", ACTION_TYPE_NONE }, { "LockDeviceButton", ACTION_TYPE_NONE }, { "DeviceValuator", ACTION_TYPE_NONE }, { "DevVal", ACTION_TYPE_NONE }, { "DeviceVal", ACTION_TYPE_NONE }, { "DevValuator", ACTION_TYPE_NONE }, { NULL, 0 }, }; const LookupEntry symInterpretMatchMaskNames[] = { { "NoneOf", MATCH_NONE }, { "AnyOfOrNone", MATCH_ANY_OR_NONE }, { "AnyOf", MATCH_ANY }, { "AllOf", MATCH_ALL }, { "Exactly", MATCH_EXACTLY }, { NULL, 0 }, }; const char * ModIndexText(struct xkb_context *ctx, const struct xkb_mod_set *mods, xkb_mod_index_t ndx) { if (ndx == XKB_MOD_INVALID) return "none"; if (ndx >= mods->num_mods) return NULL; return xkb_atom_text(ctx, mods->mods[ndx].name); } const char * ActionTypeText(enum xkb_action_type type) { const char *name = LookupValue(actionTypeNames, type); return name ? name : "Private"; } const char * KeysymText(struct xkb_context *ctx, xkb_keysym_t sym) { char *buffer = xkb_context_get_buffer(ctx, 64); xkb_keysym_get_name(sym, buffer, 64); return buffer; } const char * KeyNameText(struct xkb_context *ctx, xkb_atom_t name) { const char *sname = xkb_atom_text(ctx, name); size_t len = strlen_safe(sname) + 3; char *buf = xkb_context_get_buffer(ctx, len); snprintf(buf, len, "<%s>", strempty(sname)); return buf; } const char * SIMatchText(enum xkb_match_operation type) { return LookupValue(symInterpretMatchMaskNames, type); } const char * ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods, xkb_mod_mask_t mask) { char buf[1024] = {0}; size_t pos = 0; xkb_mod_index_t i; const struct xkb_mod *mod; if (mask == 0) return "none"; if (mask == MOD_REAL_MASK_ALL) return "all"; xkb_mods_enumerate(i, mod, mods) { int ret; if (!(mask & (1u << i))) continue; ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", xkb_atom_text(ctx, mod->name)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else pos += ret; } return strncpy(xkb_context_get_buffer(ctx, pos + 1), buf, pos + 1); } const char * LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask) { char buf[1024] = {0}; size_t pos = 0; if (mask == 0) return "0"; for (unsigned i = 0; mask; i++) { int ret; if (!(mask & (1u << i))) continue; mask &= ~(1u << i); ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", LookupValue(modComponentMaskNames, 1u << i)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else pos += ret; } return strncpy(xkb_context_get_buffer(ctx, pos + 1), buf, pos + 1); } const char * ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask) { char buf[1024] = {0}; size_t pos = 0; if (mask == 0) return "none"; if (mask == CONTROL_ALL) return "all"; for (unsigned i = 0; mask; i++) { int ret; if (!(mask & (1u << i))) continue; mask &= ~(1u << i); ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", pos == 0 ? "" : "+", LookupValue(ctrlMaskNames, 1u << i)); if (ret <= 0 || pos + ret >= sizeof(buf)) break; else pos += ret; } return strncpy(xkb_context_get_buffer(ctx, pos + 1), buf, pos + 1); }