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)
63 #include "xkbcommon/xkbcommon.h"
64 #include "XKBcommonint.h"
68 struct xkb_state *state;
69 union xkb_action action;
70 xkb_keycode_t keycode;
72 int (*func)(struct xkb_filter *filter, xkb_keycode_t key,
73 enum xkb_key_direction direction);
75 struct xkb_filter *next;
78 static union xkb_action *
79 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
83 if (!XkbKeyHasActions(state->xkb, key) ||
84 !XkbKeycodeInRange(state->xkb, key)) {
85 static union xkb_action fake;
86 memset(&fake, 0, sizeof(fake));
87 fake.type = XkbSA_NoAction;
91 group = xkb_key_get_group(state, key);
92 level = xkb_key_get_level(state, key, group);
94 return XkbKeyActionEntry(state->xkb, key, level, group);
97 static struct xkb_filter *
98 xkb_filter_new(struct xkb_state *state)
101 int old_size = state->num_filters;
102 struct xkb_filter *filters = state->filters;
104 for (i = 0; i < state->num_filters; i++) {
107 filters[i].state = state;
108 filters[i].refcnt = 1;
112 if (state->num_filters > 0)
113 state->num_filters *= 2;
115 state->num_filters = 4;
116 filters = realloc(filters, state->num_filters * sizeof(*filters));
117 if (!filters) { /* WSGO */
118 state->num_filters = old_size;
121 state->filters = filters;
122 memset(&filters[old_size], 0,
123 (state->num_filters - old_size) * sizeof(*filters));
125 filters[old_size].state = state;
126 filters[old_size].refcnt = 1;
128 return &filters[old_size];
131 /***====================================================================***/
134 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
135 enum xkb_key_direction direction)
137 if (keycode != filter->keycode) {
138 filter->action.group.flags &= ~XkbSA_ClearLocks;
142 if (direction == XKB_KEY_DOWN) {
146 else if (--filter->refcnt > 0) {
150 if (filter->action.group.flags & XkbSA_GroupAbsolute)
151 filter->state->base_group = filter->action.group.group;
153 filter->state->base_group = -filter->action.group.group;
154 if (filter->action.group.flags & XkbSA_ClearLocks)
155 filter->state->locked_group = 0;
163 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
164 union xkb_action *action)
166 struct xkb_filter *filter = xkb_filter_new(state);
168 if (!filter) /* WSGO */
170 filter->keycode = keycode;
171 filter->func = xkb_filter_group_set_func;
172 filter->action = *action;
174 if (action->group.flags & XkbSA_GroupAbsolute) {
175 filter->action.group.group = filter->state->base_group;
176 filter->state->base_group = action->group.group;
179 filter->state->base_group += action->group.group;
186 xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
187 enum xkb_key_direction direction)
189 if (keycode != filter->keycode)
192 if (direction == XKB_KEY_DOWN) {
196 if (--filter->refcnt > 0)
204 xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
205 union xkb_action *action)
207 struct xkb_filter *filter = xkb_filter_new(state);
212 filter->keycode = keycode;
213 filter->func = xkb_filter_group_lock_func;
214 filter->action = *action;
216 if (action->group.flags & XkbSA_GroupAbsolute)
217 filter->state->locked_group = action->group.group;
219 filter->state->locked_group += action->group.group;
225 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
226 enum xkb_key_direction direction)
228 if (keycode != filter->keycode) {
229 filter->action.mods.flags &= ~XkbSA_ClearLocks;
233 if (direction == XKB_KEY_DOWN) {
237 else if (--filter->refcnt > 0) {
241 filter->state->base_mods &= ~(filter->action.mods.mask);
242 if (filter->action.mods.flags & XkbSA_ClearLocks)
243 filter->state->locked_mods &= ~filter->action.mods.mask;
251 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
252 union xkb_action *action)
254 struct xkb_filter *filter = xkb_filter_new(state);
256 if (!filter) /* WSGO */
258 filter->keycode = keycode;
259 filter->func = xkb_filter_mod_set_func;
260 filter->action = *action;
262 filter->state->base_mods |= action->mods.mask;
268 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
269 enum xkb_key_direction direction)
271 if (keycode != filter->keycode)
274 if (direction == XKB_KEY_DOWN) {
278 if (--filter->refcnt > 0)
281 filter->state->locked_mods &= ~filter->priv;
287 xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
288 union xkb_action *action)
290 struct xkb_filter *filter = xkb_filter_new(state);
292 if (!filter) /* WSGO */
295 filter->keycode = keycode;
296 filter->func = xkb_filter_mod_lock_func;
297 filter->action = *action;
298 filter->priv = state->locked_mods & action->mods.mask;
299 state->locked_mods |= action->mods.mask;
304 enum xkb_key_latch_state {
311 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
312 enum xkb_key_direction direction)
314 enum xkb_key_latch_state latch = filter->priv;
316 if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
317 /* If this is a new keypress and we're awaiting our single latched
318 * keypress, then either break the latch if any random key is pressed,
319 * or promote it to a lock or plain base set if it's the same
321 union xkb_action *action = xkb_key_get_action(filter->state, keycode);
322 if (action->type == XkbSA_LatchMods &&
323 action->mods.flags == filter->action.mods.flags &&
324 action->mods.mask == filter->action.mods.mask) {
325 filter->action = *action;
326 if (filter->action.mods.flags & XkbSA_LatchToLock) {
327 filter->action.type = XkbSA_LockMods;
328 filter->func = xkb_filter_mod_lock_func;
329 filter->state->locked_mods |= filter->action.mods.mask;
332 filter->action.type = XkbSA_SetMods;
333 filter->func = xkb_filter_mod_set_func;
334 filter->state->base_mods |= filter->action.mods.mask;
336 filter->keycode = keycode;
337 filter->state->latched_mods &= ~filter->action.mods.mask;
341 else if (((1 << action->type) & XkbSA_BreakLatch)) {
342 /* XXX: This may be totally broken, we might need to break the
343 * latch in the next run after this press? */
344 filter->state->latched_mods &= ~filter->action.mods.mask;
349 else if (direction == XKB_KEY_UP && keycode == filter->keycode) {
350 /* Our key got released. If we've set it to clear locks, and we
351 * currently have the same modifiers locked, then release them and
352 * don't actually latch. Else we've actually hit the latching
353 * stage, so set PENDING and move our modifier from base to
355 if (latch == NO_LATCH ||
356 ((filter->action.mods.flags & XkbSA_ClearLocks) &&
357 (filter->state->locked_mods & filter->action.mods.mask) ==
358 filter->action.mods.mask)) {
359 /* XXX: We might be a bit overenthusiastic about clearing
360 * mods other filters have set here? */
361 if (latch == LATCH_PENDING)
362 filter->state->latched_mods &= ~filter->action.mods.mask;
364 filter->state->base_mods &= ~filter->action.mods.mask;
365 filter->state->locked_mods &= ~filter->action.mods.mask;
369 latch = LATCH_PENDING;
370 filter->state->base_mods &= ~filter->action.mods.mask;
371 filter->state->latched_mods |= filter->action.mods.mask;
375 else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
376 /* Someone's pressed another key while we've still got the latching
377 * key held down, so keep the base modifier state active (from
378 * xkb_filter_mod_latch_new), but don't trip the latch, just clear
379 * it as soon as the modifier gets released. */
383 filter->priv = latch;
389 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
390 union xkb_action *action)
392 struct xkb_filter *filter = xkb_filter_new(state);
393 enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
395 if (!filter) /* WSGO */
397 filter->keycode = keycode;
398 filter->priv = latch;
399 filter->func = xkb_filter_mod_latch_func;
400 filter->action = *action;
402 filter->state->base_mods |= action->mods.mask;
408 * Applies any relevant filters to the key, first from the list of filters
409 * that are currently active, then if no filter has claimed the key, possibly
410 * apply a new filter from the key action.
413 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
414 enum xkb_key_direction direction)
416 struct xkb_filter *filters = state->filters;
417 union xkb_action *act = NULL;
421 /* First run through all the currently active filters and see if any of
422 * them have claimed this event. */
423 for (i = 0; i < state->num_filters; i++) {
424 if (!filters[i].func)
426 send &= (*filters[i].func)(&filters[i], key, direction);
429 if (!send || direction == XKB_KEY_UP)
432 act = xkb_key_get_action(state, key);
435 send = xkb_filter_mod_set_new(state, key, act);
437 case XkbSA_LatchMods:
438 send = xkb_filter_mod_latch_new(state, key, act);
441 send = xkb_filter_mod_lock_new(state, key, act);
444 send = xkb_filter_group_set_new(state, key, act);
447 case XkbSA_LatchGroup:
448 send = xkb_filter_mod_latch_new(state, key, act);
451 case XkbSA_LockGroup:
452 send = xkb_filter_group_lock_new(state, key, act);
459 _X_EXPORT struct xkb_state *
460 xkb_state_new(struct xkb_keymap *xkb)
462 struct xkb_state *ret;
467 ret = calloc(sizeof(*ret), 1);
472 ret->xkb = xkb_map_ref(xkb);
477 _X_EXPORT struct xkb_state *
478 xkb_state_ref(struct xkb_state *state)
485 xkb_state_unref(struct xkb_state *state)
488 assert(state->refcnt >= 0);
489 if (state->refcnt > 0)
492 xkb_map_unref(state->xkb);
493 free(state->filters);
497 _X_EXPORT struct xkb_keymap *
498 xkb_state_get_map(struct xkb_state *state)
504 * Update the LED state to match the rest of the xkb_state.
507 xkb_state_led_update_all(struct xkb_state *state)
513 for (led = 0; led < XkbNumIndicators; led++) {
514 struct xkb_indicator_map *map = &state->xkb->indicators->maps[led];
515 uint32_t mod_mask = 0;
516 uint32_t group_mask = 0;
518 if (!map->which_mods && !map->which_groups && !map->ctrls)
521 if (map->which_mods) {
522 if (map->which_mods & XkbIM_UseBase)
523 mod_mask |= state->base_mods;
524 if (map->which_mods & XkbIM_UseLatched)
525 mod_mask |= state->latched_mods;
526 if (map->which_mods & XkbIM_UseLocked)
527 mod_mask |= state->locked_mods;
528 if (map->which_mods & XkbIM_UseEffective)
529 mod_mask |= state->mods;
530 if ((map->mods.mask & mod_mask))
531 state->leds |= (1 << led);
533 else if (map->which_groups) {
534 if (map->which_mods & XkbIM_UseBase)
535 group_mask |= (1 << state->base_group);
536 if (map->which_mods & XkbIM_UseLatched)
537 group_mask |= (1 << state->latched_group);
538 if (map->which_mods & XkbIM_UseLocked)
539 group_mask |= (1 << state->locked_group);
540 if (map->which_mods & XkbIM_UseEffective)
541 group_mask |= (1 << state->group);
542 if ((map->groups & group_mask))
543 state->leds |= (1 << led);
545 else if (map->ctrls) {
546 if ((map->ctrls & state->xkb->ctrls->enabled_ctrls))
547 state->leds |= (1 << led);
553 * Calculates the derived state (effective mods/group and LEDs) from an
554 * up-to-date xkb_state.
557 xkb_state_update_derived(struct xkb_state *state)
559 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
560 /* FIXME: Clamp/wrap locked_group */
561 state->group = state->locked_group + state->base_group +
562 state->latched_group;
563 /* FIXME: Clamp/wrap effective group */
565 xkb_state_led_update_all(state);
569 * Given a particular key event, updates the state structure to reflect the
573 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
574 enum xkb_key_direction direction)
576 xkb_filter_apply_all(state, key, direction);
577 xkb_state_update_derived(state);
581 * Updates the state from a set of explicit masks as gained from
582 * xkb_state_serialise_mods and xkb_state_serialise_groups. As noted in the
583 * documentation for these functions in xkbcommon.h, this round-trip is
584 * lossy, and should only be used to update a slave state mirroring the
585 * master, e.g. in a client/server window system.
588 xkb_state_update_mask(struct xkb_state *state,
589 xkb_mod_mask_t base_mods,
590 xkb_mod_mask_t latched_mods,
591 xkb_mod_mask_t locked_mods,
592 xkb_group_index_t base_group,
593 xkb_group_index_t latched_group,
594 xkb_group_index_t locked_group)
598 state->base_mods = 0;
599 state->latched_mods = 0;
600 state->locked_mods = 0;
601 for (mod = 0; mod < xkb_map_num_mods(state->xkb); mod++) {
602 xkb_mod_mask_t idx = (1 << mod);
604 state->base_mods |= idx;
605 if (latched_mods & idx)
606 state->latched_mods |= idx;
607 if (locked_mods & idx)
608 state->locked_mods |= idx;
611 state->base_group = base_group;
612 state->latched_group = latched_group;
613 state->locked_group = locked_group;
615 xkb_state_update_derived(state);
619 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
620 * the same disclaimers as in xkb_state_update_mask.
622 _X_EXPORT xkb_mod_mask_t
623 xkb_state_serialise_mods(struct xkb_state *state,
624 enum xkb_state_component type)
626 xkb_mod_mask_t ret = 0;
628 if (type == XKB_STATE_EFFECTIVE)
631 if (type & XKB_STATE_DEPRESSED)
632 ret |= state->base_mods;
633 if (type & XKB_STATE_LATCHED)
634 ret |= state->latched_mods;
635 if (type & XKB_STATE_LOCKED)
636 ret |= state->locked_mods;
642 * Serialises the requested group state, with all the same disclaimers as
643 * in xkb_state_update_mask.
645 _X_EXPORT xkb_group_index_t
646 xkb_state_serialise_group(struct xkb_state *state,
647 enum xkb_state_component type)
649 xkb_group_index_t ret = 0;
651 if (type == XKB_STATE_EFFECTIVE)
654 if (type & XKB_STATE_DEPRESSED)
655 ret += state->base_group;
656 if (type & XKB_STATE_LATCHED)
657 ret += state->latched_group;
658 if (type & XKB_STATE_LOCKED)
659 ret += state->locked_group;
665 * Returns 1 if the given modifier is active with the specified type(s), 0 if
666 * not, or -1 if the modifier is invalid.
669 xkb_state_mod_index_is_active(struct xkb_state *state,
671 enum xkb_state_component type)
675 if (idx >= xkb_map_num_mods(state->xkb))
678 if (type & XKB_STATE_DEPRESSED)
679 ret |= (state->base_mods & (1 << idx));
680 if (type & XKB_STATE_LATCHED)
681 ret |= (state->latched_mods & (1 << idx));
682 if (type & XKB_STATE_LOCKED)
683 ret |= (state->locked_mods & (1 << idx));
689 * Returns 1 if the given modifier is active with the specified type(s), 0 if
690 * not, or -1 if the modifier is invalid.
693 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
694 enum xkb_state_component type)
696 xkb_mod_index_t idx = xkb_map_mod_get_index(state->xkb, name);
698 if (idx == XKB_MOD_INVALID)
701 return xkb_state_mod_index_is_active(state, idx, type);
705 * Returns 1 if the given group is active with the specified type(s), 0 if
706 * not, or -1 if the group is invalid.
709 xkb_state_group_index_is_active(struct xkb_state *state,
710 xkb_group_index_t idx,
711 enum xkb_state_component type)
715 if (idx >= xkb_map_num_groups(state->xkb))
718 if (type & XKB_STATE_DEPRESSED)
719 ret |= (state->base_group == idx);
720 if (type & XKB_STATE_LATCHED)
721 ret |= (state->latched_group == idx);
722 if (type & XKB_STATE_LOCKED)
723 ret |= (state->locked_group == idx);
729 * Returns 1 if the given modifier is active with the specified type(s), 0 if
730 * not, or -1 if the modifier is invalid.
733 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
734 enum xkb_state_component type)
736 xkb_group_index_t idx = xkb_map_group_get_index(state->xkb, name);
738 if (idx == XKB_GROUP_INVALID)
741 return xkb_state_group_index_is_active(state, idx, type);
745 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
748 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
750 if (idx >= xkb_map_num_leds(state->xkb))
753 return !!(state->leds & (1 << idx));
757 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
760 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
762 xkb_led_index_t idx = xkb_map_led_get_index(state->xkb, name);
764 if (idx == XKB_LED_INVALID)
767 return xkb_state_led_index_is_active(state, idx);