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)
66 struct xkb_state *state;
67 union xkb_action action;
68 xkb_keycode_t keycode;
70 int (*func)(struct xkb_filter *filter, xkb_keycode_t key,
71 enum xkb_key_direction direction);
73 struct xkb_filter *next;
76 static union xkb_action *
77 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
81 if (!XkbKeyHasActions(state->xkb, key) ||
82 !XkbKeycodeInRange(state->xkb, key)) {
83 static union xkb_action fake;
84 memset(&fake, 0, sizeof(fake));
85 fake.type = XkbSA_NoAction;
89 group = xkb_key_get_group(state, key);
90 level = xkb_key_get_level(state, key, group);
92 return XkbKeyActionEntry(state->xkb, key, level, group);
95 static struct xkb_filter *
96 xkb_filter_new(struct xkb_state *state)
99 int old_size = state->num_filters;
100 struct xkb_filter *filters = state->filters;
102 for (i = 0; i < state->num_filters; i++) {
105 filters[i].state = state;
106 filters[i].refcnt = 1;
110 if (state->num_filters > 0)
111 state->num_filters *= 2;
113 state->num_filters = 4;
114 filters = realloc(filters, state->num_filters * sizeof(*filters));
115 if (!filters) { /* WSGO */
116 state->num_filters = old_size;
119 state->filters = filters;
120 memset(&filters[old_size], 0,
121 (state->num_filters - old_size) * sizeof(*filters));
123 filters[old_size].state = state;
124 filters[old_size].refcnt = 1;
126 return &filters[old_size];
129 /***====================================================================***/
132 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
133 enum xkb_key_direction direction)
135 if (keycode != filter->keycode) {
136 filter->action.group.flags &= ~XkbSA_ClearLocks;
140 if (direction == XKB_KEY_DOWN) {
144 else if (--filter->refcnt > 0) {
148 if (filter->action.group.flags & XkbSA_GroupAbsolute)
149 filter->state->base_group = filter->action.group.group;
151 filter->state->base_group = -filter->action.group.group;
152 if (filter->action.group.flags & XkbSA_ClearLocks)
153 filter->state->locked_group = 0;
161 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
162 union xkb_action *action)
164 struct xkb_filter *filter = xkb_filter_new(state);
166 if (!filter) /* WSGO */
168 filter->keycode = keycode;
169 filter->func = xkb_filter_group_set_func;
170 filter->action = *action;
172 if (action->group.flags & XkbSA_GroupAbsolute) {
173 filter->action.group.group = filter->state->base_group;
174 filter->state->base_group = action->group.group;
177 filter->state->base_group += action->group.group;
184 xkb_filter_group_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
185 enum xkb_key_direction direction)
187 if (keycode != filter->keycode)
190 if (direction == XKB_KEY_DOWN) {
194 if (--filter->refcnt > 0)
202 xkb_filter_group_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
203 union xkb_action *action)
205 struct xkb_filter *filter = xkb_filter_new(state);
210 filter->keycode = keycode;
211 filter->func = xkb_filter_group_lock_func;
212 filter->action = *action;
214 if (action->group.flags & XkbSA_GroupAbsolute)
215 filter->state->locked_group = action->group.group;
217 filter->state->locked_group += action->group.group;
223 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
224 enum xkb_key_direction direction)
226 if (keycode != filter->keycode) {
227 filter->action.mods.flags &= ~XkbSA_ClearLocks;
231 if (direction == XKB_KEY_DOWN) {
235 else if (--filter->refcnt > 0) {
239 filter->state->base_mods &= ~(filter->action.mods.mask);
240 if (filter->action.mods.flags & XkbSA_ClearLocks)
241 filter->state->locked_mods &= ~filter->action.mods.mask;
249 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
250 union xkb_action *action)
252 struct xkb_filter *filter = xkb_filter_new(state);
254 if (!filter) /* WSGO */
256 filter->keycode = keycode;
257 filter->func = xkb_filter_mod_set_func;
258 filter->action = *action;
260 filter->state->base_mods |= action->mods.mask;
266 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
267 enum xkb_key_direction direction)
269 if (keycode != filter->keycode)
272 if (direction == XKB_KEY_DOWN) {
276 if (--filter->refcnt > 0)
279 filter->state->locked_mods &= ~filter->priv;
285 xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
286 union xkb_action *action)
288 struct xkb_filter *filter = xkb_filter_new(state);
290 if (!filter) /* WSGO */
293 filter->keycode = keycode;
294 filter->func = xkb_filter_mod_lock_func;
295 filter->action = *action;
296 filter->priv = state->locked_mods & action->mods.mask;
297 state->locked_mods |= action->mods.mask;
302 enum xkb_key_latch_state {
309 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
310 enum xkb_key_direction direction)
312 enum xkb_key_latch_state latch = filter->priv;
314 if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
315 /* If this is a new keypress and we're awaiting our single latched
316 * keypress, then either break the latch if any random key is pressed,
317 * or promote it to a lock or plain base set if it's the same
319 union xkb_action *action = xkb_key_get_action(filter->state, keycode);
320 if (action->type == XkbSA_LatchMods &&
321 action->mods.flags == filter->action.mods.flags &&
322 action->mods.mask == filter->action.mods.mask) {
323 filter->action = *action;
324 if (filter->action.mods.flags & XkbSA_LatchToLock) {
325 filter->action.type = XkbSA_LockMods;
326 filter->func = xkb_filter_mod_lock_func;
327 filter->state->locked_mods |= filter->action.mods.mask;
330 filter->action.type = XkbSA_SetMods;
331 filter->func = xkb_filter_mod_set_func;
332 filter->state->base_mods |= filter->action.mods.mask;
334 filter->keycode = keycode;
335 filter->state->latched_mods &= ~filter->action.mods.mask;
339 else if (((1 << action->type) & XkbSA_BreakLatch)) {
340 /* XXX: This may be totally broken, we might need to break the
341 * latch in the next run after this press? */
342 filter->state->latched_mods &= ~filter->action.mods.mask;
347 else if (direction == XKB_KEY_UP && keycode == filter->keycode) {
348 /* Our key got released. If we've set it to clear locks, and we
349 * currently have the same modifiers locked, then release them and
350 * don't actually latch. Else we've actually hit the latching
351 * stage, so set PENDING and move our modifier from base to
353 if (latch == NO_LATCH ||
354 ((filter->action.mods.flags & XkbSA_ClearLocks) &&
355 (filter->state->locked_mods & filter->action.mods.mask) ==
356 filter->action.mods.mask)) {
357 /* XXX: We might be a bit overenthusiastic about clearing
358 * mods other filters have set here? */
359 if (latch == LATCH_PENDING)
360 filter->state->latched_mods &= ~filter->action.mods.mask;
362 filter->state->base_mods &= ~filter->action.mods.mask;
363 filter->state->locked_mods &= ~filter->action.mods.mask;
367 latch = LATCH_PENDING;
368 filter->state->base_mods &= ~filter->action.mods.mask;
369 filter->state->latched_mods |= filter->action.mods.mask;
373 else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
374 /* Someone's pressed another key while we've still got the latching
375 * key held down, so keep the base modifier state active (from
376 * xkb_filter_mod_latch_new), but don't trip the latch, just clear
377 * it as soon as the modifier gets released. */
381 filter->priv = latch;
387 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
388 union xkb_action *action)
390 struct xkb_filter *filter = xkb_filter_new(state);
391 enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
393 if (!filter) /* WSGO */
395 filter->keycode = keycode;
396 filter->priv = latch;
397 filter->func = xkb_filter_mod_latch_func;
398 filter->action = *action;
400 filter->state->base_mods |= action->mods.mask;
406 * Applies any relevant filters to the key, first from the list of filters
407 * that are currently active, then if no filter has claimed the key, possibly
408 * apply a new filter from the key action.
411 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
412 enum xkb_key_direction direction)
414 struct xkb_filter *filters = state->filters;
415 union xkb_action *act = NULL;
419 /* First run through all the currently active filters and see if any of
420 * them have claimed this event. */
421 for (i = 0; i < state->num_filters; i++) {
422 if (!filters[i].func)
424 send &= (*filters[i].func)(&filters[i], key, direction);
427 if (!send || direction == XKB_KEY_UP)
430 act = xkb_key_get_action(state, key);
433 send = xkb_filter_mod_set_new(state, key, act);
435 case XkbSA_LatchMods:
436 send = xkb_filter_mod_latch_new(state, key, act);
439 send = xkb_filter_mod_lock_new(state, key, act);
442 send = xkb_filter_group_set_new(state, key, act);
445 case XkbSA_LatchGroup:
446 send = xkb_filter_mod_latch_new(state, key, act);
449 case XkbSA_LockGroup:
450 send = xkb_filter_group_lock_new(state, key, act);
457 _X_EXPORT struct xkb_state *
458 xkb_state_new(struct xkb_keymap *xkb)
460 struct xkb_state *ret;
465 ret = calloc(sizeof(*ret), 1);
470 ret->xkb = xkb_map_ref(xkb);
475 _X_EXPORT struct xkb_state *
476 xkb_state_ref(struct xkb_state *state)
483 xkb_state_unref(struct xkb_state *state)
486 assert(state->refcnt >= 0);
487 if (state->refcnt > 0)
490 xkb_map_unref(state->xkb);
491 free(state->filters);
495 _X_EXPORT struct xkb_keymap *
496 xkb_state_get_map(struct xkb_state *state)
502 * Update the LED state to match the rest of the xkb_state.
505 xkb_state_led_update_all(struct xkb_state *state)
511 for (led = 0; led < XkbNumIndicators; led++) {
512 struct xkb_indicator_map *map = &state->xkb->indicators->maps[led];
513 uint32_t mod_mask = 0;
514 uint32_t group_mask = 0;
516 if (!map->which_mods && !map->which_groups && !map->ctrls)
519 if (map->which_mods) {
520 if (map->which_mods & XkbIM_UseBase)
521 mod_mask |= state->base_mods;
522 if (map->which_mods & XkbIM_UseLatched)
523 mod_mask |= state->latched_mods;
524 if (map->which_mods & XkbIM_UseLocked)
525 mod_mask |= state->locked_mods;
526 if (map->which_mods & XkbIM_UseEffective)
527 mod_mask |= state->mods;
528 if ((map->mods.mask & mod_mask))
529 state->leds |= (1 << led);
531 else if (map->which_groups) {
532 if (map->which_mods & XkbIM_UseBase)
533 group_mask |= (1 << state->base_group);
534 if (map->which_mods & XkbIM_UseLatched)
535 group_mask |= (1 << state->latched_group);
536 if (map->which_mods & XkbIM_UseLocked)
537 group_mask |= (1 << state->locked_group);
538 if (map->which_mods & XkbIM_UseEffective)
539 group_mask |= (1 << state->group);
540 if ((map->groups & group_mask))
541 state->leds |= (1 << led);
543 else if (map->ctrls) {
544 if ((map->ctrls & state->xkb->ctrls->enabled_ctrls))
545 state->leds |= (1 << led);
551 * Calculates the derived state (effective mods/group and LEDs) from an
552 * up-to-date xkb_state.
555 xkb_state_update_derived(struct xkb_state *state)
557 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
558 /* FIXME: Clamp/wrap locked_group */
559 state->group = state->locked_group + state->base_group +
560 state->latched_group;
561 /* FIXME: Clamp/wrap effective group */
563 xkb_state_led_update_all(state);
567 * Given a particular key event, updates the state structure to reflect the
571 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
572 enum xkb_key_direction direction)
574 xkb_filter_apply_all(state, key, direction);
575 xkb_state_update_derived(state);
579 * Updates the state from a set of explicit masks as gained from
580 * xkb_state_serialise_mods and xkb_state_serialise_groups. As noted in the
581 * documentation for these functions in xkbcommon.h, this round-trip is
582 * lossy, and should only be used to update a slave state mirroring the
583 * master, e.g. in a client/server window system.
586 xkb_state_update_mask(struct xkb_state *state,
587 xkb_mod_mask_t base_mods,
588 xkb_mod_mask_t latched_mods,
589 xkb_mod_mask_t locked_mods,
590 xkb_group_index_t base_group,
591 xkb_group_index_t latched_group,
592 xkb_group_index_t locked_group)
596 state->base_mods = 0;
597 state->latched_mods = 0;
598 state->locked_mods = 0;
599 for (mod = 0; mod < xkb_map_num_mods(state->xkb); mod++) {
600 xkb_mod_mask_t idx = (1 << mod);
602 state->base_mods |= idx;
603 if (latched_mods & idx)
604 state->latched_mods |= idx;
605 if (locked_mods & idx)
606 state->locked_mods |= idx;
609 state->base_group = base_group;
610 state->latched_group = latched_group;
611 state->locked_group = locked_group;
613 xkb_state_update_derived(state);
617 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
618 * the same disclaimers as in xkb_state_update_mask.
620 _X_EXPORT xkb_mod_mask_t
621 xkb_state_serialise_mods(struct xkb_state *state,
622 enum xkb_state_component type)
624 xkb_mod_mask_t ret = 0;
626 if (type == XKB_STATE_EFFECTIVE)
629 if (type & XKB_STATE_DEPRESSED)
630 ret |= state->base_mods;
631 if (type & XKB_STATE_LATCHED)
632 ret |= state->latched_mods;
633 if (type & XKB_STATE_LOCKED)
634 ret |= state->locked_mods;
640 * Serialises the requested group state, with all the same disclaimers as
641 * in xkb_state_update_mask.
643 _X_EXPORT xkb_group_index_t
644 xkb_state_serialise_group(struct xkb_state *state,
645 enum xkb_state_component type)
647 xkb_group_index_t ret = 0;
649 if (type == XKB_STATE_EFFECTIVE)
652 if (type & XKB_STATE_DEPRESSED)
653 ret += state->base_group;
654 if (type & XKB_STATE_LATCHED)
655 ret += state->latched_group;
656 if (type & XKB_STATE_LOCKED)
657 ret += state->locked_group;
663 * Returns 1 if the given modifier is active with the specified type(s), 0 if
664 * not, or -1 if the modifier is invalid.
667 xkb_state_mod_index_is_active(struct xkb_state *state,
669 enum xkb_state_component type)
673 if (idx >= xkb_map_num_mods(state->xkb))
676 if (type & XKB_STATE_DEPRESSED)
677 ret |= (state->base_mods & (1 << idx));
678 if (type & XKB_STATE_LATCHED)
679 ret |= (state->latched_mods & (1 << idx));
680 if (type & XKB_STATE_LOCKED)
681 ret |= (state->locked_mods & (1 << idx));
687 * Returns 1 if the given modifier is active with the specified type(s), 0 if
688 * not, or -1 if the modifier is invalid.
691 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
692 enum xkb_state_component type)
694 xkb_mod_index_t idx = xkb_map_mod_get_index(state->xkb, name);
696 if (idx == XKB_MOD_INVALID)
699 return xkb_state_mod_index_is_active(state, idx, type);
703 * Returns 1 if the given group is active with the specified type(s), 0 if
704 * not, or -1 if the group is invalid.
707 xkb_state_group_index_is_active(struct xkb_state *state,
708 xkb_group_index_t idx,
709 enum xkb_state_component type)
713 if (idx >= xkb_map_num_groups(state->xkb))
716 if (type & XKB_STATE_DEPRESSED)
717 ret |= (state->base_group == idx);
718 if (type & XKB_STATE_LATCHED)
719 ret |= (state->latched_group == idx);
720 if (type & XKB_STATE_LOCKED)
721 ret |= (state->locked_group == idx);
727 * Returns 1 if the given modifier is active with the specified type(s), 0 if
728 * not, or -1 if the modifier is invalid.
731 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
732 enum xkb_state_component type)
734 xkb_group_index_t idx = xkb_map_group_get_index(state->xkb, name);
736 if (idx == XKB_GROUP_INVALID)
739 return xkb_state_group_index_is_active(state, idx, type);
743 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
746 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
748 if (idx >= xkb_map_num_leds(state->xkb))
751 return !!(state->leds & (1 << idx));
755 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
758 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
760 xkb_led_index_t idx = xkb_map_led_get_index(state->xkb, name);
762 if (idx == XKB_LED_INVALID)
765 return xkb_state_led_index_is_active(state, idx);