Home | History | Annotate | Download | only in src
      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 (at) 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 (at) 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 #include "keysym.h"
     64 #include "utf8.h"
     65 
     66 struct xkb_filter {
     67     union xkb_action action;
     68     const struct xkb_key *key;
     69     uint32_t priv;
     70     bool (*func)(struct xkb_state *state,
     71                  struct xkb_filter *filter,
     72                  const struct xkb_key *key,
     73                  enum xkb_key_direction direction);
     74     int refcnt;
     75 };
     76 
     77 struct state_components {
     78     /* These may be negative, because of -1 group actions. */
     79     int32_t base_group; /**< depressed */
     80     int32_t latched_group;
     81     int32_t locked_group;
     82     xkb_layout_index_t group; /**< effective */
     83 
     84     xkb_mod_mask_t base_mods; /**< depressed */
     85     xkb_mod_mask_t latched_mods;
     86     xkb_mod_mask_t locked_mods;
     87     xkb_mod_mask_t mods; /**< effective */
     88 
     89     xkb_led_mask_t leds;
     90 };
     91 
     92 struct xkb_state {
     93     /*
     94      * Before updating the state, we keep a copy of just this struct. This
     95      * allows us to report which components of the state have changed.
     96      */
     97     struct state_components components;
     98 
     99     /*
    100      * At each event, we accumulate all the needed modifications to the base
    101      * modifiers, and apply them at the end. These keep track of this state.
    102      */
    103     xkb_mod_mask_t set_mods;
    104     xkb_mod_mask_t clear_mods;
    105 
    106     /*
    107      * We mustn't clear a base modifier if there's another depressed key
    108      * which affects it, e.g. given this sequence
    109      * < Left Shift down, Right Shift down, Left Shift Up >
    110      * the modifier should still be set. This keeps the count.
    111      */
    112     int16_t mod_key_count[XKB_MAX_MODS];
    113 
    114     int refcnt;
    115     darray(struct xkb_filter) filters;
    116     struct xkb_keymap *keymap;
    117 };
    118 
    119 static const struct xkb_key_type_entry *
    120 get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key,
    121                         xkb_layout_index_t group)
    122 {
    123     const struct xkb_key_type *type = key->groups[group].type;
    124     xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask;
    125 
    126     for (unsigned i = 0; i < type->num_entries; i++) {
    127         /*
    128          * If the virtual modifiers are not bound to anything, we're
    129          * supposed to skip the entry (xserver does this with cached
    130          * entry->active field).
    131          */
    132         if (type->entries[i].mods.mods != 0 && type->entries[i].mods.mask == 0)
    133             continue;
    134 
    135         if (type->entries[i].mods.mask == active_mods)
    136             return &type->entries[i];
    137     }
    138 
    139     return NULL;
    140 }
    141 
    142 /**
    143  * Returns the level to use for the given key and state, or
    144  * XKB_LEVEL_INVALID.
    145  */
    146 XKB_EXPORT xkb_level_index_t
    147 xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t kc,
    148                         xkb_layout_index_t layout)
    149 {
    150     const struct xkb_key *key = XkbKey(state->keymap, kc);
    151     const struct xkb_key_type_entry *entry;
    152 
    153     if (!key || layout >= key->num_groups)
    154         return XKB_LEVEL_INVALID;
    155 
    156     /* If we don't find an explicit match the default is 0. */
    157     entry = get_entry_for_key_state(state, key, layout);
    158     if (!entry)
    159         return 0;
    160 
    161     return entry->level;
    162 }
    163 
    164 xkb_layout_index_t
    165 XkbWrapGroupIntoRange(int32_t group,
    166                       xkb_layout_index_t num_groups,
    167                       enum xkb_range_exceed_type out_of_range_group_action,
    168                       xkb_layout_index_t out_of_range_group_number)
    169 {
    170     if (num_groups == 0)
    171         return XKB_LAYOUT_INVALID;
    172 
    173     if (group >= 0 && (xkb_layout_index_t) group < num_groups)
    174         return group;
    175 
    176     switch (out_of_range_group_action) {
    177     case RANGE_REDIRECT:
    178         if (out_of_range_group_number >= num_groups)
    179             return 0;
    180         return out_of_range_group_number;
    181 
    182     case RANGE_SATURATE:
    183         if (group < 0)
    184             return 0;
    185         else
    186             return num_groups - 1;
    187 
    188     case RANGE_WRAP:
    189     default:
    190         /*
    191          * C99 says a negative dividend in a modulo operation always
    192          * gives a negative result.
    193          */
    194         if (group < 0)
    195             return ((int) num_groups + (group % (int) num_groups));
    196         else
    197             return group % num_groups;
    198     }
    199 }
    200 
    201 /**
    202  * Returns the layout to use for the given key and state, taking
    203  * wrapping/clamping/etc into account, or XKB_LAYOUT_INVALID.
    204  */
    205 XKB_EXPORT xkb_layout_index_t
    206 xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
    207 {
    208     const struct xkb_key *key = XkbKey(state->keymap, kc);
    209 
    210     if (!key)
    211         return XKB_LAYOUT_INVALID;
    212 
    213     return XkbWrapGroupIntoRange(state->components.group, key->num_groups,
    214                                  key->out_of_range_group_action,
    215                                  key->out_of_range_group_number);
    216 }
    217 
    218 static const union xkb_action fake = { .type = ACTION_TYPE_NONE };
    219 
    220 static const union xkb_action *
    221 xkb_key_get_action(struct xkb_state *state, const struct xkb_key *key)
    222 {
    223     xkb_layout_index_t layout;
    224     xkb_level_index_t level;
    225 
    226     layout = xkb_state_key_get_layout(state, key->keycode);
    227     if (layout == XKB_LAYOUT_INVALID)
    228         return &fake;
    229 
    230     level = xkb_state_key_get_level(state, key->keycode, layout);
    231     if (level == XKB_LEVEL_INVALID)
    232         return &fake;
    233 
    234     return &key->groups[layout].levels[level].action;
    235 }
    236 
    237 static struct xkb_filter *
    238 xkb_filter_new(struct xkb_state *state)
    239 {
    240     struct xkb_filter *filter = NULL, *iter;
    241 
    242     darray_foreach(iter, state->filters) {
    243         if (iter->func)
    244             continue;
    245         filter = iter;
    246         break;
    247     }
    248 
    249     if (!filter) {
    250         darray_resize0(state->filters, darray_size(state->filters) + 1);
    251         filter = &darray_item(state->filters, darray_size(state->filters) -1);
    252     }
    253 
    254     filter->refcnt = 1;
    255     return filter;
    256 }
    257 
    258 /***====================================================================***/
    259 
    260 static bool
    261 xkb_filter_group_set_func(struct xkb_state *state,
    262                           struct xkb_filter *filter,
    263                           const struct xkb_key *key,
    264                           enum xkb_key_direction direction)
    265 {
    266     if (key != filter->key) {
    267         filter->action.group.flags &= ~ACTION_LOCK_CLEAR;
    268         return true;
    269     }
    270 
    271     if (direction == XKB_KEY_DOWN) {
    272         filter->refcnt++;
    273         return false;
    274     }
    275     else if (--filter->refcnt > 0) {
    276         return false;
    277     }
    278 
    279     state->components.base_group = filter->priv;
    280 
    281     if (filter->action.group.flags & ACTION_LOCK_CLEAR)
    282         state->components.locked_group = 0;
    283 
    284     filter->func = NULL;
    285     return true;
    286 }
    287 
    288 static void
    289 xkb_filter_group_set_new(struct xkb_state *state, struct xkb_filter *filter)
    290 {
    291     filter->priv = state->components.base_group;
    292     if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH)
    293         state->components.base_group = filter->action.group.group;
    294     else
    295         state->components.base_group += filter->action.group.group;
    296 }
    297 
    298 static bool
    299 xkb_filter_group_lock_func(struct xkb_state *state,
    300                            struct xkb_filter *filter,
    301                            const struct xkb_key *key,
    302                            enum xkb_key_direction direction)
    303 {
    304     if (key != filter->key)
    305         return true;
    306 
    307     if (direction == XKB_KEY_DOWN) {
    308         filter->refcnt++;
    309         return false;
    310     }
    311     if (--filter->refcnt > 0)
    312         return false;
    313 
    314     filter->func = NULL;
    315     return true;
    316 }
    317 
    318 static void
    319 xkb_filter_group_lock_new(struct xkb_state *state, struct xkb_filter *filter)
    320 {
    321     if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH)
    322         state->components.locked_group = filter->action.group.group;
    323     else
    324         state->components.locked_group += filter->action.group.group;
    325 }
    326 
    327 static bool
    328 xkb_filter_mod_set_func(struct xkb_state *state,
    329                         struct xkb_filter *filter,
    330                         const struct xkb_key *key,
    331                         enum xkb_key_direction direction)
    332 {
    333     if (key != filter->key) {
    334         filter->action.mods.flags &= ~ACTION_LOCK_CLEAR;
    335         return true;
    336     }
    337 
    338     if (direction == XKB_KEY_DOWN) {
    339         filter->refcnt++;
    340         return false;
    341     }
    342     else if (--filter->refcnt > 0) {
    343         return false;
    344     }
    345 
    346     state->clear_mods = filter->action.mods.mods.mask;
    347     if (filter->action.mods.flags & ACTION_LOCK_CLEAR)
    348         state->components.locked_mods &= ~filter->action.mods.mods.mask;
    349 
    350     filter->func = NULL;
    351     return true;
    352 }
    353 
    354 static void
    355 xkb_filter_mod_set_new(struct xkb_state *state, struct xkb_filter *filter)
    356 {
    357     state->set_mods = filter->action.mods.mods.mask;
    358 }
    359 
    360 static bool
    361 xkb_filter_mod_lock_func(struct xkb_state *state,
    362                          struct xkb_filter *filter,
    363                          const struct xkb_key *key,
    364                          enum xkb_key_direction direction)
    365 {
    366     if (key != filter->key)
    367         return true;
    368 
    369     if (direction == XKB_KEY_DOWN) {
    370         filter->refcnt++;
    371         return false;
    372     }
    373     if (--filter->refcnt > 0)
    374         return false;
    375 
    376     state->clear_mods |= filter->action.mods.mods.mask;
    377     if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK))
    378         state->components.locked_mods &= ~filter->priv;
    379 
    380     filter->func = NULL;
    381     return true;
    382 }
    383 
    384 static void
    385 xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_filter *filter)
    386 {
    387     filter->priv = (state->components.locked_mods &
    388                     filter->action.mods.mods.mask);
    389     state->set_mods |= filter->action.mods.mods.mask;
    390     if (!(filter->action.mods.flags & ACTION_LOCK_NO_LOCK))
    391         state->components.locked_mods |= filter->action.mods.mods.mask;
    392 }
    393 
    394 enum xkb_key_latch_state {
    395     NO_LATCH,
    396     LATCH_KEY_DOWN,
    397     LATCH_PENDING,
    398 };
    399 
    400 static bool
    401 xkb_action_breaks_latch(const union xkb_action *action)
    402 {
    403     switch (action->type) {
    404     case ACTION_TYPE_NONE:
    405     case ACTION_TYPE_PTR_BUTTON:
    406     case ACTION_TYPE_PTR_LOCK:
    407     case ACTION_TYPE_CTRL_SET:
    408     case ACTION_TYPE_CTRL_LOCK:
    409     case ACTION_TYPE_SWITCH_VT:
    410     case ACTION_TYPE_TERMINATE:
    411         return true;
    412     default:
    413         return false;
    414     }
    415 }
    416 
    417 static bool
    418 xkb_filter_mod_latch_func(struct xkb_state *state,
    419                           struct xkb_filter *filter,
    420                           const struct xkb_key *key,
    421                           enum xkb_key_direction direction)
    422 {
    423     enum xkb_key_latch_state latch = filter->priv;
    424 
    425     if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
    426         /* If this is a new keypress and we're awaiting our single latched
    427          * keypress, then either break the latch if any random key is pressed,
    428          * or promote it to a lock or plain base set if it's the same
    429          * modifier. */
    430         const union xkb_action *action = xkb_key_get_action(state, key);
    431         if (action->type == ACTION_TYPE_MOD_LATCH &&
    432             action->mods.flags == filter->action.mods.flags &&
    433             action->mods.mods.mask == filter->action.mods.mods.mask) {
    434             filter->action = *action;
    435             if (filter->action.mods.flags & ACTION_LATCH_TO_LOCK) {
    436                 filter->action.type = ACTION_TYPE_MOD_LOCK;
    437                 filter->func = xkb_filter_mod_lock_func;
    438                 state->components.locked_mods |= filter->action.mods.mods.mask;
    439             }
    440             else {
    441                 filter->action.type = ACTION_TYPE_MOD_SET;
    442                 filter->func = xkb_filter_mod_set_func;
    443                 state->set_mods = filter->action.mods.mods.mask;
    444             }
    445             filter->key = key;
    446             state->components.latched_mods &= ~filter->action.mods.mods.mask;
    447             /* XXX beep beep! */
    448             return false;
    449         }
    450         else if (xkb_action_breaks_latch(action)) {
    451             /* XXX: This may be totally broken, we might need to break the
    452              *      latch in the next run after this press? */
    453             state->components.latched_mods &= ~filter->action.mods.mods.mask;
    454             filter->func = NULL;
    455             return true;
    456         }
    457     }
    458     else if (direction == XKB_KEY_UP && key == filter->key) {
    459         /* Our key got released.  If we've set it to clear locks, and we
    460          * currently have the same modifiers locked, then release them and
    461          * don't actually latch.  Else we've actually hit the latching
    462          * stage, so set PENDING and move our modifier from base to
    463          * latched. */
    464         if (latch == NO_LATCH ||
    465             ((filter->action.mods.flags & ACTION_LOCK_CLEAR) &&
    466              (state->components.locked_mods & filter->action.mods.mods.mask) ==
    467              filter->action.mods.mods.mask)) {
    468             /* XXX: We might be a bit overenthusiastic about clearing
    469              *      mods other filters have set here? */
    470             if (latch == LATCH_PENDING)
    471                 state->components.latched_mods &=
    472                     ~filter->action.mods.mods.mask;
    473             else
    474                 state->clear_mods = filter->action.mods.mods.mask;
    475             state->components.locked_mods &= ~filter->action.mods.mods.mask;
    476             filter->func = NULL;
    477         }
    478         else {
    479             latch = LATCH_PENDING;
    480             state->clear_mods = filter->action.mods.mods.mask;
    481             state->components.latched_mods |= filter->action.mods.mods.mask;
    482             /* XXX beep beep! */
    483         }
    484     }
    485     else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
    486         /* Someone's pressed another key while we've still got the latching
    487          * key held down, so keep the base modifier state active (from
    488          * xkb_filter_mod_latch_new), but don't trip the latch, just clear
    489          * it as soon as the modifier gets released. */
    490         latch = NO_LATCH;
    491     }
    492 
    493     filter->priv = latch;
    494 
    495     return true;
    496 }
    497 
    498 static void
    499 xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_filter *filter)
    500 {
    501     filter->priv = LATCH_KEY_DOWN;
    502     state->set_mods = filter->action.mods.mods.mask;
    503 }
    504 
    505 static const struct {
    506     void (*new)(struct xkb_state *state, struct xkb_filter *filter);
    507     bool (*func)(struct xkb_state *state, struct xkb_filter *filter,
    508                  const struct xkb_key *key, enum xkb_key_direction direction);
    509 } filter_action_funcs[_ACTION_TYPE_NUM_ENTRIES] = {
    510     [ACTION_TYPE_MOD_SET]    = { xkb_filter_mod_set_new,
    511                                  xkb_filter_mod_set_func },
    512     [ACTION_TYPE_MOD_LATCH]  = { xkb_filter_mod_latch_new,
    513                                  xkb_filter_mod_latch_func },
    514     [ACTION_TYPE_MOD_LOCK]   = { xkb_filter_mod_lock_new,
    515                                  xkb_filter_mod_lock_func },
    516     [ACTION_TYPE_GROUP_SET]  = { xkb_filter_group_set_new,
    517                                  xkb_filter_group_set_func },
    518     [ACTION_TYPE_GROUP_LOCK] = { xkb_filter_group_lock_new,
    519                                  xkb_filter_group_lock_func },
    520 };
    521 
    522 /**
    523  * Applies any relevant filters to the key, first from the list of filters
    524  * that are currently active, then if no filter has claimed the key, possibly
    525  * apply a new filter from the key action.
    526  */
    527 static void
    528 xkb_filter_apply_all(struct xkb_state *state,
    529                      const struct xkb_key *key,
    530                      enum xkb_key_direction direction)
    531 {
    532     struct xkb_filter *filter;
    533     const union xkb_action *action;
    534     bool send = true;
    535 
    536     /* First run through all the currently active filters and see if any of
    537      * them have claimed this event. */
    538     darray_foreach(filter, state->filters) {
    539         if (!filter->func)
    540             continue;
    541         send = filter->func(state, filter, key, direction) && send;
    542     }
    543 
    544     if (!send || direction == XKB_KEY_UP)
    545         return;
    546 
    547     action = xkb_key_get_action(state, key);
    548 
    549     /*
    550      * It's possible for the keymap to set action->type explicitly, like so:
    551      *     interpret XF86_Next_VMode {
    552      *         action = Private(type=0x86, data="+VMode");
    553      *     };
    554      * We don't handle those.
    555      */
    556     if (action->type >= _ACTION_TYPE_NUM_ENTRIES)
    557         return;
    558 
    559     if (!filter_action_funcs[action->type].new)
    560         return;
    561 
    562     filter = xkb_filter_new(state);
    563     if (!filter)
    564         return; /* WSGO */
    565 
    566     filter->key = key;
    567     filter->func = filter_action_funcs[action->type].func;
    568     filter->action = *action;
    569     filter_action_funcs[action->type].new(state, filter);
    570 }
    571 
    572 XKB_EXPORT struct xkb_state *
    573 xkb_state_new(struct xkb_keymap *keymap)
    574 {
    575     struct xkb_state *ret;
    576 
    577     ret = calloc(sizeof(*ret), 1);
    578     if (!ret)
    579         return NULL;
    580 
    581     ret->refcnt = 1;
    582     ret->keymap = xkb_keymap_ref(keymap);
    583 
    584     return ret;
    585 }
    586 
    587 XKB_EXPORT struct xkb_state *
    588 xkb_state_ref(struct xkb_state *state)
    589 {
    590     state->refcnt++;
    591     return state;
    592 }
    593 
    594 XKB_EXPORT void
    595 xkb_state_unref(struct xkb_state *state)
    596 {
    597     if (!state || --state->refcnt > 0)
    598         return;
    599 
    600     xkb_keymap_unref(state->keymap);
    601     darray_free(state->filters);
    602     free(state);
    603 }
    604 
    605 XKB_EXPORT struct xkb_keymap *
    606 xkb_state_get_keymap(struct xkb_state *state)
    607 {
    608     return state->keymap;
    609 }
    610 
    611 /**
    612  * Update the LED state to match the rest of the xkb_state.
    613  */
    614 static void
    615 xkb_state_led_update_all(struct xkb_state *state)
    616 {
    617     xkb_led_index_t idx;
    618     const struct xkb_led *led;
    619 
    620     state->components.leds = 0;
    621 
    622     xkb_leds_enumerate(idx, led, state->keymap) {
    623         xkb_mod_mask_t mod_mask = 0;
    624         xkb_layout_mask_t group_mask = 0;
    625 
    626         if (led->which_mods != 0 && led->mods.mask != 0) {
    627             if (led->which_mods & XKB_STATE_MODS_EFFECTIVE)
    628                 mod_mask |= state->components.mods;
    629             if (led->which_mods & XKB_STATE_MODS_DEPRESSED)
    630                 mod_mask |= state->components.base_mods;
    631             if (led->which_mods & XKB_STATE_MODS_LATCHED)
    632                 mod_mask |= state->components.latched_mods;
    633             if (led->which_mods & XKB_STATE_MODS_LOCKED)
    634                 mod_mask |= state->components.locked_mods;
    635 
    636             if (led->mods.mask & mod_mask) {
    637                 state->components.leds |= (1u << idx);
    638                 continue;
    639             }
    640         }
    641 
    642         if (led->which_groups != 0 && led->groups != 0) {
    643             if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
    644                 group_mask |= (1u << state->components.group);
    645             if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
    646                 group_mask |= (1u << state->components.base_group);
    647             if (led->which_groups & XKB_STATE_LAYOUT_LATCHED)
    648                 group_mask |= (1u << state->components.latched_group);
    649             if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
    650                 group_mask |= (1u << state->components.locked_group);
    651 
    652             if (led->groups & group_mask) {
    653                 state->components.leds |= (1u << idx);
    654                 continue;
    655             }
    656         }
    657 
    658         if (led->ctrls & state->keymap->enabled_ctrls) {
    659             state->components.leds |= (1u << idx);
    660             continue;
    661         }
    662     }
    663 }
    664 
    665 /**
    666  * Calculates the derived state (effective mods/group and LEDs) from an
    667  * up-to-date xkb_state.
    668  */
    669 static void
    670 xkb_state_update_derived(struct xkb_state *state)
    671 {
    672     xkb_layout_index_t wrapped;
    673 
    674     state->components.mods = (state->components.base_mods |
    675                               state->components.latched_mods |
    676                               state->components.locked_mods);
    677 
    678     /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */
    679 
    680     wrapped = XkbWrapGroupIntoRange(state->components.locked_group,
    681                                     state->keymap->num_groups,
    682                                     RANGE_WRAP, 0);
    683     state->components.locked_group =
    684         (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped);
    685 
    686     wrapped = XkbWrapGroupIntoRange(state->components.base_group +
    687                                     state->components.latched_group +
    688                                     state->components.locked_group,
    689                                     state->keymap->num_groups,
    690                                     RANGE_WRAP, 0);
    691     state->components.group =
    692         (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped);
    693 
    694     xkb_state_led_update_all(state);
    695 }
    696 
    697 static enum xkb_state_component
    698 get_state_component_changes(const struct state_components *a,
    699                             const struct state_components *b)
    700 {
    701     xkb_mod_mask_t mask = 0;
    702 
    703     if (a->group != b->group)
    704         mask |= XKB_STATE_LAYOUT_EFFECTIVE;
    705     if (a->base_group != b->base_group)
    706         mask |= XKB_STATE_LAYOUT_DEPRESSED;
    707     if (a->latched_group != b->latched_group)
    708         mask |= XKB_STATE_LAYOUT_LATCHED;
    709     if (a->locked_group != b->locked_group)
    710         mask |= XKB_STATE_LAYOUT_LOCKED;
    711     if (a->mods != b->mods)
    712         mask |= XKB_STATE_MODS_EFFECTIVE;
    713     if (a->base_mods != b->base_mods)
    714         mask |= XKB_STATE_MODS_DEPRESSED;
    715     if (a->latched_mods != b->latched_mods)
    716         mask |= XKB_STATE_MODS_LATCHED;
    717     if (a->locked_mods != b->locked_mods)
    718         mask |= XKB_STATE_MODS_LOCKED;
    719     if (a->leds != b->leds)
    720         mask |= XKB_STATE_LEDS;
    721 
    722     return mask;
    723 }
    724 
    725 /**
    726  * Given a particular key event, updates the state structure to reflect the
    727  * new modifiers.
    728  */
    729 XKB_EXPORT enum xkb_state_component
    730 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc,
    731                      enum xkb_key_direction direction)
    732 {
    733     xkb_mod_index_t i;
    734     xkb_mod_mask_t bit;
    735     struct state_components prev_components;
    736     const struct xkb_key *key = XkbKey(state->keymap, kc);
    737 
    738     if (!key)
    739         return 0;
    740 
    741     prev_components = state->components;
    742 
    743     state->set_mods = 0;
    744     state->clear_mods = 0;
    745 
    746     xkb_filter_apply_all(state, key, direction);
    747 
    748     for (i = 0, bit = 1; state->set_mods; i++, bit <<= 1) {
    749         if (state->set_mods & bit) {
    750             state->mod_key_count[i]++;
    751             state->components.base_mods |= bit;
    752             state->set_mods &= ~bit;
    753         }
    754     }
    755 
    756     for (i = 0, bit = 1; state->clear_mods; i++, bit <<= 1) {
    757         if (state->clear_mods & bit) {
    758             state->mod_key_count[i]--;
    759             if (state->mod_key_count[i] <= 0) {
    760                 state->components.base_mods &= ~bit;
    761                 state->mod_key_count[i] = 0;
    762             }
    763             state->clear_mods &= ~bit;
    764         }
    765     }
    766 
    767     xkb_state_update_derived(state);
    768 
    769     return get_state_component_changes(&prev_components, &state->components);
    770 }
    771 
    772 /**
    773  * Updates the state from a set of explicit masks as gained from
    774  * xkb_state_serialize_mods and xkb_state_serialize_groups.  As noted in the
    775  * documentation for these functions in xkbcommon.h, this round-trip is
    776  * lossy, and should only be used to update a slave state mirroring the
    777  * master, e.g. in a client/server window system.
    778  */
    779 XKB_EXPORT enum xkb_state_component
    780 xkb_state_update_mask(struct xkb_state *state,
    781                       xkb_mod_mask_t base_mods,
    782                       xkb_mod_mask_t latched_mods,
    783                       xkb_mod_mask_t locked_mods,
    784                       xkb_layout_index_t base_group,
    785                       xkb_layout_index_t latched_group,
    786                       xkb_layout_index_t locked_group)
    787 {
    788     struct state_components prev_components;
    789     xkb_mod_mask_t mask;
    790 
    791     prev_components = state->components;
    792 
    793     /* Only include modifiers which exist in the keymap. */
    794     mask = (xkb_mod_mask_t) ((1ull << xkb_keymap_num_mods(state->keymap)) - 1u);
    795 
    796     state->components.base_mods = base_mods & mask;
    797     state->components.latched_mods = latched_mods & mask;
    798     state->components.locked_mods = locked_mods & mask;
    799 
    800     /* Make sure the mods are fully resolved - since we get arbitrary
    801      * input, they might not be.
    802      *
    803      * It might seem more reasonable to do this only for components.mods
    804      * in xkb_state_update_derived(), rather than for each component
    805      * seperately.  That would allow to distinguish between "really"
    806      * depressed mods (would be in MODS_DEPRESSED) and indirectly
    807      * depressed to to a mapping (would only be in MODS_EFFECTIVE).
    808      * However, the traditional behavior of xkb_state_update_key() is that
    809      * if a vmod is depressed, its mappings are depressed with it; so we're
    810      * expected to do the same here.  Also, LEDs (usually) look if a real
    811      * mod is locked, not just effective; otherwise it won't be lit.
    812      *
    813      * We OR here because mod_mask_get_effective() drops vmods. */
    814     state->components.base_mods |=
    815         mod_mask_get_effective(state->keymap, state->components.base_mods);
    816     state->components.latched_mods |=
    817         mod_mask_get_effective(state->keymap, state->components.latched_mods);
    818     state->components.locked_mods |=
    819         mod_mask_get_effective(state->keymap, state->components.locked_mods);
    820 
    821     state->components.base_group = base_group;
    822     state->components.latched_group = latched_group;
    823     state->components.locked_group = locked_group;
    824 
    825     xkb_state_update_derived(state);
    826 
    827     return get_state_component_changes(&prev_components, &state->components);
    828 }
    829 
    830 /**
    831  * Provides the symbols to use for the given key and state.  Returns the
    832  * number of symbols pointed to in syms_out.
    833  */
    834 XKB_EXPORT int
    835 xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t kc,
    836                        const xkb_keysym_t **syms_out)
    837 {
    838     xkb_layout_index_t layout;
    839     xkb_level_index_t level;
    840 
    841     layout = xkb_state_key_get_layout(state, kc);
    842     if (layout == XKB_LAYOUT_INVALID)
    843         goto err;
    844 
    845     level = xkb_state_key_get_level(state, kc, layout);
    846     if (level == XKB_LEVEL_INVALID)
    847         goto err;
    848 
    849     return xkb_keymap_key_get_syms_by_level(state->keymap, kc, layout, level,
    850                                             syms_out);
    851 
    852 err:
    853     *syms_out = NULL;
    854     return 0;
    855 }
    856 
    857 /*
    858  * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
    859  */
    860 static bool
    861 should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc)
    862 {
    863     xkb_mod_index_t caps =
    864         xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
    865 
    866     return
    867         xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 &&
    868         xkb_state_mod_index_is_consumed(state, kc, caps) == 0;
    869 }
    870 
    871 /*
    872  * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
    873  */
    874 static bool
    875 should_do_ctrl_transformation(struct xkb_state *state, xkb_keycode_t kc)
    876 {
    877     xkb_mod_index_t ctrl =
    878         xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL);
    879 
    880     return
    881         xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0 &&
    882         xkb_state_mod_index_is_consumed(state, kc, ctrl) == 0;
    883 }
    884 
    885 /* Verbatim from libX11:src/xkb/XKBBind.c */
    886 static char
    887 XkbToControl(char ch)
    888 {
    889     char c = ch;
    890 
    891     if ((c >= '@' && c < '\177') || c == ' ')
    892         c &= 0x1F;
    893     else if (c == '2')
    894         c = '\000';
    895     else if (c >= '3' && c <= '7')
    896         c -= ('3' - '\033');
    897     else if (c == '8')
    898         c = '\177';
    899     else if (c == '/')
    900         c = '_' & 0x1F;
    901     return c;
    902 }
    903 
    904 /**
    905  * Provides either exactly one symbol, or XKB_KEY_NoSymbol.
    906  */
    907 XKB_EXPORT xkb_keysym_t
    908 xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
    909 {
    910     const xkb_keysym_t *syms;
    911     xkb_keysym_t sym;
    912     int num_syms;
    913 
    914     num_syms = xkb_state_key_get_syms(state, kc, &syms);
    915     if (num_syms != 1)
    916         return XKB_KEY_NoSymbol;
    917 
    918     sym = syms[0];
    919 
    920     if (should_do_caps_transformation(state, kc))
    921         sym = xkb_keysym_to_upper(sym);
    922 
    923     return sym;
    924 }
    925 
    926 /*
    927  * The caps and ctrl transformations require some special handling,
    928  * so we cannot simply use xkb_state_get_one_sym() for them.
    929  * In particular, if Control is set, we must try very hard to find
    930  * some layout in which the keysym is ASCII and thus can be (maybe)
    931  * converted to a control character. libX11 allows to disable this
    932  * behavior with the XkbLC_ControlFallback (see XkbSetXlibControls(3)),
    933  * but it is enabled by default, yippee.
    934  */
    935 static xkb_keysym_t
    936 get_one_sym_for_string(struct xkb_state *state, xkb_keycode_t kc)
    937 {
    938     xkb_level_index_t level;
    939     xkb_layout_index_t layout, num_layouts;
    940     const xkb_keysym_t *syms;
    941     int nsyms;
    942     xkb_keysym_t sym;
    943 
    944     layout = xkb_state_key_get_layout(state, kc);
    945     num_layouts = xkb_keymap_num_layouts_for_key(state->keymap, kc);
    946     level = xkb_state_key_get_level(state, kc, layout);
    947     if (layout == XKB_LAYOUT_INVALID || num_layouts == 0 ||
    948         level == XKB_LEVEL_INVALID)
    949         return XKB_KEY_NoSymbol;
    950 
    951     nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc,
    952                                              layout, level, &syms);
    953     if (nsyms != 1)
    954         return XKB_KEY_NoSymbol;
    955     sym = syms[0];
    956 
    957     if (should_do_ctrl_transformation(state, kc) && sym > 127u) {
    958         for (xkb_layout_index_t i = 0; i < num_layouts; i++) {
    959             level = xkb_state_key_get_level(state, kc, i);
    960             if (level == XKB_LEVEL_INVALID)
    961                 continue;
    962 
    963             nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc,
    964                                                      i, level, &syms);
    965             if (nsyms == 1 && syms[0] <= 127u) {
    966                 sym = syms[0];
    967                 break;
    968             }
    969         }
    970     }
    971 
    972     if (should_do_caps_transformation(state, kc)) {
    973         sym = xkb_keysym_to_upper(sym);
    974     }
    975 
    976     return sym;
    977 }
    978 
    979 XKB_EXPORT int
    980 xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t kc,
    981                        char *buffer, size_t size)
    982 {
    983     xkb_keysym_t sym;
    984     const xkb_keysym_t *syms;
    985     int nsyms;
    986     int offset;
    987     char tmp[7];
    988 
    989     sym = get_one_sym_for_string(state, kc);
    990     if (sym != XKB_KEY_NoSymbol) {
    991         nsyms = 1; syms = &sym;
    992     }
    993     else {
    994         nsyms = xkb_state_key_get_syms(state, kc, &syms);
    995     }
    996 
    997     /* Make sure not to truncate in the middle of a UTF-8 sequence. */
    998     offset = 0;
    999     for (int i = 0; i < nsyms; i++) {
   1000         int ret = xkb_keysym_to_utf8(syms[i], tmp, sizeof(tmp));
   1001         if (ret <= 0)
   1002             goto err_bad;
   1003 
   1004         ret--;
   1005         if ((size_t) (offset + ret) <= size)
   1006             memcpy(buffer + offset, tmp, ret);
   1007         offset += ret;
   1008     }
   1009 
   1010     if ((size_t) offset >= size)
   1011         goto err_trunc;
   1012     buffer[offset] = '\0';
   1013 
   1014     if (!is_valid_utf8(buffer, offset))
   1015         goto err_bad;
   1016 
   1017     if (offset == 1 && (unsigned int) buffer[0] <= 127u &&
   1018         should_do_ctrl_transformation(state, kc))
   1019         buffer[0] = XkbToControl(buffer[0]);
   1020 
   1021     return offset;
   1022 
   1023 err_trunc:
   1024     if (size > 0)
   1025         buffer[size - 1] = '\0';
   1026     return offset;
   1027 
   1028 err_bad:
   1029     if (size > 0)
   1030         buffer[0] = '\0';
   1031     return 0;
   1032 }
   1033 
   1034 XKB_EXPORT uint32_t
   1035 xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t kc)
   1036 {
   1037     xkb_keysym_t sym;
   1038     uint32_t cp;
   1039 
   1040     sym = get_one_sym_for_string(state, kc);
   1041     cp = xkb_keysym_to_utf32(sym);
   1042 
   1043     if (cp <= 127u && should_do_ctrl_transformation(state, kc))
   1044         cp = (uint32_t) XkbToControl((char) cp);
   1045 
   1046     return cp;
   1047 }
   1048 
   1049 /**
   1050  * Serialises the requested modifier state into an xkb_mod_mask_t, with all
   1051  * the same disclaimers as in xkb_state_update_mask.
   1052  */
   1053 XKB_EXPORT xkb_mod_mask_t
   1054 xkb_state_serialize_mods(struct xkb_state *state,
   1055                          enum xkb_state_component type)
   1056 {
   1057     xkb_mod_mask_t ret = 0;
   1058 
   1059     if (type & XKB_STATE_MODS_EFFECTIVE)
   1060         return state->components.mods;
   1061 
   1062     if (type & XKB_STATE_MODS_DEPRESSED)
   1063         ret |= state->components.base_mods;
   1064     if (type & XKB_STATE_MODS_LATCHED)
   1065         ret |= state->components.latched_mods;
   1066     if (type & XKB_STATE_MODS_LOCKED)
   1067         ret |= state->components.locked_mods;
   1068 
   1069     return ret;
   1070 }
   1071 
   1072 /**
   1073  * Serialises the requested group state, with all the same disclaimers as
   1074  * in xkb_state_update_mask.
   1075  */
   1076 XKB_EXPORT xkb_layout_index_t
   1077 xkb_state_serialize_layout(struct xkb_state *state,
   1078                            enum xkb_state_component type)
   1079 {
   1080     xkb_layout_index_t ret = 0;
   1081 
   1082     if (type & XKB_STATE_LAYOUT_EFFECTIVE)
   1083         return state->components.group;
   1084 
   1085     if (type & XKB_STATE_LAYOUT_DEPRESSED)
   1086         ret += state->components.base_group;
   1087     if (type & XKB_STATE_LAYOUT_LATCHED)
   1088         ret += state->components.latched_group;
   1089     if (type & XKB_STATE_LAYOUT_LOCKED)
   1090         ret += state->components.locked_group;
   1091 
   1092     return ret;
   1093 }
   1094 
   1095 /**
   1096  * Gets a modifier mask and returns the resolved effective mask; this
   1097  * is needed because some modifiers can also map to other modifiers, e.g.
   1098  * the "NumLock" modifier usually also sets the "Mod2" modifier.
   1099  */
   1100 xkb_mod_mask_t
   1101 mod_mask_get_effective(struct xkb_keymap *keymap, xkb_mod_mask_t mods)
   1102 {
   1103     const struct xkb_mod *mod;
   1104     xkb_mod_index_t i;
   1105     xkb_mod_mask_t mask;
   1106 
   1107     /* The effective mask is only real mods for now. */
   1108     mask = mods & MOD_REAL_MASK_ALL;
   1109 
   1110     xkb_mods_enumerate(i, mod, &keymap->mods)
   1111         if (mods & (1u << i))
   1112             mask |= mod->mapping;
   1113 
   1114     return mask;
   1115 }
   1116 
   1117 /**
   1118  * Returns 1 if the given modifier is active with the specified type(s), 0 if
   1119  * not, or -1 if the modifier is invalid.
   1120  */
   1121 XKB_EXPORT int
   1122 xkb_state_mod_index_is_active(struct xkb_state *state,
   1123                               xkb_mod_index_t idx,
   1124                               enum xkb_state_component type)
   1125 {
   1126     if (idx >= xkb_keymap_num_mods(state->keymap))
   1127         return -1;
   1128 
   1129     return !!(xkb_state_serialize_mods(state, type) & (1u << idx));
   1130 }
   1131 
   1132 /**
   1133  * Helper function for xkb_state_mod_indices_are_active and
   1134  * xkb_state_mod_names_are_active.
   1135  */
   1136 static int
   1137 match_mod_masks(struct xkb_state *state,
   1138                 enum xkb_state_component type,
   1139                 enum xkb_state_match match,
   1140                 xkb_mod_mask_t wanted)
   1141 {
   1142     xkb_mod_mask_t active = xkb_state_serialize_mods(state, type);
   1143 
   1144     if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted))
   1145         return 0;
   1146 
   1147     if (match & XKB_STATE_MATCH_ANY)
   1148         return !!(active & wanted);
   1149     else
   1150         return (active & wanted) == wanted;
   1151 
   1152     return 0;
   1153 }
   1154 
   1155 /**
   1156  * Returns 1 if the modifiers are active with the specified type(s), 0 if
   1157  * not, or -1 if any of the modifiers are invalid.
   1158  */
   1159 XKB_EXPORT int
   1160 xkb_state_mod_indices_are_active(struct xkb_state *state,
   1161                                  enum xkb_state_component type,
   1162                                  enum xkb_state_match match,
   1163                                  ...)
   1164 {
   1165     va_list ap;
   1166     xkb_mod_index_t idx = 0;
   1167     xkb_mod_mask_t wanted = 0;
   1168     int ret = 0;
   1169     xkb_mod_index_t num_mods = xkb_keymap_num_mods(state->keymap);
   1170 
   1171     va_start(ap, match);
   1172     while (1) {
   1173         idx = va_arg(ap, xkb_mod_index_t);
   1174         if (idx == XKB_MOD_INVALID)
   1175             break;
   1176         if (idx >= num_mods) {
   1177             ret = -1;
   1178             break;
   1179         }
   1180         wanted |= (1u << idx);
   1181     }
   1182     va_end(ap);
   1183 
   1184     if (ret == -1)
   1185         return ret;
   1186 
   1187     return match_mod_masks(state, type, match, wanted);
   1188 }
   1189 
   1190 /**
   1191  * Returns 1 if the given modifier is active with the specified type(s), 0 if
   1192  * not, or -1 if the modifier is invalid.
   1193  */
   1194 XKB_EXPORT int
   1195 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
   1196                              enum xkb_state_component type)
   1197 {
   1198     xkb_mod_index_t idx = xkb_keymap_mod_get_index(state->keymap, name);
   1199 
   1200     if (idx == XKB_MOD_INVALID)
   1201         return -1;
   1202 
   1203     return xkb_state_mod_index_is_active(state, idx, type);
   1204 }
   1205 
   1206 /**
   1207  * Returns 1 if the modifiers are active with the specified type(s), 0 if
   1208  * not, or -1 if any of the modifiers are invalid.
   1209  */
   1210 XKB_EXPORT ATTR_NULL_SENTINEL int
   1211 xkb_state_mod_names_are_active(struct xkb_state *state,
   1212                                enum xkb_state_component type,
   1213                                enum xkb_state_match match,
   1214                                ...)
   1215 {
   1216     va_list ap;
   1217     xkb_mod_index_t idx = 0;
   1218     xkb_mod_mask_t wanted = 0;
   1219     int ret = 0;
   1220 
   1221     va_start(ap, match);
   1222     while (1) {
   1223         const char *str = va_arg(ap, const char *);
   1224         if (str == NULL)
   1225             break;
   1226         idx = xkb_keymap_mod_get_index(state->keymap, str);
   1227         if (idx == XKB_MOD_INVALID) {
   1228             ret = -1;
   1229             break;
   1230         }
   1231         wanted |= (1u << idx);
   1232     }
   1233     va_end(ap);
   1234 
   1235     if (ret == -1)
   1236         return ret;
   1237 
   1238     return match_mod_masks(state, type, match, wanted);
   1239 }
   1240 
   1241 /**
   1242  * Returns 1 if the given group is active with the specified type(s), 0 if
   1243  * not, or -1 if the group is invalid.
   1244  */
   1245 XKB_EXPORT int
   1246 xkb_state_layout_index_is_active(struct xkb_state *state,
   1247                                 xkb_layout_index_t idx,
   1248                                 enum xkb_state_component type)
   1249 {
   1250     int ret = 0;
   1251 
   1252     if (idx >= state->keymap->num_groups)
   1253         return -1;
   1254 
   1255     if (type & XKB_STATE_LAYOUT_EFFECTIVE)
   1256         ret |= (state->components.group == idx);
   1257     if (type & XKB_STATE_LAYOUT_DEPRESSED)
   1258         ret |= (state->components.base_group == (int32_t) idx);
   1259     if (type & XKB_STATE_LAYOUT_LATCHED)
   1260         ret |= (state->components.latched_group == (int32_t) idx);
   1261     if (type & XKB_STATE_LAYOUT_LOCKED)
   1262         ret |= (state->components.locked_group == (int32_t) idx);
   1263 
   1264     return ret;
   1265 }
   1266 
   1267 /**
   1268  * Returns 1 if the given modifier is active with the specified type(s), 0 if
   1269  * not, or -1 if the modifier is invalid.
   1270  */
   1271 XKB_EXPORT int
   1272 xkb_state_layout_name_is_active(struct xkb_state *state, const char *name,
   1273                                 enum xkb_state_component type)
   1274 {
   1275     xkb_layout_index_t idx = xkb_keymap_layout_get_index(state->keymap, name);
   1276 
   1277     if (idx == XKB_LAYOUT_INVALID)
   1278         return -1;
   1279 
   1280     return xkb_state_layout_index_is_active(state, idx, type);
   1281 }
   1282 
   1283 /**
   1284  * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
   1285  */
   1286 XKB_EXPORT int
   1287 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
   1288 {
   1289     if (idx >= state->keymap->num_leds ||
   1290         state->keymap->leds[idx].name == XKB_ATOM_NONE)
   1291         return -1;
   1292 
   1293     return !!(state->components.leds & (1u << idx));
   1294 }
   1295 
   1296 /**
   1297  * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
   1298  */
   1299 XKB_EXPORT int
   1300 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
   1301 {
   1302     xkb_led_index_t idx = xkb_keymap_led_get_index(state->keymap, name);
   1303 
   1304     if (idx == XKB_LED_INVALID)
   1305         return -1;
   1306 
   1307     return xkb_state_led_index_is_active(state, idx);
   1308 }
   1309 
   1310 static xkb_mod_mask_t
   1311 key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
   1312 {
   1313     const struct xkb_key_type *type;
   1314     const struct xkb_key_type_entry *entry;
   1315     xkb_mod_mask_t preserve;
   1316     xkb_layout_index_t group;
   1317 
   1318     group = xkb_state_key_get_layout(state, key->keycode);
   1319     if (group == XKB_LAYOUT_INVALID)
   1320         return 0;
   1321 
   1322     type = key->groups[group].type;
   1323 
   1324     entry = get_entry_for_key_state(state, key, group);
   1325     if (entry)
   1326         preserve = entry->preserve.mask;
   1327     else
   1328         preserve = 0;
   1329 
   1330     return type->mods.mask & ~preserve;
   1331 }
   1332 
   1333 /**
   1334  * Tests to see if a modifier is used up by our translation of a
   1335  * keycode to keysyms, taking note of the current modifier state and
   1336  * the appropriate key type's preserve information, if any. This allows
   1337  * the user to mask out the modifier in later processing of the
   1338  * modifiers, e.g. when implementing hot keys or accelerators.
   1339  *
   1340  * See also, for example:
   1341  * - XkbTranslateKeyCode(3), mod_rtrn return value, from libX11.
   1342  * - gdk_keymap_translate_keyboard_state, consumed_modifiers return value,
   1343  *   from gtk+.
   1344  */
   1345 XKB_EXPORT int
   1346 xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
   1347                                 xkb_mod_index_t idx)
   1348 {
   1349     const struct xkb_key *key = XkbKey(state->keymap, kc);
   1350 
   1351     if (!key || idx >= xkb_keymap_num_mods(state->keymap))
   1352         return -1;
   1353 
   1354     return !!((1u << idx) & key_get_consumed(state, key));
   1355 }
   1356 
   1357 /**
   1358  * Calculates which modifiers should be consumed during key processing,
   1359  * and returns the mask with all these modifiers removed.  e.g. if
   1360  * given a state of Alt and Shift active for a two-level alphabetic
   1361  * key containing plus and equal on the first and second level
   1362  * respectively, will return a mask of only Alt, as Shift has been
   1363  * consumed by the type handling.
   1364  */
   1365 XKB_EXPORT xkb_mod_mask_t
   1366 xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
   1367                                    xkb_mod_mask_t mask)
   1368 {
   1369     const struct xkb_key *key = XkbKey(state->keymap, kc);
   1370 
   1371     if (!key)
   1372         return 0;
   1373 
   1374     return mask & ~key_get_consumed(state, key);
   1375 }
   1376 
   1377 XKB_EXPORT xkb_mod_mask_t
   1378 xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t kc)
   1379 {
   1380     const struct xkb_key *key = XkbKey(state->keymap, kc);
   1381 
   1382     if (!key)
   1383         return 0;
   1384 
   1385     return key_get_consumed(state, key);
   1386 }
   1387