Handle key names consistently
[platform/upstream/libxkbcommon.git] / src / text.c
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 "text.h"
28
29 #define BUFFER_SIZE 1024
30
31 static char *
32 GetBuffer(size_t size)
33 {
34     static char buffer[BUFFER_SIZE];
35     static size_t next;
36     char *rtrn;
37
38     if (size >= BUFFER_SIZE)
39         return NULL;
40
41     if (BUFFER_SIZE - next <= size)
42         next = 0;
43
44     rtrn = &buffer[next];
45     next += size;
46
47     return rtrn;
48 }
49
50 static const char *
51 VModIndexText(struct xkb_keymap *keymap, xkb_mod_index_t ndx)
52 {
53     int len;
54     char *rtrn;
55     const char *tmp = NULL;
56     char buf[20];
57
58     if (ndx >= XkbNumVirtualMods)
59          tmp = "illegal";
60     else
61          tmp = keymap->vmod_names[ndx];
62
63     if (!tmp) {
64         snprintf(buf, sizeof(buf) - 1, "%d", ndx);
65         tmp = buf;
66     }
67
68     len = strlen(tmp) + 1;
69     if (len >= BUFFER_SIZE)
70         len = BUFFER_SIZE - 1;
71
72     rtrn = GetBuffer(len);
73     strncpy(rtrn, tmp, len);
74
75     return rtrn;
76 }
77
78 const char *
79 VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t modMask,
80              xkb_mod_mask_t mask)
81 {
82     xkb_mod_index_t i;
83     xkb_mod_mask_t bit;
84     int len, rem;
85     const char *mm = NULL;
86     char *rtrn, *str;
87     char buf[BUFFER_SIZE];
88
89     if (modMask == 0 && mask == 0)
90         return "none";
91
92     if (modMask != 0)
93         mm = ModMaskText(modMask, false);
94
95     str = buf;
96     buf[0] = '\0';
97     rem = BUFFER_SIZE;
98
99     if (mask) {
100         for (i = 0, bit = 1; i < XkbNumVirtualMods && rem > 1; i++, bit <<=
101                  1) {
102             if (!(mask & bit))
103                 continue;
104
105             len = snprintf(str, rem, "%s%s",
106                            (str != buf) ? "+" : "",
107                            VModIndexText(keymap, i));
108             rem -= len;
109             str += len;
110         }
111
112         str = buf;
113     }
114     else
115         str = NULL;
116
117     len = (str ? strlen(str) : 0) + (mm ? strlen(mm) : 0) +
118           (str && mm ? 1 : 0);
119     if (len >= BUFFER_SIZE)
120         len = BUFFER_SIZE - 1;
121
122     rtrn = GetBuffer(len + 1);
123     rtrn[0] = '\0';
124
125     snprintf(rtrn, len + 1, "%s%s%s", (mm ? mm : ""),
126              (mm && str ? "+" : ""), (str ? str : ""));
127
128     return rtrn;
129 }
130
131 static const char *modNames[XkbNumModifiers] = {
132     [ShiftMapIndex]   = "Shift",
133     [LockMapIndex]    = "Lock",
134     [ControlMapIndex] = "Control",
135     [Mod1MapIndex]    = "Mod1",
136     [Mod2MapIndex]    = "Mod2",
137     [Mod3MapIndex]    = "Mod3",
138     [Mod4MapIndex]    = "Mod4",
139     [Mod5MapIndex]    = "Mod5",
140 };
141
142 xkb_mod_index_t
143 ModNameToIndex(const char *name)
144 {
145     xkb_mod_index_t i;
146
147     for (i = 0; i < XkbNumModifiers; i++)
148         if (istreq(name, modNames[i]))
149             return i;
150
151     return XKB_MOD_INVALID;
152 }
153
154 const char *
155 ModIndexToName(xkb_mod_index_t ndx)
156 {
157     if (ndx < XkbNumModifiers)
158         return modNames[ndx];
159     return NULL;
160 }
161
162 const char *
163 ModIndexText(xkb_mod_index_t ndx)
164 {
165     const char *name;
166     char *buf;
167
168     name = ModIndexToName(ndx);
169     if (name)
170         return name;
171
172     if (ndx == XkbNoModifier)
173         return "none";
174
175     buf = GetBuffer(32);
176     snprintf(buf, 32, "ILLEGAL_%02x", ndx);
177
178     return buf;
179 }
180
181 const char *
182 ModMaskText(xkb_mod_mask_t mask, bool cFormat)
183 {
184     int i, rem;
185     xkb_mod_index_t bit;
186     char *str, *buf;
187
188     if ((mask & 0xff) == 0xff)
189         return (cFormat ? "0xff" : "all");
190
191     if ((mask & 0xff) == 0)
192         return (cFormat ? "0" : "none");
193
194     rem = 64;
195     buf = GetBuffer(rem);
196     str = buf;
197     buf[0] = '\0';
198     for (i = 0, bit = 1; i < XkbNumModifiers && rem > 1; i++, bit <<= 1) {
199         int len;
200
201         if (!(mask & bit))
202             continue;
203
204         len = snprintf(str, rem, "%s%s%s",
205                        (str != buf) ? (cFormat ? "|" : "+") : "",
206                        modNames[i],
207                        cFormat ? "Mask" : "");
208         rem -= len;
209         str += len;
210     }
211
212     return buf;
213 }
214
215 const char *
216 FileTypeText(enum xkb_file_type type)
217 {
218     switch (type) {
219     case FILE_TYPE_KEYMAP:
220         return "xkb_keymap";
221     case FILE_TYPE_TYPES:
222         return "xkb_types";
223     case FILE_TYPE_COMPAT:
224         return "xkb_compatability";
225     case FILE_TYPE_SYMBOLS:
226         return "xkb_symbols";
227     case FILE_TYPE_KEYCODES:
228         return "xkb_keycodes";
229     case FILE_TYPE_RULES:
230         return "rules";
231     default:
232         return "unknown";
233     }
234 }
235
236 static const char *actionTypeNames[XkbSA_NumActions] = {
237     [XkbSA_NoAction]       = "NoAction",
238     [XkbSA_SetMods]        = "SetMods",
239     [XkbSA_LatchMods]      = "LatchMods",
240     [XkbSA_LockMods]       = "LockMods",
241     [XkbSA_SetGroup]       = "SetGroup",
242     [XkbSA_LatchGroup]     = "LatchGroup",
243     [XkbSA_LockGroup]      = "LockGroup",
244     [XkbSA_MovePtr]        = "MovePtr",
245     [XkbSA_PtrBtn]         = "PtrBtn",
246     [XkbSA_LockPtrBtn]     = "LockPtrBtn",
247     [XkbSA_SetPtrDflt]     = "SetPtrDflt",
248     [XkbSA_ISOLock]        = "ISOLock",
249     [XkbSA_Terminate]      = "Terminate",
250     [XkbSA_SwitchScreen]   = "SwitchScreen",
251     [XkbSA_SetControls]    = "SetControls",
252     [XkbSA_LockControls]   = "LockControls",
253     [XkbSA_ActionMessage]  = "ActionMessage",
254     [XkbSA_RedirectKey]    = "RedirectKey",
255     [XkbSA_DeviceBtn]      = "DeviceBtn",
256     [XkbSA_LockDeviceBtn]  = "LockDeviceBtn",
257     [XkbSA_DeviceValuator] = "DeviceValuator"
258 };
259
260 const char *
261 ActionTypeText(unsigned type)
262 {
263     if (type <= XkbSA_LastAction)
264         return actionTypeNames[type];
265     return "Private";
266 }
267
268 const char *
269 KeysymText(xkb_keysym_t sym)
270 {
271     static char buffer[64];
272
273     xkb_keysym_get_name(sym, buffer, sizeof buffer);
274
275     return buffer;
276 }
277
278 const char *
279 KeyNameText(const char name[XkbKeyNameLength])
280 {
281     char *buf;
282     int len;
283
284     buf = GetBuffer(7);
285     buf[0] = '<';
286     strncpy(&buf[1], name, 4);
287     buf[5] = '\0';
288     len = strlen(buf);
289     buf[len++] = '>';
290     buf[len] = '\0';
291
292     return buf;
293 }
294
295 static const char *siMatchText[5] = {
296     "NoneOf",       /* XkbSI_NoneOf */
297     "AnyOfOrNone",  /* XkbSI_AnyOfOrNone */
298     "AnyOf",        /* XkbSI_AnyOf */
299     "AllOf",        /* XkbSI_AllOf */
300     "Exactly"       /* XkbSI_Exactly */
301 };
302
303 const char *
304 SIMatchText(unsigned type)
305 {
306     char *buf;
307
308     switch (type & XkbSI_OpMask) {
309     case XkbSI_NoneOf:
310         return siMatchText[0];
311     case XkbSI_AnyOfOrNone:
312         return siMatchText[1];
313     case XkbSI_AnyOf:
314         return siMatchText[2];
315     case XkbSI_AllOf:
316         return siMatchText[3];
317     case XkbSI_Exactly:
318         return siMatchText[4];
319     default:
320         buf = GetBuffer(40);
321         snprintf(buf, 40, "0x%x", type & XkbSI_OpMask);
322         return buf;
323     }
324 }