a41facacd04078bbf381438c261ed04313f8f411
[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 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 #include "xkbmisc.h"
31 #include "xkbcommon/xkbcommon.h"
32 #include "XKBcommonint.h"
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36
37 #define BUFFER_SIZE 1024
38 static char textBuffer[BUFFER_SIZE];
39 static int tbNext = 0;
40
41 static char *
42 tbGetBuffer(unsigned int size)
43 {
44     char *rtrn;
45
46     if (size >= BUFFER_SIZE)
47         return NULL;
48
49     if ((BUFFER_SIZE - tbNext) <= size)
50         tbNext = 0;
51
52     rtrn = &textBuffer[tbNext];
53     tbNext += size;
54
55     return rtrn;
56 }
57
58 static const char *
59 XkbcVModIndexText(struct xkb_desc * xkb, unsigned ndx)
60 {
61     int len;
62     uint32_t *vmodNames;
63     char *rtrn, *tmp = NULL;
64
65     if (xkb && xkb->names)
66         vmodNames = xkb->names->vmods;
67     else
68         vmodNames = NULL;
69
70     if (ndx >= XkbNumVirtualMods)
71          tmp = strdup("illegal");
72     else if (vmodNames && (vmodNames[ndx] != None))
73          tmp = XkbcAtomGetString(vmodNames[ndx]);
74
75     if (!tmp) {
76         tmp = malloc(20 * sizeof(char));
77         snprintf(tmp, 20, "%d", ndx);
78     }
79
80     len = strlen(tmp) + 1;
81     if (len >= BUFFER_SIZE)
82         len = BUFFER_SIZE - 1;
83
84     rtrn = tbGetBuffer(len);
85     strncpy(rtrn, tmp, len);
86
87     free(tmp);
88
89     return rtrn;
90 }
91
92 const char *
93 XkbcVModMaskText(struct xkb_desc * xkb, unsigned modMask, unsigned mask)
94 {
95     int i, bit, len, rem;
96     const char *mm = NULL;
97     char *rtrn, *str;
98     char buf[BUFFER_SIZE];
99
100     if ((modMask == 0) && (mask == 0))
101         return "none";
102
103     if (modMask != 0)
104         mm = XkbcModMaskText(modMask, False);
105
106     str = buf;
107     buf[0]= '\0';
108     rem = BUFFER_SIZE;
109
110     if (mask) {
111         for (i = 0, bit = 1; i < XkbNumVirtualMods && rem > 1; i++, bit <<= 1)
112         {
113             if (!(mask & bit))
114                 continue;
115
116             len = snprintf(str, rem, "%s%s",
117                            (str != buf) ? "+" : "",
118                            XkbcVModIndexText(xkb, i));
119             rem -= len;
120             str += len;
121         }
122
123         str = buf;
124     }
125     else
126         str = NULL;
127
128     len = ((str) ? strlen(str) : 0) + ((mm) ? strlen(mm) : 0) +
129           ((str && mm) ? 1 : 0);
130     if (len >= BUFFER_SIZE)
131         len = BUFFER_SIZE - 1;
132
133     rtrn = tbGetBuffer(len + 1);
134     rtrn[0] = '\0';
135
136     snprintf(rtrn, len + 1, "%s%s%s", (mm) ? mm : "",
137              (mm && str) ? "+" : "", (str) ? str : "");
138
139     return rtrn;
140 }
141
142 static const char *modNames[XkbNumModifiers] = {
143     "Shift",
144     "Lock",
145     "Control",
146     "Mod1",
147     "Mod2",
148     "Mod3",
149     "Mod4",
150     "Mod5"
151 };
152
153 const char *
154 XkbcModIndexText(unsigned ndx)
155 {
156     char *buf;
157
158     if (ndx < XkbNumModifiers)
159         return modNames[ndx];
160     else if (ndx == XkbNoModifier)
161         return "none";
162
163     buf = tbGetBuffer(32);
164     snprintf(buf, 32, "ILLEGAL_%02x", ndx);
165
166     return buf;
167 }
168
169 const char *
170 XkbcModMaskText(unsigned mask, Bool cFormat)
171 {
172     int i, rem, bit;
173     char *str, *buf;
174
175     if ((mask & 0xff) == 0xff)
176         return (cFormat ? "0xff" : "all");
177
178     if ((mask & 0xff) == 0)
179         return (cFormat ? "0" : "none");
180
181     rem = 64;
182     buf = tbGetBuffer(rem);
183     str = buf;
184     buf[0] = '\0';
185     for (i = 0, bit = 1; i < XkbNumModifiers && rem > 1; i++, bit <<= 1) {
186         int len;
187
188         if (!(mask & bit))
189             continue;
190
191         len = snprintf(str, rem, "%s%s%s",
192                        (str != buf) ? (cFormat ? "|" : "+") : "",
193                        modNames[i],
194                        cFormat ? "Mask" : "");
195         rem -= len;
196         str += len;
197     }
198
199     return buf;
200 }
201
202 const char *
203 XkbcConfigText(unsigned config)
204 {
205     switch (config) {
206     case XkmSemanticsFile:
207         return "Semantics";
208     case XkmLayoutFile:
209         return "Layout";
210     case XkmKeymapFile:
211         return "Keymap";
212     case XkmTypesIndex:
213         return "Types";
214     case XkmCompatMapIndex:
215         return "CompatMap";
216     case XkmSymbolsIndex:
217         return "Symbols";
218     case XkmIndicatorsIndex:
219         return "Indicators";
220     case XkmKeyNamesIndex:
221         return "KeyNames";
222     case XkmVirtualModsIndex:
223         return "VirtualMods";
224     default:
225         return "unknown";
226     }
227 }
228
229 static const char *actionTypeNames[XkbSA_NumActions]= {
230     "NoAction",         /* XkbSA_NoAction */
231     "SetMods",          /* XkbSA_SetMods */
232     "LatchMods",        /* XkbSA_LatchMods */
233     "LockMods",         /* XkbSA_LockMods */
234     "SetGroup",         /* XkbSA_SetGroup */
235     "LatchGroup",       /* XkbSA_LatchGroup */
236     "LockGroup",        /* XkbSA_LockGroup */
237     "MovePtr",          /* XkbSA_MovePtr */
238     "PtrBtn",           /* XkbSA_PtrBtn */
239     "LockPtrBtn",       /* XkbSA_LockPtrBtn */
240     "SetPtrDflt",       /* XkbSA_SetPtrDflt */
241     "ISOLock",          /* XkbSA_ISOLock */
242     "Terminate",        /* XkbSA_Terminate */
243     "SwitchScreen",     /* XkbSA_SwitchScreen */
244     "SetControls",      /* XkbSA_SetControls */
245     "LockControls",     /* XkbSA_LockControls */
246     "ActionMessage",    /* XkbSA_ActionMessage */
247     "RedirectKey",      /* XkbSA_RedirectKey */
248     "DeviceBtn",        /* XkbSA_DeviceBtn */
249     "LockDeviceBtn",    /* XkbSA_LockDeviceBtn */
250     "DeviceValuator"    /* XkbSA_DeviceValuator */
251 };
252
253 const char *
254 XkbcActionTypeText(unsigned type)
255 {
256     if (type <= XkbSA_LastAction)
257         return actionTypeNames[type];
258     return "Private";
259 }
260
261 const char *
262 XkbcKeysymText(uint32_t sym)
263 {
264     static char buffer[16];
265
266     xkb_keysym_to_string(sym, buffer, sizeof buffer);
267
268     return buffer;
269 }
270
271 const char *
272 XkbcKeyNameText(char *name)
273 {
274     char *buf;
275     int len;
276
277     buf = tbGetBuffer(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 XkbcSIMatchText(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 = tbGetBuffer(40);
314         snprintf(buf, 40, "0x%x", type & XkbSI_OpMask);
315         return buf;
316     }
317 }