Use CARD32 instead of Atom, move geom headers in
[platform/upstream/libxkbcommon.git] / src / misc.c
1 /************************************************************
2 Copyright (c) 1993 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
31 #include "xkballoc.h"
32 #include "xkbmisc.h"
33 #include "X11/extensions/XKBcommon.h"
34 #include "XKBcommonint.h"
35 #include <X11/keysym.h>
36 #include <X11/extensions/XKBfilecommon.h>
37
38 #define mapSize(m) (sizeof(m) / sizeof(XkbKTMapEntryRec))
39 static XkbKTMapEntryRec map2Level[]= {
40     { True, ShiftMask, {1, ShiftMask, 0} }
41 };
42
43 static XkbKTMapEntryRec mapAlpha[]= {
44     { True, ShiftMask, { 1, ShiftMask, 0 } },
45     { True, LockMask,  { 0, LockMask,  0 } }
46 };
47
48 static XkbModsRec preAlpha[]= {
49     { 0,        0,        0 },
50     { LockMask, LockMask, 0 }
51 };
52
53 #define NL_VMOD_MASK 0
54 static  XkbKTMapEntryRec mapKeypad[]= {
55     { True,  ShiftMask, { 1, ShiftMask, 0 } },
56     { False, 0,         { 1, 0, NL_VMOD_MASK } }
57 };
58
59 static XkbcKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = {
60     { { 0, 0, 0 },
61       1,        /* num_levels */
62       0,        /* map_count */
63       NULL, NULL,
64       None, NULL
65     },
66     { { ShiftMask, ShiftMask, 0 },
67       2,        /* num_levels */
68       mapSize(map2Level),   /* map_count */
69       map2Level, NULL,
70       None,      NULL
71     },
72     { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
73       2,        /* num_levels */
74       mapSize(mapAlpha),    /* map_count */
75       mapAlpha, preAlpha,
76       None,     NULL
77     },
78     { { ShiftMask, ShiftMask, NL_VMOD_MASK },
79       2,        /* num_levels */
80       mapSize(mapKeypad),   /* map_count */
81       mapKeypad, NULL,
82       None,      NULL
83     }
84 };
85
86 int
87 XkbcInitCanonicalKeyTypes(XkbcDescPtr xkb, unsigned which, int keypadVMod)
88 {
89     XkbcClientMapPtr map;
90     XkbcKeyTypePtr from,to;
91     int rtrn;
92
93     if (!xkb)
94         return BadMatch;
95
96     rtrn= XkbcAllocClientMap(xkb, XkbKeyTypesMask, XkbNumRequiredTypes);
97     if (rtrn != Success)
98         return rtrn;
99
100     map= xkb->map;
101     if ((which & XkbAllRequiredTypes) == 0)
102         return Success;
103
104     rtrn = Success;
105     from = canonicalTypes;
106     to = map->types;
107
108     if (which & XkbOneLevelMask)
109         rtrn = XkbcCopyKeyType(&from[XkbOneLevelIndex], &to[XkbOneLevelIndex]);
110
111     if ((which & XkbTwoLevelMask) && (rtrn == Success))
112         rtrn = XkbcCopyKeyType(&from[XkbTwoLevelIndex], &to[XkbTwoLevelIndex]);
113
114     if ((which & XkbAlphabeticMask) && (rtrn == Success))
115         rtrn = XkbcCopyKeyType(&from[XkbAlphabeticIndex],
116                                &to[XkbAlphabeticIndex]);
117
118     if ((which & XkbKeypadMask) && (rtrn == Success)) {
119         XkbcKeyTypePtr type;
120
121         rtrn = XkbcCopyKeyType(&from[XkbKeypadIndex], &to[XkbKeypadIndex]);
122         type = &to[XkbKeypadIndex];
123
124         if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) &&
125             (rtrn == Success)) {
126             type->mods.vmods = (1 << keypadVMod);
127             type->map[0].active = True;
128             type->map[0].mods.mask = ShiftMask;
129             type->map[0].mods.real_mods = ShiftMask;
130             type->map[0].mods.vmods = 0;
131             type->map[0].level = 1;
132             type->map[1].active = False;
133             type->map[1].mods.mask = 0;
134             type->map[1].mods.real_mods = 0;
135             type->map[1].mods.vmods = (1 << keypadVMod);
136             type->map[1].level = 1;
137         }
138     }
139
140     return Success;
141 }
142
143 Bool
144 XkbcVirtualModsToReal(XkbcDescPtr xkb, unsigned virtual_mask,
145                       unsigned *mask_rtrn)
146 {
147     int i, bit;
148     unsigned mask;
149
150     if (!xkb)
151         return False;
152     if (virtual_mask == 0) {
153         *mask_rtrn = 0;
154         return True;
155     }
156     if (!xkb->server)
157         return False;
158
159     for (i = mask = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
160         if (virtual_mask & bit)
161             mask |= xkb->server->vmods[i];
162     }
163
164     *mask_rtrn = mask;
165     return True;
166 }
167
168 /*
169  * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
170  * wildcards.
171  */
172 static unsigned char componentSpecLegal[] = {
173     0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
174     0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
175     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176     0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
177 };
178
179 void
180 XkbcEnsureSafeMapName(char *name)
181 {
182     if (!name)
183         return;
184
185     while (*name!='\0') {
186         if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
187             *name= '_';
188         name++;
189     }
190 }
191
192 unsigned
193 _XkbcKSCheckCase(CARD32 ks)
194 {
195     unsigned set = (ks & (~0xff)) >> 8;
196     unsigned rtrn = 0;
197
198     switch (set) {
199     case 0: /* latin 1 */
200         if ((ks >= XK_A && ks <= XK_Z) ||
201             (ks >= XK_Agrave && ks <= XK_THORN && ks != XK_multiply))
202             rtrn |= _XkbKSUpper;
203         if ((ks >= XK_a && ks <= XK_z) ||
204             (ks >= XK_agrave && ks <= XK_ydiaeresis))
205             rtrn |= _XkbKSLower;
206         break;
207     case 1: /* latin 2 */
208         if ((ks >= XK_Aogonek && ks <= XK_Zabovedot && ks != XK_breve) ||
209             (ks >= XK_Racute && ks<=XK_Tcedilla))
210             rtrn |= _XkbKSUpper;
211         if ((ks >= XK_aogonek && ks <= XK_zabovedot && ks != XK_caron) ||
212             (ks >= XK_racute && ks <= XK_tcedilla))
213             rtrn |= _XkbKSLower;
214         break;
215     case 2: /* latin 3 */
216         if ((ks >= XK_Hstroke && ks <= XK_Jcircumflex) ||
217             (ks >= XK_Cabovedot && ks <= XK_Scircumflex))
218             rtrn |= _XkbKSUpper;
219         if ((ks >= XK_hstroke && ks <= XK_jcircumflex) ||
220             (ks >= XK_cabovedot && ks <= XK_scircumflex))
221             rtrn |= _XkbKSLower;
222         break;
223     case 3: /* latin 4 */
224         if ((ks >= XK_Rcedilla && ks <= XK_Tslash) ||
225             (ks == XK_ENG) ||
226             (ks >= XK_Amacron && ks <= XK_Umacron))
227             rtrn |= _XkbKSUpper;
228         if ((ks >= XK_rcedilla && ks <= XK_tslash) ||
229             (ks == XK_eng) ||
230             (ks >= XK_amacron && ks <= XK_umacron))
231             rtrn |= _XkbKSLower;
232         break;
233     case 18: /* latin 8 */
234         if ((ks == XK_Babovedot) ||
235             (ks >= XK_Dabovedot && ks <= XK_Wacute) ||
236             (ks >= XK_Ygrave && ks <= XK_Fabovedot) ||
237             (ks == XK_Mabovedot) ||
238             (ks == XK_Pabovedot) ||
239             (ks == XK_Sabovedot) ||
240             (ks == XK_Wdiaeresis) ||
241             (ks >= XK_Wcircumflex && ks <= XK_Ycircumflex))
242             rtrn |= _XkbKSUpper;
243         if ((ks == XK_babovedot) ||
244             (ks == XK_dabovedot) ||
245             (ks == XK_fabovedot) ||
246             (ks == XK_mabovedot) ||
247             (ks >= XK_wgrave && ks <= XK_wacute) ||
248             (ks == XK_ygrave) ||
249             (ks >= XK_wdiaeresis && ks <= XK_ycircumflex))
250             rtrn |= _XkbKSLower;
251         break;
252     case 19: /* latin 9 */
253         if (ks == XK_OE || ks == XK_Ydiaeresis)
254             rtrn |= _XkbKSUpper;
255         if (ks == XK_oe)
256             rtrn |= _XkbKSLower;
257         break;
258     }
259
260     return rtrn;
261 }
262
263 #define UNMATCHABLE(c) ((c) == '(' || (c) == ')' || (c) == '/')
264
265 Bool
266 XkbcNameMatchesPattern(char *name, char *ptrn)
267 {
268     while (ptrn[0] != '\0') {
269         if (name[0] == '\0') {
270             if (ptrn[0] == '*') {
271                 ptrn++;
272                 continue;
273             }
274             return False;
275         }
276
277         if (ptrn[0] == '?') {
278             if (UNMATCHABLE(name[0]))
279                 return False;
280         }
281         else if (ptrn[0] == '*') {
282             if (!UNMATCHABLE(name[0]) &&
283                 XkbcNameMatchesPattern(name + 1, ptrn))
284                 return True;
285             return XkbcNameMatchesPattern(name, ptrn + 1);
286         }
287         else if (ptrn[0] != name[0])
288             return False;
289
290         name++;
291         ptrn++;
292     }
293
294     /* if we get here, the pattern is exhausted (-:just like me:-) */
295     return (name[0] == '\0');
296 }