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 */
89 * At each event, we accumulate all the needed modifications to the base
90 * modifiers, and apply them at the end. These keep track of this state.
92 xkb_mod_mask_t set_mods;
93 xkb_mod_mask_t clear_mods;
95 * We mustn't clear a base modifier if there's another depressed key
96 * which affects it, e.g. given this sequence
97 * < Left Shift down, Right Shift down, Left Shift Up >
98 * the modifier should still be set. This keeps the count.
100 int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8];
105 darray(struct xkb_filter) filters;
106 struct xkb_keymap *keymap;
109 static union xkb_action *
110 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
114 if (!XkbKeyHasActions(state->keymap, key) ||
115 !XkbKeycodeInRange(state->keymap, key)) {
116 static union xkb_action fake;
117 memset(&fake, 0, sizeof(fake));
118 fake.type = XkbSA_NoAction;
122 group = xkb_key_get_group(state, key);
123 level = xkb_key_get_level(state, key, group);
125 return XkbKeyActionEntry(state->keymap, key, level, group);
128 static struct xkb_filter *
129 xkb_filter_new(struct xkb_state *state)
131 int old_size = darray_size(state->filters);
132 struct xkb_filter *filter = NULL, *iter;
134 darray_foreach(iter, state->filters) {
142 darray_resize0(state->filters, darray_size(state->filters) + 1);
143 filter = &darray_item(state->filters, old_size);
146 filter->state = state;
151 /***====================================================================***/
154 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
155 enum xkb_key_direction direction)
157 if (keycode != filter->keycode) {
158 filter->action.group.flags &= ~XkbSA_ClearLocks;
162 if (direction == XKB_KEY_DOWN) {
166 else if (--filter->refcnt > 0) {
170 if (filter->action.group.flags & XkbSA_GroupAbsolute)
171 filter->state->base_group = filter->action.group.group;
173 filter->state->base_group = -filter->action.group.group;
174 if (filter->action.group.flags & XkbSA_ClearLocks)
175 filter->state->locked_group = 0;
183 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
184 union xkb_action *action)
186 struct xkb_filter *filter = xkb_filter_new(state);
188 if (!filter) /* WSGO */
190 filter->keycode = keycode;
191 filter->func = xkb_filter_group_set_func;
192 filter->action = *action;
194 if (action->group.flags & XkbSA_GroupAbsolute) {
195 filter->action.group.group = filter->state->base_group;
196 filter->state->base_group = action->group.group;
199 filter->state->base_group += action->group.group;
206 xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
207 enum xkb_key_direction direction)
209 if (keycode != filter->keycode)
212 if (direction == XKB_KEY_DOWN) {
216 if (--filter->refcnt > 0)
224 xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
225 union xkb_action *action)
227 struct xkb_filter *filter = xkb_filter_new(state);
232 filter->keycode = keycode;
233 filter->func = xkb_filter_group_lock_func;
234 filter->action = *action;
236 if (action->group.flags & XkbSA_GroupAbsolute)
237 filter->state->locked_group = action->group.group;
239 filter->state->locked_group += action->group.group;
245 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
246 enum xkb_key_direction direction)
248 if (keycode != filter->keycode) {
249 filter->action.mods.flags &= ~XkbSA_ClearLocks;
253 if (direction == XKB_KEY_DOWN) {
257 else if (--filter->refcnt > 0) {
261 filter->state->clear_mods = filter->action.mods.mask;
262 if (filter->action.mods.flags & XkbSA_ClearLocks)
263 filter->state->locked_mods &= ~filter->action.mods.mask;
271 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
272 union xkb_action *action)
274 struct xkb_filter *filter = xkb_filter_new(state);
276 if (!filter) /* WSGO */
278 filter->keycode = keycode;
279 filter->func = xkb_filter_mod_set_func;
280 filter->action = *action;
282 filter->state->set_mods = action->mods.mask;
288 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
289 enum xkb_key_direction direction)
291 if (keycode != filter->keycode)
294 if (direction == XKB_KEY_DOWN) {
298 if (--filter->refcnt > 0)
301 filter->state->locked_mods &= ~filter->priv;
307 xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
308 union xkb_action *action)
310 struct xkb_filter *filter = xkb_filter_new(state);
312 if (!filter) /* WSGO */
315 filter->keycode = keycode;
316 filter->func = xkb_filter_mod_lock_func;
317 filter->action = *action;
318 filter->priv = state->locked_mods & action->mods.mask;
319 state->locked_mods |= action->mods.mask;
324 enum xkb_key_latch_state {
331 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
332 enum xkb_key_direction direction)
334 enum xkb_key_latch_state latch = filter->priv;
336 if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
337 /* If this is a new keypress and we're awaiting our single latched
338 * keypress, then either break the latch if any random key is pressed,
339 * or promote it to a lock or plain base set if it's the same
341 union xkb_action *action = xkb_key_get_action(filter->state, keycode);
342 if (action->type == XkbSA_LatchMods &&
343 action->mods.flags == filter->action.mods.flags &&
344 action->mods.mask == filter->action.mods.mask) {
345 filter->action = *action;
346 if (filter->action.mods.flags & XkbSA_LatchToLock) {
347 filter->action.type = XkbSA_LockMods;
348 filter->func = xkb_filter_mod_lock_func;
349 filter->state->locked_mods |= filter->action.mods.mask;
352 filter->action.type = XkbSA_SetMods;
353 filter->func = xkb_filter_mod_set_func;
354 filter->state->set_mods = filter->action.mods.mask;
356 filter->keycode = keycode;
357 filter->state->latched_mods &= ~filter->action.mods.mask;
361 else if (((1 << action->type) & XkbSA_BreakLatch)) {
362 /* XXX: This may be totally broken, we might need to break the
363 * latch in the next run after this press? */
364 filter->state->latched_mods &= ~filter->action.mods.mask;
369 else if (direction == XKB_KEY_UP && keycode == filter->keycode) {
370 /* Our key got released. If we've set it to clear locks, and we
371 * currently have the same modifiers locked, then release them and
372 * don't actually latch. Else we've actually hit the latching
373 * stage, so set PENDING and move our modifier from base to
375 if (latch == NO_LATCH ||
376 ((filter->action.mods.flags & XkbSA_ClearLocks) &&
377 (filter->state->locked_mods & filter->action.mods.mask) ==
378 filter->action.mods.mask)) {
379 /* XXX: We might be a bit overenthusiastic about clearing
380 * mods other filters have set here? */
381 if (latch == LATCH_PENDING)
382 filter->state->latched_mods &= ~filter->action.mods.mask;
384 filter->state->clear_mods = filter->action.mods.mask;
385 filter->state->locked_mods &= ~filter->action.mods.mask;
389 latch = LATCH_PENDING;
390 filter->state->clear_mods = filter->action.mods.mask;
391 filter->state->latched_mods |= filter->action.mods.mask;
395 else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
396 /* Someone's pressed another key while we've still got the latching
397 * key held down, so keep the base modifier state active (from
398 * xkb_filter_mod_latch_new), but don't trip the latch, just clear
399 * it as soon as the modifier gets released. */
403 filter->priv = latch;
409 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
410 union xkb_action *action)
412 struct xkb_filter *filter = xkb_filter_new(state);
413 enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
415 if (!filter) /* WSGO */
417 filter->keycode = keycode;
418 filter->priv = latch;
419 filter->func = xkb_filter_mod_latch_func;
420 filter->action = *action;
422 filter->state->set_mods = action->mods.mask;
428 * Applies any relevant filters to the key, first from the list of filters
429 * that are currently active, then if no filter has claimed the key, possibly
430 * apply a new filter from the key action.
433 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
434 enum xkb_key_direction direction)
436 struct xkb_filter *filter;
437 union xkb_action *act = NULL;
440 /* First run through all the currently active filters and see if any of
441 * them have claimed this event. */
442 darray_foreach(filter, state->filters) {
445 send &= filter->func(filter, key, direction);
448 if (!send || direction == XKB_KEY_UP)
451 act = xkb_key_get_action(state, key);
454 send = xkb_filter_mod_set_new(state, key, act);
456 case XkbSA_LatchMods:
457 send = xkb_filter_mod_latch_new(state, key, act);
460 send = xkb_filter_mod_lock_new(state, key, act);
463 send = xkb_filter_group_set_new(state, key, act);
466 case XkbSA_LatchGroup:
467 send = xkb_filter_mod_latch_new(state, key, act);
470 case XkbSA_LockGroup:
471 send = xkb_filter_group_lock_new(state, key, act);
478 _X_EXPORT struct xkb_state *
479 xkb_state_new(struct xkb_keymap *keymap)
481 struct xkb_state *ret;
486 ret = calloc(sizeof(*ret), 1);
491 ret->keymap = xkb_map_ref(keymap);
496 _X_EXPORT struct xkb_state *
497 xkb_state_ref(struct xkb_state *state)
504 xkb_state_unref(struct xkb_state *state)
507 assert(state->refcnt >= 0);
508 if (state->refcnt > 0)
511 xkb_map_unref(state->keymap);
512 darray_free(state->filters);
516 _X_EXPORT struct xkb_keymap *
517 xkb_state_get_map(struct xkb_state *state)
519 return state->keymap;
523 * Update the LED state to match the rest of the xkb_state.
526 xkb_state_led_update_all(struct xkb_state *state)
532 for (led = 0; led < XkbNumIndicators; led++) {
533 struct xkb_indicator_map *map = &state->keymap->indicators->maps[led];
534 uint32_t mod_mask = 0;
535 uint32_t group_mask = 0;
537 if (!map->which_mods && !map->which_groups && !map->ctrls)
540 if (map->which_mods) {
541 if (map->which_mods & XkbIM_UseBase)
542 mod_mask |= state->base_mods;
543 if (map->which_mods & XkbIM_UseLatched)
544 mod_mask |= state->latched_mods;
545 if (map->which_mods & XkbIM_UseLocked)
546 mod_mask |= state->locked_mods;
547 if (map->which_mods & XkbIM_UseEffective)
548 mod_mask |= state->mods;
549 if ((map->mods.mask & mod_mask))
550 state->leds |= (1 << led);
552 else if (map->which_groups) {
553 if (map->which_mods & XkbIM_UseBase)
554 group_mask |= (1 << state->base_group);
555 if (map->which_mods & XkbIM_UseLatched)
556 group_mask |= (1 << state->latched_group);
557 if (map->which_mods & XkbIM_UseLocked)
558 group_mask |= (1 << state->locked_group);
559 if (map->which_mods & XkbIM_UseEffective)
560 group_mask |= (1 << state->group);
561 if ((map->groups & group_mask))
562 state->leds |= (1 << led);
564 else if (map->ctrls) {
565 if ((map->ctrls & state->keymap->ctrls->enabled_ctrls))
566 state->leds |= (1 << led);
572 * Calculates the derived state (effective mods/group and LEDs) from an
573 * up-to-date xkb_state.
576 xkb_state_update_derived(struct xkb_state *state)
578 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
579 /* FIXME: Clamp/wrap locked_group */
580 state->group = state->locked_group + state->base_group +
581 state->latched_group;
582 /* FIXME: Clamp/wrap effective group */
584 xkb_state_led_update_all(state);
588 * Given a particular key event, updates the state structure to reflect the
592 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
593 enum xkb_key_direction direction)
599 state->clear_mods = 0;
601 xkb_filter_apply_all(state, key, direction);
603 for (i = 0, bit = 1; state->set_mods; i++, bit <<= 1) {
604 if (state->set_mods & bit) {
605 state->mod_key_count[i]++;
606 state->base_mods |= bit;
607 state->set_mods &= ~bit;
611 for (i = 0, bit = 1; state->clear_mods; i++, bit <<= 1) {
612 if (state->clear_mods & bit) {
613 state->mod_key_count[i]--;
614 if (state->mod_key_count[i] <= 0) {
615 state->base_mods &= ~bit;
616 state->mod_key_count[i] = 0;
618 state->clear_mods &= ~bit;
622 xkb_state_update_derived(state);
626 * Updates the state from a set of explicit masks as gained from
627 * xkb_state_serialize_mods and xkb_state_serialize_groups. As noted in the
628 * documentation for these functions in xkbcommon.h, this round-trip is
629 * lossy, and should only be used to update a slave state mirroring the
630 * master, e.g. in a client/server window system.
633 xkb_state_update_mask(struct xkb_state *state,
634 xkb_mod_mask_t base_mods,
635 xkb_mod_mask_t latched_mods,
636 xkb_mod_mask_t locked_mods,
637 xkb_group_index_t base_group,
638 xkb_group_index_t latched_group,
639 xkb_group_index_t locked_group)
643 state->base_mods = 0;
644 state->latched_mods = 0;
645 state->locked_mods = 0;
646 for (mod = 0; mod < xkb_map_num_mods(state->keymap); mod++) {
647 xkb_mod_mask_t idx = (1 << mod);
649 state->base_mods |= idx;
650 if (latched_mods & idx)
651 state->latched_mods |= idx;
652 if (locked_mods & idx)
653 state->locked_mods |= idx;
656 state->base_group = base_group;
657 state->latched_group = latched_group;
658 state->locked_group = locked_group;
660 xkb_state_update_derived(state);
664 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
665 * the same disclaimers as in xkb_state_update_mask.
667 _X_EXPORT xkb_mod_mask_t
668 xkb_state_serialize_mods(struct xkb_state *state,
669 enum xkb_state_component type)
671 xkb_mod_mask_t ret = 0;
673 if (type == XKB_STATE_EFFECTIVE)
676 if (type & XKB_STATE_DEPRESSED)
677 ret |= state->base_mods;
678 if (type & XKB_STATE_LATCHED)
679 ret |= state->latched_mods;
680 if (type & XKB_STATE_LOCKED)
681 ret |= state->locked_mods;
687 * Serialises the requested group state, with all the same disclaimers as
688 * in xkb_state_update_mask.
690 _X_EXPORT xkb_group_index_t
691 xkb_state_serialize_group(struct xkb_state *state,
692 enum xkb_state_component type)
694 xkb_group_index_t ret = 0;
696 if (type == XKB_STATE_EFFECTIVE)
699 if (type & XKB_STATE_DEPRESSED)
700 ret += state->base_group;
701 if (type & XKB_STATE_LATCHED)
702 ret += state->latched_group;
703 if (type & XKB_STATE_LOCKED)
704 ret += state->locked_group;
710 * Returns 1 if the given modifier is active with the specified type(s), 0 if
711 * not, or -1 if the modifier is invalid.
714 xkb_state_mod_index_is_active(struct xkb_state *state,
716 enum xkb_state_component type)
720 if (idx >= xkb_map_num_mods(state->keymap))
723 if (type & XKB_STATE_DEPRESSED)
724 ret |= (state->base_mods & (1 << idx));
725 if (type & XKB_STATE_LATCHED)
726 ret |= (state->latched_mods & (1 << idx));
727 if (type & XKB_STATE_LOCKED)
728 ret |= (state->locked_mods & (1 << idx));
734 * Helper function for xkb_state_mod_indices_are_active and
735 * xkb_state_mod_names_are_active.
738 match_mod_masks(struct xkb_state *state, enum xkb_state_match match,
741 uint32_t active = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
743 if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
746 if (match & XKB_STATE_MATCH_ANY)
747 return !!(active & wanted);
749 return (active & wanted) == wanted;
755 * Returns 1 if the modifiers are active with the specified type(s), 0 if
756 * not, or -1 if any of the modifiers are invalid.
759 xkb_state_mod_indices_are_active(struct xkb_state *state,
760 enum xkb_state_component type,
761 enum xkb_state_match match,
765 xkb_mod_index_t idx = 0;
771 idx = va_arg(ap, xkb_mod_index_t);
772 if (idx == XKB_MOD_INVALID ||
773 idx >= xkb_map_num_mods(state->keymap)) {
777 wanted |= (1 << idx);
784 return match_mod_masks(state, match, wanted);
788 * Returns 1 if the given modifier is active with the specified type(s), 0 if
789 * not, or -1 if the modifier is invalid.
792 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
793 enum xkb_state_component type)
795 xkb_mod_index_t idx = xkb_map_mod_get_index(state->keymap, name);
797 if (idx == XKB_MOD_INVALID)
800 return xkb_state_mod_index_is_active(state, idx, type);
804 * Returns 1 if the modifiers are active with the specified type(s), 0 if
805 * not, or -1 if any of the modifiers are invalid.
808 xkb_state_mod_names_are_active(struct xkb_state *state,
809 enum xkb_state_component type,
810 enum xkb_state_match match,
814 xkb_mod_index_t idx = 0;
821 str = va_arg(ap, const char *);
824 idx = xkb_map_mod_get_index(state->keymap, str);
825 if (idx == XKB_MOD_INVALID) {
829 wanted |= (1 << idx);
836 return match_mod_masks(state, match, wanted);
840 * Returns 1 if the given group is active with the specified type(s), 0 if
841 * not, or -1 if the group is invalid.
844 xkb_state_group_index_is_active(struct xkb_state *state,
845 xkb_group_index_t idx,
846 enum xkb_state_component type)
850 if (idx >= xkb_map_num_groups(state->keymap))
853 if (type & XKB_STATE_DEPRESSED)
854 ret |= (state->base_group == idx);
855 if (type & XKB_STATE_LATCHED)
856 ret |= (state->latched_group == idx);
857 if (type & XKB_STATE_LOCKED)
858 ret |= (state->locked_group == idx);
864 * Returns 1 if the given modifier is active with the specified type(s), 0 if
865 * not, or -1 if the modifier is invalid.
868 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
869 enum xkb_state_component type)
871 xkb_group_index_t idx = xkb_map_group_get_index(state->keymap, name);
873 if (idx == XKB_GROUP_INVALID)
876 return xkb_state_group_index_is_active(state, idx, type);
880 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
883 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
885 if (idx >= xkb_map_num_leds(state->keymap))
888 return !!(state->leds & (1 << idx));
892 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
895 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
897 xkb_led_index_t idx = xkb_map_led_get_index(state->keymap, name);
899 if (idx == XKB_LED_INVALID)
902 return xkb_state_led_index_is_active(state, idx);