Properly free xkb_state's
[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  *
30  * Permission is hereby granted, free of charge, to any person obtaining a
31  * copy of this software and associated documentation files (the "Software"),
32  * to deal in the Software without restriction, including without limitation
33  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34  * and/or sell copies of the Software, and to permit persons to whom the
35  * Software is furnished to do so, subject to the following conditions:
36  *
37  * The above copyright notice and this permission notice (including the next
38  * paragraph) shall be included in all copies or substantial portions of the
39  * Software.
40  *
41  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47  * DEALINGS IN THE SOFTWARE.
48  *
49  * Author: Daniel Stone <daniel@fooishbar.org>
50  */
51
52 /*
53  * This is a bastardised version of xkbActions.c from the X server which
54  * does not support, for the moment:
55  *   - AccessX sticky/debounce/etc (will come later)
56  *   - pointer keys (may come later)
57  *   - key redirects (unlikely)
58  *   - messages (very unlikely)
59  */
60
61 #ifdef HAVE_CONFIG_H
62 #include <config.h>
63 #endif
64
65 #include <assert.h>
66
67 #include "xkbcommon/xkbcommon.h"
68 #include "XKBcommonint.h"
69
70 struct xkb_filter {
71     struct xkb_state *state;
72     union xkb_action action;
73     xkb_keycode_t keycode;
74     uint32_t priv;
75     int (*func)(struct xkb_filter *filter, xkb_keycode_t key,
76                 enum xkb_key_direction direction);
77     int refcnt;
78     struct xkb_filter *next;
79 };
80
81 static union xkb_action *
82 xkb_key_get_action(struct xkb_state *state, xkb_keycode_t key)
83 {
84     int group, level;
85
86     if (!XkbKeyHasActions(state->xkb, key) ||
87         !XkbKeycodeInRange(state->xkb, key)) {
88         static union xkb_action fake;
89         memset(&fake, 0, sizeof(fake));
90         fake.type = XkbSA_NoAction;
91         return &fake;
92     }
93
94     group = xkb_key_get_group(state, key);
95     level = xkb_key_get_level(state, key, group);
96
97     return XkbKeyActionEntry(state->xkb, key, level, group);
98 }
99
100 static struct xkb_filter *
101 xkb_filter_new(struct xkb_state *state)
102 {
103     int i;
104     int old_size = state->num_filters;
105     struct xkb_filter *filters = state->filters;
106
107     for (i = 0; i < state->num_filters; i++) {
108         if (filters[i].func)
109             continue;
110         filters[i].state = state;
111         filters[i].refcnt = 1;
112         return &filters[i];
113     }
114
115     if (state->num_filters > 0)
116         state->num_filters *= 2;
117     else
118         state->num_filters = 4;
119     filters = realloc(filters, state->num_filters * sizeof(*filters));
120     if (!filters) { /* WSGO */
121         state->num_filters = old_size;
122         return NULL;
123     }
124     state->filters = filters;
125     memset(&filters[old_size], 0,
126            (state->num_filters - old_size) * sizeof(*filters));
127
128     filters[old_size].state = state;
129     filters[old_size].refcnt = 1;
130
131     return &filters[old_size];
132 }
133
134 /***====================================================================***/
135
136 static int
137 xkb_filter_group_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
138                           enum xkb_key_direction direction)
139 {
140     if (keycode != filter->keycode) {
141         filter->action.group.flags &= ~XkbSA_ClearLocks;
142         return 1;
143     }
144
145     if (direction == XKB_KEY_DOWN) {
146         filter->refcnt++;
147         return 0;
148     }
149     else if (--filter->refcnt > 0) {
150         return 0;
151     }
152
153     if (filter->action.group.flags & XkbSA_GroupAbsolute)
154         filter->state->base_group = filter->action.group.group;
155     else
156         filter->state->base_group = -filter->action.group.group;
157     if (filter->action.group.flags & XkbSA_ClearLocks)
158         filter->state->locked_group = 0;
159
160     filter->func = NULL;
161
162     return 1;
163 }
164
165 static int
166 xkb_filter_group_set_new(struct xkb_state *state, xkb_keycode_t keycode,
167                          union xkb_action *action)
168 {
169     struct xkb_filter *filter = xkb_filter_new(state);
170
171     if (!filter) /* WSGO */
172         return -1;
173     filter->keycode = keycode;
174     filter->func = xkb_filter_group_set_func;
175     filter->action = *action;
176
177     if (action->group.flags & XkbSA_GroupAbsolute) {
178         filter->action.group.group = filter->state->base_group;
179         filter->state->base_group = action->group.group;
180     }
181     else {
182         filter->state->base_group += action->group.group;
183     }
184
185     return 1;
186 }
187
188 static int
189 xkb_filter_mod_set_func(struct xkb_filter *filter, xkb_keycode_t keycode,
190                         enum xkb_key_direction direction)
191 {
192     if (keycode != filter->keycode) {
193         filter->action.mods.flags &= ~XkbSA_ClearLocks;
194         return 1;
195     }
196
197     if (direction == XKB_KEY_DOWN) {
198         filter->refcnt++;
199         return 0;
200     }
201     else if (--filter->refcnt > 0) {
202         return 0;
203     }
204
205     filter->state->base_mods &= ~(filter->action.mods.mask);
206     if (filter->action.mods.flags & XkbSA_ClearLocks)
207         filter->state->locked_mods &= ~filter->action.mods.mask;
208
209     filter->func = NULL;
210
211     return 1;
212 }
213
214 static int
215 xkb_filter_mod_set_new(struct xkb_state *state, xkb_keycode_t keycode,
216                        union xkb_action *action)
217 {
218     struct xkb_filter *filter = xkb_filter_new(state);
219
220     if (!filter) /* WSGO */
221         return -1;
222     filter->keycode = keycode;
223     filter->func = xkb_filter_mod_set_func;
224     filter->action = *action;
225
226     filter->state->base_mods |= action->mods.mask;
227
228     return 1;
229 }
230
231 static int
232 xkb_filter_mod_lock_func(struct xkb_filter *filter, xkb_keycode_t keycode,
233                          enum xkb_key_direction direction)
234 {
235     if (keycode != filter->keycode)
236         return 1;
237
238     if (direction == XKB_KEY_DOWN) {
239         filter->refcnt++;
240         return 0;
241     }
242     if (--filter->refcnt > 0)
243         return 0;
244
245     filter->state->locked_mods &= ~filter->priv;
246     filter->func = NULL;
247     return 1;
248 }
249
250 static int
251 xkb_filter_mod_lock_new(struct xkb_state *state, xkb_keycode_t keycode,
252                         union xkb_action *action)
253 {
254     struct xkb_filter *filter = xkb_filter_new(state);
255
256     if (!filter) /* WSGO */
257         return 0;
258
259     filter->keycode = keycode;
260     filter->func = xkb_filter_mod_lock_func;
261     filter->action = *action;
262     filter->priv = state->locked_mods & action->mods.mask;
263     state->locked_mods |= action->mods.mask;
264
265     return 1;
266 }
267
268 enum xkb_key_latch_state {
269     NO_LATCH,
270     LATCH_KEY_DOWN,
271     LATCH_PENDING,
272 };
273
274 static int
275 xkb_filter_mod_latch_func(struct xkb_filter *filter, xkb_keycode_t keycode,
276                           enum xkb_key_direction direction)
277 {
278     enum xkb_key_latch_state latch = filter->priv;
279
280     if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) {
281         /* If this is a new keypress and we're awaiting our single latched
282          * keypress, then either break the latch if any random key is pressed,
283          * or promote it to a lock or plain base set if it's the same
284          * modifier. */
285         union xkb_action *action = xkb_key_get_action(filter->state, keycode);
286         if (action->type == XkbSA_LatchMods &&
287             action->mods.flags == filter->action.mods.flags &&
288             action->mods.mask == filter->action.mods.mask) {
289             filter->action = *action;
290             if (filter->action.mods.flags & XkbSA_LatchToLock) {
291                 filter->action.type = XkbSA_LockMods;
292                 filter->func = xkb_filter_mod_lock_func;
293                 filter->state->locked_mods |= filter->action.mods.mask;
294             }
295             else {
296                 filter->action.type = XkbSA_SetMods;
297                 filter->func = xkb_filter_mod_set_func;
298                 filter->state->base_mods |= filter->action.mods.mask;
299             }
300             filter->keycode = keycode;
301             filter->state->latched_mods &= ~filter->action.mods.mask;
302             /* XXX beep beep! */
303             return 0;
304         }
305         else if (((1 << action->type) & XkbSA_BreakLatch)) {
306             /* XXX: This may be totally broken, we might need to break the
307              *      latch in the next run after this press? */
308             filter->state->latched_mods &= ~filter->action.mods.mask;
309             filter->func = NULL;
310             return 1;
311         }
312     }
313     else if (direction == XKB_KEY_UP && keycode == filter->keycode) {
314         /* Our key got released.  If we've set it to clear locks, and we
315          * currently have the same modifiers locked, then release them and
316          * don't actually latch.  Else we've actually hit the latching
317          * stage, so set PENDING and move our modifier from base to
318          * latched. */
319         if (latch == NO_LATCH ||
320             ((filter->action.mods.flags & XkbSA_ClearLocks) &&
321              (filter->state->locked_mods & filter->action.mods.mask) ==
322              filter->action.mods.mask)) {
323             /* XXX: We might be a bit overenthusiastic about clearing
324              *      mods other filters have set here? */
325             if (latch == LATCH_PENDING)
326                 filter->state->latched_mods &= ~filter->action.mods.mask;
327             else
328                 filter->state->base_mods &= ~filter->action.mods.mask;
329             filter->state->locked_mods &= ~filter->action.mods.mask;
330             filter->func = NULL;
331         }
332         else {
333             latch = LATCH_PENDING;
334             filter->state->base_mods &= ~filter->action.mods.mask;
335             filter->state->latched_mods |= filter->action.mods.mask;
336             /* XXX beep beep! */
337         }
338     }
339     else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) {
340         /* Someone's pressed another key while we've still got the latching
341          * key held down, so keep the base modifier state active (from
342          * xkb_filter_mod_latch_new), but don't trip the latch, just clear
343          * it as soon as the modifier gets released. */
344         latch = NO_LATCH;
345     }
346
347     filter->priv = latch;
348
349     return 1;
350 }
351
352 static int
353 xkb_filter_mod_latch_new(struct xkb_state *state, xkb_keycode_t keycode,
354                          union xkb_action *action)
355 {
356     struct xkb_filter *filter = xkb_filter_new(state);
357     enum xkb_key_latch_state latch = LATCH_KEY_DOWN;
358
359     if (!filter) /* WSGO */
360         return -1;
361     filter->keycode = keycode;
362     filter->priv = latch;
363     filter->func = xkb_filter_mod_latch_func;
364     filter->action = *action;
365
366     filter->state->base_mods |= action->mods.mask;
367
368     return 1;
369 }
370
371 /**
372  * Applies any relevant filters to the key, first from the list of filters
373  * that are currently active, then if no filter has claimed the key, possibly
374  * apply a new filter from the key action.
375  */
376 static void
377 xkb_filter_apply_all(struct xkb_state *state, xkb_keycode_t key,
378                      enum xkb_key_direction direction)
379 {
380     struct xkb_filter *filters = state->filters;
381     union xkb_action *act = NULL;
382     int send = 1;
383     int i;
384
385     /* First run through all the currently active filters and see if any of
386      * them have claimed this event. */
387     for (i = 0; i < state->num_filters; i++) {
388         if (!filters[i].func)
389             continue;
390         send &= (*filters[i].func)(&filters[i], key, direction);
391     }
392
393     if (!send || direction == XKB_KEY_UP)
394         return;
395
396     act = xkb_key_get_action(state, key);
397     switch (act->type) {
398     case XkbSA_SetMods:
399         send = xkb_filter_mod_set_new(state, key, act);
400         break;
401     case XkbSA_LatchMods:
402         send = xkb_filter_mod_latch_new(state, key, act);
403         break;
404     case XkbSA_LockMods:
405         send = xkb_filter_mod_lock_new(state, key, act);
406         break;
407     case XkbSA_SetGroup:
408         send = xkb_filter_group_set_new(state, key, act);
409         break;
410 #if 0
411     case XkbSA_LatchGroup:
412         send = xkb_filter_mod_latch_new(state, key, act);
413         break;
414     case XkbSA_LockGroup:
415         send = xkb_filter_group_lock_new(state, key, act);
416         break;
417 #endif
418     }
419
420     return;
421 }
422
423 struct xkb_state *
424 xkb_state_new(struct xkb_desc *xkb)
425 {
426     struct xkb_state *ret;
427
428     if (!xkb)
429         return NULL;
430
431     ret = calloc(sizeof(*ret), 1);
432     if (!ret)
433         return NULL;
434
435     ret->refcnt = 1;
436     ret->xkb = xkb;
437     xkb_map_ref(xkb);
438
439     return ret;
440 }
441
442 void
443 xkb_state_unref(struct xkb_state *state)
444 {
445     state->refcnt--;
446     assert(state->refcnt >= 0);
447     if (state->refcnt > 0)
448         return;
449
450     xkb_map_unref(state->xkb);
451     free(state->filters);
452     free(state);
453 }
454
455 /**
456  * Update the LED state to match the rest of the xkb_state.
457  */
458 static void
459 xkb_state_led_update_all(struct xkb_state *state)
460 {
461     xkb_led_index_t led;
462
463     state->leds = 0;
464
465     for (led = 0; led < XkbNumIndicators; led++) {
466         struct xkb_indicator_map *map = &state->xkb->indicators->maps[led];
467         uint32_t mod_mask = 0;
468         uint32_t group_mask = 0;
469
470         if (!map->which_mods && !map->which_groups && !map->ctrls)
471             continue;
472
473         if (map->which_mods) {
474             if (map->which_mods & XkbIM_UseBase)
475                 mod_mask |= state->base_mods;
476             if (map->which_mods & XkbIM_UseLatched)
477                 mod_mask |= state->latched_mods;
478             if (map->which_mods & XkbIM_UseLocked)
479                 mod_mask |= state->locked_mods;
480             if (map->which_mods & XkbIM_UseEffective)
481                 mod_mask |= state->mods;
482             if ((map->mods.mask & mod_mask))
483                 state->leds |= (1 << led);
484         }
485         else if (map->which_groups) {
486             if (map->which_mods & XkbIM_UseBase)
487                 group_mask |= (1 << state->base_group);
488             if (map->which_mods & XkbIM_UseLatched)
489                 group_mask |= (1 << state->latched_group);
490             if (map->which_mods & XkbIM_UseLocked)
491                 group_mask |= (1 << state->locked_group);
492             if (map->which_mods & XkbIM_UseEffective)
493                 group_mask |= (1 << state->group);
494             if ((map->groups & group_mask))
495                 state->leds |= (1 << led);
496         }
497         else if (map->ctrls) {
498             if ((map->ctrls & state->xkb->ctrls->enabled_ctrls))
499                 state->leds |= (1 << led);
500         }
501     }
502 }
503
504 /**
505  * Calculates the derived state (effective mods/group and LEDs) from an
506  * up-to-date xkb_state.
507  */
508 static void
509 xkb_state_update_derived(struct xkb_state *state)
510 {
511     state->mods = (state->base_mods | state->latched_mods | state->locked_mods);
512     /* FIXME: Clamp/wrap locked_group */
513     state->group = state->locked_group + state->base_group +
514                    state->latched_group;
515     /* FIXME: Clamp/wrap effective group */
516
517     xkb_state_led_update_all(state);
518 }
519
520 /**
521  * Given a particular key event, updates the state structure to reflect the
522  * new modifiers.
523  */
524 void
525 xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
526                      enum xkb_key_direction direction)
527 {
528     xkb_filter_apply_all(state, key, direction);
529     xkb_state_update_derived(state);
530 }
531
532 /**
533  * Updates the state from a set of explicit masks as gained from
534  * xkb_state_serialise_mods and xkb_state_serialise_groups.  As noted in the
535  * documentation for these functions in xkbcommon.h, this round-trip is
536  * lossy, and should only be used to update a slave state mirroring the
537  * master, e.g. in a client/server window system.
538  */
539 void
540 xkb_state_update_mask(struct xkb_state *state,
541                       xkb_mod_mask_t base_mods,
542                       xkb_mod_mask_t latched_mods,
543                       xkb_mod_mask_t locked_mods,
544                       xkb_group_index_t base_group,
545                       xkb_group_index_t latched_group,
546                       xkb_group_index_t locked_group)
547 {
548     xkb_mod_mask_t mod;
549
550     state->base_mods = 0;
551     state->latched_mods = 0;
552     state->locked_mods = 0;
553     for (mod = 0; mod < xkb_map_num_mods(state->xkb); mod++) {
554         xkb_mod_mask_t idx = (1 << mod);
555         if (base_mods & idx)
556             state->base_mods |= idx;
557         if (latched_mods & idx)
558             state->latched_mods |= idx;
559         if (locked_mods & idx)
560             state->locked_mods |= idx;
561     }
562
563     state->base_group = base_group;
564     state->latched_group = latched_group;
565     state->locked_group = locked_group;
566
567     xkb_state_update_derived(state);
568 }
569
570 /**
571  * Serialises the requested modifier state into an xkb_mod_mask_t, with all
572  * the same disclaimers as in xkb_state_update_mask.
573  */
574 xkb_mod_mask_t
575 xkb_state_serialise_mods(struct xkb_state *state,
576                          enum xkb_state_component type)
577 {
578     xkb_mod_mask_t ret = 0;
579
580     if (type == XKB_STATE_EFFECTIVE)
581         return state->mods;
582
583     if (type & XKB_STATE_DEPRESSED)
584         ret |= state->base_mods;
585     if (type & XKB_STATE_LATCHED)
586         ret |= state->latched_mods;
587     if (type & XKB_STATE_LOCKED)
588         ret |= state->locked_mods;
589
590     return ret;
591 }
592
593 /**
594  * Serialises the requested group state, with all the same disclaimers as
595  * in xkb_state_update_mask.
596  */
597 xkb_group_index_t
598 xkb_state_serialise_group(struct xkb_state *state,
599                           enum xkb_state_component type)
600 {
601     xkb_group_index_t ret = 0;
602
603     if (type == XKB_STATE_EFFECTIVE)
604         return state->group;
605
606     if (type & XKB_STATE_DEPRESSED)
607         ret += state->base_group;
608     if (type & XKB_STATE_LATCHED)
609         ret += state->latched_group;
610     if (type & XKB_STATE_LOCKED)
611         ret += state->locked_group;
612
613     return ret;
614 }
615
616 /**
617  * Returns 1 if the given modifier is active with the specified type(s), 0 if
618  * not, or -1 if the modifier is invalid.
619  */
620 int
621 xkb_state_mod_index_is_active(struct xkb_state *state,
622                               xkb_mod_index_t idx,
623                               enum xkb_state_component type)
624 {
625     int ret = 0;
626
627     if (idx >= xkb_map_num_mods(state->xkb))
628         return -1;
629
630     if (type & XKB_STATE_DEPRESSED)
631         ret |= (state->base_mods & (1 << idx));
632     if (type & XKB_STATE_LATCHED)
633         ret |= (state->latched_mods & (1 << idx));
634     if (type & XKB_STATE_LOCKED)
635         ret |= (state->locked_mods & (1 << idx));
636
637     return ret;
638 }
639
640 /**
641  * Returns 1 if the given modifier is active with the specified type(s), 0 if
642  * not, or -1 if the modifier is invalid.
643  */
644 int
645 xkb_state_mod_name_is_active(struct xkb_state *state, const char *name,
646                              enum xkb_state_component type)
647 {
648     xkb_mod_index_t idx = xkb_map_mod_get_index(state->xkb, name);
649
650     if (idx == XKB_MOD_INVALID)
651         return -1;
652
653     return xkb_state_mod_index_is_active(state, idx, type);
654 }
655
656 /**
657  * Returns 1 if the given group is active with the specified type(s), 0 if
658  * not, or -1 if the group is invalid.
659  */
660 int
661 xkb_state_group_index_is_active(struct xkb_state *state,
662                                 xkb_group_index_t idx,
663                                 enum xkb_state_component type)
664 {
665     int ret = 0;
666
667     if (idx >= xkb_map_num_groups(state->xkb))
668         return -1;
669
670     if (type & XKB_STATE_DEPRESSED)
671         ret |= (state->base_group == idx);
672     if (type & XKB_STATE_LATCHED)
673         ret |= (state->latched_group == idx);
674     if (type & XKB_STATE_LOCKED)
675         ret |= (state->locked_group == idx);
676
677     return ret;
678 }
679
680 /**
681  * Returns 1 if the given modifier is active with the specified type(s), 0 if
682  * not, or -1 if the modifier is invalid.
683  */
684 int
685 xkb_state_group_name_is_active(struct xkb_state *state, const char *name,
686                                enum xkb_state_component type)
687 {
688     xkb_group_index_t idx = xkb_map_group_get_index(state->xkb, name);
689
690     if (idx == XKB_GROUP_INVALID)
691         return -1;
692
693     return xkb_state_group_index_is_active(state, idx, type);
694 }
695
696 /**
697  * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
698  */
699 int
700 xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
701 {
702     if (idx >= xkb_map_num_leds(state->xkb))
703         return -1;
704
705     return !!(state->leds & (1 << idx));
706 }
707
708 /**
709  * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid.
710  */
711 int
712 xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
713 {
714     xkb_led_index_t idx = xkb_map_led_get_index(state->xkb, name);
715
716     if (idx == XKB_LED_INVALID)
717         return -1;
718
719     return xkb_state_led_index_is_active(state, idx);
720 }