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