state: use darray for filters
[platform/upstream/libxkbcommon.git] / test / state.c
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Author: Daniel Stone <daniel@fooishbar.org>
24  */
25
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <linux/input.h>
30
31 #include "xkbcommon/xkbcommon.h"
32 #include "xkbcommon/xkbcommon-names.h"
33 #include "xkb-priv.h"
34
35 /* Offset between evdev keycodes (where KEY_ESCAPE is 1), and the evdev XKB
36  * keycode set (where ESC is 9). */
37 #define EVDEV_OFFSET 8
38
39 static void
40 print_state(struct xkb_state *state)
41 {
42     struct xkb_keymap *keymap;
43     xkb_group_index_t group;
44     xkb_mod_index_t mod;
45     xkb_led_index_t led;
46
47     group = xkb_state_serialize_group(state, XKB_STATE_EFFECTIVE);
48     mod = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
49     /* led = xkb_state_serialize_leds(state, XKB_STATE_EFFECTIVE); */
50     if (!group && !mod /* && !led */) {
51         fprintf(stderr, "\tno state\n");
52         return;
53     }
54
55     keymap = xkb_state_get_map(state);
56
57     for (group = 0; group < xkb_map_num_groups(keymap); group++) {
58         if (!xkb_state_group_index_is_active(state, group, XKB_STATE_EFFECTIVE))
59             continue;
60         fprintf(stderr, "\tgroup %s (%d): %s%s%s%s\n",
61                 xkb_map_group_get_name(keymap, group),
62                 group,
63                 xkb_state_group_index_is_active(state, group, XKB_STATE_EFFECTIVE) ?
64                     "effective " : "",
65                 xkb_state_group_index_is_active(state, group, XKB_STATE_DEPRESSED) ?
66                     "depressed " : "",
67                 xkb_state_group_index_is_active(state, group, XKB_STATE_LATCHED) ?
68                     "latched " : "",
69                 xkb_state_group_index_is_active(state, group, XKB_STATE_LOCKED) ?
70                     "locked " : "");
71     }
72
73     for (mod = 0; mod < xkb_map_num_mods(keymap); mod++) {
74         if (!xkb_state_mod_index_is_active(state, mod, XKB_STATE_EFFECTIVE))
75             continue;
76         fprintf(stderr, "\tmod %s (%d): %s%s%s\n",
77                 xkb_map_mod_get_name(keymap, mod),
78                 mod,
79                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_DEPRESSED) ?
80                     "depressed " : "",
81                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_LATCHED) ?
82                     "latched " : "",
83                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_LOCKED) ?
84                     "locked " : "");
85     }
86
87     for (led = 0; led < xkb_map_num_leds(keymap); led++) {
88         if (!xkb_state_led_index_is_active(state, led))
89             continue;
90         fprintf(stderr, "\tled %s (%d): active\n",
91                 xkb_map_led_get_name(keymap, led),
92                 led);
93     }
94 }
95
96 static void
97 test_update_key(struct xkb_keymap *keymap)
98 {
99     struct xkb_state *state = xkb_state_new(keymap);
100     const xkb_keysym_t *syms;
101     int num_syms;
102
103     assert(state);
104
105     /* LCtrl down */
106     xkb_state_update_key(state, KEY_LEFTCTRL + EVDEV_OFFSET, XKB_KEY_DOWN);
107     fprintf(stderr, "dumping state for LCtrl down:\n");
108     print_state(state);
109     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
110                                         XKB_STATE_DEPRESSED));
111
112     /* LCtrl + RAlt down */
113     xkb_state_update_key(state, KEY_RIGHTALT + EVDEV_OFFSET, XKB_KEY_DOWN);
114     fprintf(stderr, "dumping state for LCtrl + RAlt down:\n");
115     print_state(state);
116     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
117                                         XKB_STATE_DEPRESSED));
118     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
119                                         XKB_STATE_DEPRESSED));
120     assert(xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
121                                           XKB_STATE_MATCH_ALL,
122                                           XKB_MOD_NAME_CTRL,
123                                           XKB_MOD_NAME_ALT,
124                                           NULL));
125     assert(!xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
126                                            XKB_STATE_MATCH_ALL,
127                                            XKB_MOD_NAME_ALT,
128                                            NULL));
129     assert(xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
130                                           (XKB_STATE_MATCH_ANY |
131                                            XKB_STATE_MATCH_NON_EXCLUSIVE),
132                                           XKB_MOD_NAME_ALT,
133                                           NULL));
134
135     /* RAlt down */
136     xkb_state_update_key(state, KEY_LEFTCTRL + EVDEV_OFFSET, XKB_KEY_UP);
137     fprintf(stderr, "dumping state for RAlt down:\n");
138     print_state(state);
139     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
140                                          XKB_STATE_EFFECTIVE));
141     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
142                                         XKB_STATE_DEPRESSED));
143     assert(xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
144                                           XKB_STATE_MATCH_ANY,
145                                           XKB_MOD_NAME_CTRL,
146                                           XKB_MOD_NAME_ALT,
147                                           NULL));
148
149     /* none down */
150     xkb_state_update_key(state, KEY_RIGHTALT + EVDEV_OFFSET, XKB_KEY_UP);
151     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
152                                          XKB_STATE_EFFECTIVE));
153
154     /* Caps locked */
155     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
156     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
157     fprintf(stderr, "dumping state for Caps Lock:\n");
158     print_state(state);
159     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
160                                         XKB_STATE_LOCKED));
161     assert(xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS));
162     num_syms = xkb_key_get_syms(state, KEY_Q + EVDEV_OFFSET, &syms);
163     assert(num_syms == 1 && syms[0] == XKB_KEY_Q);
164
165     /* Caps unlocked */
166     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
167     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
168     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
169                                          XKB_STATE_EFFECTIVE));
170     assert(!xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS));
171     num_syms = xkb_key_get_syms(state, KEY_Q + EVDEV_OFFSET, &syms);
172     assert(num_syms == 1 && syms[0] == XKB_KEY_q);
173
174     xkb_state_unref(state);
175 }
176
177 static void
178 test_serialisation(struct xkb_keymap *keymap)
179 {
180     struct xkb_state *state = xkb_state_new(keymap);
181     xkb_mod_mask_t base_mods;
182     xkb_mod_mask_t latched_mods;
183     xkb_mod_mask_t locked_mods;
184     xkb_mod_mask_t effective_mods;
185     xkb_mod_index_t caps, shift, ctrl;
186     xkb_group_index_t base_group = 0;
187     xkb_group_index_t latched_group = 0;
188     xkb_group_index_t locked_group = 0;
189
190     assert(state);
191
192     caps = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
193     assert(caps != XKB_MOD_INVALID);
194     shift = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
195     assert(shift != XKB_MOD_INVALID);
196     ctrl = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
197     assert(ctrl != XKB_MOD_INVALID);
198
199     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
200     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
201     base_mods = xkb_state_serialize_mods(state, XKB_STATE_DEPRESSED);
202     assert(base_mods == 0);
203     latched_mods = xkb_state_serialize_mods(state, XKB_STATE_LATCHED);
204     assert(latched_mods == 0);
205     locked_mods = xkb_state_serialize_mods(state, XKB_STATE_LOCKED);
206     assert(locked_mods == (1 << caps));
207     effective_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
208     assert(effective_mods == locked_mods);
209
210     xkb_state_update_key(state, KEY_LEFTSHIFT + EVDEV_OFFSET, XKB_KEY_DOWN);
211     base_mods = xkb_state_serialize_mods(state, XKB_STATE_DEPRESSED);
212     assert(base_mods == (1 << shift));
213     latched_mods = xkb_state_serialize_mods(state, XKB_STATE_LATCHED);
214     assert(latched_mods == 0);
215     locked_mods = xkb_state_serialize_mods(state, XKB_STATE_LOCKED);
216     assert(locked_mods == (1 << caps));
217     effective_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
218     assert(effective_mods == (base_mods | locked_mods));
219
220     base_mods |= (1 << ctrl);
221     xkb_state_update_mask(state, base_mods, latched_mods, locked_mods,
222                           base_group, latched_group, locked_group);
223
224     assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_DEPRESSED));
225     assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_EFFECTIVE));
226
227     xkb_state_unref(state);
228 }
229
230 int
231 main(void)
232 {
233     struct xkb_context *context;
234     struct xkb_keymap *keymap;
235     struct xkb_rule_names rmlvo = {
236         .rules = "evdev",
237         .model = "pc104",
238         .layout = "us",
239         .variant = NULL,
240         .options = NULL,
241     };
242
243     context = xkb_context_new(0);
244     assert(context);
245
246     keymap = xkb_map_new_from_names(context, &rmlvo, 0);
247     assert(keymap);
248
249     test_update_key(keymap);
250     test_serialisation(keymap);
251
252     xkb_map_unref(keymap);
253     xkb_context_unref(context);
254 }