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 #include "xkbcommon/xkbcommon.h"
68 #include "XKBcommonint.h"
71 struct xkb_state *state;
72 union xkb_action action;
73 xkb_keycode_t keycode;
75 int (*func)(struct xkb_filter *filter, xkb_keycode_t key, int down);
77 struct xkb_filter *next;
80 static union xkb_action *
81 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
85 if (!XkbKeyHasActions(state->xkb, key) ||
86 !XkbKeycodeInRange(state->xkb, key)) {
87 static union xkb_action fake;
88 memset(&fake, 0, sizeof(fake));
89 fake.type = XkbSA_NoAction;
93 group = xkb_key_get_group(state, key);
94 level = xkb_key_get_level(state, key, group);
96 return XkbKeyActionEntry(state->xkb, key, level, group);
99 static struct xkb_filter *
100 xkb_filter_new(struct xkb_state *state)
103 int old_size = state->num_filters;
104 struct xkb_filter *filters = state->filters;
106 for (i = 0; i < state->num_filters; i++) {
109 filters[i].state = state;
110 filters[i].refcnt = 1;
114 if (state->num_filters > 0)
115 state->num_filters *= 2;
117 state->num_filters = 4;
118 filters = realloc(filters, state->num_filters * sizeof(*filters));
119 if (!filters) { /* WSGO */
120 state->num_filters = old_size;
123 state->filters = filters;
124 memset(&filters[old_size], 0,
125 (state->num_filters - old_size) * sizeof(*filters));
127 filters[old_size].state = state;
128 filters[old_size].refcnt = 1;
130 return &filters[old_size];
133 /***====================================================================***/
136 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
139 if (keycode != filter->keycode) {
140 filter->action.group.flags &= ~XkbSA_ClearLocks;
148 else if (--filter->refcnt > 0) {
152 if (filter->action.group.flags & XkbSA_GroupAbsolute)
153 filter->state->base_group = filter->action.group.group;
155 filter->state->base_group = -filter->action.group.group;
156 if (filter->action.group.flags & XkbSA_ClearLocks)
157 filter->state->locked_group = 0;
165 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
166 union xkb_action *action)
168 struct xkb_filter *filter = xkb_filter_new(state);
170 if (!filter) /* WSGO */
172 filter->keycode = keycode;
173 filter->func = xkb_filter_group_set_func;
174 filter->action = *action;
176 if (action->group.flags & XkbSA_GroupAbsolute) {
177 filter->action.group.group = filter->state->base_group;
178 filter->state->base_group = action->group.group;
181 filter->state->base_group += action->group.group;
188 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
191 if (keycode != filter->keycode) {
192 filter->action.mods.flags &= ~XkbSA_ClearLocks;
200 else if (--filter->refcnt > 0) {
204 filter->state->base_mods &= ~(filter->action.mods.mask);
205 if (filter->action.mods.flags & XkbSA_ClearLocks)
206 filter->state->locked_mods &= ~filter->action.mods.mask;
214 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
215 union xkb_action *action)
217 struct xkb_filter *filter = xkb_filter_new(state);
219 if (!filter) /* WSGO */
221 filter->keycode = keycode;
222 filter->func = xkb_filter_mod_set_func;
223 filter->action = *action;
225 filter->state->base_mods |= action->mods.mask;
231 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
234 if (keycode != filter->keycode)
241 if (--filter->refcnt > 0)
244 filter->state->locked_mods &= ~filter->priv;
250 xkb_filter_mod_lock_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 */
258 filter->keycode = keycode;
259 filter->func = xkb_filter_mod_lock_func;
260 filter->action = *action;
261 filter->priv = state->locked_mods & action->mods.mask;
262 state->locked_mods |= action->mods.mask;
267 enum xkb_key_latch_state {
274 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
277 enum xkb_key_latch_state latch = filter->priv;
279 if (down && latch == LATCH_PENDING) {
280 /* If this is a new keypress and we're awaiting our single latched
281 * keypress, then either break the latch if any random key is pressed,
282 * or promote it to a lock or plain base set if it's the same
284 union xkb_action *action = xkb_key_get_action(filter->state, keycode);
285 if (action->type == XkbSA_LatchMods &&
286 action->mods.flags == filter->action.mods.flags &&
287 action->mods.mask == filter->action.mods.mask) {
288 filter->action = *action;
289 if (filter->action.mods.flags & XkbSA_LatchToLock) {
290 filter->action.type = XkbSA_LockMods;
291 filter->func = xkb_filter_mod_lock_func;
292 filter->state->locked_mods |= filter->action.mods.mask;
295 filter->action.type = XkbSA_SetMods;
296 filter->func = xkb_filter_mod_set_func;
297 filter->state->base_mods |= filter->action.mods.mask;
299 filter->keycode = keycode;
300 filter->state->latched_mods &= ~filter->action.mods.mask;
304 else if (((1 << action->type) & XkbSA_BreakLatch)) {
305 /* XXX: This may be totally broken, we might need to break the
306 * latch in the next run after this press? */
307 filter->state->latched_mods &= ~filter->action.mods.mask;
312 else if (!down && keycode == filter->keycode) {
313 /* Our key got released. If we've set it to clear locks, and we
314 * currently have the same modifiers locked, then release them and
315 * don't actually latch. Else we've actually hit the latching
316 * stage, so set PENDING and move our modifier from base to
318 if (latch == NO_LATCH ||
319 ((filter->action.mods.flags & XkbSA_ClearLocks) &&
320 (filter->state->locked_mods & filter->action.mods.mask) ==
321 filter->action.mods.mask)) {
322 /* XXX: We might be a bit overenthusiastic about clearing
323 * mods other filters have set here? */
324 if (latch == LATCH_PENDING)
325 filter->state->latched_mods &= ~filter->action.mods.mask;
327 filter->state->base_mods &= ~filter->action.mods.mask;
328 filter->state->locked_mods &= ~filter->action.mods.mask;
332 latch = LATCH_PENDING;
333 filter->state->base_mods &= ~filter->action.mods.mask;
334 filter->state->latched_mods |= filter->action.mods.mask;
338 else if (down && latch == LATCH_KEY_DOWN) {
339 /* Someone's pressed another key while we've still got the latching
340 * key held down, so keep the base modifier state active (from
341 * xkb_filter_mod_latch_new), but don't trip the latch, just clear
342 * it as soon as the modifier gets released. */
346 filter->priv = latch;
352 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
353 union xkb_action *action)
355 struct xkb_filter *filter = xkb_filter_new(state);
356 enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
358 if (!filter) /* WSGO */
360 filter->keycode = keycode;
361 filter->priv = latch;
362 filter->func = xkb_filter_mod_latch_func;
363 filter->action = *action;
365 filter->state->base_mods |= action->mods.mask;
371 * Applies any relevant filters to the key, first from the list of filters
372 * that are currently active, then if no filter has claimed the key, possibly
373 * apply a new filter from the key action.
376 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key, int down)
378 struct xkb_filter *filters = state->filters;
379 union xkb_action *act = NULL;
383 /* First run through all the currently active filters and see if any of
384 * them have claimed this event. */
385 for (i = 0; i < state->num_filters; i++) {
386 if (!filters[i].func)
388 send &= (*filters[i].func)(&filters[i], key, down);
394 act = xkb_key_get_action(state, key);
397 send = xkb_filter_mod_set_new(state, key, act);
399 case XkbSA_LatchMods:
400 send = xkb_filter_mod_latch_new(state, key, act);
403 send = xkb_filter_mod_lock_new(state, key, act);
406 send = xkb_filter_group_set_new(state, key, act);
409 case XkbSA_LatchGroup:
410 send = xkb_filter_mod_latch_new(state, key, act);
412 case XkbSA_LockGroup:
413 send = xkb_filter_group_lock_new(state, key, act);
422 xkb_state_new(struct xkb_desc *xkb)
424 struct xkb_state *ret;
429 ret = calloc(sizeof(*ret), 1);
441 xkb_state_unref(struct xkb_state *state)
444 assert(state->refcnt >= 0);
445 if (state->refcnt == 0)
448 xkb_map_unref(state->xkb);
453 * Update the LED state to match the rest of the xkb_state.
456 xkb_state_led_update_all(struct xkb_state *state)
462 for (led = 0; led < XkbNumIndicators; led++) {
463 struct xkb_indicator_map *map = &state->xkb->indicators->maps[led];
464 uint32_t mod_mask = 0;
465 uint32_t group_mask = 0;
467 if (!map->which_mods && !map->which_groups && !map->ctrls)
470 if (map->which_mods) {
471 if (map->which_mods & XkbIM_UseBase)
472 mod_mask |= state->base_mods;
473 if (map->which_mods & XkbIM_UseLatched)
474 mod_mask |= state->latched_mods;
475 if (map->which_mods & XkbIM_UseLocked)
476 mod_mask |= state->locked_mods;
477 if (map->which_mods & XkbIM_UseEffective)
478 mod_mask |= state->mods;
479 if ((map->mods.mask & mod_mask))
480 state->leds |= (1 << led);
482 else if (map->which_groups) {
483 if (map->which_mods & XkbIM_UseBase)
484 group_mask |= (1 << state->base_group);
485 if (map->which_mods & XkbIM_UseLatched)
486 group_mask |= (1 << state->latched_group);
487 if (map->which_mods & XkbIM_UseLocked)
488 group_mask |= (1 << state->locked_group);
489 if (map->which_mods & XkbIM_UseEffective)
490 group_mask |= (1 << state->group);
491 if ((map->groups & group_mask))
492 state->leds |= (1 << led);
494 else if (map->ctrls) {
495 if ((map->ctrls & state->xkb->ctrls->enabled_ctrls))
496 state->leds |= (1 << led);
502 * Calculates the derived state (effective mods/group and LEDs) from an
503 * up-to-date xkb_state.
506 xkb_state_update_derived(struct xkb_state *state)
508 state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
509 /* FIXME: Clamp/wrap locked_group */
510 state->group = state->locked_group + state->base_group +
511 state->latched_group;
512 /* FIXME: Clamp/wrap effective group */
514 xkb_state_led_update_all(state);
518 * Given a particular key event, updates the state structure to reflect the
522 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key, int down)
524 xkb_filter_apply_all(state, key, down);
525 xkb_state_update_derived(state);
529 * Updates the state from a set of explicit masks as gained from
530 * xkb_state_serialise_mods and xkb_state_serialise_groups. As noted in the
531 * documentation for these functions in xkbcommon.h, this round-trip is
532 * lossy, and should only be used to update a slave state mirroring the
533 * master, e.g. in a client/server window system.
536 xkb_state_update_mask(struct xkb_state *state,
537 xkb_mod_mask_t base_mods,
538 xkb_mod_mask_t latched_mods,
539 xkb_mod_mask_t locked_mods,
540 xkb_group_index_t base_group,
541 xkb_group_index_t latched_group,
542 xkb_group_index_t locked_group)
546 state->base_mods = 0;
547 state->latched_mods = 0;
548 state->locked_mods = 0;
549 for (mod = 0; mod < xkb_map_num_mods(state->xkb); mod++) {
550 xkb_mod_mask_t idx = (1 << mod);
552 state->base_mods |= idx;
553 if (latched_mods & idx)
554 state->latched_mods |= idx;
555 if (locked_mods & idx)
556 state->locked_mods |= idx;
559 state->base_group = base_group;
560 state->latched_group = latched_group;
561 state->locked_group = locked_group;
563 xkb_state_update_derived(state);
567 * Serialises the requested modifier state into an xkb_mod_mask_t, with all
568 * the same disclaimers as in xkb_state_update_mask.
571 xkb_state_serialise_mods(struct xkb_state *state,
572 enum xkb_state_component type)
574 xkb_mod_mask_t ret = 0;
576 if (type == XKB_STATE_EFFECTIVE)
579 if (type & XKB_STATE_DEPRESSED)
580 ret |= state->base_mods;
581 if (type & XKB_STATE_LATCHED)
582 ret |= state->latched_mods;
583 if (type & XKB_STATE_LOCKED)
584 ret |= state->locked_mods;
590 * Serialises the requested group state, with all the same disclaimers as
591 * in xkb_state_update_mask.
594 xkb_state_serialise_group(struct xkb_state *state,
595 enum xkb_state_component type)
597 xkb_group_index_t ret = 0;
599 if (type == XKB_STATE_EFFECTIVE)
602 if (type & XKB_STATE_DEPRESSED)
603 ret += state->base_group;
604 if (type & XKB_STATE_LATCHED)
605 ret += state->latched_group;
606 if (type & XKB_STATE_LOCKED)
607 ret += state->locked_group;
613 * Returns 1 if the given modifier is active with the specified type(s), 0 if
614 * not, or -1 if the modifier is invalid.
617 xkb_state_mod_index_is_active(struct xkb_state *state,
619 enum xkb_state_component type)
623 if (idx >= xkb_map_num_mods(state->xkb))
626 if (type & XKB_STATE_DEPRESSED)
627 ret |= (state->base_mods & (1 << idx));
628 if (type & XKB_STATE_LATCHED)
629 ret |= (state->latched_mods & (1 << idx));
630 if (type & XKB_STATE_LOCKED)
631 ret |= (state->locked_mods & (1 << idx));
637 * Returns 1 if the given modifier is active with the specified type(s), 0 if
638 * not, or -1 if the modifier is invalid.
641 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
642 enum xkb_state_component type)
644 xkb_mod_index_t idx = xkb_map_mod_get_index(state->xkb, name);
646 if (idx == XKB_MOD_INVALID)
649 return xkb_state_mod_index_is_active(state, idx, type);
653 * Returns 1 if the given group is active with the specified type(s), 0 if
654 * not, or -1 if the group is invalid.
657 xkb_state_group_index_is_active(struct xkb_state *state,
658 xkb_group_index_t idx,
659 enum xkb_state_component type)
663 if (idx >= xkb_map_num_groups(state->xkb))
666 if (type & XKB_STATE_DEPRESSED)
667 ret |= (state->base_group == idx);
668 if (type & XKB_STATE_LATCHED)
669 ret |= (state->latched_group == idx);
670 if (type & XKB_STATE_LOCKED)
671 ret |= (state->locked_group == idx);
677 * Returns 1 if the given modifier is active with the specified type(s), 0 if
678 * not, or -1 if the modifier is invalid.
681 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
682 enum xkb_state_component type)
684 xkb_group_index_t idx = xkb_map_group_get_index(state->xkb, name);
686 if (idx == XKB_GROUP_INVALID)
689 return xkb_state_group_index_is_active(state, idx, type);
693 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
696 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
698 if (idx >= xkb_map_num_leds(state->xkb))
701 return !!(state->leds & (1 << idx));
705 * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
708 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
710 xkb_led_index_t idx = xkb_map_led_get_index(state->xkb, name);
712 if (idx == XKB_LED_INVALID)
715 return xkb_state_led_index_is_active(state, idx);