Rename map.{c,h} to keymap.{c,h}
[platform/upstream/libxkbcommon.git] / src / keymap.c
1 /**
2  * Copyright © 2012 Intel Corporation
3  * Copyright © 2012 Ran Benita <ran234@gmail.com>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Author: Daniel Stone <daniel@fooishbar.org>
25  */
26
27 /************************************************************
28  * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
29  *
30  * Permission to use, copy, modify, and distribute this
31  * software and its documentation for any purpose and without
32  * fee is hereby granted, provided that the above copyright
33  * notice appear in all copies and that both that copyright
34  * notice and this permission notice appear in supporting
35  * documentation, and that the name of Silicon Graphics not be
36  * used in advertising or publicity pertaining to distribution
37  * of the software without specific prior written permission.
38  * Silicon Graphics makes no representation about the suitability
39  * of this software for any purpose. It is provided "as is"
40  * without any express or implied warranty.
41  *
42  * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
43  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
44  * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
45  * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
46  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
47  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
48  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
49  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
50  *
51  * ********************************************************/
52
53 #include "keymap.h"
54 #include "text.h"
55
56 struct xkb_keymap *
57 xkb_keymap_new(struct xkb_context *ctx)
58 {
59     struct xkb_keymap *keymap;
60
61     keymap = calloc(1, sizeof(*keymap));
62     if (!keymap)
63         return NULL;
64
65     keymap->refcnt = 1;
66     keymap->ctx = xkb_context_ref(ctx);
67
68     return keymap;
69 }
70
71 XKB_EXPORT struct xkb_keymap *
72 xkb_keymap_ref(struct xkb_keymap *keymap)
73 {
74     keymap->refcnt++;
75     return keymap;
76 }
77
78 XKB_EXPORT void
79 xkb_keymap_unref(struct xkb_keymap *keymap)
80 {
81     unsigned int i;
82     struct xkb_key *key;
83
84     if (!keymap || --keymap->refcnt > 0)
85         return;
86
87     for (i = 0; i < keymap->num_types; i++) {
88         free(keymap->types[i].map);
89         free(keymap->types[i].level_names);
90     }
91     free(keymap->types);
92     darray_foreach(key, keymap->keys) {
93         free(key->sym_index);
94         free(key->num_syms);
95         free(key->syms);
96         free(key->actions);
97     }
98     darray_free(keymap->keys);
99     darray_free(keymap->sym_interpret);
100     darray_free(keymap->key_aliases);
101     free(keymap->keycodes_section_name);
102     free(keymap->symbols_section_name);
103     free(keymap->types_section_name);
104     free(keymap->compat_section_name);
105     xkb_context_unref(keymap->ctx);
106     free(keymap);
107 }
108
109 /**
110  * Returns the total number of modifiers active in the keymap.
111  */
112 XKB_EXPORT xkb_mod_index_t
113 xkb_keymap_num_mods(struct xkb_keymap *keymap)
114 {
115     xkb_mod_index_t i;
116
117     for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++)
118         if (!keymap->vmod_names[i])
119             break;
120
121     /* We always have all the core modifiers (for now), plus any virtual
122      * modifiers we may have defined. */
123     return i + XKB_NUM_CORE_MODS;
124 }
125
126 /**
127  * Return the name for a given modifier.
128  */
129 XKB_EXPORT const char *
130 xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
131 {
132     const char *name;
133
134     if (idx >= xkb_keymap_num_mods(keymap))
135         return NULL;
136
137     /* First try to find a legacy modifier name.  If that fails, try to
138      * find a virtual mod name. */
139     name = ModIndexToName(idx);
140     if (!name)
141         name = xkb_atom_text(keymap->ctx,
142                              keymap->vmod_names[idx - XKB_NUM_CORE_MODS]);
143
144     return name;
145 }
146
147 /**
148  * Returns the index for a named modifier.
149  */
150 XKB_EXPORT xkb_mod_index_t
151 xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
152 {
153     xkb_mod_index_t i;
154     xkb_atom_t atom;
155
156     i = ModNameToIndex(name);
157     if (i != XKB_MOD_INVALID)
158         return i;
159
160     atom = xkb_atom_lookup(keymap->ctx, name);
161     if (atom == XKB_ATOM_NONE)
162         return XKB_MOD_INVALID;
163
164     for (i = 0; i < XKB_NUM_VIRTUAL_MODS; i++) {
165         if (keymap->vmod_names[i] == XKB_ATOM_NONE)
166             break;
167         if (keymap->vmod_names[i] == atom)
168             return i + XKB_NUM_CORE_MODS;
169     }
170
171     return XKB_MOD_INVALID;
172 }
173
174 /**
175  * Return the total number of active groups in the keymap.
176  */
177 XKB_EXPORT xkb_layout_index_t
178 xkb_keymap_num_layouts(struct xkb_keymap *keymap)
179 {
180     return keymap->num_groups;
181 }
182
183 /**
184  * Returns the name for a given group.
185  */
186 XKB_EXPORT const char *
187 xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx)
188 {
189     if (idx >= xkb_keymap_num_layouts(keymap))
190         return NULL;
191
192     return xkb_atom_text(keymap->ctx, keymap->group_names[idx]);
193 }
194
195 /**
196  * Returns the index for a named layout.
197  */
198 XKB_EXPORT xkb_layout_index_t
199 xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name)
200 {
201     xkb_layout_index_t num_groups = xkb_keymap_num_layouts(keymap);
202     xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
203     xkb_layout_index_t i;
204
205     if (atom == XKB_ATOM_NONE)
206         return XKB_LAYOUT_INVALID;
207
208     for (i = 0; i < num_groups; i++)
209         if (keymap->group_names[i] == atom)
210             return i;
211
212     return XKB_LAYOUT_INVALID;
213 }
214
215 /**
216  * Returns the number of layouts active for a particular key.
217  */
218 XKB_EXPORT xkb_layout_index_t
219 xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc)
220 {
221     const struct xkb_key *key = XkbKey(keymap, kc);
222
223     if (!key)
224         return 0;
225
226     return key->num_groups;
227 }
228
229 /**
230  * Returns the number of levels active for a particular key and layout.
231  */
232 XKB_EXPORT xkb_level_index_t
233 xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc,
234                               xkb_layout_index_t layout)
235 {
236     const struct xkb_key *key = XkbKey(keymap, kc);
237
238     if (!key)
239         return 0;
240
241     return XkbKeyGroupWidth(keymap, key, layout);
242 }
243
244 /**
245  * Return the total number of active LEDs in the keymap.
246  */
247 XKB_EXPORT xkb_led_index_t
248 xkb_keymap_num_leds(struct xkb_keymap *keymap)
249 {
250     xkb_led_index_t ret = 0;
251     xkb_led_index_t i;
252
253     for (i = 0; i < XKB_NUM_INDICATORS; i++)
254         if (keymap->indicators[i].which_groups ||
255             keymap->indicators[i].which_mods ||
256             keymap->indicators[i].ctrls)
257             ret++;
258
259     return ret;
260 }
261
262 /**
263  * Returns the name for a given group.
264  */
265 XKB_EXPORT const char *
266 xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
267 {
268     if (idx >= xkb_keymap_num_leds(keymap))
269         return NULL;
270
271     return xkb_atom_text(keymap->ctx, keymap->indicators[idx].name);
272 }
273
274 /**
275  * Returns the index for a named group.
276  */
277 XKB_EXPORT xkb_layout_index_t
278 xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
279 {
280     xkb_led_index_t num_leds = xkb_keymap_num_leds(keymap);
281     xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
282     xkb_led_index_t i;
283
284     if (atom == XKB_ATOM_NONE)
285         return XKB_LED_INVALID;
286
287     for (i = 0; i < num_leds; i++)
288         if (keymap->indicators[i].name == atom)
289             return i;
290
291     return XKB_LED_INVALID;
292 }
293
294 /**
295  * As below, but takes an explicit layout/level rather than state.
296  */
297 XKB_EXPORT int
298 xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
299                                  xkb_keycode_t kc,
300                                  xkb_layout_index_t layout,
301                                  xkb_level_index_t level,
302                                  const xkb_keysym_t **syms_out)
303 {
304     const struct xkb_key *key = XkbKey(keymap, kc);
305     int num_syms;
306
307     if (!key)
308         goto err;
309     if (layout >= key->num_groups)
310         goto err;
311     if (level >= XkbKeyGroupWidth(keymap, key, layout))
312         goto err;
313
314     num_syms = XkbKeyNumSyms(key, layout, level);
315     if (num_syms == 0)
316         goto err;
317
318     *syms_out = XkbKeySymEntry(key, layout, level);
319     return num_syms;
320
321 err:
322     *syms_out = NULL;
323     return 0;
324 }
325
326 /**
327  * Simple boolean specifying whether or not the key should repeat.
328  */
329 XKB_EXPORT int
330 xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
331 {
332     const struct xkb_key *key = XkbKey(keymap, kc);
333
334     if (!key)
335         return 0;
336
337     return key->repeats;
338 }