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);
498 * Update the LED state to match the rest of the xkb_state.
501 xkb_state_led_update_all(struct xkb_state *state)
507 for (led = 0; led < XkbNumIndicators; led++) {
508 struct xkb_indicator_map *map = &state->xkb->indicators->maps[led];
509 uint32_t mod_mask = 0;
510 uint32_t group_mask = 0;
512 if (!map->which_mods && !map->which_groups && !map->ctrls)
515 if (map->which_mods) {
516 if (map->which_mods & XkbIM_UseBase)
517 mod_mask |= state->base_mods;
518 if (map->which_mods & XkbIM_UseLatched)
519 mod_mask |= state->latched_mods;
520 if (map->which_mods & XkbIM_UseLocked)
521 mod_mask |= state->locked_mods;
522 if (map->which_mods & XkbIM_UseEffective)
523 mod_mask |= state->mods;
524 if ((map->mods.mask & mod_mask))
525 state->leds |= (1 << led);
527 else if (map->which_groups) {
528 if (map->which_mods & XkbIM_UseBase)
529 group_mask |= (1 << state->base_group);
530 if (map->which_mods & XkbIM_UseLatched)
531 group_mask |= (1 << state->latched_group);
532 if (map->which_mods & XkbIM_UseLocked)
533 group_mask |= (1 << state->locked_group);
534 if (map->which_mods & XkbIM_UseEffective)
535 group_mask |= (1 << state->group);
536 if ((map->groups & group_mask))
537 state->leds |= (1 << led);
539 else if (map->ctrls) {
540 if ((map->ctrls & state->xkb->ctrls->enabled_ctrls))
541 state->leds |= (1 << led);
547 * Calculates the derived state (effective mods/group and LEDs) from an
548 * up-to-date xkb_state.
551 xkb_state_update_derived(struct xkb_state *state)
553 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
554 /* FIXME: Clamp/wrap locked_group */
555 state->group = state->locked_group + state->base_group +
556 state->latched_group;
557 /* FIXME: Clamp/wrap effective group */
559 xkb_state_led_update_all(state);
563 * Given a particular key event, updates the state structure to reflect the
567 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
568 enum xkb_key_direction direction)
570 xkb_filter_apply_all(state, key, direction);
571 xkb_state_update_derived(state);
575 * Updates the state from a set of explicit masks as gained from
576 * xkb_state_serialise_mods and xkb_state_serialise_groups. As noted in the
577 * documentation for these functions in xkbcommon.h, this round-trip is
578 * lossy, and should only be used to update a slave state mirroring the
579 * master, e.g. in a client/server window system.
582 xkb_state_update_mask(struct xkb_state *state,
583 xkb_mod_mask_t base_mods,
584 xkb_mod_mask_t latched_mods,
585 xkb_mod_mask_t locked_mods,
586 xkb_group_index_t base_group,
587 xkb_group_index_t latched_group,
588 xkb_group_index_t locked_group)
592 state->base_mods = 0;
593 state->latched_mods = 0;
594 state->locked_mods = 0;
595 for (mod = 0; mod < xkb_map_num_mods(state->xkb); mod++) {
596 xkb_mod_mask_t idx = (1 << mod);
598 state->base_mods |= idx;
599 if (latched_mods & idx)
600 state->latched_mods |= idx;
601 if (locked_mods & idx)
602 state->locked_mods |= idx;
605 state->base_group = base_group;
606 state->latched_group = latched_group;
607 state->locked_group = locked_group;
609 xkb_state_update_derived(state);
613 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
614 * the same disclaimers as in xkb_state_update_mask.
616 _X_EXPORT xkb_mod_mask_t
617 xkb_state_serialise_mods(struct xkb_state *state,
618 enum xkb_state_component type)
620 xkb_mod_mask_t ret = 0;
622 if (type == XKB_STATE_EFFECTIVE)
625 if (type & XKB_STATE_DEPRESSED)
626 ret |= state->base_mods;
627 if (type & XKB_STATE_LATCHED)
628 ret |= state->latched_mods;
629 if (type & XKB_STATE_LOCKED)
630 ret |= state->locked_mods;
636 * Serialises the requested group state, with all the same disclaimers as
637 * in xkb_state_update_mask.
639 _X_EXPORT xkb_group_index_t
640 xkb_state_serialise_group(struct xkb_state *state,
641 enum xkb_state_component type)
643 xkb_group_index_t ret = 0;
645 if (type == XKB_STATE_EFFECTIVE)
648 if (type & XKB_STATE_DEPRESSED)
649 ret += state->base_group;
650 if (type & XKB_STATE_LATCHED)
651 ret += state->latched_group;
652 if (type & XKB_STATE_LOCKED)
653 ret += state->locked_group;
659 * Returns 1 if the given modifier is active with the specified type(s), 0 if
660 * not, or -1 if the modifier is invalid.
663 xkb_state_mod_index_is_active(struct xkb_state *state,
665 enum xkb_state_component type)
669 if (idx >= xkb_map_num_mods(state->xkb))
672 if (type & XKB_STATE_DEPRESSED)
673 ret |= (state->base_mods & (1 << idx));
674 if (type & XKB_STATE_LATCHED)
675 ret |= (state->latched_mods & (1 << idx));
676 if (type & XKB_STATE_LOCKED)
677 ret |= (state->locked_mods & (1 << idx));
683 * Returns 1 if the given modifier is active with the specified type(s), 0 if
684 * not, or -1 if the modifier is invalid.
687 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
688 enum xkb_state_component type)
690 xkb_mod_index_t idx = xkb_map_mod_get_index(state->xkb, name);
692 if (idx == XKB_MOD_INVALID)
695 return xkb_state_mod_index_is_active(state, idx, type);
699 * Returns 1 if the given group is active with the specified type(s), 0 if
700 * not, or -1 if the group is invalid.
703 xkb_state_group_index_is_active(struct xkb_state *state,
704 xkb_group_index_t idx,
705 enum xkb_state_component type)
709 if (idx >= xkb_map_num_groups(state->xkb))
712 if (type & XKB_STATE_DEPRESSED)
713 ret |= (state->base_group == idx);
714 if (type & XKB_STATE_LATCHED)
715 ret |= (state->latched_group == idx);
716 if (type & XKB_STATE_LOCKED)
717 ret |= (state->locked_group == idx);
723 * Returns 1 if the given modifier is active with the specified type(s), 0 if
724 * not, or -1 if the modifier is invalid.
727 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
728 enum xkb_state_component type)
730 xkb_group_index_t idx = xkb_map_group_get_index(state->xkb, name);
732 if (idx == XKB_GROUP_INVALID)
735 return xkb_state_group_index_is_active(state, idx, type);
739 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
742 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
744 if (idx >= xkb_map_num_leds(state->xkb))
747 return !!(state->leds & (1 << idx));
751 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
754 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
756 xkb_led_index_t idx = xkb_map_led_get_index(state->xkb, name);
758 if (idx == XKB_LED_INVALID)
761 return xkb_state_led_index_is_active(state, idx);