state: rename state->cur to state->components
[platform/upstream/libxkbcommon.git] / src / state.c
1 /************************************************************
2  * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3  *
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.
15  *
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.
24  *
25  ********************************************************/
26
27 /*
28  * Copyright © 2012 Intel Corporation
29  * Copyright © 2012 Ran Benita <ran234@gmail.com>
30  *
31  * Permission is hereby granted, free of charge, to any person obtaining a
32  * copy of this software and associated documentation files (the "Software"),
33  * to deal in the Software without restriction, including without limitation
34  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35  * and/or sell copies of the Software, and to permit persons to whom the
36  * Software is furnished to do so, subject to the following conditions:
37  *
38  * The above copyright notice and this permission notice (including the next
39  * paragraph) shall be included in all copies or substantial portions of the
40  * Software.
41  *
42  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
45  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
47  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
48  * DEALINGS IN THE SOFTWARE.
49  *
50  * Author: Daniel Stone <daniel@fooishbar.org>
51  */
52
53 /*
54  * This is a bastardised version of xkbActions.c from the X server which
55  * does not support, for the moment:
56  *   - AccessX sticky/debounce/etc (will come later)
57  *   - pointer keys (may come later)
58  *   - key redirects (unlikely)
59  *   - messages (very unlikely)
60  */
61
62 #include "keymap.h"
63
64 struct xkb_filter {
65     union xkb_action action;
66     const struct xkb_key *key;
67     uint32_t priv;
68     int (*func)(struct xkb_state *state,
69                 struct xkb_filter *filter,
70                 const struct xkb_key *key,
71                 enum xkb_key_direction direction);
72     int refcnt;
73 };
74
75 struct state_components {
76     /* These may be negative, because of -1 group actions. */
77     int32_t base_group; /**< depressed */
78     int32_t latched_group;
79     int32_t locked_group;
80     xkb_layout_index_t group; /**< effective */
81
82     xkb_mod_mask_t base_mods; /**< depressed */
83     xkb_mod_mask_t latched_mods;
84     xkb_mod_mask_t locked_mods;
85     xkb_mod_mask_t mods; /**< effective */
86
87     xkb_led_mask_t leds;
88 };
89
90 struct xkb_state {
91     /*
92      * Before updating the state, we keep a copy of just this struct. This
93      * allows us to report which components of the state have changed.
94      */
95     struct state_components components;
96
97     /*
98      * At each event, we accumulate all the needed modifications to the base
99      * modifiers, and apply them at the end. These keep track of this state.
100      */
101     xkb_mod_mask_t set_mods;
102     xkb_mod_mask_t clear_mods;
103
104     /*
105      * We mustn't clear a base modifier if there's another depressed key
106      * which affects it, e.g. given this sequence
107      * < Left Shift down, Right Shift down, Left Shift Up >
108      * the modifier should still be set. This keeps the count.
109      */
110     int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8];
111
112     int refcnt;
113     darray(struct xkb_filter) filters;
114     struct xkb_keymap *keymap;
115 };
116
117 static const struct xkb_kt_map_entry *
118 get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key,
119                         xkb_layout_index_t group)
120 {
121     const struct xkb_key_type *type = key->groups[group].type;
122     xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask;
123     unsigned int i;
124
125     for (i = 0; i < type->num_entries; i++)
126         if (type->map[i].mods.mask == active_mods)
127             return &type->map[i];
128
129     return NULL;
130 }
131
132 /**
133  * Returns the level to use for the given key and state, or
134  * XKB_LEVEL_INVALID.
135  */
136 XKB_EXPORT xkb_level_index_t
137 xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
138                         xkb_layout_index_t layout)
139 {
140     const struct xkb_key *key = XkbKey(state->keymap, kc);
141     const struct xkb_kt_map_entry *entry;
142
143     if (!key || layout >= key->num_groups)
144         return XKB_LEVEL_INVALID;
145
146     /* If we don't find an explicit match the default is 0. */
147     entry = get_entry_for_key_state(state, key, layout);
148     if (!entry)
149         return 0;
150
151     return entry->level;
152 }
153
154 xkb_layout_index_t
155 wrap_group_into_range(int32_t group,
156                       xkb_layout_index_t num_groups,
157                       enum xkb_range_exceed_type out_of_range_group_action,
158                       xkb_layout_index_t out_of_range_group_number)
159 {
160     if (num_groups == 0)
161         return XKB_LAYOUT_INVALID;
162
163     if (group < num_groups)
164         return group;
165
166     switch (out_of_range_group_action) {
167     case RANGE_REDIRECT:
168         if (out_of_range_group_number >= num_groups)
169             return 0;
170         return out_of_range_group_number;
171
172     case RANGE_SATURATE:
173         if (group < 0)
174             return 0;
175         else
176             return num_groups - 1;
177
178     case RANGE_WRAP:
179     default:
180         /*
181          * C99 says a negative dividend in a modulo operation always
182          * gives a negative result.
183          */
184         if (group < 0)
185             return ((int) num_groups + (group % (int) num_groups));
186         else
187             return group % num_groups;
188     }
189 }
190
191 /**
192  * Returns the layout to use for the given key and state, taking
193  * wrapping/clamping/etc into account, or XKB_LAYOUT_INVALID.
194  */
195 XKB_EXPORT xkb_layout_index_t
196 xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
197 {
198     const struct xkb_key *key = XkbKey(state->keymap, kc);
199
200     if (!key)
201         return XKB_LAYOUT_INVALID;
202
203     return wrap_group_into_range(state->components.group, key->num_groups,
204                                  key->out_of_range_group_action,
205                                  key->out_of_range_group_number);
206 }
207
208 static const union xkb_action fake = { .type = ACTION_TYPE_NONE };
209
210 static const union xkb_action *
211 xkb_key_get_action(struct xkb_state *state, const struct xkb_key *key)
212 {
213     xkb_layout_index_t layout;
214     xkb_level_index_t level;
215
216     layout = xkb_state_key_get_layout(state, key->keycode);
217     if (layout == XKB_LAYOUT_INVALID)
218         return &fake;
219
220     level = xkb_state_key_get_level(state, key->keycode, layout);
221     if (level == XKB_LEVEL_INVALID)
222         return &fake;
223
224     return &key->groups[layout].levels[level].action;
225 }
226
227 static struct xkb_filter *
228 xkb_filter_new(struct xkb_state *state)
229 {
230     struct xkb_filter *filter = NULL, *iter;
231
232     darray_foreach(iter, state->filters) {
233         if (iter->func)
234             continue;
235         filter = iter;
236         break;
237     }
238
239     if (!filter) {
240         darray_resize0(state->filters, darray_size(state->filters) + 1);
241         filter = &darray_item(state->filters, darray_size(state->filters) -1);
242     }
243
244     filter->refcnt = 1;
245     return filter;
246 }
247
248 /***====================================================================***/
249
250 static int
251 xkb_filter_group_set_func(struct xkb_state *state,
252                           struct xkb_filter *filter,
253                           const struct xkb_key *key,
254                           enum xkb_key_direction direction)
255 {
256     if (key != filter->key) {
257         filter->action.group.flags &= ~ACTION_LOCK_CLEAR;
258         return 1;
259     }
260
261     if (direction == XKB_KEY_DOWN) {
262         filter->refcnt++;
263         return 0;
264     }
265     else if (--filter->refcnt > 0) {
266         return 0;
267     }
268
269     state->components.base_group = filter->priv;
270
271     if (filter->action.group.flags & ACTION_LOCK_CLEAR)
272         state->components.locked_group = 0;
273
274     filter->func = NULL;
275     return 1;
276 }
277
278 static void
279 xkb_filter_group_set_new(struct xkb_state *state, struct xkb_filter *filter)
280 {
281     filter->priv = state->components.base_group;
282     if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH)
283         state->components.base_group = filter->action.group.group;
284     else
285         state->components.base_group += filter->action.group.group;
286 }
287
288 static int
289 xkb_filter_group_lock_func(struct xkb_state *state,
290                            struct xkb_filter *filter,
291                            const struct xkb_key *key,
292                            enum xkb_key_direction direction)
293 {
294     if (key != filter->key)
295         return 1;
296
297     if (direction == XKB_KEY_DOWN) {
298         filter->refcnt++;
299         return 0;
300     }
301     if (--filter->refcnt > 0)
302         return 0;
303
304     filter->func = NULL;
305     return 1;
306 }
307
308 static void
309 xkb_filter_group_lock_new(struct xkb_state *state, struct xkb_filter *filter)
310 {
311     if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH)
312         state->components.locked_group = filter->action.group.group;
313     else
314         state->components.locked_group += filter->action.group.group;
315 }
316
317 static int
318 xkb_filter_mod_set_func(struct xkb_state *state,
319                         struct xkb_filter *filter,
320                         const struct xkb_key *key,
321                         enum xkb_key_direction direction)
322 {
323     if (key != filter->key) {
324         filter->action.mods.flags &= ~ACTION_LOCK_CLEAR;
325         return 1;
326     }
327
328     if (direction == XKB_KEY_DOWN) {
329         filter->refcnt++;
330         return 0;
331     }
332     else if (--filter->refcnt > 0) {
333         return 0;
334     }
335
336     state->clear_mods = filter->action.mods.mods.mask;
337     if (filter->action.mods.flags & ACTION_LOCK_CLEAR)
338         state->components.locked_mods &= ~filter->action.mods.mods.mask;
339
340     filter->func = NULL;
341     return 1;
342 }
343
344 static void
345 xkb_filter_mod_set_new(struct xkb_state *state, struct xkb_filter *filter)
346 {
347     state->set_mods = filter->action.mods.mods.mask;
348 }
349
350 static int
351 xkb_filter_mod_lock_func(struct xkb_state *state,
352                          struct xkb_filter *filter,
353                          const struct xkb_key *key,
354                          enum xkb_key_direction direction)
355 {
356     if (key != filter->key)
357         return 1;
358
359     if (direction == XKB_KEY_DOWN) {
360         filter->refcnt++;
361         return 0;
362     }
363     if (--filter->refcnt > 0)
364         return 0;
365
366     state->clear_mods |= filter->action.mods.mods.mask;
367     if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK))
368         state->components.locked_mods &= ~filter->priv;
369
370     filter->func = NULL;
371     return 1;
372 }
373
374 static void
375 xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_filter *filter)
376 {
377     filter->priv = (state->components.locked_mods &
378                     filter->action.mods.mods.mask);
379     state->set_mods |= filter->action.mods.mods.mask;
380     if (!(filter->action.mods.flags & ACTION_LOCK_NO_LOCK))
381         state->components.locked_mods |= filter->action.mods.mods.mask;
382 }
383
384 enum xkb_key_latch_state {
385     NO_LATCH,
386     LATCH_KEY_DOWN,
387     LATCH_PENDING,
388 };
389
390 static bool
391 xkb_action_breaks_latch(const union xkb_action *action)
392 {
393     switch (action->type) {
394     case ACTION_TYPE_NONE:
395     case ACTION_TYPE_PTR_BUTTON:
396     case ACTION_TYPE_PTR_LOCK:
397     case ACTION_TYPE_CTRL_SET:
398     case ACTION_TYPE_CTRL_LOCK:
399     case ACTION_TYPE_KEY_REDIRECT:
400     case ACTION_TYPE_SWITCH_VT:
401     case ACTION_TYPE_TERMINATE:
402         return true;
403     default:
404         return false;
405     }
406 }
407
408 static int
409 xkb_filter_mod_latch_func(struct xkb_state *state,
410                           struct xkb_filter *filter,
411                           const struct xkb_key *key,
412                           enum xkb_key_direction direction)
413 {
414     enum xkb_key_latch_state latch = filter->priv;
415
416     if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
417         /* If this is a new keypress and we're awaiting our single latched
418          * keypress, then either break the latch if any random key is pressed,
419          * or promote it to a lock or plain base set if it's the same
420          * modifier. */
421         const union xkb_action *action = xkb_key_get_action(state, key);
422         if (action->type == ACTION_TYPE_MOD_LATCH &&
423             action->mods.flags == filter->action.mods.flags &&
424             action->mods.mods.mask == filter->action.mods.mods.mask) {
425             filter->action = *action;
426             if (filter->action.mods.flags & ACTION_LATCH_TO_LOCK) {
427                 filter->action.type = ACTION_TYPE_MOD_LOCK;
428                 filter->func = xkb_filter_mod_lock_func;
429                 state->components.locked_mods |= filter->action.mods.mods.mask;
430             }
431             else {
432                 filter->action.type = ACTION_TYPE_MOD_SET;
433                 filter->func = xkb_filter_mod_set_func;
434                 state->set_mods = filter->action.mods.mods.mask;
435             }
436             filter->key = key;
437             state->components.latched_mods &= ~filter->action.mods.mods.mask;
438             /* XXX beep beep! */
439             return 0;
440         }
441         else if (xkb_action_breaks_latch(action)) {
442             /* XXX: This may be totally broken, we might need to break the
443              *      latch in the next run after this press? */
444             state->components.latched_mods &= ~filter->action.mods.mods.mask;
445             filter->func = NULL;
446             return 1;
447         }
448     }
449     else if (direction == XKB_KEY_UP && key == filter->key) {
450         /* Our key got released.  If we've set it to clear locks, and we
451          * currently have the same modifiers locked, then release them and
452          * don't actually latch.  Else we've actually hit the latching
453          * stage, so set PENDING and move our modifier from base to
454          * latched. */
455         if (latch == NO_LATCH ||
456             ((filter->action.mods.flags & ACTION_LOCK_CLEAR) &&
457              (state->components.locked_mods & filter->action.mods.mods.mask) ==
458              filter->action.mods.mods.mask)) {
459             /* XXX: We might be a bit overenthusiastic about clearing
460              *      mods other filters have set here? */
461             if (latch == LATCH_PENDING)
462                 state->components.latched_mods &=
463                     ~filter->action.mods.mods.mask;
464             else
465                 state->clear_mods = filter->action.mods.mods.mask;
466             state->components.locked_mods &= ~filter->action.mods.mods.mask;
467             filter->func = NULL;
468         }
469         else {
470             latch = LATCH_PENDING;
471             state->clear_mods = filter->action.mods.mods.mask;
472             state->components.latched_mods |= filter->action.mods.mods.mask;
473             /* XXX beep beep! */
474         }
475     }
476     else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
477         /* Someone's pressed another key while we've still got the latching
478          * key held down, so keep the base modifier state active (from
479          * xkb_filter_mod_latch_new), but don't trip the latch, just clear
480          * it as soon as the modifier gets released. */
481         latch = NO_LATCH;
482     }
483
484     filter->priv = latch;
485
486     return 1;
487 }
488
489 static void
490 xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_filter *filter)
491 {
492     filter->priv = LATCH_KEY_DOWN;
493     state->set_mods = filter->action.mods.mods.mask;
494 }
495
496 static const struct {
497     void (*new)(struct xkb_state *state, struct xkb_filter *filter);
498     int (*func)(struct xkb_state *state, struct xkb_filter *filter,
499                 const struct xkb_key *key, enum xkb_key_direction direction);
500 } filter_action_funcs[_ACTION_TYPE_NUM_ENTRIES] = {
501     [ACTION_TYPE_MOD_SET]    = { xkb_filter_mod_set_new,
502                                  xkb_filter_mod_set_func },
503     [ACTION_TYPE_MOD_LATCH]  = { xkb_filter_mod_latch_new,
504                                  xkb_filter_mod_latch_func },
505     [ACTION_TYPE_MOD_LOCK]   = { xkb_filter_mod_lock_new,
506                                  xkb_filter_mod_lock_func },
507     [ACTION_TYPE_GROUP_SET]  = { xkb_filter_group_set_new,
508                                  xkb_filter_group_set_func },
509     [ACTION_TYPE_GROUP_LOCK] = { xkb_filter_group_lock_new,
510                                  xkb_filter_group_lock_func },
511 };
512
513 /**
514  * Applies any relevant filters to the key, first from the list of filters
515  * that are currently active, then if no filter has claimed the key, possibly
516  * apply a new filter from the key action.
517  */
518 static void
519 xkb_filter_apply_all(struct xkb_state *state,
520                      const struct xkb_key *key,
521                      enum xkb_key_direction direction)
522 {
523     struct xkb_filter *filter;
524     const union xkb_action *action;
525     int send = 1;
526
527     /* First run through all the currently active filters and see if any of
528      * them have claimed this event. */
529     darray_foreach(filter, state->filters) {
530         if (!filter->func)
531             continue;
532         send &= filter->func(state, filter, key, direction);
533     }
534
535     if (!send || direction == XKB_KEY_UP)
536         return;
537
538     action = xkb_key_get_action(state, key);
539
540     /*
541      * It's possible for the keymap to set action->type explicitly, like so:
542      *     interpret XF86_Next_VMode {
543      *         action = Private(type=0x86, data="+VMode");
544      *     };
545      * We don't handle those.
546      */
547     if (action->type >= _ACTION_TYPE_NUM_ENTRIES)
548         return;
549
550     if (!filter_action_funcs[action->type].new)
551         return;
552
553     filter = xkb_filter_new(state);
554     if (!filter)
555         return; /* WSGO */
556
557     filter->key = key;
558     filter->func = filter_action_funcs[action->type].func;
559     filter->action = *action;
560     filter_action_funcs[action->type].new(state, filter);
561 }
562
563 XKB_EXPORT struct xkb_state *
564 xkb_state_new(struct xkb_keymap *keymap)
565 {
566     struct xkb_state *ret;
567
568     ret = calloc(sizeof(*ret), 1);
569     if (!ret)
570         return NULL;
571
572     ret->refcnt = 1;
573     ret->keymap = xkb_keymap_ref(keymap);
574
575     return ret;
576 }
577
578 XKB_EXPORT struct xkb_state *
579 xkb_state_ref(struct xkb_state *state)
580 {
581     state->refcnt++;
582     return state;
583 }
584
585 XKB_EXPORT void
586 xkb_state_unref(struct xkb_state *state)
587 {
588     if (!state || --state->refcnt > 0)
589         return;
590
591     xkb_keymap_unref(state->keymap);
592     darray_free(state->filters);
593     free(state);
594 }
595
596 XKB_EXPORT struct xkb_keymap *
597 xkb_state_get_keymap(struct xkb_state *state)
598 {
599     return state->keymap;
600 }
601
602 /**
603  * Update the LED state to match the rest of the xkb_state.
604  */
605 static void
606 xkb_state_led_update_all(struct xkb_state *state)
607 {
608     xkb_led_index_t led;
609     const struct xkb_indicator_map *map;
610
611     state->components.leds = 0;
612
613     darray_enumerate(led, map, state->keymap->indicators) {
614         xkb_mod_mask_t mod_mask = 0;
615         xkb_layout_mask_t group_mask = 0;
616
617         if (map->which_mods & XKB_STATE_MODS_EFFECTIVE)
618             mod_mask |= state->components.mods;
619         if (map->which_mods & XKB_STATE_MODS_DEPRESSED)
620             mod_mask |= state->components.base_mods;
621         if (map->which_mods & XKB_STATE_MODS_LATCHED)
622             mod_mask |= state->components.latched_mods;
623         if (map->which_mods & XKB_STATE_MODS_LOCKED)
624             mod_mask |= state->components.locked_mods;
625         if (map->mods.mask & mod_mask)
626             state->components.leds |= (1 << led);
627
628         if (map->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
629             group_mask |= (1 << state->components.group);
630         if (map->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
631             group_mask |= (1 << state->components.base_group);
632         if (map->which_groups & XKB_STATE_LAYOUT_LATCHED)
633             group_mask |= (1 << state->components.latched_group);
634         if (map->which_groups & XKB_STATE_LAYOUT_LOCKED)
635             group_mask |= (1 << state->components.locked_group);
636         if (map->groups & group_mask)
637             state->components.leds |= (1 << led);
638
639         if (map->ctrls & state->keymap->enabled_ctrls)
640             state->components.leds |= (1 << led);
641     }
642 }
643
644 /**
645  * Calculates the derived state (effective mods/group and LEDs) from an
646  * up-to-date xkb_state.
647  */
648 static void
649 xkb_state_update_derived(struct xkb_state *state)
650 {
651     state->components.mods = (state->components.base_mods |
652                        state->components.latched_mods |
653                        state->components.locked_mods);
654
655     /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */
656
657     state->components.locked_group = wrap_group_into_range(state->components.locked_group,
658                                                     state->keymap->num_groups,
659                                                     RANGE_WRAP, 0);
660
661     state->components.group = wrap_group_into_range(state->components.base_group +
662                                              state->components.latched_group +
663                                              state->components.locked_group,
664                                              state->keymap->num_groups,
665                                              RANGE_WRAP, 0);
666
667     xkb_state_led_update_all(state);
668 }
669
670 static enum xkb_state_component
671 get_state_component_changes(const struct state_components *a,
672                             const struct state_components *b)
673 {
674     xkb_mod_mask_t mask = 0;
675
676     if (a->group != b->group)
677         mask |= XKB_STATE_LAYOUT_EFFECTIVE;
678     if (a->base_group != b->base_group)
679         mask |= XKB_STATE_LAYOUT_DEPRESSED;
680     if (a->latched_group != b->latched_group)
681         mask |= XKB_STATE_LAYOUT_LATCHED;
682     if (a->locked_group != b->locked_group)
683         mask |= XKB_STATE_LAYOUT_LOCKED;
684     if (a->mods != b->mods)
685         mask |= XKB_STATE_MODS_EFFECTIVE;
686     if (a->base_mods != b->base_mods)
687         mask |= XKB_STATE_MODS_DEPRESSED;
688     if (a->latched_mods != b->latched_mods)
689         mask |= XKB_STATE_MODS_LATCHED;
690     if (a->locked_mods != b->locked_mods)
691         mask |= XKB_STATE_MODS_LOCKED;
692     if (a->leds != b->leds)
693         mask |= XKB_STATE_LEDS;
694
695     return mask;
696 }
697
698 /**
699  * Given a particular key event, updates the state structure to reflect the
700  * new modifiers.
701  */
702 XKB_EXPORT enum xkb_state_component
703 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc,
704                      enum xkb_key_direction direction)
705 {
706     xkb_mod_index_t i;
707     xkb_mod_mask_t bit;
708     struct state_components prev_components;
709     const struct xkb_key *key = XkbKey(state->keymap, kc);
710
711     if (!key)
712         return 0;
713
714     prev_components = state->components;
715
716     state->set_mods = 0;
717     state->clear_mods = 0;
718
719     xkb_filter_apply_all(state, key, direction);
720
721     for (i = 0, bit = 1; state->set_mods; i++, bit <<= 1) {
722         if (state->set_mods & bit) {
723             state->mod_key_count[i]++;
724             state->components.base_mods |= bit;
725             state->set_mods &= ~bit;
726         }
727     }
728
729     for (i = 0, bit = 1; state->clear_mods; i++, bit <<= 1) {
730         if (state->clear_mods & bit) {
731             state->mod_key_count[i]--;
732             if (state->mod_key_count[i] <= 0) {
733                 state->components.base_mods &= ~bit;
734                 state->mod_key_count[i] = 0;
735             }
736             state->clear_mods &= ~bit;
737         }
738     }
739
740     xkb_state_update_derived(state);
741
742     return get_state_component_changes(&prev_components, &state->components);
743 }
744
745 /**
746  * Updates the state from a set of explicit masks as gained from
747  * xkb_state_serialize_mods and xkb_state_serialize_groups.  As noted in the
748  * documentation for these functions in xkbcommon.h, this round-trip is
749  * lossy, and should only be used to update a slave state mirroring the
750  * master, e.g. in a client/server window system.
751  */
752 XKB_EXPORT enum xkb_state_component
753 xkb_state_update_mask(struct xkb_state *state,
754                       xkb_mod_mask_t base_mods,
755                       xkb_mod_mask_t latched_mods,
756                       xkb_mod_mask_t locked_mods,
757                       xkb_layout_index_t base_group,
758                       xkb_layout_index_t latched_group,
759                       xkb_layout_index_t locked_group)
760 {
761     struct state_components prev_components;
762     xkb_mod_index_t num_mods;
763     xkb_mod_index_t idx;
764
765     prev_components = state->components;
766
767     state->components.base_mods = 0;
768     state->components.latched_mods = 0;
769     state->components.locked_mods = 0;
770     num_mods = xkb_keymap_num_mods(state->keymap);
771
772     for (idx = 0; idx < num_mods; idx++) {
773         xkb_mod_mask_t mod = (1 << idx);
774         if (base_mods & mod)
775             state->components.base_mods |= mod;
776         if (latched_mods & mod)
777             state->components.latched_mods |= mod;
778         if (locked_mods & mod)
779             state->components.locked_mods |= mod;
780     }
781
782     state->components.base_group = base_group;
783     state->components.latched_group = latched_group;
784     state->components.locked_group = locked_group;
785
786     xkb_state_update_derived(state);
787
788     return get_state_component_changes(&prev_components, &state->components);
789 }
790
791 /**
792  * Provides the symbols to use for the given key and state.  Returns the
793  * number of symbols pointed to in syms_out.
794  */
795 XKB_EXPORT int
796 xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t kc,
797                        const xkb_keysym_t **syms_out)
798 {
799     xkb_layout_index_t layout;
800     xkb_level_index_t level;
801
802     layout = xkb_state_key_get_layout(state, kc);
803     if (layout == XKB_LAYOUT_INVALID)
804         goto err;
805
806     level = xkb_state_key_get_level(state, kc, layout);
807     if (level == XKB_LEVEL_INVALID)
808         goto err;
809
810     return xkb_keymap_key_get_syms_by_level(state->keymap, kc, layout, level,
811                                             syms_out);
812
813 err:
814     *syms_out = NULL;
815     return 0;
816 }
817
818 /**
819  * Provides either exactly one symbol, or XKB_KEY_NoSymbol.
820  */
821 XKB_EXPORT xkb_keysym_t
822 xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
823 {
824     const xkb_keysym_t *syms;
825     int num_syms;
826
827     num_syms = xkb_state_key_get_syms(state, kc, &syms);
828     if (num_syms != 1)
829         return XKB_KEY_NoSymbol;
830
831     return syms[0];
832 }
833
834 /**
835  * Serialises the requested modifier state into an xkb_mod_mask_t, with all
836  * the same disclaimers as in xkb_state_update_mask.
837  */
838 XKB_EXPORT xkb_mod_mask_t
839 xkb_state_serialize_mods(struct xkb_state *state,
840                          enum xkb_state_component type)
841 {
842     xkb_mod_mask_t ret = 0;
843
844     if (type & XKB_STATE_MODS_EFFECTIVE)
845         return state->components.mods;
846
847     if (type & XKB_STATE_MODS_DEPRESSED)
848         ret |= state->components.base_mods;
849     if (type & XKB_STATE_MODS_LATCHED)
850         ret |= state->components.latched_mods;
851     if (type & XKB_STATE_MODS_LOCKED)
852         ret |= state->components.locked_mods;
853
854     return ret;
855 }
856
857 /**
858  * Serialises the requested group state, with all the same disclaimers as
859  * in xkb_state_update_mask.
860  */
861 XKB_EXPORT xkb_layout_index_t
862 xkb_state_serialize_layout(struct xkb_state *state,
863                            enum xkb_state_component type)
864 {
865     xkb_layout_index_t ret = 0;
866
867     if (type & XKB_STATE_LAYOUT_EFFECTIVE)
868         return state->components.group;
869
870     if (type & XKB_STATE_LAYOUT_DEPRESSED)
871         ret += state->components.base_group;
872     if (type & XKB_STATE_LAYOUT_LATCHED)
873         ret += state->components.latched_group;
874     if (type & XKB_STATE_LAYOUT_LOCKED)
875         ret += state->components.locked_group;
876
877     return ret;
878 }
879
880 /**
881  * Returns 1 if the given modifier is active with the specified type(s), 0 if
882  * not, or -1 if the modifier is invalid.
883  */
884 XKB_EXPORT int
885 xkb_state_mod_index_is_active(struct xkb_state *state,
886                               xkb_mod_index_t idx,
887                               enum xkb_state_component type)
888 {
889     if (idx >= xkb_keymap_num_mods(state->keymap))
890         return -1;
891
892     return !!(xkb_state_serialize_mods(state, type) & (1 << idx));
893 }
894
895 /**
896  * Helper function for xkb_state_mod_indices_are_active and
897  * xkb_state_mod_names_are_active.
898  */
899 static int
900 match_mod_masks(struct xkb_state *state,
901                 enum xkb_state_component type,
902                 enum xkb_state_match match,
903                 xkb_mod_mask_t wanted)
904 {
905     xkb_mod_mask_t active = xkb_state_serialize_mods(state, type);
906
907     if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
908         return 0;
909
910     if (match & XKB_STATE_MATCH_ANY)
911         return !!(active & wanted);
912     else
913         return (active & wanted) == wanted;
914
915     return 0;
916 }
917
918 /**
919  * Returns 1 if the modifiers are active with the specified type(s), 0 if
920  * not, or -1 if any of the modifiers are invalid.
921  */
922 XKB_EXPORT int
923 xkb_state_mod_indices_are_active(struct xkb_state *state,
924                                  enum xkb_state_component type,
925                                  enum xkb_state_match match,
926                                  ...)
927 {
928     va_list ap;
929     xkb_mod_index_t idx = 0;
930     xkb_mod_mask_t wanted = 0;
931     int ret = 0;
932     xkb_mod_index_t num_mods = xkb_keymap_num_mods(state->keymap);
933
934     va_start(ap, match);
935     while (1) {
936         idx = va_arg(ap, xkb_mod_index_t);
937         if (idx == XKB_MOD_INVALID)
938             break;
939         if (idx >= num_mods) {
940             ret = -1;
941             break;
942         }
943         wanted |= (1 << idx);
944     }
945     va_end(ap);
946
947     if (ret == -1)
948         return ret;
949
950     return match_mod_masks(state, type, match, wanted);
951 }
952
953 /**
954  * Returns 1 if the given modifier is active with the specified type(s), 0 if
955  * not, or -1 if the modifier is invalid.
956  */
957 XKB_EXPORT int
958 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
959                              enum xkb_state_component type)
960 {
961     xkb_mod_index_t idx = xkb_keymap_mod_get_index(state->keymap, name);
962
963     if (idx == XKB_MOD_INVALID)
964         return -1;
965
966     return xkb_state_mod_index_is_active(state, idx, type);
967 }
968
969 /**
970  * Returns 1 if the modifiers are active with the specified type(s), 0 if
971  * not, or -1 if any of the modifiers are invalid.
972  */
973 XKB_EXPORT ATTR_NULL_SENTINEL int
974 xkb_state_mod_names_are_active(struct xkb_state *state,
975                                enum xkb_state_component type,
976                                enum xkb_state_match match,
977                                ...)
978 {
979     va_list ap;
980     xkb_mod_index_t idx = 0;
981     const char *str;
982     xkb_mod_mask_t wanted = 0;
983     int ret = 0;
984
985     va_start(ap, match);
986     while (1) {
987         str = va_arg(ap, const char *);
988         if (str == NULL)
989             break;
990         idx = xkb_keymap_mod_get_index(state->keymap, str);
991         if (idx == XKB_MOD_INVALID) {
992             ret = -1;
993             break;
994         }
995         wanted |= (1 << idx);
996     }
997     va_end(ap);
998
999     if (ret == -1)
1000         return ret;
1001
1002     return match_mod_masks(state, type, match, wanted);
1003 }
1004
1005 /**
1006  * Returns 1 if the given group is active with the specified type(s), 0 if
1007  * not, or -1 if the group is invalid.
1008  */
1009 XKB_EXPORT int
1010 xkb_state_layout_index_is_active(struct xkb_state *state,
1011                                 xkb_layout_index_t idx,
1012                                 enum xkb_state_component type)
1013 {
1014     int ret = 0;
1015
1016     if (idx >= state->keymap->num_groups)
1017         return -1;
1018
1019     if (type & XKB_STATE_LAYOUT_EFFECTIVE)
1020         ret |= (state->components.group == idx);
1021     if (type & XKB_STATE_LAYOUT_DEPRESSED)
1022         ret |= (state->components.base_group == idx);
1023     if (type & XKB_STATE_LAYOUT_LATCHED)
1024         ret |= (state->components.latched_group == idx);
1025     if (type & XKB_STATE_LAYOUT_LOCKED)
1026         ret |= (state->components.locked_group == idx);
1027
1028     return ret;
1029 }
1030
1031 /**
1032  * Returns 1 if the given modifier is active with the specified type(s), 0 if
1033  * not, or -1 if the modifier is invalid.
1034  */
1035 XKB_EXPORT int
1036 xkb_state_layout_name_is_active(struct xkb_state *state, const char *name,
1037                                 enum xkb_state_component type)
1038 {
1039     xkb_layout_index_t idx = xkb_keymap_layout_get_index(state->keymap, name);
1040
1041     if (idx == XKB_LAYOUT_INVALID)
1042         return -1;
1043
1044     return xkb_state_layout_index_is_active(state, idx, type);
1045 }
1046
1047 /**
1048  * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
1049  */
1050 XKB_EXPORT int
1051 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
1052 {
1053     if (idx >= darray_size(state->keymap->indicators) ||
1054         darray_item(state->keymap->indicators, idx).name == XKB_ATOM_NONE)
1055         return -1;
1056
1057     return !!(state->components.leds & (1 << idx));
1058 }
1059
1060 /**
1061  * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
1062  */
1063 XKB_EXPORT int
1064 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
1065 {
1066     xkb_led_index_t idx = xkb_keymap_led_get_index(state->keymap, name);
1067
1068     if (idx == XKB_LED_INVALID)
1069         return -1;
1070
1071     return xkb_state_led_index_is_active(state, idx);
1072 }
1073
1074 static xkb_mod_mask_t
1075 key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
1076 {
1077     const struct xkb_kt_map_entry *entry;
1078     xkb_layout_index_t group;
1079
1080     group = xkb_state_key_get_layout(state, key->keycode);
1081     if (group == XKB_LAYOUT_INVALID)
1082         return 0;
1083
1084     entry = get_entry_for_key_state(state, key, group);
1085     if (!entry)
1086         return 0;
1087
1088     return entry->mods.mask & ~entry->preserve.mask;
1089 }
1090
1091 /**
1092  * Tests to see if a modifier is used up by our translation of a
1093  * keycode to keysyms, taking note of the current modifier state and
1094  * the appropriate key type's preserve information, if any. This allows
1095  * the user to mask out the modifier in later processing of the
1096  * modifiers, e.g. when implementing hot keys or accelerators.
1097  *
1098  * See also, for example:
1099  * - XkbTranslateKeyCode(3), mod_rtrn retrun value, from libX11.
1100  * - gdk_keymap_translate_keyboard_state, consumed_modifiers return value,
1101  *   from gtk+.
1102  */
1103 XKB_EXPORT int
1104 xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
1105                                 xkb_mod_index_t idx)
1106 {
1107     const struct xkb_key *key = XkbKey(state->keymap, kc);
1108
1109     if (!key || idx >= xkb_keymap_num_mods(state->keymap))
1110         return -1;
1111
1112     return !!((1 << idx) & key_get_consumed(state, key));
1113 }
1114
1115 /**
1116  * Calculates which modifiers should be consumed during key processing,
1117  * and returns the mask with all these modifiers removed.  e.g. if
1118  * given a state of Alt and Shift active for a two-level alphabetic
1119  * key containing plus and equal on the first and second level
1120  * respectively, will return a mask of only Alt, as Shift has been
1121  * consumed by the type handling.
1122  */
1123 XKB_EXPORT xkb_mod_mask_t
1124 xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
1125                                    xkb_mod_mask_t mask)
1126 {
1127     const struct xkb_key *key = XkbKey(state->keymap, kc);
1128
1129     if (!key)
1130         return 0;
1131
1132     return mask & ~key_get_consumed(state, key);
1133 }