@@ -176,23 +176,27 @@ xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc)
176176 key -> out_of_range_group_number );
177177}
178178
179- static const union xkb_action *
180- xkb_key_get_action (struct xkb_state * state , const struct xkb_key * key )
179+ static unsigned int
180+ xkb_key_get_actions (struct xkb_state * state , const struct xkb_key * key ,
181+ const union xkb_action * * actions )
181182{
182- static const union xkb_action dummy = { .type = ACTION_TYPE_NONE };
183-
184183 xkb_layout_index_t layout ;
185184 xkb_level_index_t level ;
186185
187186 layout = xkb_state_key_get_layout (state , key -> keycode );
188187 if (layout == XKB_LAYOUT_INVALID )
189- return & dummy ;
188+ goto err ;
190189
191190 level = xkb_state_key_get_level (state , key -> keycode , layout );
192191 if (level == XKB_LEVEL_INVALID )
193- return & dummy ;
192+ goto err ;
194193
195- return & key -> groups [layout ].levels [level ].action ;
194+ return xkb_keymap_key_get_actions_by_level (state -> keymap , key -> keycode ,
195+ layout , level , actions );
196+
197+ err :
198+ * actions = NULL ;
199+ return 0 ;
196200}
197201
198202static struct xkb_filter *
@@ -377,34 +381,37 @@ xkb_filter_group_latch_func(struct xkb_state *state,
377381 * keypress, then either break the latch if any random key is pressed,
378382 * or promote it to a lock or plain base set if it's the same
379383 * group delta & flags. */
380- const union xkb_action * action = xkb_key_get_action (state , key );
381- if (action -> type == ACTION_TYPE_GROUP_LATCH &&
382- action -> group .group == filter -> action .group .group &&
383- action -> group .flags == filter -> action .group .flags ) {
384- filter -> action = * action ;
385- if (filter -> action .group .flags & ACTION_LATCH_TO_LOCK &&
386- filter -> action .group .group != 0 ) {
387- /* Promote to lock */
388- filter -> action .type = ACTION_TYPE_GROUP_LOCK ;
389- filter -> func = xkb_filter_group_lock_func ;
390- xkb_filter_group_lock_new (state , filter );
384+ const union xkb_action * actions = NULL ;
385+ unsigned int count = xkb_key_get_actions (state , key , & actions );
386+ for (unsigned int k = 0 ; k < count ; k ++ ) {
387+ if (actions [k ].type == ACTION_TYPE_GROUP_LATCH &&
388+ actions [k ].group .group == filter -> action .group .group &&
389+ actions [k ].group .flags == filter -> action .group .flags ) {
390+ filter -> action = actions [k ];
391+ if (filter -> action .group .flags & ACTION_LATCH_TO_LOCK &&
392+ filter -> action .group .group != 0 ) {
393+ /* Promote to lock */
394+ filter -> action .type = ACTION_TYPE_GROUP_LOCK ;
395+ filter -> func = xkb_filter_group_lock_func ;
396+ xkb_filter_group_lock_new (state , filter );
397+ }
398+ else {
399+ /* Degrade to plain set */
400+ filter -> action .type = ACTION_TYPE_GROUP_SET ;
401+ filter -> func = xkb_filter_group_set_func ;
402+ xkb_filter_group_set_new (state , filter );
403+ }
404+ filter -> key = key ;
405+ state -> components .latched_group -= priv .group_delta ;
406+ /* XXX beep beep! */
407+ return XKB_FILTER_CONSUME ;
391408 }
392- else {
393- /* Degrade to plain set */
394- filter -> action . type = ACTION_TYPE_GROUP_SET ;
395- filter -> func = xkb_filter_group_set_func ;
396- xkb_filter_group_set_new ( state , filter ) ;
409+ else if ( xkb_action_breaks_latch ( & ( actions [ k ]))) {
410+ /* Breaks the latch */
411+ state -> components . latched_group = 0 ;
412+ filter -> func = NULL ;
413+ return XKB_FILTER_CONTINUE ;
397414 }
398- filter -> key = key ;
399- state -> components .latched_group -= priv .group_delta ;
400- /* XXX beep beep! */
401- return XKB_FILTER_CONSUME ;
402- }
403- else if (xkb_action_breaks_latch (action )) {
404- /* Breaks the latch */
405- state -> components .latched_group = 0 ;
406- filter -> func = NULL ;
407- return XKB_FILTER_CONTINUE ;
408415 }
409416 }
410417 else if (direction == XKB_KEY_UP && key == filter -> key ) {
@@ -533,32 +540,35 @@ xkb_filter_mod_latch_func(struct xkb_state *state,
533540 * keypress, then either break the latch if any random key is pressed,
534541 * or promote it to a lock or plain base set if it's the same
535542 * modifier. */
536- const union xkb_action * action = xkb_key_get_action (state , key );
537- if (action -> type == ACTION_TYPE_MOD_LATCH &&
538- action -> mods .flags == filter -> action .mods .flags &&
539- action -> mods .mods .mask == filter -> action .mods .mods .mask ) {
540- filter -> action = * action ;
541- if (filter -> action .mods .flags & ACTION_LATCH_TO_LOCK ) {
542- filter -> action .type = ACTION_TYPE_MOD_LOCK ;
543- filter -> func = xkb_filter_mod_lock_func ;
544- state -> components .locked_mods |= filter -> action .mods .mods .mask ;
543+ const union xkb_action * actions = NULL ;
544+ unsigned int count = xkb_key_get_actions (state , key , & actions );
545+ for (unsigned int k = 0 ; k < count ; k ++ ) {
546+ if (actions [k ].type == ACTION_TYPE_MOD_LATCH &&
547+ actions [k ].mods .flags == filter -> action .mods .flags &&
548+ actions [k ].mods .mods .mask == filter -> action .mods .mods .mask ) {
549+ filter -> action = actions [k ];
550+ if (filter -> action .mods .flags & ACTION_LATCH_TO_LOCK ) {
551+ filter -> action .type = ACTION_TYPE_MOD_LOCK ;
552+ filter -> func = xkb_filter_mod_lock_func ;
553+ state -> components .locked_mods |= filter -> action .mods .mods .mask ;
554+ }
555+ else {
556+ filter -> action .type = ACTION_TYPE_MOD_SET ;
557+ filter -> func = xkb_filter_mod_set_func ;
558+ state -> set_mods = filter -> action .mods .mods .mask ;
559+ }
560+ filter -> key = key ;
561+ state -> components .latched_mods &= ~filter -> action .mods .mods .mask ;
562+ /* XXX beep beep! */
563+ return XKB_FILTER_CONSUME ;
545564 }
546- else {
547- filter -> action .type = ACTION_TYPE_MOD_SET ;
548- filter -> func = xkb_filter_mod_set_func ;
549- state -> set_mods = filter -> action .mods .mods .mask ;
565+ else if (xkb_action_breaks_latch (& (actions [k ]))) {
566+ /* XXX: This may be totally broken, we might need to break the
567+ * latch in the next run after this press? */
568+ state -> components .latched_mods &= ~filter -> action .mods .mods .mask ;
569+ filter -> func = NULL ;
570+ return XKB_FILTER_CONTINUE ;
550571 }
551- filter -> key = key ;
552- state -> components .latched_mods &= ~filter -> action .mods .mods .mask ;
553- /* XXX beep beep! */
554- return XKB_FILTER_CONSUME ;
555- }
556- else if (xkb_action_breaks_latch (action )) {
557- /* XXX: This may be totally broken, we might need to break the
558- * latch in the next run after this press? */
559- state -> components .latched_mods &= ~filter -> action .mods .mods .mask ;
560- filter -> func = NULL ;
561- return XKB_FILTER_CONTINUE ;
562572 }
563573 }
564574 else if (direction == XKB_KEY_UP && key == filter -> key ) {
@@ -631,7 +641,8 @@ xkb_filter_apply_all(struct xkb_state *state,
631641 enum xkb_key_direction direction )
632642{
633643 struct xkb_filter * filter ;
634- const union xkb_action * action ;
644+ const union xkb_action * actions = NULL ;
645+ unsigned int count ;
635646 bool consumed ;
636647
637648 /* First run through all the currently active filters and see if any of
@@ -648,28 +659,38 @@ xkb_filter_apply_all(struct xkb_state *state,
648659 return ;
649660
650661 /* No filter consumed this event, so proceed with the key action */
651- action = xkb_key_get_action (state , key );
652-
653- /*
654- * It's possible for the keymap to set action->type explicitly, like so:
655- * interpret XF86_Next_VMode {
656- * action = Private(type=0x86, data="+VMode");
657- * };
658- * We don't handle those.
659- */
660- if (action -> type >= _ACTION_TYPE_NUM_ENTRIES )
661- return ;
662+ count = xkb_key_get_actions (state , key , & actions );
663+
664+ for (unsigned int k = 0 ; k < count ; k ++ ) {
665+ /* FIXME: remove debug */
666+ if (count > 1 ) {
667+ log_vrb (
668+ state -> keymap -> ctx , 0 , 0 ,
669+ "xkb_filter_apply_all: key: %u, index: %u, action type: %d\n" ,
670+ key -> keycode , k , actions [k ].type
671+ );
672+ }
673+ /*
674+ * It's possible for the keymap to set action->type explicitly, like so:
675+ * interpret XF86_Next_VMode {
676+ * action = Private(type=0x86, data="+VMode");
677+ * };
678+ * We don't handle those.
679+ */
680+ if (actions [k ].type >= _ACTION_TYPE_NUM_ENTRIES )
681+ return ;
662682
663683 /* Return if no corresponding action */
664- if (!filter_action_funcs [action -> type ].new )
665- return ;
684+ if (!filter_action_funcs [actions [ k ]. type ].new )
685+ return ;
666686
667687 /* Add a new filter and run the corresponding initial action */
668- filter = xkb_filter_new (state );
669- filter -> key = key ;
670- filter -> func = filter_action_funcs [action -> type ].func ;
671- filter -> action = * action ;
672- filter_action_funcs [action -> type ].new (state , filter );
688+ filter = xkb_filter_new (state );
689+ filter -> key = key ;
690+ filter -> func = filter_action_funcs [actions [k ].type ].func ;
691+ filter -> action = actions [k ];
692+ filter_action_funcs [actions [k ].type ].new (state , filter );
693+ }
673694}
674695
675696XKB_EXPORT struct xkb_state *
0 commit comments