keymap: move XkbEscapeMapName() to keymap.c.
[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 static void
57 update_builtin_keymap_fields(struct xkb_keymap *keymap)
58 {
59     struct xkb_context *ctx = keymap->ctx;
60
61     /*
62      * Add predefined (AKA real, core, X11) modifiers.
63      * The order is important!
64      */
65     darray_appends_t(keymap->mods, struct xkb_mod,
66         { .name = xkb_atom_intern_literal(ctx, "Shift"),   .type = MOD_REAL },
67         { .name = xkb_atom_intern_literal(ctx, "Lock"),    .type = MOD_REAL },
68         { .name = xkb_atom_intern_literal(ctx, "Control"), .type = MOD_REAL },
69         { .name = xkb_atom_intern_literal(ctx, "Mod1"),    .type = MOD_REAL },
70         { .name = xkb_atom_intern_literal(ctx, "Mod2"),    .type = MOD_REAL },
71         { .name = xkb_atom_intern_literal(ctx, "Mod3"),    .type = MOD_REAL },
72         { .name = xkb_atom_intern_literal(ctx, "Mod4"),    .type = MOD_REAL },
73         { .name = xkb_atom_intern_literal(ctx, "Mod5"),    .type = MOD_REAL });
74 }
75
76 static struct xkb_keymap *
77 xkb_keymap_new(struct xkb_context *ctx,
78                enum xkb_keymap_format format,
79                enum xkb_keymap_compile_flags flags)
80 {
81     struct xkb_keymap *keymap;
82
83     keymap = calloc(1, sizeof(*keymap));
84     if (!keymap)
85         return NULL;
86
87     keymap->refcnt = 1;
88     keymap->ctx = xkb_context_ref(ctx);
89
90     keymap->format = format;
91     keymap->flags = flags;
92
93     update_builtin_keymap_fields(keymap);
94
95     return keymap;
96 }
97
98 XKB_EXPORT struct xkb_keymap *
99 xkb_keymap_ref(struct xkb_keymap *keymap)
100 {
101     keymap->refcnt++;
102     return keymap;
103 }
104
105 XKB_EXPORT void
106 xkb_keymap_unref(struct xkb_keymap *keymap)
107 {
108     if (!keymap || --keymap->refcnt > 0)
109         return;
110
111     if (keymap->keys) {
112         struct xkb_key *key;
113         xkb_foreach_key(key, keymap) {
114             if (key->groups) {
115                 for (unsigned i = 0; i < key->num_groups; i++) {
116                     if (key->groups[i].levels) {
117                         for (unsigned j = 0; j < XkbKeyGroupWidth(key, i); j++)
118                             if (key->groups[i].levels[j].num_syms > 1)
119                                 free(key->groups[i].levels[j].u.syms);
120                         free(key->groups[i].levels);
121                     }
122                 }
123                 free(key->groups);
124             }
125         }
126         free(keymap->keys);
127     }
128     if (keymap->types) {
129         for (unsigned i = 0; i < keymap->num_types; i++) {
130             free(keymap->types[i].entries);
131             free(keymap->types[i].level_names);
132         }
133         free(keymap->types);
134     }
135     free(keymap->sym_interprets);
136     free(keymap->key_aliases);
137     free(keymap->group_names);
138     darray_free(keymap->mods);
139     darray_free(keymap->leds);
140     free(keymap->keycodes_section_name);
141     free(keymap->symbols_section_name);
142     free(keymap->types_section_name);
143     free(keymap->compat_section_name);
144     xkb_context_unref(keymap->ctx);
145     free(keymap);
146 }
147
148 static const struct xkb_keymap_format_ops *
149 get_keymap_format_ops(enum xkb_keymap_format format)
150 {
151     static const struct xkb_keymap_format_ops *keymap_format_ops[] = {
152         [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops,
153     };
154
155     if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops))
156         return NULL;
157
158     return keymap_format_ops[format];
159 }
160
161 XKB_EXPORT struct xkb_keymap *
162 xkb_keymap_new_from_names(struct xkb_context *ctx,
163                           const struct xkb_rule_names *rmlvo_in,
164                           enum xkb_keymap_compile_flags flags)
165 {
166     struct xkb_keymap *keymap;
167     struct xkb_rule_names rmlvo;
168     const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
169     const struct xkb_keymap_format_ops *ops;
170
171     ops = get_keymap_format_ops(format);
172     if (!ops || !ops->keymap_new_from_names) {
173         log_err_func(ctx, "unsupported keymap format: %d\n", format);
174         return NULL;
175     }
176
177     if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
178         log_err_func(ctx, "unrecognized flags: %#x\n", flags);
179         return NULL;
180     }
181
182     if (rmlvo_in)
183         rmlvo = *rmlvo_in;
184     else
185         memset(&rmlvo, 0, sizeof(rmlvo));
186
187     if (isempty(rmlvo.rules))
188         rmlvo.rules = xkb_context_get_default_rules(ctx);
189     if (isempty(rmlvo.model))
190         rmlvo.model = xkb_context_get_default_model(ctx);
191     /* Layout and variant are tied together, so don't try to use one from
192      * the caller and one from the environment. */
193     if (isempty(rmlvo.layout)) {
194         rmlvo.layout = xkb_context_get_default_layout(ctx);
195         rmlvo.variant = xkb_context_get_default_variant(ctx);
196     }
197     /* Options can be empty, so respect that if passed in. */
198     if (rmlvo.options == NULL)
199         rmlvo.options = xkb_context_get_default_options(ctx);
200
201     keymap = xkb_keymap_new(ctx, format, flags);
202     if (!keymap)
203         return NULL;
204
205     if (!ops->keymap_new_from_names(keymap, &rmlvo)) {
206         xkb_keymap_unref(keymap);
207         return NULL;
208     }
209
210     return keymap;
211 }
212
213 XKB_EXPORT struct xkb_keymap *
214 xkb_keymap_new_from_string(struct xkb_context *ctx,
215                            const char *string,
216                            enum xkb_keymap_format format,
217                            enum xkb_keymap_compile_flags flags)
218 {
219     return xkb_keymap_new_from_buffer(ctx, string, strlen(string),
220                                       format, flags);
221 }
222
223 XKB_EXPORT struct xkb_keymap *
224 xkb_keymap_new_from_buffer(struct xkb_context *ctx,
225                            const char *buffer, size_t length,
226                            enum xkb_keymap_format format,
227                            enum xkb_keymap_compile_flags flags)
228 {
229     struct xkb_keymap *keymap;
230     const struct xkb_keymap_format_ops *ops;
231
232     ops = get_keymap_format_ops(format);
233     if (!ops || !ops->keymap_new_from_string) {
234         log_err_func(ctx, "unsupported keymap format: %d\n", format);
235         return NULL;
236     }
237
238     if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
239         log_err_func(ctx, "unrecognized flags: %#x\n", flags);
240         return NULL;
241     }
242
243     if (!buffer) {
244         log_err_func1(ctx, "no buffer specified\n");
245         return NULL;
246     }
247
248     keymap = xkb_keymap_new(ctx, format, flags);
249     if (!keymap)
250         return NULL;
251
252     if (!ops->keymap_new_from_string(keymap, buffer, length)) {
253         xkb_keymap_unref(keymap);
254         return NULL;
255     }
256
257     return keymap;
258 }
259
260 XKB_EXPORT struct xkb_keymap *
261 xkb_keymap_new_from_file(struct xkb_context *ctx,
262                          FILE *file,
263                          enum xkb_keymap_format format,
264                          enum xkb_keymap_compile_flags flags)
265 {
266     struct xkb_keymap *keymap;
267     const struct xkb_keymap_format_ops *ops;
268
269     ops = get_keymap_format_ops(format);
270     if (!ops || !ops->keymap_new_from_file) {
271         log_err_func(ctx, "unsupported keymap format: %d\n", format);
272         return NULL;
273     }
274
275     if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
276         log_err_func(ctx, "unrecognized flags: %#x\n", flags);
277         return NULL;
278     }
279
280     if (!file) {
281         log_err_func1(ctx, "no file specified\n");
282         return NULL;
283     }
284
285     keymap = xkb_keymap_new(ctx, format, flags);
286     if (!keymap)
287         return NULL;
288
289     if (!ops->keymap_new_from_file(keymap, file)) {
290         xkb_keymap_unref(keymap);
291         return NULL;
292     }
293
294     return keymap;
295 }
296
297 XKB_EXPORT char *
298 xkb_keymap_get_as_string(struct xkb_keymap *keymap,
299                          enum xkb_keymap_format format)
300 {
301     const struct xkb_keymap_format_ops *ops;
302
303     if (format == XKB_KEYMAP_USE_ORIGINAL_FORMAT)
304         format = keymap->format;
305
306     ops = get_keymap_format_ops(format);
307     if (!ops || !ops->keymap_get_as_string) {
308         log_err_func(keymap->ctx, "unsupported keymap format: %d\n", format);
309         return NULL;
310     }
311
312     return ops->keymap_get_as_string(keymap);
313 }
314
315 /**
316  * Returns the total number of modifiers active in the keymap.
317  */
318 XKB_EXPORT xkb_mod_index_t
319 xkb_keymap_num_mods(struct xkb_keymap *keymap)
320 {
321     return darray_size(keymap->mods);
322 }
323
324 /**
325  * Return the name for a given modifier.
326  */
327 XKB_EXPORT const char *
328 xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
329 {
330     if (idx >= darray_size(keymap->mods))
331         return NULL;
332
333     return xkb_atom_text(keymap->ctx, darray_item(keymap->mods, idx).name);
334 }
335
336 /**
337  * Returns the index for a named modifier.
338  */
339 XKB_EXPORT xkb_mod_index_t
340 xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
341 {
342     xkb_mod_index_t i;
343     xkb_atom_t atom;
344     const struct xkb_mod *mod;
345
346     atom = xkb_atom_lookup(keymap->ctx, name);
347     if (atom == XKB_ATOM_NONE)
348         return XKB_MOD_INVALID;
349
350     darray_enumerate(i, mod, keymap->mods)
351         if (mod->name == atom)
352             return i;
353
354     return XKB_MOD_INVALID;
355 }
356
357 /**
358  * Return the total number of active groups in the keymap.
359  */
360 XKB_EXPORT xkb_layout_index_t
361 xkb_keymap_num_layouts(struct xkb_keymap *keymap)
362 {
363     return keymap->num_groups;
364 }
365
366 /**
367  * Returns the name for a given group.
368  */
369 XKB_EXPORT const char *
370 xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx)
371 {
372     if (idx >= keymap->num_group_names)
373         return NULL;
374
375     return xkb_atom_text(keymap->ctx, keymap->group_names[idx]);
376 }
377
378 /**
379  * Returns the index for a named layout.
380  */
381 XKB_EXPORT xkb_layout_index_t
382 xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name)
383 {
384     xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
385     xkb_layout_index_t i;
386
387     if (atom == XKB_ATOM_NONE)
388         return XKB_LAYOUT_INVALID;
389
390     for (i = 0; i < keymap->num_group_names; i++)
391         if (keymap->group_names[i] == atom)
392             return i;
393
394     return XKB_LAYOUT_INVALID;
395 }
396
397 /**
398  * Returns the number of layouts active for a particular key.
399  */
400 XKB_EXPORT xkb_layout_index_t
401 xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc)
402 {
403     const struct xkb_key *key = XkbKey(keymap, kc);
404
405     if (!key)
406         return 0;
407
408     return key->num_groups;
409 }
410
411 /**
412  * Returns the number of levels active for a particular key and layout.
413  */
414 XKB_EXPORT xkb_level_index_t
415 xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc,
416                               xkb_layout_index_t layout)
417 {
418     const struct xkb_key *key = XkbKey(keymap, kc);
419
420     if (!key)
421         return 0;
422
423     layout = wrap_group_into_range(layout, key->num_groups,
424                                    key->out_of_range_group_action,
425                                    key->out_of_range_group_number);
426     if (layout == XKB_LAYOUT_INVALID)
427         return 0;
428
429     return XkbKeyGroupWidth(key, layout);
430 }
431
432 /**
433  * Return the total number of LEDs in the keymap.
434  */
435 XKB_EXPORT xkb_led_index_t
436 xkb_keymap_num_leds(struct xkb_keymap *keymap)
437 {
438     return darray_size(keymap->leds);
439 }
440
441 /**
442  * Returns the name for a given LED.
443  */
444 XKB_EXPORT const char *
445 xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
446 {
447     if (idx >= darray_size(keymap->leds))
448         return NULL;
449
450     return xkb_atom_text(keymap->ctx, darray_item(keymap->leds, idx).name);
451 }
452
453 /**
454  * Returns the index for a named LED.
455  */
456 XKB_EXPORT xkb_led_index_t
457 xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
458 {
459     xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
460     xkb_led_index_t i;
461     const struct xkb_led *led;
462
463     if (atom == XKB_ATOM_NONE)
464         return XKB_LED_INVALID;
465
466     darray_enumerate(i, led, keymap->leds)
467         if (led->name == atom)
468             return i;
469
470     return XKB_LED_INVALID;
471 }
472
473 /**
474  * As below, but takes an explicit layout/level rather than state.
475  */
476 XKB_EXPORT int
477 xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
478                                  xkb_keycode_t kc,
479                                  xkb_layout_index_t layout,
480                                  xkb_level_index_t level,
481                                  const xkb_keysym_t **syms_out)
482 {
483     const struct xkb_key *key = XkbKey(keymap, kc);
484     int num_syms;
485
486     if (!key)
487         goto err;
488
489     layout = wrap_group_into_range(layout, key->num_groups,
490                                    key->out_of_range_group_action,
491                                    key->out_of_range_group_number);
492     if (layout == XKB_LAYOUT_INVALID)
493         goto err;
494
495     if (level >= XkbKeyGroupWidth(key, layout))
496         goto err;
497
498     num_syms = key->groups[layout].levels[level].num_syms;
499     if (num_syms == 0)
500         goto err;
501
502     if (num_syms == 1)
503         *syms_out = &key->groups[layout].levels[level].u.sym;
504     else
505         *syms_out = key->groups[layout].levels[level].u.syms;
506
507     return num_syms;
508
509 err:
510     *syms_out = NULL;
511     return 0;
512 }
513
514 XKB_EXPORT xkb_keycode_t
515 xkb_keymap_min_keycode(struct xkb_keymap *keymap)
516 {
517     return keymap->min_key_code;
518 }
519
520 XKB_EXPORT xkb_keycode_t
521 xkb_keymap_max_keycode(struct xkb_keymap *keymap)
522 {
523     return keymap->max_key_code;
524 }
525
526 XKB_EXPORT void
527 xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
528                         void *data)
529 {
530     struct xkb_key *key;
531
532     xkb_foreach_key(key, keymap)
533         iter(keymap, key->keycode, data);
534 }
535
536 /**
537  * Simple boolean specifying whether or not the key should repeat.
538  */
539 XKB_EXPORT int
540 xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
541 {
542     const struct xkb_key *key = XkbKey(keymap, kc);
543
544     if (!key)
545         return 0;
546
547     return key->repeats;
548 }
549
550 struct xkb_key *
551 XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
552 {
553     struct xkb_key *key;
554
555     xkb_foreach_key(key, keymap)
556         if (key->name == name)
557             return key;
558
559     if (use_aliases) {
560         xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
561         if (new_name != XKB_ATOM_NONE)
562             return XkbKeyByName(keymap, new_name, false);
563     }
564
565     return NULL;
566 }
567
568 xkb_atom_t
569 XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name)
570 {
571     for (unsigned i = 0; i < keymap->num_key_aliases; i++)
572         if (keymap->key_aliases[i].alias == name)
573             return keymap->key_aliases[i].real;
574
575     return XKB_ATOM_NONE;
576 }
577
578 void
579 XkbEscapeMapName(char *name)
580 {
581     /*
582      * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
583      * wildcards.
584      */
585     static const unsigned char legal[] = {
586         0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
587         0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
588         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589         0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
590     };
591
592     if (!name)
593         return;
594
595     while (*name) {
596         if (!(legal[*name / 8] & (1 << (*name % 8))))
597             *name = '_';
598         name++;
599     }
600 }