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