Fix latin8 upper/lower case check
[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 "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(xkb_keysym_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_Wcircumflex) ||
234             (ks == XK_Ycircumflex) ||
235             (ks == XK_Babovedot) ||
236             (ks == XK_Dabovedot) ||
237             (ks == XK_Fabovedot) ||
238             (ks == XK_Mabovedot) ||
239             (ks == XK_Pabovedot) ||
240             (ks == XK_Sabovedot) ||
241             (ks == XK_Tabovedot) ||
242             (ks == XK_Wdiaeresis) ||
243             (ks == XK_Ygrave))
244             rtrn |= _XkbKSUpper;
245         if ((ks == XK_wcircumflex) ||
246             (ks == XK_ycircumflex) ||
247             (ks == XK_babovedot) ||
248             (ks == XK_dabovedot) ||
249             (ks == XK_fabovedot) ||
250             (ks == XK_mabovedot) ||
251             (ks == XK_pabovedot) ||
252             (ks == XK_sabovedot) ||
253             (ks == XK_tabovedot) ||
254             (ks == XK_wdiaeresis) ||
255             (ks == XK_ygrave))
256             rtrn |= _XkbKSLower;
257         break;
258     case 19: /* latin 9 */
259         if (ks == XK_OE || ks == XK_Ydiaeresis)
260             rtrn |= _XkbKSUpper;
261         if (ks == XK_oe)
262             rtrn |= _XkbKSLower;
263         break;
264     }
265
266     return rtrn;
267 }
268
269 #define UNMATCHABLE(c) ((c) == '(' || (c) == ')' || (c) == '/')
270
271 Bool
272 XkbcNameMatchesPattern(char *name, char *ptrn)
273 {
274     while (ptrn[0] != '\0') {
275         if (name[0] == '\0') {
276             if (ptrn[0] == '*') {
277                 ptrn++;
278                 continue;
279             }
280             return False;
281         }
282
283         if (ptrn[0] == '?') {
284             if (UNMATCHABLE(name[0]))
285                 return False;
286         }
287         else if (ptrn[0] == '*') {
288             if (!UNMATCHABLE(name[0]) &&
289                 XkbcNameMatchesPattern(name + 1, ptrn))
290                 return True;
291             return XkbcNameMatchesPattern(name, ptrn + 1);
292         }
293         else if (ptrn[0] != name[0])
294             return False;
295
296         name++;
297         ptrn++;
298     }
299
300     /* if we get here, the pattern is exhausted (-:just like me:-) */
301     return (name[0] == '\0');
302 }