2 * Copyright © 2012 Intel Corporation
3 * Copyright © 2012 Ran Benita <ran234@gmail.com>
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:
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
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.
24 * Author: Daniel Stone <daniel@fooishbar.org>
27 /************************************************************
28 * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
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.
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.
51 * ********************************************************/
57 update_builtin_keymap_fields(struct xkb_keymap *keymap)
59 struct xkb_context *ctx = keymap->ctx;
62 * Add predefined (AKA real, core, X11) modifiers.
63 * The order is important!
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 });
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)
81 struct xkb_keymap *keymap;
83 keymap = calloc(1, sizeof(*keymap));
88 keymap->ctx = xkb_context_ref(ctx);
90 keymap->format = format;
91 keymap->flags = flags;
93 update_builtin_keymap_fields(keymap);
98 XKB_EXPORT struct xkb_keymap *
99 xkb_keymap_ref(struct xkb_keymap *keymap)
106 xkb_keymap_unref(struct xkb_keymap *keymap)
108 if (!keymap || --keymap->refcnt > 0)
113 xkb_foreach_key(key, keymap) {
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);
129 for (unsigned i = 0; i < keymap->num_types; i++) {
130 free(keymap->types[i].entries);
131 free(keymap->types[i].level_names);
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);
148 static const struct xkb_keymap_format_ops *
149 get_keymap_format_ops(enum xkb_keymap_format format)
151 static const struct xkb_keymap_format_ops *keymap_format_ops[] = {
152 [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops,
155 if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops))
158 return keymap_format_ops[format];
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)
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;
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);
177 if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
178 log_err_func(ctx, "unrecognized flags: %#x\n", flags);
185 memset(&rmlvo, 0, sizeof(rmlvo));
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);
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);
201 keymap = xkb_keymap_new(ctx, format, flags);
205 if (!ops->keymap_new_from_names(keymap, &rmlvo)) {
206 xkb_keymap_unref(keymap);
213 XKB_EXPORT struct xkb_keymap *
214 xkb_keymap_new_from_string(struct xkb_context *ctx,
216 enum xkb_keymap_format format,
217 enum xkb_keymap_compile_flags flags)
219 return xkb_keymap_new_from_buffer(ctx, string, strlen(string),
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)
229 struct xkb_keymap *keymap;
230 const struct xkb_keymap_format_ops *ops;
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);
238 if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
239 log_err_func(ctx, "unrecognized flags: %#x\n", flags);
244 log_err_func1(ctx, "no buffer specified\n");
248 keymap = xkb_keymap_new(ctx, format, flags);
252 if (!ops->keymap_new_from_string(keymap, buffer, length)) {
253 xkb_keymap_unref(keymap);
260 XKB_EXPORT struct xkb_keymap *
261 xkb_keymap_new_from_file(struct xkb_context *ctx,
263 enum xkb_keymap_format format,
264 enum xkb_keymap_compile_flags flags)
266 struct xkb_keymap *keymap;
267 const struct xkb_keymap_format_ops *ops;
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);
275 if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
276 log_err_func(ctx, "unrecognized flags: %#x\n", flags);
281 log_err_func1(ctx, "no file specified\n");
285 keymap = xkb_keymap_new(ctx, format, flags);
289 if (!ops->keymap_new_from_file(keymap, file)) {
290 xkb_keymap_unref(keymap);
298 xkb_keymap_get_as_string(struct xkb_keymap *keymap,
299 enum xkb_keymap_format format)
301 const struct xkb_keymap_format_ops *ops;
303 if (format == XKB_KEYMAP_USE_ORIGINAL_FORMAT)
304 format = keymap->format;
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);
312 return ops->keymap_get_as_string(keymap);
316 * Returns the total number of modifiers active in the keymap.
318 XKB_EXPORT xkb_mod_index_t
319 xkb_keymap_num_mods(struct xkb_keymap *keymap)
321 return darray_size(keymap->mods);
325 * Return the name for a given modifier.
327 XKB_EXPORT const char *
328 xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx)
330 if (idx >= darray_size(keymap->mods))
333 return xkb_atom_text(keymap->ctx, darray_item(keymap->mods, idx).name);
337 * Returns the index for a named modifier.
339 XKB_EXPORT xkb_mod_index_t
340 xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name)
344 const struct xkb_mod *mod;
346 atom = xkb_atom_lookup(keymap->ctx, name);
347 if (atom == XKB_ATOM_NONE)
348 return XKB_MOD_INVALID;
350 darray_enumerate(i, mod, keymap->mods)
351 if (mod->name == atom)
354 return XKB_MOD_INVALID;
358 * Return the total number of active groups in the keymap.
360 XKB_EXPORT xkb_layout_index_t
361 xkb_keymap_num_layouts(struct xkb_keymap *keymap)
363 return keymap->num_groups;
367 * Returns the name for a given group.
369 XKB_EXPORT const char *
370 xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx)
372 if (idx >= keymap->num_group_names)
375 return xkb_atom_text(keymap->ctx, keymap->group_names[idx]);
379 * Returns the index for a named layout.
381 XKB_EXPORT xkb_layout_index_t
382 xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name)
384 xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
385 xkb_layout_index_t i;
387 if (atom == XKB_ATOM_NONE)
388 return XKB_LAYOUT_INVALID;
390 for (i = 0; i < keymap->num_group_names; i++)
391 if (keymap->group_names[i] == atom)
394 return XKB_LAYOUT_INVALID;
398 * Returns the number of layouts active for a particular key.
400 XKB_EXPORT xkb_layout_index_t
401 xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc)
403 const struct xkb_key *key = XkbKey(keymap, kc);
408 return key->num_groups;
412 * Returns the number of levels active for a particular key and layout.
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)
418 const struct xkb_key *key = XkbKey(keymap, kc);
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)
429 return XkbKeyGroupWidth(key, layout);
433 * Return the total number of LEDs in the keymap.
435 XKB_EXPORT xkb_led_index_t
436 xkb_keymap_num_leds(struct xkb_keymap *keymap)
438 return darray_size(keymap->leds);
442 * Returns the name for a given LED.
444 XKB_EXPORT const char *
445 xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx)
447 if (idx >= darray_size(keymap->leds))
450 return xkb_atom_text(keymap->ctx, darray_item(keymap->leds, idx).name);
454 * Returns the index for a named LED.
456 XKB_EXPORT xkb_led_index_t
457 xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name)
459 xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name);
461 const struct xkb_led *led;
463 if (atom == XKB_ATOM_NONE)
464 return XKB_LED_INVALID;
466 darray_enumerate(i, led, keymap->leds)
467 if (led->name == atom)
470 return XKB_LED_INVALID;
474 * As below, but takes an explicit layout/level rather than state.
477 xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap,
479 xkb_layout_index_t layout,
480 xkb_level_index_t level,
481 const xkb_keysym_t **syms_out)
483 const struct xkb_key *key = XkbKey(keymap, kc);
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)
495 if (level >= XkbKeyGroupWidth(key, layout))
498 num_syms = key->groups[layout].levels[level].num_syms;
503 *syms_out = &key->groups[layout].levels[level].u.sym;
505 *syms_out = key->groups[layout].levels[level].u.syms;
514 XKB_EXPORT xkb_keycode_t
515 xkb_keymap_min_keycode(struct xkb_keymap *keymap)
517 return keymap->min_key_code;
520 XKB_EXPORT xkb_keycode_t
521 xkb_keymap_max_keycode(struct xkb_keymap *keymap)
523 return keymap->max_key_code;
527 xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
532 xkb_foreach_key(key, keymap)
533 iter(keymap, key->keycode, data);
537 * Simple boolean specifying whether or not the key should repeat.
540 xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
542 const struct xkb_key *key = XkbKey(keymap, kc);
551 XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
555 xkb_foreach_key(key, keymap)
556 if (key->name == name)
560 xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
561 if (new_name != XKB_ATOM_NONE)
562 return XkbKeyByName(keymap, new_name, false);
569 XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name)
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;
575 return XKB_ATOM_NONE;
579 XkbEscapeMapName(char *name)
582 * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
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
596 if (!(legal[*name / 8] & (1 << (*name % 8))))