1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
33 #include "xkbcommon/xkbcommon.h"
34 #include "XKBcommonint.h"
35 #include <X11/keysym.h>
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} }
42 static struct xkb_kt_map_entry mapAlpha[]= {
43 { True, ShiftMask, { 1, ShiftMask, 0 } },
44 { True, LockMask, { 0, LockMask, 0 } }
47 static struct xkb_mods preAlpha[]= {
49 { LockMask, LockMask, 0 }
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 } }
58 static struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
65 { { ShiftMask, ShiftMask, 0 },
67 mapSize(map2Level), /* map_count */
71 { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
73 mapSize(mapAlpha), /* map_count */
77 { { ShiftMask, ShiftMask, NL_VMOD_MASK },
79 mapSize(mapKeypad), /* map_count */
86 XkbcInitCanonicalKeyTypes(struct xkb_desc * xkb, unsigned which, int keypadVMod)
88 struct xkb_client_map * map;
89 struct xkb_key_type *from, *to;
95 rtrn= XkbcAllocClientMap(xkb, XkbKeyTypesMask, XkbNumRequiredTypes);
100 if ((which & XkbAllRequiredTypes) == 0)
104 from = canonicalTypes;
107 if (which & XkbOneLevelMask)
108 rtrn = XkbcCopyKeyType(&from[XkbOneLevelIndex], &to[XkbOneLevelIndex]);
110 if ((which & XkbTwoLevelMask) && (rtrn == Success))
111 rtrn = XkbcCopyKeyType(&from[XkbTwoLevelIndex], &to[XkbTwoLevelIndex]);
113 if ((which & XkbAlphabeticMask) && (rtrn == Success))
114 rtrn = XkbcCopyKeyType(&from[XkbAlphabeticIndex],
115 &to[XkbAlphabeticIndex]);
117 if ((which & XkbKeypadMask) && (rtrn == Success)) {
118 struct xkb_key_type * type;
120 rtrn = XkbcCopyKeyType(&from[XkbKeypadIndex], &to[XkbKeypadIndex]);
121 type = &to[XkbKeypadIndex];
123 if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) &&
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;
143 XkbcVirtualModsToReal(struct xkb_desc * xkb, unsigned virtual_mask,
151 if (virtual_mask == 0) {
158 for (i = mask = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) {
159 if (virtual_mask & bit)
160 mask |= xkb->server->vmods[i];
168 * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
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
179 XkbcEnsureSafeMapName(char *name)
184 while (*name!='\0') {
185 if ((componentSpecLegal[(*name) / 8] & (1 << ((*name) % 8))) == 0)
192 _XkbcKSCheckCase(uint32_t ks)
194 unsigned set = (ks & (~0xff)) >> 8;
198 case 0: /* latin 1 */
199 if ((ks >= XK_A && ks <= XK_Z) ||
200 (ks >= XK_Agrave && ks <= XK_THORN && ks != XK_multiply))
202 if ((ks >= XK_a && ks <= XK_z) ||
203 (ks >= XK_agrave && ks <= XK_ydiaeresis))
206 case 1: /* latin 2 */
207 if ((ks >= XK_Aogonek && ks <= XK_Zabovedot && ks != XK_breve) ||
208 (ks >= XK_Racute && ks<=XK_Tcedilla))
210 if ((ks >= XK_aogonek && ks <= XK_zabovedot && ks != XK_caron) ||
211 (ks >= XK_racute && ks <= XK_tcedilla))
214 case 2: /* latin 3 */
215 if ((ks >= XK_Hstroke && ks <= XK_Jcircumflex) ||
216 (ks >= XK_Cabovedot && ks <= XK_Scircumflex))
218 if ((ks >= XK_hstroke && ks <= XK_jcircumflex) ||
219 (ks >= XK_cabovedot && ks <= XK_scircumflex))
222 case 3: /* latin 4 */
223 if ((ks >= XK_Rcedilla && ks <= XK_Tslash) ||
225 (ks >= XK_Amacron && ks <= XK_Umacron))
227 if ((ks >= XK_rcedilla && ks <= XK_tslash) ||
229 (ks >= XK_amacron && ks <= XK_umacron))
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))
242 if ((ks == XK_babovedot) ||
243 (ks == XK_dabovedot) ||
244 (ks == XK_fabovedot) ||
245 (ks == XK_mabovedot) ||
246 (ks >= XK_wgrave && ks <= XK_wacute) ||
248 (ks >= XK_wdiaeresis && ks <= XK_ycircumflex))
251 case 19: /* latin 9 */
252 if (ks == XK_OE || ks == XK_Ydiaeresis)
262 #define UNMATCHABLE(c) ((c) == '(' || (c) == ')' || (c) == '/')
265 XkbcNameMatchesPattern(char *name, char *ptrn)
267 while (ptrn[0] != '\0') {
268 if (name[0] == '\0') {
269 if (ptrn[0] == '*') {
276 if (ptrn[0] == '?') {
277 if (UNMATCHABLE(name[0]))
280 else if (ptrn[0] == '*') {
281 if (!UNMATCHABLE(name[0]) &&
282 XkbcNameMatchesPattern(name + 1, ptrn))
284 return XkbcNameMatchesPattern(name, ptrn + 1);
286 else if (ptrn[0] != name[0])
293 /* if we get here, the pattern is exhausted (-:just like me:-) */
294 return (name[0] == '\0');