Remove all non-public API from XKBcommon.h header
[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 "X11/extensions/XKBcommon.h"
32 #include "XKBcommonint.h"
33 #include <X11/extensions/XKM.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #define BUFFER_SIZE 512
39 static char textBuffer[BUFFER_SIZE];
40 static int tbNext = 0;
41
42 static char *
43 tbGetBuffer(unsigned size)
44 {
45     char *rtrn;
46
47     if (size >= BUFFER_SIZE)
48         return NULL;
49
50     if ((BUFFER_SIZE - tbNext) <= size)
51         tbNext = 0;
52
53     rtrn = &textBuffer[tbNext];
54     tbNext += size;
55
56     return rtrn;
57 }
58
59 static char *
60 XkbStringText(char *str)
61 {
62     char *buf, *in, *out;
63     int len;
64     Bool ok;
65
66     if (!str) {
67         buf = tbGetBuffer(2);
68         buf[0] = '\0';
69         return buf;
70     }
71
72     /* Find if there are any non-printable characters */
73     for (ok = True, len = 0, in = str; *in != '\0'; in++, len++) {
74         if (isprint(*in))
75             continue;
76
77         ok = False;
78         switch (*in) {
79         case '\n': case '\t': case '\v':
80         case '\b': case '\r': case '\f':
81             len++;
82             break;
83         default:
84             /* octal: \0ooo */
85             len += 4;
86             break;
87         }
88     }
89
90     if (ok)
91         return str;
92
93     /* Cleanup non-printable characters */
94     buf = tbGetBuffer(len + 1);
95     for (in = str, out = buf; *in != '\0'; in++) {
96         if (isprint(*in)) {
97             *out++ = *in;
98             continue;
99         }
100
101         *out++ = '\\';
102         switch (*in) {
103         case '\n':
104             *out++ = 'n';
105             break;
106         case '\t':
107             *out++ = 't';
108             break;
109         case '\v':
110             *out++ = 'v';
111             break;
112         case '\b':
113             *out++ = 'b';
114             break;
115         case '\r':
116             *out++ = 'r';
117             break;
118         case '\f':
119             *out++ = 'f';
120             break;
121         default:
122             *out++ = '0';
123             snprintf(out, 3, "%o", *in);
124             while (*out != '\0')
125                 out++;
126         }
127     }
128
129     *out++ = '\0';
130     return buf;
131 }
132
133 char *
134 XkbcAtomText(Atom atm)
135 {
136     char *tmp, *rtrn;
137     int len;
138
139     tmp = XkbcAtomGetString(atm);
140
141     if (!tmp)
142         return "";
143
144     len = strlen(tmp) + 1;
145     if (len >= BUFFER_SIZE)
146         len = BUFFER_SIZE - 2;
147
148     rtrn = tbGetBuffer(len);
149     strncpy(rtrn, tmp, len);
150     rtrn[len] = '\0';
151
152     _XkbFree(tmp);
153
154     return XkbStringText(rtrn);
155 }
156
157 char *
158 XkbcVModIndexText(XkbcDescPtr xkb, unsigned ndx)
159 {
160     int len;
161     Atom *vmodNames;
162     char *rtrn, *tmp = NULL;
163
164     if (xkb && xkb->names)
165         vmodNames = xkb->names->vmods;
166     else
167         vmodNames = NULL;
168
169     if (ndx >= XkbNumVirtualMods)
170          tmp = strdup("illegal");
171     else if (vmodNames && (vmodNames[ndx] != None))
172          tmp = XkbcAtomGetString(vmodNames[ndx]);
173
174     if (!tmp) {
175         tmp = _XkbAlloc(20 * sizeof(char));
176         snprintf(tmp, 20, "%d", ndx);
177     }
178
179     len = strlen(tmp) + 1;
180     if (len >= BUFFER_SIZE)
181         len = BUFFER_SIZE - 1;
182
183     rtrn = tbGetBuffer(len);
184     strncpy(rtrn, tmp, len);
185
186     _XkbFree(tmp);
187
188     return rtrn;
189 }
190
191 char *
192 XkbcVModMaskText(XkbcDescPtr xkb, unsigned modMask, unsigned mask)
193 {
194     int i, bit, len, rem;
195     char *mm = NULL, *rtrn, *str;
196     char buf[BUFFER_SIZE];
197
198     if ((modMask == 0) && (mask == 0))
199         return "none";
200
201     if (modMask != 0)
202         mm = XkbcModMaskText(modMask, False);
203
204     str = buf;
205     buf[0]= '\0';
206     rem = BUFFER_SIZE;
207
208     if (mask) {
209         for (i = 0, bit = 1; i < XkbNumVirtualMods && rem > 1; i++, bit <<= 1)
210         {
211             if (!(mask & bit))
212                 continue;
213
214             len = snprintf(str, rem, "%s%s",
215                            (str != buf) ? "+" : "",
216                            XkbcVModIndexText(xkb, i));
217             rem -= len;
218             str += len;
219         }
220
221         str = buf;
222     }
223     else
224         str = NULL;
225
226     len = ((str) ? strlen(str) : 0) + ((mm) ? strlen(mm) : 0) +
227           ((str && mm) ? 1 : 0);
228     if (len >= BUFFER_SIZE)
229         len = BUFFER_SIZE - 1;
230
231     rtrn = tbGetBuffer(len + 1);
232     rtrn[0] = '\0';
233
234     snprintf(rtrn, len + 1, "%s%s%s", (mm) ? mm : "",
235              (mm && str) ? "+" : "", (str) ? str : "");
236
237     return rtrn;
238 }
239
240 static char *modNames[XkbNumModifiers] = {
241     "Shift",
242     "Lock",
243     "Control",
244     "Mod1",
245     "Mod2",
246     "Mod3",
247     "Mod4",
248     "Mod5"
249 };
250
251 char *
252 XkbcModIndexText(unsigned ndx)
253 {
254     char *buf;
255
256     if (ndx < XkbNumModifiers)
257         return modNames[ndx];
258     else if (ndx == XkbNoModifier)
259         return "none";
260
261     buf = tbGetBuffer(32);
262     snprintf(buf, 32, "ILLEGAL_%02x", ndx);
263
264     return buf;
265 }
266
267 char *
268 XkbcModMaskText(unsigned mask, Bool cFormat)
269 {
270     int i, rem, bit;
271     char *str, *buf;
272
273     if ((mask & 0xff) == 0xff)
274         return (cFormat ? "0xff" : "all");
275
276     if ((mask & 0xff) == 0)
277         return (cFormat ? "0" : "none");
278
279     rem = 64;
280     buf = tbGetBuffer(rem);
281     str = buf;
282     buf[0] = '\0';
283     for (i = 0, bit = 1; i < XkbNumModifiers && rem > 1; i++, bit <<= 1) {
284         int len;
285
286         if (!(mask & bit))
287             continue;
288
289         len = snprintf(str, rem, "%s%s%s",
290                        (str != buf) ? (cFormat ? "|" : "+") : "",
291                        modNames[i],
292                        cFormat ? "Mask" : "");
293         rem -= len;
294         str += len;
295     }
296
297     return buf;
298 }
299
300 char *
301 XkbcConfigText(unsigned config)
302 {
303     switch (config) {
304     case XkmSemanticsFile:
305         return "Semantics";
306     case XkmLayoutFile:
307         return "Layout";
308     case XkmKeymapFile:
309         return "Keymap";
310     case XkmGeometryFile:
311     case XkmGeometryIndex:
312         return "Geometry";
313     case XkmTypesIndex:
314         return "Types";
315     case XkmCompatMapIndex:
316         return "CompatMap";
317     case XkmSymbolsIndex:
318         return "Symbols";
319     case XkmIndicatorsIndex:
320         return "Indicators";
321     case XkmKeyNamesIndex:
322         return "KeyNames";
323     case XkmVirtualModsIndex:
324         return "VirtualMods";
325     default:
326         return "unknown";
327     }
328 }
329
330 char *
331 XkbcGeomFPText(int val)
332 {
333     char *buf;
334     int whole, frac;
335
336     buf = tbGetBuffer(12);
337     whole = val / XkbGeomPtsPerMM;
338     frac = val % XkbGeomPtsPerMM;
339
340     if (frac != 0)
341         snprintf(buf, 12, "%d.%d", whole, frac);
342     else
343         snprintf(buf, 12, "%d", whole);
344
345     return buf;
346 }
347
348 static char *actionTypeNames[XkbSA_NumActions]= {
349     "NoAction",         /* XkbSA_NoAction */
350     "SetMods",          /* XkbSA_SetMods */
351     "LatchMods",        /* XkbSA_LatchMods */
352     "LockMods",         /* XkbSA_LockMods */
353     "SetGroup",         /* XkbSA_SetGroup */
354     "LatchGroup",       /* XkbSA_LatchGroup */
355     "LockGroup",        /* XkbSA_LockGroup */
356     "MovePtr",          /* XkbSA_MovePtr */
357     "PtrBtn",           /* XkbSA_PtrBtn */
358     "LockPtrBtn",       /* XkbSA_LockPtrBtn */
359     "SetPtrDflt",       /* XkbSA_SetPtrDflt */
360     "ISOLock",          /* XkbSA_ISOLock */
361     "Terminate",        /* XkbSA_Terminate */
362     "SwitchScreen",     /* XkbSA_SwitchScreen */
363     "SetControls",      /* XkbSA_SetControls */
364     "LockControls",     /* XkbSA_LockControls */
365     "ActionMessage",    /* XkbSA_ActionMessage */
366     "RedirectKey",      /* XkbSA_RedirectKey */
367     "DeviceBtn",        /* XkbSA_DeviceBtn */
368     "LockDeviceBtn",    /* XkbSA_LockDeviceBtn */
369     "DeviceValuator"    /* XkbSA_DeviceValuator */
370 };
371
372 char *
373 XkbcActionTypeText(unsigned type)
374 {
375     if (type <= XkbSA_LastAction)
376         return actionTypeNames[type];
377     return "Private";
378 }
379
380 char *
381 XkbcKeysymText(KeySym sym)
382 {
383     char *buf;
384
385     if (sym == NoSymbol)
386         return "NoSymbol";
387
388     if ((buf = XkbcKeysymToString(sym)))
389         return buf;
390
391     buf = tbGetBuffer(32);
392     snprintf(buf, 32, "0x%lx", (long)sym);
393     return buf;
394 }
395
396 char *
397 XkbcKeyNameText(char *name)
398 {
399     char *buf;
400     int len;
401
402     buf = tbGetBuffer(7);
403     buf[0] = '<';
404     strncpy(&buf[1], name, 4);
405     buf[5] = '\0';
406     len = strlen(buf);
407     buf[len++] = '>';
408     buf[len] = '\0';
409
410     return buf;
411 }
412
413 static char *siMatchText[5] = {
414     "NoneOf",       /* XkbSI_NoneOf */
415     "AnyOfOrNone",  /* XkbSI_AnyOfOrNone */
416     "AnyOf",        /* XkbSI_AnyOf */
417     "AllOf",        /* XkbSI_AllOf */
418     "Exactly"       /* XkbSI_Exactly */
419 };
420
421 char *
422 XkbcSIMatchText(unsigned type)
423 {
424     char *buf;
425
426     switch (type & XkbSI_OpMask) {
427     case XkbSI_NoneOf:
428         return siMatchText[0];
429     case XkbSI_AnyOfOrNone:
430         return siMatchText[1];
431     case XkbSI_AnyOf:
432         return siMatchText[2];
433     case XkbSI_AllOf:
434         return siMatchText[3];
435     case XkbSI_Exactly:
436         return siMatchText[4];
437     default:
438         buf = tbGetBuffer(40);
439         snprintf(buf, 40, "0x%x", type & XkbSI_OpMask);
440         return buf;
441     }
442 }