Home | History | Annotate | Download | only in src
      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 
     30 bool
     31 LookupString(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 
     47 const char *
     48 LookupValue(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 
     57 const 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 
     78 const 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 
     89 const 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 
     99 const 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 
    113 const 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 
    125 const 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 
    137 const 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 
    147 const LookupEntry useModMapValueNames[] = {
    148     { "LevelOne", 1 },
    149     { "Level1", 1 },
    150     { "AnyLevel", 0 },
    151     { "any", 0 },
    152     { NULL, 0 }
    153 };
    154 
    155 const 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 
    201 const 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 
    209 const char *
    210 ModIndexText(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 
    222 const char *
    223 ActionTypeText(enum xkb_action_type type)
    224 {
    225     const char *name = LookupValue(actionTypeNames, type);
    226     return name ? name : "Private";
    227 }
    228 
    229 const char *
    230 KeysymText(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 
    237 const char *
    238 KeyNameText(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 
    247 const char *
    248 SIMatchText(enum xkb_match_operation type)
    249 {
    250     return LookupValue(symInterpretMatchMaskNames, type);
    251 }
    252 
    253 const char *
    254 ModMaskText(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 
    286 const char *
    287 LedStateMaskText(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 
    315 const char *
    316 ControlMaskText(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