Remove xproto build dependency
[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 /*
132  * IMPORTATNT
133  * The indices used for the legacy core modifiers is derived from
134  * the order of the names in this table. It matches the values
135  * ShiftMapIndex, LockMapIndex, etc. from X11/X.h. Take note before
136  * changing.
137  */
138 static const char *modNames[XkbNumModifiers] = {
139     "Shift",
140     "Lock",
141     "Control",
142     "Mod1",
143     "Mod2",
144     "Mod3",
145     "Mod4",
146     "Mod5",
147 };
148
149 xkb_mod_index_t
150 ModNameToIndex(const char *name)
151 {
152     xkb_mod_index_t i;
153
154     for (i = 0; i < XkbNumModifiers; i++)
155         if (istreq(name, modNames[i]))
156             return i;
157
158     return XKB_MOD_INVALID;
159 }
160
161 const char *
162 ModIndexToName(xkb_mod_index_t ndx)
163 {
164     if (ndx < XkbNumModifiers)
165         return modNames[ndx];
166     return NULL;
167 }
168
169 const char *
170 ModIndexText(xkb_mod_index_t ndx)
171 {
172     const char *name;
173     char *buf;
174
175     name = ModIndexToName(ndx);
176     if (name)
177         return name;
178
179     if (ndx == XkbNoModifier)
180         return "none";
181
182     buf = GetBuffer(32);
183     snprintf(buf, 32, "ILLEGAL_%02x", ndx);
184
185     return buf;
186 }
187
188 const char *
189 ModMaskText(xkb_mod_mask_t mask, bool cFormat)
190 {
191     int i, rem;
192     xkb_mod_index_t bit;
193     char *str, *buf;
194
195     if ((mask & 0xff) == 0xff)
196         return (cFormat ? "0xff" : "all");
197
198     if ((mask & 0xff) == 0)
199         return (cFormat ? "0" : "none");
200
201     rem = 64;
202     buf = GetBuffer(rem);
203     str = buf;
204     buf[0] = '\0';
205     for (i = 0, bit = 1; i < XkbNumModifiers && rem > 1; i++, bit <<= 1) {
206         int len;
207
208         if (!(mask & bit))
209             continue;
210
211         len = snprintf(str, rem, "%s%s%s",
212                        (str != buf) ? (cFormat ? "|" : "+") : "",
213                        modNames[i],
214                        cFormat ? "Mask" : "");
215         rem -= len;
216         str += len;
217     }
218
219     return buf;
220 }
221
222 const char *
223 FileTypeText(enum xkb_file_type type)
224 {
225     switch (type) {
226     case FILE_TYPE_KEYMAP:
227         return "xkb_keymap";
228     case FILE_TYPE_TYPES:
229         return "xkb_types";
230     case FILE_TYPE_COMPAT:
231         return "xkb_compatability";
232     case FILE_TYPE_SYMBOLS:
233         return "xkb_symbols";
234     case FILE_TYPE_KEYCODES:
235         return "xkb_keycodes";
236     case FILE_TYPE_RULES:
237         return "rules";
238     default:
239         return "unknown";
240     }
241 }
242
243 static const char *actionTypeNames[XkbSA_NumActions] = {
244     [XkbSA_NoAction]       = "NoAction",
245     [XkbSA_SetMods]        = "SetMods",
246     [XkbSA_LatchMods]      = "LatchMods",
247     [XkbSA_LockMods]       = "LockMods",
248     [XkbSA_SetGroup]       = "SetGroup",
249     [XkbSA_LatchGroup]     = "LatchGroup",
250     [XkbSA_LockGroup]      = "LockGroup",
251     [XkbSA_MovePtr]        = "MovePtr",
252     [XkbSA_PtrBtn]         = "PtrBtn",
253     [XkbSA_LockPtrBtn]     = "LockPtrBtn",
254     [XkbSA_SetPtrDflt]     = "SetPtrDflt",
255     [XkbSA_ISOLock]        = "ISOLock",
256     [XkbSA_Terminate]      = "Terminate",
257     [XkbSA_SwitchScreen]   = "SwitchScreen",
258     [XkbSA_SetControls]    = "SetControls",
259     [XkbSA_LockControls]   = "LockControls",
260     [XkbSA_ActionMessage]  = "ActionMessage",
261     [XkbSA_RedirectKey]    = "RedirectKey",
262     [XkbSA_DeviceBtn]      = "DeviceBtn",
263     [XkbSA_LockDeviceBtn]  = "LockDeviceBtn",
264     [XkbSA_DeviceValuator] = "DeviceValuator"
265 };
266
267 const char *
268 ActionTypeText(unsigned type)
269 {
270     if (type <= XkbSA_LastAction)
271         return actionTypeNames[type];
272     return "Private";
273 }
274
275 const char *
276 KeysymText(xkb_keysym_t sym)
277 {
278     static char buffer[64];
279
280     xkb_keysym_get_name(sym, buffer, sizeof buffer);
281
282     return buffer;
283 }
284
285 const char *
286 KeyNameText(const char name[XkbKeyNameLength])
287 {
288     char *buf;
289     int len;
290
291     buf = GetBuffer(7);
292     buf[0] = '<';
293     strncpy(&buf[1], name, 4);
294     buf[5] = '\0';
295     len = strlen(buf);
296     buf[len++] = '>';
297     buf[len] = '\0';
298
299     return buf;
300 }
301
302 static const char *siMatchText[5] = {
303     "NoneOf",       /* XkbSI_NoneOf */
304     "AnyOfOrNone",  /* XkbSI_AnyOfOrNone */
305     "AnyOf",        /* XkbSI_AnyOf */
306     "AllOf",        /* XkbSI_AllOf */
307     "Exactly"       /* XkbSI_Exactly */
308 };
309
310 const char *
311 SIMatchText(unsigned type)
312 {
313     char *buf;
314
315     switch (type & XkbSI_OpMask) {
316     case XkbSI_NoneOf:
317         return siMatchText[0];
318     case XkbSI_AnyOfOrNone:
319         return siMatchText[1];
320     case XkbSI_AnyOf:
321         return siMatchText[2];
322     case XkbSI_AllOf:
323         return siMatchText[3];
324     case XkbSI_Exactly:
325         return siMatchText[4];
326     default:
327         buf = GetBuffer(40);
328         snprintf(buf, 40, "0x%x", type & XkbSI_OpMask);
329         return buf;
330     }
331 }