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