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;
77 static union xkb_action *
78 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
82 if (!XkbKeyHasActions(state->xkb, key) ||
83 !XkbKeycodeInRange(state->xkb, key)) {
84 static union xkb_action fake;
85 memset(&fake, 0, sizeof(fake));
86 fake.type = XkbSA_NoAction;
90 group = xkb_key_get_group(state, key);
91 level = xkb_key_get_level(state, key, group);
93 return XkbKeyActionEntry(state->xkb, key, level, group);
96 static struct xkb_filter *
97 xkb_filter_new(struct xkb_state *state)
100 int old_size = state->num_filters;
101 struct xkb_filter *filters = state->filters;
103 for (i = 0; i < state->num_filters; i++) {
106 filters[i].state = state;
107 filters[i].refcnt = 1;
111 if (state->num_filters > 0)
112 state->num_filters *= 2;
114 state->num_filters = 4;
115 filters = realloc(filters, state->num_filters * sizeof(*filters));
116 if (!filters) { /* WSGO */
117 state->num_filters = old_size;
120 state->filters = filters;
121 memset(&filters[old_size], 0,
122 (state->num_filters - old_size) * sizeof(*filters));
124 filters[old_size].state = state;
125 filters[old_size].refcnt = 1;
127 return &filters[old_size];
130 /***====================================================================***/
133 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
134 enum xkb_key_direction direction)
136 if (keycode != filter->keycode) {
137 filter->action.group.flags &= ~XkbSA_ClearLocks;
141 if (direction == XKB_KEY_DOWN) {
145 else if (--filter->refcnt > 0) {
149 if (filter->action.group.flags & XkbSA_GroupAbsolute)
150 filter->state->base_group = filter->action.group.group;
152 filter->state->base_group = -filter->action.group.group;
153 if (filter->action.group.flags & XkbSA_ClearLocks)
154 filter->state->locked_group = 0;
162 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
163 union xkb_action *action)
165 struct xkb_filter *filter = xkb_filter_new(state);
167 if (!filter) /* WSGO */
169 filter->keycode = keycode;
170 filter->func = xkb_filter_group_set_func;
171 filter->action = *action;
173 if (action->group.flags & XkbSA_GroupAbsolute) {
174 filter->action.group.group = filter->state->base_group;
175 filter->state->base_group = action->group.group;
178 filter->state->base_group += action->group.group;
185 xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
186 enum xkb_key_direction direction)
188 if (keycode != filter->keycode)
191 if (direction == XKB_KEY_DOWN) {
195 if (--filter->refcnt > 0)
203 xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
204 union xkb_action *action)
206 struct xkb_filter *filter = xkb_filter_new(state);
211 filter->keycode = keycode;
212 filter->func = xkb_filter_group_lock_func;
213 filter->action = *action;
215 if (action->group.flags & XkbSA_GroupAbsolute)
216 filter->state->locked_group = action->group.group;
218 filter->state->locked_group += action->group.group;
224 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
225 enum xkb_key_direction direction)
227 if (keycode != filter->keycode) {
228 filter->action.mods.flags &= ~XkbSA_ClearLocks;
232 if (direction == XKB_KEY_DOWN) {
236 else if (--filter->refcnt > 0) {
240 filter->state->base_mods &= ~(filter->action.mods.mask);
241 if (filter->action.mods.flags & XkbSA_ClearLocks)
242 filter->state->locked_mods &= ~filter->action.mods.mask;
250 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
251 union xkb_action *action)
253 struct xkb_filter *filter = xkb_filter_new(state);
255 if (!filter) /* WSGO */
257 filter->keycode = keycode;
258 filter->func = xkb_filter_mod_set_func;
259 filter->action = *action;
261 filter->state->base_mods |= action->mods.mask;
267 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
268 enum xkb_key_direction direction)
270 if (keycode != filter->keycode)
273 if (direction == XKB_KEY_DOWN) {
277 if (--filter->refcnt > 0)
280 filter->state->locked_mods &= ~filter->priv;
286 xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
287 union xkb_action *action)
289 struct xkb_filter *filter = xkb_filter_new(state);
291 if (!filter) /* WSGO */
294 filter->keycode = keycode;
295 filter->func = xkb_filter_mod_lock_func;
296 filter->action = *action;
297 filter->priv = state->locked_mods & action->mods.mask;
298 state->locked_mods |= action->mods.mask;
303 enum xkb_key_latch_state {
310 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
311 enum xkb_key_direction direction)
313 enum xkb_key_latch_state latch = filter->priv;
315 if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
316 /* If this is a new keypress and we're awaiting our single latched
317 * keypress, then either break the latch if any random key is pressed,
318 * or promote it to a lock or plain base set if it's the same
320 union xkb_action *action = xkb_key_get_action(filter->state, keycode);
321 if (action->type == XkbSA_LatchMods &&
322 action->mods.flags == filter->action.mods.flags &&
323 action->mods.mask == filter->action.mods.mask) {
324 filter->action = *action;
325 if (filter->action.mods.flags & XkbSA_LatchToLock) {
326 filter->action.type = XkbSA_LockMods;
327 filter->func = xkb_filter_mod_lock_func;
328 filter->state->locked_mods |= filter->action.mods.mask;
331 filter->action.type = XkbSA_SetMods;
332 filter->func = xkb_filter_mod_set_func;
333 filter->state->base_mods |= filter->action.mods.mask;
335 filter->keycode = keycode;
336 filter->state->latched_mods &= ~filter->action.mods.mask;
340 else if (((1 << action->type) & XkbSA_BreakLatch)) {
341 /* XXX: This may be totally broken, we might need to break the
342 * latch in the next run after this press? */
343 filter->state->latched_mods &= ~filter->action.mods.mask;
348 else if (direction == XKB_KEY_UP && keycode == filter->keycode) {
349 /* Our key got released. If we've set it to clear locks, and we
350 * currently have the same modifiers locked, then release them and
351 * don't actually latch. Else we've actually hit the latching
352 * stage, so set PENDING and move our modifier from base to
354 if (latch == NO_LATCH ||
355 ((filter->action.mods.flags & XkbSA_ClearLocks) &&
356 (filter->state->locked_mods & filter->action.mods.mask) ==
357 filter->action.mods.mask)) {
358 /* XXX: We might be a bit overenthusiastic about clearing
359 * mods other filters have set here? */
360 if (latch == LATCH_PENDING)
361 filter->state->latched_mods &= ~filter->action.mods.mask;
363 filter->state->base_mods &= ~filter->action.mods.mask;
364 filter->state->locked_mods &= ~filter->action.mods.mask;
368 latch = LATCH_PENDING;
369 filter->state->base_mods &= ~filter->action.mods.mask;
370 filter->state->latched_mods |= filter->action.mods.mask;
374 else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
375 /* Someone's pressed another key while we've still got the latching
376 * key held down, so keep the base modifier state active (from
377 * xkb_filter_mod_latch_new), but don't trip the latch, just clear
378 * it as soon as the modifier gets released. */
382 filter->priv = latch;
388 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
389 union xkb_action *action)
391 struct xkb_filter *filter = xkb_filter_new(state);
392 enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
394 if (!filter) /* WSGO */
396 filter->keycode = keycode;
397 filter->priv = latch;
398 filter->func = xkb_filter_mod_latch_func;
399 filter->action = *action;
401 filter->state->base_mods |= action->mods.mask;
407 * Applies any relevant filters to the key, first from the list of filters
408 * that are currently active, then if no filter has claimed the key, possibly
409 * apply a new filter from the key action.
412 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
413 enum xkb_key_direction direction)
415 struct xkb_filter *filters = state->filters;
416 union xkb_action *act = NULL;
420 /* First run through all the currently active filters and see if any of
421 * them have claimed this event. */
422 for (i = 0; i < state->num_filters; i++) {
423 if (!filters[i].func)
425 send &= (*filters[i].func)(&filters[i], key, direction);
428 if (!send || direction == XKB_KEY_UP)
431 act = xkb_key_get_action(state, key);
434 send = xkb_filter_mod_set_new(state, key, act);
436 case XkbSA_LatchMods:
437 send = xkb_filter_mod_latch_new(state, key, act);
440 send = xkb_filter_mod_lock_new(state, key, act);
443 send = xkb_filter_group_set_new(state, key, act);
446 case XkbSA_LatchGroup:
447 send = xkb_filter_mod_latch_new(state, key, act);
450 case XkbSA_LockGroup:
451 send = xkb_filter_group_lock_new(state, key, act);
458 _X_EXPORT struct xkb_state *
459 xkb_state_new(struct xkb_keymap *xkb)
461 struct xkb_state *ret;
466 ret = calloc(sizeof(*ret), 1);
471 ret->xkb = xkb_map_ref(xkb);
476 _X_EXPORT struct xkb_state *
477 xkb_state_ref(struct xkb_state *state)
484 xkb_state_unref(struct xkb_state *state)
487 assert(state->refcnt >= 0);
488 if (state->refcnt > 0)
491 xkb_map_unref(state->xkb);
492 free(state->filters);
496 _X_EXPORT struct xkb_keymap *
497 xkb_state_get_map(struct xkb_state *state)
503 * Update the LED state to match the rest of the xkb_state.
506 xkb_state_led_update_all(struct xkb_state *state)
512 for (led = 0; led < XkbNumIndicators; led++) {
513 struct xkb_indicator_map *map = &state->xkb->indicators->maps[led];
514 uint32_t mod_mask = 0;
515 uint32_t group_mask = 0;
517 if (!map->which_mods && !map->which_groups && !map->ctrls)
520 if (map->which_mods) {
521 if (map->which_mods & XkbIM_UseBase)
522 mod_mask |= state->base_mods;
523 if (map->which_mods & XkbIM_UseLatched)
524 mod_mask |= state->latched_mods;
525 if (map->which_mods & XkbIM_UseLocked)
526 mod_mask |= state->locked_mods;
527 if (map->which_mods & XkbIM_UseEffective)
528 mod_mask |= state->mods;
529 if ((map->mods.mask & mod_mask))
530 state->leds |= (1 << led);
532 else if (map->which_groups) {
533 if (map->which_mods & XkbIM_UseBase)
534 group_mask |= (1 << state->base_group);
535 if (map->which_mods & XkbIM_UseLatched)
536 group_mask |= (1 << state->latched_group);
537 if (map->which_mods & XkbIM_UseLocked)
538 group_mask |= (1 << state->locked_group);
539 if (map->which_mods & XkbIM_UseEffective)
540 group_mask |= (1 << state->group);
541 if ((map->groups & group_mask))
542 state->leds |= (1 << led);
544 else if (map->ctrls) {
545 if ((map->ctrls & state->xkb->ctrls->enabled_ctrls))
546 state->leds |= (1 << led);
552 * Calculates the derived state (effective mods/group and LEDs) from an
553 * up-to-date xkb_state.
556 xkb_state_update_derived(struct xkb_state *state)
558 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
559 /* FIXME: Clamp/wrap locked_group */
560 state->group = state->locked_group + state->base_group +
561 state->latched_group;
562 /* FIXME: Clamp/wrap effective group */
564 xkb_state_led_update_all(state);
568 * Given a particular key event, updates the state structure to reflect the
572 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
573 enum xkb_key_direction direction)
575 xkb_filter_apply_all(state, key, direction);
576 xkb_state_update_derived(state);
580 * Updates the state from a set of explicit masks as gained from
581 * xkb_state_serialise_mods and xkb_state_serialise_groups. As noted in the
582 * documentation for these functions in xkbcommon.h, this round-trip is
583 * lossy, and should only be used to update a slave state mirroring the
584 * master, e.g. in a client/server window system.
587 xkb_state_update_mask(struct xkb_state *state,
588 xkb_mod_mask_t base_mods,
589 xkb_mod_mask_t latched_mods,
590 xkb_mod_mask_t locked_mods,
591 xkb_group_index_t base_group,
592 xkb_group_index_t latched_group,
593 xkb_group_index_t locked_group)
597 state->base_mods = 0;
598 state->latched_mods = 0;
599 state->locked_mods = 0;
600 for (mod = 0; mod < xkb_map_num_mods(state->xkb); mod++) {
601 xkb_mod_mask_t idx = (1 << mod);
603 state->base_mods |= idx;
604 if (latched_mods & idx)
605 state->latched_mods |= idx;
606 if (locked_mods & idx)
607 state->locked_mods |= idx;
610 state->base_group = base_group;
611 state->latched_group = latched_group;
612 state->locked_group = locked_group;
614 xkb_state_update_derived(state);
618 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
619 * the same disclaimers as in xkb_state_update_mask.
621 _X_EXPORT xkb_mod_mask_t
622 xkb_state_serialise_mods(struct xkb_state *state,
623 enum xkb_state_component type)
625 xkb_mod_mask_t ret = 0;
627 if (type == XKB_STATE_EFFECTIVE)
630 if (type & XKB_STATE_DEPRESSED)
631 ret |= state->base_mods;
632 if (type & XKB_STATE_LATCHED)
633 ret |= state->latched_mods;
634 if (type & XKB_STATE_LOCKED)
635 ret |= state->locked_mods;
641 * Serialises the requested group state, with all the same disclaimers as
642 * in xkb_state_update_mask.
644 _X_EXPORT xkb_group_index_t
645 xkb_state_serialise_group(struct xkb_state *state,
646 enum xkb_state_component type)
648 xkb_group_index_t ret = 0;
650 if (type == XKB_STATE_EFFECTIVE)
653 if (type & XKB_STATE_DEPRESSED)
654 ret += state->base_group;
655 if (type & XKB_STATE_LATCHED)
656 ret += state->latched_group;
657 if (type & XKB_STATE_LOCKED)
658 ret += state->locked_group;
664 * Returns 1 if the given modifier is active with the specified type(s), 0 if
665 * not, or -1 if the modifier is invalid.
668 xkb_state_mod_index_is_active(struct xkb_state *state,
670 enum xkb_state_component type)
674 if (idx >= xkb_map_num_mods(state->xkb))
677 if (type & XKB_STATE_DEPRESSED)
678 ret |= (state->base_mods & (1 << idx));
679 if (type & XKB_STATE_LATCHED)
680 ret |= (state->latched_mods & (1 << idx));
681 if (type & XKB_STATE_LOCKED)
682 ret |= (state->locked_mods & (1 << idx));
688 * Helper function for xkb_state_mod_indices_are_active and
689 * xkb_state_mod_names_are_active.
692 match_mod_masks(struct xkb_state *state, enum xkb_state_match match,
695 uint32_t active = xkb_state_serialise_mods(state, XKB_STATE_EFFECTIVE);
697 if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
700 if (match & XKB_STATE_MATCH_ANY)
701 return !!(active & wanted);
703 return (active & wanted) == wanted;
709 * Returns 1 if the modifiers are active with the specified type(s), 0 if
710 * not, or -1 if any of the modifiers are invalid.
713 xkb_state_mod_indices_are_active(struct xkb_state *state,
714 enum xkb_state_component type,
715 enum xkb_state_match match,
719 xkb_mod_index_t idx = 0;
725 idx = va_arg(ap, xkb_mod_index_t);
726 if (idx == XKB_MOD_INVALID || idx >= xkb_map_num_mods(state->xkb)) {
730 wanted |= (1 << idx);
737 return match_mod_masks(state, match, wanted);
741 * Returns 1 if the given modifier is active with the specified type(s), 0 if
742 * not, or -1 if the modifier is invalid.
745 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
746 enum xkb_state_component type)
748 xkb_mod_index_t idx = xkb_map_mod_get_index(state->xkb, name);
750 if (idx == XKB_MOD_INVALID)
753 return xkb_state_mod_index_is_active(state, idx, type);
757 * Returns 1 if the modifiers are active with the specified type(s), 0 if
758 * not, or -1 if any of the modifiers are invalid.
761 xkb_state_mod_names_are_active(struct xkb_state *state,
762 enum xkb_state_component type,
763 enum xkb_state_match match,
767 xkb_mod_index_t idx = 0;
774 str = va_arg(ap, const char *);
777 idx = xkb_map_mod_get_index(state->xkb, str);
778 if (idx == XKB_MOD_INVALID) {
782 wanted |= (1 << idx);
789 return match_mod_masks(state, match, wanted);
793 * Returns 1 if the given group is active with the specified type(s), 0 if
794 * not, or -1 if the group is invalid.
797 xkb_state_group_index_is_active(struct xkb_state *state,
798 xkb_group_index_t idx,
799 enum xkb_state_component type)
803 if (idx >= xkb_map_num_groups(state->xkb))
806 if (type & XKB_STATE_DEPRESSED)
807 ret |= (state->base_group == idx);
808 if (type & XKB_STATE_LATCHED)
809 ret |= (state->latched_group == idx);
810 if (type & XKB_STATE_LOCKED)
811 ret |= (state->locked_group == idx);
817 * Returns 1 if the given modifier is active with the specified type(s), 0 if
818 * not, or -1 if the modifier is invalid.
821 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
822 enum xkb_state_component type)
824 xkb_group_index_t idx = xkb_map_group_get_index(state->xkb, name);
826 if (idx == XKB_GROUP_INVALID)
829 return xkb_state_group_index_is_active(state, idx, type);
833 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
836 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
838 if (idx >= xkb_map_num_leds(state->xkb))
841 return !!(state->leds & (1 << idx));
845 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
848 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
850 xkb_led_index_t idx = xkb_map_led_get_index(state->xkb, name);
852 if (idx == XKB_LED_INVALID)
855 return xkb_state_led_index_is_active(state, idx);