Add xkb_map_get_as_string
[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 #include "xkb-priv.h"
28 #include "alloc.h"
29
30 static struct xkb_kt_map_entry map2Level[]= {
31     {
32         .active = true,
33         .level = ShiftMask,
34         .mods = {.mask = 1, .vmods = ShiftMask, .real_mods = 0 }
35     }
36 };
37
38 static struct xkb_kt_map_entry mapAlpha[]= {
39     {
40         .active = true,
41         .level = ShiftMask,
42         .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
43     },
44     {
45         .active = true,
46         .level = LockMask,
47         .mods = { .mask = 0, .vmods = LockMask,  .real_mods = 0 }
48     }
49 };
50
51 static struct xkb_mods preAlpha[]= {
52     { .mask = 0,        .vmods = 0,        .real_mods = 0 },
53     { .mask = LockMask, .vmods = LockMask, .real_mods = 0 }
54 };
55
56 #define NL_VMOD_MASK 0
57 static struct xkb_kt_map_entry mapKeypad[]= {
58     {
59         .active = true,
60         .level = ShiftMask,
61         .mods = { .mask = 1, .vmods = ShiftMask, .real_mods = 0 }
62     },
63     {
64         .active = false,
65         .level = 0,
66         .mods = { .mask = 1, .vmods = 0, .real_mods = NL_VMOD_MASK }
67     }
68 };
69
70 static const struct xkb_key_type canonicalTypes[XkbNumRequiredTypes] = {
71     {
72         .mods = { .mask = 0, .vmods = 0, .real_mods = 0 },
73         .num_levels = 1,
74         .preserve = NULL,
75         .name = NULL,
76         .level_names = NULL
77     },
78     {
79         .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = 0 },
80         .num_levels = 2,
81         .map = darray_lit(map2Level),
82         .preserve = NULL,
83         .name = NULL,
84         .level_names = NULL
85     },
86     {
87         .mods = { .mask = ShiftMask|LockMask, .vmods = ShiftMask|LockMask, .real_mods = 0 },
88         .num_levels = 2,
89         .map = darray_lit(mapAlpha),
90         .preserve = preAlpha,
91         .name = NULL,
92         .level_names = NULL
93     },
94     {
95         .mods = { .mask = ShiftMask, .vmods = ShiftMask, .real_mods = NL_VMOD_MASK },
96         .num_levels = 2,
97         .map = darray_lit(mapKeypad),
98         .preserve = NULL,
99         .name = NULL,
100         .level_names = NULL
101     }
102 };
103
104 int
105 XkbcInitCanonicalKeyTypes(struct xkb_keymap *keymap, unsigned which,
106                           int keypadVMod)
107 {
108     struct xkb_client_map * map;
109     const struct xkb_key_type *from;
110     int rtrn;
111
112     if (!keymap)
113         return BadMatch;
114
115     rtrn = XkbcAllocClientMap(keymap, XkbKeyTypesMask, XkbNumRequiredTypes);
116     if (rtrn != Success)
117         return rtrn;
118
119     map = keymap->map;
120     if ((which & XkbAllRequiredTypes) == 0)
121         return Success;
122
123     rtrn = Success;
124     from = canonicalTypes;
125
126     if (which & XkbOneLevelMask)
127         rtrn = XkbcCopyKeyType(&from[XkbOneLevelIndex],
128                                &darray_item(map->types, XkbOneLevelIndex));
129
130     if ((which & XkbTwoLevelMask) && (rtrn == Success))
131         rtrn = XkbcCopyKeyType(&from[XkbTwoLevelIndex],
132                                &darray_item(map->types, XkbTwoLevelIndex));
133
134     if ((which & XkbAlphabeticMask) && (rtrn == Success))
135         rtrn = XkbcCopyKeyType(&from[XkbAlphabeticIndex],
136                                &darray_item(map->types, XkbAlphabeticIndex));
137
138     if ((which & XkbKeypadMask) && (rtrn == Success)) {
139         struct xkb_key_type * type;
140
141         rtrn = XkbcCopyKeyType(&from[XkbKeypadIndex],
142                                &darray_item(map->types, XkbKeypadIndex));
143         type = &darray_item(map->types, XkbKeypadIndex);
144
145         if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) &&
146             (rtrn == Success)) {
147             struct xkb_kt_map_entry *entry;
148             type->mods.vmods = (1 << keypadVMod);
149
150             entry = &darray_item(type->map, 0);
151             entry->active = true;
152             entry->mods.mask = ShiftMask;
153             entry->mods.real_mods = ShiftMask;
154             entry->mods.vmods = 0;
155             entry->level = 1;
156
157             entry = &darray_item(type->map, 1);
158             entry->active = false;
159             entry->mods.mask = 0;
160             entry->mods.real_mods = 0;
161             entry->mods.vmods = (1 << keypadVMod);
162             entry->level = 1;
163         }
164     }
165
166     return Success;
167 }
168
169 unsigned
170 _XkbcKSCheckCase(xkb_keysym_t ks)
171 {
172     unsigned set = (ks & (~0xff)) >> 8;
173     unsigned rtrn = 0;
174
175     switch (set) {
176     case 0: /* latin 1 */
177         if ((ks >= XKB_KEY_A && ks <= XKB_KEY_Z) ||
178             (ks >= XKB_KEY_Agrave && ks <= XKB_KEY_THORN && ks != XKB_KEY_multiply))
179             rtrn |= _XkbKSUpper;
180         if ((ks >= XKB_KEY_a && ks <= XKB_KEY_z) ||
181             (ks >= XKB_KEY_agrave && ks <= XKB_KEY_ydiaeresis))
182             rtrn |= _XkbKSLower;
183         break;
184     case 1: /* latin 2 */
185         if ((ks >= XKB_KEY_Aogonek && ks <= XKB_KEY_Zabovedot && ks != XKB_KEY_breve) ||
186             (ks >= XKB_KEY_Racute && ks<=XKB_KEY_Tcedilla))
187             rtrn |= _XkbKSUpper;
188         if ((ks >= XKB_KEY_aogonek && ks <= XKB_KEY_zabovedot && ks != XKB_KEY_caron) ||
189             (ks >= XKB_KEY_racute && ks <= XKB_KEY_tcedilla))
190             rtrn |= _XkbKSLower;
191         break;
192     case 2: /* latin 3 */
193         if ((ks >= XKB_KEY_Hstroke && ks <= XKB_KEY_Jcircumflex) ||
194             (ks >= XKB_KEY_Cabovedot && ks <= XKB_KEY_Scircumflex))
195             rtrn |= _XkbKSUpper;
196         if ((ks >= XKB_KEY_hstroke && ks <= XKB_KEY_jcircumflex) ||
197             (ks >= XKB_KEY_cabovedot && ks <= XKB_KEY_scircumflex))
198             rtrn |= _XkbKSLower;
199         break;
200     case 3: /* latin 4 */
201         if ((ks >= XKB_KEY_Rcedilla && ks <= XKB_KEY_Tslash) ||
202             (ks == XKB_KEY_ENG) ||
203             (ks >= XKB_KEY_Amacron && ks <= XKB_KEY_Umacron))
204             rtrn |= _XkbKSUpper;
205         if ((ks >= XKB_KEY_rcedilla && ks <= XKB_KEY_tslash) ||
206             (ks == XKB_KEY_eng) ||
207             (ks >= XKB_KEY_amacron && ks <= XKB_KEY_umacron))
208             rtrn |= _XkbKSLower;
209         break;
210     case 18: /* latin 8 */
211         if ((ks == XKB_KEY_Wcircumflex) ||
212             (ks == XKB_KEY_Ycircumflex) ||
213             (ks == XKB_KEY_Babovedot) ||
214             (ks == XKB_KEY_Dabovedot) ||
215             (ks == XKB_KEY_Fabovedot) ||
216             (ks == XKB_KEY_Mabovedot) ||
217             (ks == XKB_KEY_Pabovedot) ||
218             (ks == XKB_KEY_Sabovedot) ||
219             (ks == XKB_KEY_Tabovedot) ||
220             (ks == XKB_KEY_Wdiaeresis) ||
221             (ks == XKB_KEY_Ygrave))
222             rtrn |= _XkbKSUpper;
223         if ((ks == XKB_KEY_wcircumflex) ||
224             (ks == XKB_KEY_ycircumflex) ||
225             (ks == XKB_KEY_babovedot) ||
226             (ks == XKB_KEY_dabovedot) ||
227             (ks == XKB_KEY_fabovedot) ||
228             (ks == XKB_KEY_mabovedot) ||
229             (ks == XKB_KEY_pabovedot) ||
230             (ks == XKB_KEY_sabovedot) ||
231             (ks == XKB_KEY_tabovedot) ||
232             (ks == XKB_KEY_wdiaeresis) ||
233             (ks == XKB_KEY_ygrave))
234             rtrn |= _XkbKSLower;
235         break;
236     case 19: /* latin 9 */
237         if (ks == XKB_KEY_OE || ks == XKB_KEY_Ydiaeresis)
238             rtrn |= _XkbKSUpper;
239         if (ks == XKB_KEY_oe)
240             rtrn |= _XkbKSLower;
241         break;
242     }
243
244     return rtrn;
245 }
246
247 xkb_keycode_t
248 XkbcFindKeycodeByName(struct xkb_keymap *keymap, const char *name,
249                       bool use_aliases)
250 {
251     struct xkb_key_alias *alias;
252     xkb_keycode_t i;
253
254     for (i = keymap->min_key_code; i <= keymap->max_key_code; i++) {
255         if (strncmp(darray_item(keymap->names->keys, i).name, name,
256                     XkbKeyNameLength) == 0)
257             return i;
258     }
259
260     if (!use_aliases)
261         return 0;
262
263
264     for (i = 0; i < darray_size(keymap->names->key_aliases); i++) {
265         alias = &darray_item(keymap->names->key_aliases, i);
266         if (strncmp(name, alias->alias, XkbKeyNameLength) == 0)
267             return XkbcFindKeycodeByName(keymap, alias->real, false);
268     }
269
270     return 0;
271 }