Convert rest of names in xkb_keymap back to atoms
[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 /*
51  * Get a vmod name's text, where the vmod index is zero based
52  * (0..XkbNumVirtualMods-1).
53  */
54 static const char *
55 VModIndexText(struct xkb_keymap *keymap, xkb_mod_index_t ndx)
56 {
57     int len;
58     char *rtrn;
59     const char *tmp = NULL;
60     char buf[20];
61
62     if (ndx >= XkbNumVirtualMods)
63          tmp = "illegal";
64     else
65          tmp = xkb_atom_text(keymap->ctx, keymap->vmod_names[ndx]);
66
67     if (!tmp) {
68         snprintf(buf, sizeof(buf) - 1, "%d", ndx);
69         tmp = buf;
70     }
71
72     len = strlen(tmp) + 1;
73     if (len >= BUFFER_SIZE)
74         len = BUFFER_SIZE - 1;
75
76     rtrn = GetBuffer(len);
77     strncpy(rtrn, tmp, len);
78
79     return rtrn;
80 }
81
82 /* Get a mod mask's text, where the mask is in rmods+vmods format. */
83 const char *
84 VModMaskText(struct xkb_keymap *keymap, xkb_mod_mask_t cmask)
85 {
86     xkb_mod_index_t i;
87     xkb_mod_mask_t bit;
88     xkb_mod_mask_t rmask, vmask;
89     int len, rem;
90     const char *mm = NULL;
91     char *rtrn, *str;
92     char buf[BUFFER_SIZE];
93
94     rmask = cmask & 0xff;
95     vmask = cmask >> XkbNumModifiers;
96
97     if (rmask == 0 && vmask == 0)
98         return "none";
99
100     if (rmask != 0)
101         mm = ModMaskText(rmask);
102
103     str = buf;
104     buf[0] = '\0';
105     rem = BUFFER_SIZE;
106
107     if (vmask != 0) {
108         for (i = 0, bit = 1; i < XkbNumVirtualMods && rem > 1; i++, bit <<=
109                  1) {
110             if (!(vmask & bit))
111                 continue;
112
113             len = snprintf(str, rem, "%s%s",
114                            (str != buf) ? "+" : "",
115                            VModIndexText(keymap, i));
116             rem -= len;
117             str += len;
118         }
119
120         str = buf;
121     }
122     else
123         str = NULL;
124
125     len = (str ? strlen(str) : 0) + (mm ? strlen(mm) : 0) +
126           (str && mm ? 1 : 0);
127     if (len >= BUFFER_SIZE)
128         len = BUFFER_SIZE - 1;
129
130     rtrn = GetBuffer(len + 1);
131     rtrn[0] = '\0';
132
133     snprintf(rtrn, len + 1, "%s%s%s", (mm ? mm : ""),
134              (mm && str ? "+" : ""), (str ? str : ""));
135
136     return rtrn;
137 }
138
139 /*
140  * IMPORTATNT
141  * The indices used for the legacy core modifiers is derived from
142  * the order of the names in this table. It matches the values
143  * ShiftMapIndex, LockMapIndex, etc. from X11/X.h. Take note before
144  * changing.
145  */
146 static const char *modNames[XkbNumModifiers] = {
147     "Shift",
148     "Lock",
149     "Control",
150     "Mod1",
151     "Mod2",
152     "Mod3",
153     "Mod4",
154     "Mod5",
155 };
156
157 xkb_mod_index_t
158 ModNameToIndex(const char *name)
159 {
160     xkb_mod_index_t i;
161
162     for (i = 0; i < XkbNumModifiers; i++)
163         if (istreq(name, modNames[i]))
164             return i;
165
166     return XKB_MOD_INVALID;
167 }
168
169 const char *
170 ModIndexToName(xkb_mod_index_t ndx)
171 {
172     if (ndx < XkbNumModifiers)
173         return modNames[ndx];
174     return NULL;
175 }
176
177 const char *
178 ModIndexText(xkb_mod_index_t ndx)
179 {
180     const char *name;
181     char *buf;
182
183     name = ModIndexToName(ndx);
184     if (name)
185         return name;
186
187     if (ndx == XKB_MOD_INVALID)
188         return "none";
189
190     buf = GetBuffer(32);
191     snprintf(buf, 32, "ILLEGAL_%02x", ndx);
192
193     return buf;
194 }
195
196 /* Gets the text for the real modifiers only. */
197 const char *
198 ModMaskText(xkb_mod_mask_t mask)
199 {
200     int i, rem;
201     xkb_mod_index_t bit;
202     char *str, *buf;
203
204     if ((mask & 0xff) == 0xff)
205         return "all";
206
207     if ((mask & 0xff) == 0)
208         return "none";
209
210     rem = 64;
211     buf = GetBuffer(rem);
212     str = buf;
213     buf[0] = '\0';
214     for (i = 0, bit = 1; i < XkbNumModifiers && rem > 1; i++, bit <<= 1) {
215         int len;
216
217         if (!(mask & bit))
218             continue;
219
220         len = snprintf(str, rem, "%s%s",
221                        (str != buf ?  "+" : ""), modNames[i]);
222         rem -= len;
223         str += len;
224     }
225
226     return buf;
227 }
228
229 static const char *actionTypeNames[XkbSA_NumActions] = {
230     [XkbSA_NoAction]       = "NoAction",
231     [XkbSA_SetMods]        = "SetMods",
232     [XkbSA_LatchMods]      = "LatchMods",
233     [XkbSA_LockMods]       = "LockMods",
234     [XkbSA_SetGroup]       = "SetGroup",
235     [XkbSA_LatchGroup]     = "LatchGroup",
236     [XkbSA_LockGroup]      = "LockGroup",
237     [XkbSA_MovePtr]        = "MovePtr",
238     [XkbSA_PtrBtn]         = "PtrBtn",
239     [XkbSA_LockPtrBtn]     = "LockPtrBtn",
240     [XkbSA_SetPtrDflt]     = "SetPtrDflt",
241     [XkbSA_ISOLock]        = "ISOLock",
242     [XkbSA_Terminate]      = "Terminate",
243     [XkbSA_SwitchScreen]   = "SwitchScreen",
244     [XkbSA_SetControls]    = "SetControls",
245     [XkbSA_LockControls]   = "LockControls",
246     [XkbSA_ActionMessage]  = "ActionMessage",
247     [XkbSA_RedirectKey]    = "RedirectKey",
248     [XkbSA_DeviceBtn]      = "DeviceBtn",
249     [XkbSA_LockDeviceBtn]  = "LockDeviceBtn",
250     [XkbSA_DeviceValuator] = "DeviceValuator"
251 };
252
253 const char *
254 ActionTypeText(unsigned type)
255 {
256     if (type <= XkbSA_LastAction)
257         return actionTypeNames[type];
258     return "Private";
259 }
260
261 const char *
262 KeysymText(xkb_keysym_t sym)
263 {
264     static char buffer[64];
265
266     xkb_keysym_get_name(sym, buffer, sizeof buffer);
267
268     return buffer;
269 }
270
271 const char *
272 KeyNameText(const char name[XkbKeyNameLength])
273 {
274     char *buf;
275     int len;
276
277     buf = GetBuffer(7);
278     buf[0] = '<';
279     strncpy(&buf[1], name, 4);
280     buf[5] = '\0';
281     len = strlen(buf);
282     buf[len++] = '>';
283     buf[len] = '\0';
284
285     return buf;
286 }
287
288 static const char *siMatchText[5] = {
289     "NoneOf",       /* XkbSI_NoneOf */
290     "AnyOfOrNone",  /* XkbSI_AnyOfOrNone */
291     "AnyOf",        /* XkbSI_AnyOf */
292     "AllOf",        /* XkbSI_AllOf */
293     "Exactly"       /* XkbSI_Exactly */
294 };
295
296 const char *
297 SIMatchText(unsigned type)
298 {
299     char *buf;
300
301     switch (type & XkbSI_OpMask) {
302     case XkbSI_NoneOf:
303         return siMatchText[0];
304     case XkbSI_AnyOfOrNone:
305         return siMatchText[1];
306     case XkbSI_AnyOf:
307         return siMatchText[2];
308     case XkbSI_AllOf:
309         return siMatchText[3];
310     case XkbSI_Exactly:
311         return siMatchText[4];
312     default:
313         buf = GetBuffer(40);
314         snprintf(buf, 40, "0x%x", type & XkbSI_OpMask);
315         return buf;
316     }
317 }