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 ********************************************************/
28 * Copyright © 2012 Intel Corporation
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
37 * The above copyright notice and this permission notice (including the next
38 * paragraph) shall be included in all copies or substantial portions of the
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47 * DEALINGS IN THE SOFTWARE.
49 * Author: Daniel Stone <daniel@fooishbar.org>
53 * This is a bastardised version of xkbActions.c from the X server which
54 * does not support, for the moment:
55 * - AccessX sticky/debounce/etc (will come later)
56 * - pointer keys (may come later)
57 * - key redirects (unlikely)
58 * - messages (very unlikely)
67 struct xkb_state *state;
68 union xkb_action action;
69 xkb_keycode_t keycode;
71 int (*func)(struct xkb_filter *filter, xkb_keycode_t key,
72 enum xkb_key_direction direction);
74 struct xkb_filter *next;
78 xkb_group_index_t base_group; /**< depressed */
79 xkb_group_index_t latched_group;
80 xkb_group_index_t locked_group;
81 xkb_group_index_t group; /**< effective */
83 xkb_mod_mask_t base_mods; /**< depressed */
84 xkb_mod_mask_t latched_mods;
85 xkb_mod_mask_t locked_mods;
86 xkb_mod_mask_t mods; /**< effective */
91 darray(struct xkb_filter) filters;
92 struct xkb_keymap *keymap;
95 static union xkb_action *
96 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
100 if (!XkbKeyHasActions(state->keymap, key) ||
101 !XkbKeycodeInRange(state->keymap, key)) {
102 static union xkb_action fake;
103 memset(&fake, 0, sizeof(fake));
104 fake.type = XkbSA_NoAction;
108 group = xkb_key_get_group(state, key);
109 level = xkb_key_get_level(state, key, group);
111 return XkbKeyActionEntry(state->keymap, key, level, group);
114 static struct xkb_filter *
115 xkb_filter_new(struct xkb_state *state)
117 int old_size = darray_size(state->filters);
118 struct xkb_filter *filter = NULL, *iter;
120 darray_foreach(iter, state->filters) {
128 darray_resize0(state->filters, darray_size(state->filters) + 1);
129 filter = &darray_item(state->filters, old_size);
132 filter->state = state;
137 /***====================================================================***/
140 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
141 enum xkb_key_direction direction)
143 if (keycode != filter->keycode) {
144 filter->action.group.flags &= ~XkbSA_ClearLocks;
148 if (direction == XKB_KEY_DOWN) {
152 else if (--filter->refcnt > 0) {
156 if (filter->action.group.flags & XkbSA_GroupAbsolute)
157 filter->state->base_group = filter->action.group.group;
159 filter->state->base_group = -filter->action.group.group;
160 if (filter->action.group.flags & XkbSA_ClearLocks)
161 filter->state->locked_group = 0;
169 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
170 union xkb_action *action)
172 struct xkb_filter *filter = xkb_filter_new(state);
174 if (!filter) /* WSGO */
176 filter->keycode = keycode;
177 filter->func = xkb_filter_group_set_func;
178 filter->action = *action;
180 if (action->group.flags & XkbSA_GroupAbsolute) {
181 filter->action.group.group = filter->state->base_group;
182 filter->state->base_group = action->group.group;
185 filter->state->base_group += action->group.group;
192 xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
193 enum xkb_key_direction direction)
195 if (keycode != filter->keycode)
198 if (direction == XKB_KEY_DOWN) {
202 if (--filter->refcnt > 0)
210 xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
211 union xkb_action *action)
213 struct xkb_filter *filter = xkb_filter_new(state);
218 filter->keycode = keycode;
219 filter->func = xkb_filter_group_lock_func;
220 filter->action = *action;
222 if (action->group.flags & XkbSA_GroupAbsolute)
223 filter->state->locked_group = action->group.group;
225 filter->state->locked_group += action->group.group;
231 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
232 enum xkb_key_direction direction)
234 if (keycode != filter->keycode) {
235 filter->action.mods.flags &= ~XkbSA_ClearLocks;
239 if (direction == XKB_KEY_DOWN) {
243 else if (--filter->refcnt > 0) {
247 filter->state->base_mods &= ~(filter->action.mods.mask);
248 if (filter->action.mods.flags & XkbSA_ClearLocks)
249 filter->state->locked_mods &= ~filter->action.mods.mask;
257 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
258 union xkb_action *action)
260 struct xkb_filter *filter = xkb_filter_new(state);
262 if (!filter) /* WSGO */
264 filter->keycode = keycode;
265 filter->func = xkb_filter_mod_set_func;
266 filter->action = *action;
268 filter->state->base_mods |= action->mods.mask;
274 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
275 enum xkb_key_direction direction)
277 if (keycode != filter->keycode)
280 if (direction == XKB_KEY_DOWN) {
284 if (--filter->refcnt > 0)
287 filter->state->locked_mods &= ~filter->priv;
293 xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
294 union xkb_action *action)
296 struct xkb_filter *filter = xkb_filter_new(state);
298 if (!filter) /* WSGO */
301 filter->keycode = keycode;
302 filter->func = xkb_filter_mod_lock_func;
303 filter->action = *action;
304 filter->priv = state->locked_mods & action->mods.mask;
305 state->locked_mods |= action->mods.mask;
310 enum xkb_key_latch_state {
317 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
318 enum xkb_key_direction direction)
320 enum xkb_key_latch_state latch = filter->priv;
322 if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
323 /* If this is a new keypress and we're awaiting our single latched
324 * keypress, then either break the latch if any random key is pressed,
325 * or promote it to a lock or plain base set if it's the same
327 union xkb_action *action = xkb_key_get_action(filter->state, keycode);
328 if (action->type == XkbSA_LatchMods &&
329 action->mods.flags == filter->action.mods.flags &&
330 action->mods.mask == filter->action.mods.mask) {
331 filter->action = *action;
332 if (filter->action.mods.flags & XkbSA_LatchToLock) {
333 filter->action.type = XkbSA_LockMods;
334 filter->func = xkb_filter_mod_lock_func;
335 filter->state->locked_mods |= filter->action.mods.mask;
338 filter->action.type = XkbSA_SetMods;
339 filter->func = xkb_filter_mod_set_func;
340 filter->state->base_mods |= filter->action.mods.mask;
342 filter->keycode = keycode;
343 filter->state->latched_mods &= ~filter->action.mods.mask;
347 else if (((1 << action->type) & XkbSA_BreakLatch)) {
348 /* XXX: This may be totally broken, we might need to break the
349 * latch in the next run after this press? */
350 filter->state->latched_mods &= ~filter->action.mods.mask;
355 else if (direction == XKB_KEY_UP && keycode == filter->keycode) {
356 /* Our key got released. If we've set it to clear locks, and we
357 * currently have the same modifiers locked, then release them and
358 * don't actually latch. Else we've actually hit the latching
359 * stage, so set PENDING and move our modifier from base to
361 if (latch == NO_LATCH ||
362 ((filter->action.mods.flags & XkbSA_ClearLocks) &&
363 (filter->state->locked_mods & filter->action.mods.mask) ==
364 filter->action.mods.mask)) {
365 /* XXX: We might be a bit overenthusiastic about clearing
366 * mods other filters have set here? */
367 if (latch == LATCH_PENDING)
368 filter->state->latched_mods &= ~filter->action.mods.mask;
370 filter->state->base_mods &= ~filter->action.mods.mask;
371 filter->state->locked_mods &= ~filter->action.mods.mask;
375 latch = LATCH_PENDING;
376 filter->state->base_mods &= ~filter->action.mods.mask;
377 filter->state->latched_mods |= filter->action.mods.mask;
381 else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
382 /* Someone's pressed another key while we've still got the latching
383 * key held down, so keep the base modifier state active (from
384 * xkb_filter_mod_latch_new), but don't trip the latch, just clear
385 * it as soon as the modifier gets released. */
389 filter->priv = latch;
395 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
396 union xkb_action *action)
398 struct xkb_filter *filter = xkb_filter_new(state);
399 enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
401 if (!filter) /* WSGO */
403 filter->keycode = keycode;
404 filter->priv = latch;
405 filter->func = xkb_filter_mod_latch_func;
406 filter->action = *action;
408 filter->state->base_mods |= action->mods.mask;
414 * Applies any relevant filters to the key, first from the list of filters
415 * that are currently active, then if no filter has claimed the key, possibly
416 * apply a new filter from the key action.
419 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
420 enum xkb_key_direction direction)
422 struct xkb_filter *filter;
423 union xkb_action *act = NULL;
426 /* First run through all the currently active filters and see if any of
427 * them have claimed this event. */
428 darray_foreach(filter, state->filters) {
431 send &= filter->func(filter, key, direction);
434 if (!send || direction == XKB_KEY_UP)
437 act = xkb_key_get_action(state, key);
440 send = xkb_filter_mod_set_new(state, key, act);
442 case XkbSA_LatchMods:
443 send = xkb_filter_mod_latch_new(state, key, act);
446 send = xkb_filter_mod_lock_new(state, key, act);
449 send = xkb_filter_group_set_new(state, key, act);
452 case XkbSA_LatchGroup:
453 send = xkb_filter_mod_latch_new(state, key, act);
456 case XkbSA_LockGroup:
457 send = xkb_filter_group_lock_new(state, key, act);
464 _X_EXPORT struct xkb_state *
465 xkb_state_new(struct xkb_keymap *keymap)
467 struct xkb_state *ret;
472 ret = calloc(sizeof(*ret), 1);
477 ret->keymap = xkb_map_ref(keymap);
482 _X_EXPORT struct xkb_state *
483 xkb_state_ref(struct xkb_state *state)
490 xkb_state_unref(struct xkb_state *state)
493 assert(state->refcnt >= 0);
494 if (state->refcnt > 0)
497 xkb_map_unref(state->keymap);
498 darray_free(state->filters);
502 _X_EXPORT struct xkb_keymap *
503 xkb_state_get_map(struct xkb_state *state)
505 return state->keymap;
509 * Update the LED state to match the rest of the xkb_state.
512 xkb_state_led_update_all(struct xkb_state *state)
518 for (led = 0; led < XkbNumIndicators; led++) {
519 struct xkb_indicator_map *map = &state->keymap->indicators->maps[led];
520 uint32_t mod_mask = 0;
521 uint32_t group_mask = 0;
523 if (!map->which_mods && !map->which_groups && !map->ctrls)
526 if (map->which_mods) {
527 if (map->which_mods & XkbIM_UseBase)
528 mod_mask |= state->base_mods;
529 if (map->which_mods & XkbIM_UseLatched)
530 mod_mask |= state->latched_mods;
531 if (map->which_mods & XkbIM_UseLocked)
532 mod_mask |= state->locked_mods;
533 if (map->which_mods & XkbIM_UseEffective)
534 mod_mask |= state->mods;
535 if ((map->mods.mask & mod_mask))
536 state->leds |= (1 << led);
538 else if (map->which_groups) {
539 if (map->which_mods & XkbIM_UseBase)
540 group_mask |= (1 << state->base_group);
541 if (map->which_mods & XkbIM_UseLatched)
542 group_mask |= (1 << state->latched_group);
543 if (map->which_mods & XkbIM_UseLocked)
544 group_mask |= (1 << state->locked_group);
545 if (map->which_mods & XkbIM_UseEffective)
546 group_mask |= (1 << state->group);
547 if ((map->groups & group_mask))
548 state->leds |= (1 << led);
550 else if (map->ctrls) {
551 if ((map->ctrls & state->keymap->ctrls->enabled_ctrls))
552 state->leds |= (1 << led);
558 * Calculates the derived state (effective mods/group and LEDs) from an
559 * up-to-date xkb_state.
562 xkb_state_update_derived(struct xkb_state *state)
564 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
565 /* FIXME: Clamp/wrap locked_group */
566 state->group = state->locked_group + state->base_group +
567 state->latched_group;
568 /* FIXME: Clamp/wrap effective group */
570 xkb_state_led_update_all(state);
574 * Given a particular key event, updates the state structure to reflect the
578 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
579 enum xkb_key_direction direction)
581 xkb_filter_apply_all(state, key, direction);
582 xkb_state_update_derived(state);
586 * Updates the state from a set of explicit masks as gained from
587 * xkb_state_serialize_mods and xkb_state_serialize_groups. As noted in the
588 * documentation for these functions in xkbcommon.h, this round-trip is
589 * lossy, and should only be used to update a slave state mirroring the
590 * master, e.g. in a client/server window system.
593 xkb_state_update_mask(struct xkb_state *state,
594 xkb_mod_mask_t base_mods,
595 xkb_mod_mask_t latched_mods,
596 xkb_mod_mask_t locked_mods,
597 xkb_group_index_t base_group,
598 xkb_group_index_t latched_group,
599 xkb_group_index_t locked_group)
603 state->base_mods = 0;
604 state->latched_mods = 0;
605 state->locked_mods = 0;
606 for (mod = 0; mod < xkb_map_num_mods(state->keymap); mod++) {
607 xkb_mod_mask_t idx = (1 << mod);
609 state->base_mods |= idx;
610 if (latched_mods & idx)
611 state->latched_mods |= idx;
612 if (locked_mods & idx)
613 state->locked_mods |= idx;
616 state->base_group = base_group;
617 state->latched_group = latched_group;
618 state->locked_group = locked_group;
620 xkb_state_update_derived(state);
624 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
625 * the same disclaimers as in xkb_state_update_mask.
627 _X_EXPORT xkb_mod_mask_t
628 xkb_state_serialize_mods(struct xkb_state *state,
629 enum xkb_state_component type)
631 xkb_mod_mask_t ret = 0;
633 if (type == XKB_STATE_EFFECTIVE)
636 if (type & XKB_STATE_DEPRESSED)
637 ret |= state->base_mods;
638 if (type & XKB_STATE_LATCHED)
639 ret |= state->latched_mods;
640 if (type & XKB_STATE_LOCKED)
641 ret |= state->locked_mods;
647 * Serialises the requested group state, with all the same disclaimers as
648 * in xkb_state_update_mask.
650 _X_EXPORT xkb_group_index_t
651 xkb_state_serialize_group(struct xkb_state *state,
652 enum xkb_state_component type)
654 xkb_group_index_t ret = 0;
656 if (type == XKB_STATE_EFFECTIVE)
659 if (type & XKB_STATE_DEPRESSED)
660 ret += state->base_group;
661 if (type & XKB_STATE_LATCHED)
662 ret += state->latched_group;
663 if (type & XKB_STATE_LOCKED)
664 ret += state->locked_group;
670 * Returns 1 if the given modifier is active with the specified type(s), 0 if
671 * not, or -1 if the modifier is invalid.
674 xkb_state_mod_index_is_active(struct xkb_state *state,
676 enum xkb_state_component type)
680 if (idx >= xkb_map_num_mods(state->keymap))
683 if (type & XKB_STATE_DEPRESSED)
684 ret |= (state->base_mods & (1 << idx));
685 if (type & XKB_STATE_LATCHED)
686 ret |= (state->latched_mods & (1 << idx));
687 if (type & XKB_STATE_LOCKED)
688 ret |= (state->locked_mods & (1 << idx));
694 * Helper function for xkb_state_mod_indices_are_active and
695 * xkb_state_mod_names_are_active.
698 match_mod_masks(struct xkb_state *state, enum xkb_state_match match,
701 uint32_t active = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
703 if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
706 if (match & XKB_STATE_MATCH_ANY)
707 return !!(active & wanted);
709 return (active & wanted) == wanted;
715 * Returns 1 if the modifiers are active with the specified type(s), 0 if
716 * not, or -1 if any of the modifiers are invalid.
719 xkb_state_mod_indices_are_active(struct xkb_state *state,
720 enum xkb_state_component type,
721 enum xkb_state_match match,
725 xkb_mod_index_t idx = 0;
731 idx = va_arg(ap, xkb_mod_index_t);
732 if (idx == XKB_MOD_INVALID ||
733 idx >= xkb_map_num_mods(state->keymap)) {
737 wanted |= (1 << idx);
744 return match_mod_masks(state, match, wanted);
748 * Returns 1 if the given modifier is active with the specified type(s), 0 if
749 * not, or -1 if the modifier is invalid.
752 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
753 enum xkb_state_component type)
755 xkb_mod_index_t idx = xkb_map_mod_get_index(state->keymap, name);
757 if (idx == XKB_MOD_INVALID)
760 return xkb_state_mod_index_is_active(state, idx, type);
764 * Returns 1 if the modifiers are active with the specified type(s), 0 if
765 * not, or -1 if any of the modifiers are invalid.
768 xkb_state_mod_names_are_active(struct xkb_state *state,
769 enum xkb_state_component type,
770 enum xkb_state_match match,
774 xkb_mod_index_t idx = 0;
781 str = va_arg(ap, const char *);
784 idx = xkb_map_mod_get_index(state->keymap, str);
785 if (idx == XKB_MOD_INVALID) {
789 wanted |= (1 << idx);
796 return match_mod_masks(state, match, wanted);
800 * Returns 1 if the given group is active with the specified type(s), 0 if
801 * not, or -1 if the group is invalid.
804 xkb_state_group_index_is_active(struct xkb_state *state,
805 xkb_group_index_t idx,
806 enum xkb_state_component type)
810 if (idx >= xkb_map_num_groups(state->keymap))
813 if (type & XKB_STATE_DEPRESSED)
814 ret |= (state->base_group == idx);
815 if (type & XKB_STATE_LATCHED)
816 ret |= (state->latched_group == idx);
817 if (type & XKB_STATE_LOCKED)
818 ret |= (state->locked_group == idx);
824 * Returns 1 if the given modifier is active with the specified type(s), 0 if
825 * not, or -1 if the modifier is invalid.
828 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
829 enum xkb_state_component type)
831 xkb_group_index_t idx = xkb_map_group_get_index(state->keymap, name);
833 if (idx == XKB_GROUP_INVALID)
836 return xkb_state_group_index_is_active(state, idx, type);
840 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
843 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
845 if (idx >= xkb_map_num_leds(state->keymap))
848 return !!(state->leds & (1 << idx));
852 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
855 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
857 xkb_led_index_t idx = xkb_map_led_get_index(state->keymap, name);
859 if (idx == XKB_LED_INVALID)
862 return xkb_state_led_index_is_active(state, idx);