state: apply capitalization transformation on keysyms
[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 "test.h"
32
33 /* Offset between evdev keycodes (where KEY_ESCAPE is 1), and the evdev XKB
34  * keycode set (where ESC is 9). */
35 #define EVDEV_OFFSET 8
36
37 static void
38 print_state(struct xkb_state *state)
39 {
40     struct xkb_keymap *keymap;
41     xkb_layout_index_t group;
42     xkb_mod_index_t mod;
43     xkb_led_index_t led;
44
45     group = xkb_state_serialize_layout(state, XKB_STATE_LAYOUT_EFFECTIVE);
46     mod = xkb_state_serialize_mods(state, XKB_STATE_MODS_EFFECTIVE);
47     /* led = xkb_state_serialize_leds(state, XKB_STATE_LEDS); */
48     if (!group && !mod /* && !led */) {
49         fprintf(stderr, "\tno state\n");
50         return;
51     }
52
53     keymap = xkb_state_get_keymap(state);
54
55     for (group = 0; group < xkb_keymap_num_layouts(keymap); group++) {
56         if (xkb_state_layout_index_is_active(state, group,
57                                              XKB_STATE_LAYOUT_EFFECTIVE |
58                                              XKB_STATE_LAYOUT_DEPRESSED |
59                                              XKB_STATE_LAYOUT_LATCHED |
60                                              XKB_STATE_LAYOUT_LOCKED) <= 0)
61             continue;
62         fprintf(stderr, "\tgroup %s (%d): %s%s%s%s\n",
63                 xkb_keymap_layout_get_name(keymap, group),
64                 group,
65                 xkb_state_layout_index_is_active(state, group, XKB_STATE_LAYOUT_EFFECTIVE) > 0 ?
66                     "effective " : "",
67                 xkb_state_layout_index_is_active(state, group, XKB_STATE_LAYOUT_DEPRESSED) > 0 ?
68                     "depressed " : "",
69                 xkb_state_layout_index_is_active(state, group, XKB_STATE_LAYOUT_LATCHED) > 0 ?
70                     "latched " : "",
71                 xkb_state_layout_index_is_active(state, group, XKB_STATE_LAYOUT_LOCKED) > 0 ?
72                     "locked " : "");
73     }
74
75     for (mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) {
76         if (xkb_state_mod_index_is_active(state, mod,
77                                           XKB_STATE_MODS_EFFECTIVE |
78                                           XKB_STATE_MODS_DEPRESSED |
79                                           XKB_STATE_MODS_LATCHED |
80                                           XKB_STATE_MODS_LOCKED) <= 0)
81             continue;
82         fprintf(stderr, "\tmod %s (%d): %s%s%s%s\n",
83                 xkb_keymap_mod_get_name(keymap, mod),
84                 mod,
85                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_MODS_EFFECTIVE) > 0 ?
86                     "effective " : "",
87                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_MODS_DEPRESSED) > 0 ?
88                     "depressed " : "",
89                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_MODS_LATCHED) > 0 ?
90                     "latched " : "",
91                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_MODS_LOCKED) > 0 ?
92                     "locked " : "");
93     }
94
95     for (led = 0; led < xkb_keymap_num_leds(keymap); led++) {
96         if (xkb_state_led_index_is_active(state, led) <= 0)
97             continue;
98         fprintf(stderr, "\tled %s (%d): active\n",
99                 xkb_keymap_led_get_name(keymap, led),
100                 led);
101     }
102 }
103
104 static void
105 test_update_key(struct xkb_keymap *keymap)
106 {
107     struct xkb_state *state = xkb_state_new(keymap);
108     const xkb_keysym_t *syms;
109     xkb_keysym_t one_sym;
110     int num_syms;
111
112     assert(state);
113
114     /* LCtrl down */
115     xkb_state_update_key(state, KEY_LEFTCTRL + EVDEV_OFFSET, XKB_KEY_DOWN);
116     fprintf(stderr, "dumping state for LCtrl down:\n");
117     print_state(state);
118     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
119                                         XKB_STATE_MODS_DEPRESSED) > 0);
120
121     /* LCtrl + RAlt down */
122     xkb_state_update_key(state, KEY_RIGHTALT + EVDEV_OFFSET, XKB_KEY_DOWN);
123     fprintf(stderr, "dumping state for LCtrl + RAlt down:\n");
124     print_state(state);
125     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
126                                         XKB_STATE_MODS_DEPRESSED) > 0);
127     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
128                                         XKB_STATE_MODS_DEPRESSED) > 0);
129     assert(xkb_state_mod_names_are_active(state, XKB_STATE_MODS_DEPRESSED,
130                                           XKB_STATE_MATCH_ALL,
131                                           XKB_MOD_NAME_CTRL,
132                                           XKB_MOD_NAME_ALT,
133                                           NULL) > 0);
134     assert(xkb_state_mod_indices_are_active(state, XKB_STATE_MODS_DEPRESSED,
135                                           XKB_STATE_MATCH_ALL,
136                                           xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL),
137                                           xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT),
138                                           XKB_MOD_INVALID) > 0);
139     assert(!xkb_state_mod_names_are_active(state, XKB_STATE_MODS_DEPRESSED,
140                                            XKB_STATE_MATCH_ALL,
141                                            XKB_MOD_NAME_ALT,
142                                            NULL) > 0);
143     assert(xkb_state_mod_names_are_active(state, XKB_STATE_MODS_DEPRESSED,
144                                           (XKB_STATE_MATCH_ANY |
145                                            XKB_STATE_MATCH_NON_EXCLUSIVE),
146                                           XKB_MOD_NAME_ALT,
147                                           NULL));
148
149     /* RAlt down */
150     xkb_state_update_key(state, KEY_LEFTCTRL + EVDEV_OFFSET, XKB_KEY_UP);
151     fprintf(stderr, "dumping state for RAlt down:\n");
152     print_state(state);
153     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
154                                          XKB_STATE_MODS_EFFECTIVE) > 0);
155     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
156                                         XKB_STATE_MODS_DEPRESSED) > 0);
157     assert(xkb_state_mod_names_are_active(state, XKB_STATE_MODS_DEPRESSED,
158                                           XKB_STATE_MATCH_ANY,
159                                           XKB_MOD_NAME_CTRL,
160                                           XKB_MOD_NAME_ALT,
161                                           NULL) > 0);
162     assert(xkb_state_mod_names_are_active(state, XKB_STATE_MODS_LATCHED,
163                                           XKB_STATE_MATCH_ANY,
164                                           XKB_MOD_NAME_CTRL,
165                                           XKB_MOD_NAME_ALT,
166                                           NULL) == 0);
167
168     /* none down */
169     xkb_state_update_key(state, KEY_RIGHTALT + EVDEV_OFFSET, XKB_KEY_UP);
170     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
171                                          XKB_STATE_MODS_EFFECTIVE));
172
173     /* Caps locked */
174     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
175     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
176                                         XKB_STATE_MODS_DEPRESSED) > 0);
177     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
178     fprintf(stderr, "dumping state for Caps Lock:\n");
179     print_state(state);
180     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
181                                         XKB_STATE_MODS_DEPRESSED) == 0);
182     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
183                                         XKB_STATE_MODS_LOCKED) > 0);
184     assert(xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS) > 0);
185     num_syms = xkb_state_key_get_syms(state, KEY_Q + EVDEV_OFFSET, &syms);
186     assert(num_syms == 1 && syms[0] == XKB_KEY_Q);
187
188     /* Num Lock locked */
189     xkb_state_update_key(state, KEY_NUMLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
190     xkb_state_update_key(state, KEY_NUMLOCK + EVDEV_OFFSET, XKB_KEY_UP);
191     fprintf(stderr, "dumping state for Caps Lock + Num Lock:\n");
192     print_state(state);
193     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
194                                         XKB_STATE_MODS_LOCKED) > 0);
195     assert(xkb_state_mod_name_is_active(state, "Mod2",
196                                         XKB_STATE_MODS_LOCKED) > 0);
197     num_syms = xkb_state_key_get_syms(state, KEY_KP1 + EVDEV_OFFSET, &syms);
198     assert(num_syms == 1 && syms[0] == XKB_KEY_KP_1);
199     assert(xkb_state_led_name_is_active(state, XKB_LED_NAME_NUM) > 0);
200
201     /* Num Lock unlocked */
202     xkb_state_update_key(state, KEY_NUMLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
203     xkb_state_update_key(state, KEY_NUMLOCK + EVDEV_OFFSET, XKB_KEY_UP);
204
205     /* Switch to group 2 */
206     xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_DOWN);
207     xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_UP);
208     assert(xkb_state_led_name_is_active(state, "Group 2") > 0);
209     assert(xkb_state_led_name_is_active(state, XKB_LED_NAME_NUM) <= 0);
210
211     /* Switch back to group 1. */
212     xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_DOWN);
213     xkb_state_update_key(state, KEY_COMPOSE + EVDEV_OFFSET, XKB_KEY_UP);
214
215     /* Caps unlocked */
216     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
217     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
218     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
219                                          XKB_STATE_MODS_EFFECTIVE) > 0);
220     assert(!xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS) > 0);
221     num_syms = xkb_state_key_get_syms(state, KEY_Q + EVDEV_OFFSET, &syms);
222     assert(num_syms == 1 && syms[0] == XKB_KEY_q);
223
224     /* Multiple symbols */
225     num_syms = xkb_state_key_get_syms(state, KEY_6 + EVDEV_OFFSET, &syms);
226     assert(num_syms == 5 &&
227            syms[0] == XKB_KEY_H && syms[1] == XKB_KEY_E &&
228            syms[2] == XKB_KEY_L && syms[3] == XKB_KEY_L &&
229            syms[4] == XKB_KEY_O);
230     one_sym = xkb_state_key_get_one_sym(state, KEY_6 + EVDEV_OFFSET);
231     assert(one_sym == XKB_KEY_NoSymbol);
232     xkb_state_update_key(state, KEY_6 + EVDEV_OFFSET, XKB_KEY_DOWN);
233     xkb_state_update_key(state, KEY_6 + EVDEV_OFFSET, XKB_KEY_UP);
234
235     one_sym = xkb_state_key_get_one_sym(state, KEY_5 + EVDEV_OFFSET);
236     assert(one_sym == XKB_KEY_5);
237
238     xkb_state_unref(state);
239 }
240
241 static void
242 test_serialisation(struct xkb_keymap *keymap)
243 {
244     struct xkb_state *state = xkb_state_new(keymap);
245     xkb_mod_mask_t base_mods;
246     xkb_mod_mask_t latched_mods;
247     xkb_mod_mask_t locked_mods;
248     xkb_mod_mask_t effective_mods;
249     xkb_mod_index_t caps, shift, ctrl;
250     xkb_layout_index_t base_group = 0;
251     xkb_layout_index_t latched_group = 0;
252     xkb_layout_index_t locked_group = 0;
253
254     assert(state);
255
256     caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
257     assert(caps != XKB_MOD_INVALID);
258     shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
259     assert(shift != XKB_MOD_INVALID);
260     ctrl = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
261     assert(ctrl != XKB_MOD_INVALID);
262
263     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
264     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
265     base_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_DEPRESSED);
266     assert(base_mods == 0);
267     latched_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
268     assert(latched_mods == 0);
269     locked_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
270     assert(locked_mods == (1 << caps));
271     effective_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_EFFECTIVE);
272     assert(effective_mods == locked_mods);
273
274     xkb_state_update_key(state, KEY_LEFTSHIFT + EVDEV_OFFSET, XKB_KEY_DOWN);
275     base_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_DEPRESSED);
276     assert(base_mods == (1 << shift));
277     latched_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
278     assert(latched_mods == 0);
279     locked_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
280     assert(locked_mods == (1 << caps));
281     effective_mods = xkb_state_serialize_mods(state, XKB_STATE_MODS_EFFECTIVE);
282     assert(effective_mods == (base_mods | locked_mods));
283
284     base_mods |= (1 << ctrl);
285     xkb_state_update_mask(state, base_mods, latched_mods, locked_mods,
286                           base_group, latched_group, locked_group);
287
288     assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_DEPRESSED));
289     assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE));
290
291     xkb_state_unref(state);
292 }
293
294 static void
295 test_repeat(struct xkb_keymap *keymap)
296 {
297     assert(!xkb_keymap_key_repeats(keymap, KEY_LEFTSHIFT + 8));
298     assert(xkb_keymap_key_repeats(keymap, KEY_A + 8));
299     assert(xkb_keymap_key_repeats(keymap, KEY_8 + 8));
300     assert(xkb_keymap_key_repeats(keymap, KEY_DOWN + 8));
301     assert(xkb_keymap_key_repeats(keymap, KEY_KBDILLUMDOWN + 8));
302 }
303
304 static void
305 test_consume(struct xkb_keymap *keymap)
306 {
307     struct xkb_state *state = xkb_state_new(keymap);
308     xkb_mod_index_t alt, shift;
309     xkb_mod_mask_t mask;
310
311     assert(state);
312
313     alt = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
314     assert(alt != XKB_MOD_INVALID);
315     shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
316     assert(shift != XKB_MOD_INVALID);
317
318     xkb_state_update_key(state, KEY_LEFTALT + EVDEV_OFFSET, XKB_KEY_DOWN);
319     xkb_state_update_key(state, KEY_LEFTSHIFT + EVDEV_OFFSET, XKB_KEY_DOWN);
320     xkb_state_update_key(state, KEY_EQUAL + EVDEV_OFFSET, XKB_KEY_DOWN);
321
322     fprintf(stderr, "dumping state for Alt-Shift-+\n");
323     print_state(state);
324
325     mask = xkb_state_serialize_mods(state, XKB_STATE_MODS_EFFECTIVE);
326     assert(mask == ((1 << alt) | (1 << shift)));
327     mask = xkb_state_mod_mask_remove_consumed(state, KEY_EQUAL + EVDEV_OFFSET,
328                                               mask);
329     assert(mask == (1 << alt));
330
331     xkb_state_unref(state);
332 }
333
334 static void
335 key_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
336 {
337     int *counter = (int *) data;
338
339     assert(*counter == key);
340     (*counter)++;
341 }
342
343 static void
344 test_range(struct xkb_keymap *keymap)
345 {
346     int counter;
347
348     assert(xkb_keymap_min_keycode(keymap) == 9);
349     assert(xkb_keymap_max_keycode(keymap) == 253);
350
351     counter = xkb_keymap_min_keycode(keymap);
352     xkb_keymap_key_for_each(keymap, key_iter, &counter);
353     assert(counter == xkb_keymap_max_keycode(keymap) + 1);
354 }
355
356 static void
357 test_caps_keysym_transformation(struct xkb_keymap *keymap)
358 {
359     struct xkb_state *state = xkb_state_new(keymap);
360     xkb_mod_index_t caps, shift;
361     int nsyms;
362     xkb_keysym_t sym;
363     const xkb_keysym_t *syms;
364
365     assert(state);
366
367     /* See xkb_state_key_get_one_sym() for what's this all about. */
368
369     caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
370     shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
371     assert(caps >= 0 && shift >= 0);
372
373     assert(xkb_state_key_get_layout(state, KEY_A + 8) == 0);
374     assert(xkb_state_key_get_layout(state, KEY_SEMICOLON + 8) == 0);
375
376     /* Without caps, no transformation. */
377     assert(xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) == 0);
378     assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0);
379     assert(xkb_state_key_get_level(state, KEY_A + 8, 0) == 0);
380     sym = xkb_state_key_get_one_sym(state, KEY_A + 8);
381     assert(sym == XKB_KEY_a);
382     assert(xkb_state_key_get_level(state, KEY_SEMICOLON + 8, 0) == 0);
383     sym = xkb_state_key_get_one_sym(state, KEY_SEMICOLON + 8);
384     assert(sym == XKB_KEY_eacute);
385     nsyms = xkb_state_key_get_syms(state, KEY_SEMICOLON + 8, &syms);
386     assert(nsyms == 1 && syms[0] == XKB_KEY_eacute);
387
388     /* With shift, no transformation (only different level). */
389     xkb_state_update_key(state, KEY_LEFTSHIFT + 8, XKB_KEY_DOWN);
390     assert(xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) == 0);
391     assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) > 0);
392     assert(xkb_state_key_get_level(state, KEY_A + 8, 0) == 1);
393     sym = xkb_state_key_get_one_sym(state, KEY_A + 8);
394     assert(sym == XKB_KEY_A);
395     sym = xkb_state_key_get_one_sym(state, KEY_SEMICOLON + 8);
396     assert(sym == XKB_KEY_odiaeresis);
397     nsyms = xkb_state_key_get_syms(state, KEY_SEMICOLON + 8, &syms);
398     assert(nsyms == 1 && syms[0] == XKB_KEY_odiaeresis);
399     xkb_state_update_key(state, KEY_LEFTSHIFT + 8, XKB_KEY_UP);
400     assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0);
401
402     /* With caps, transform in same level, only with _get_one_sym(). */
403     xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_DOWN);
404     xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_UP);
405     assert(xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0);
406     assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0);
407     assert(xkb_state_key_get_level(state, KEY_A + 8, 0) == 1);
408     sym = xkb_state_key_get_one_sym(state, KEY_A + 8);
409     assert(sym == XKB_KEY_A);
410     assert(xkb_state_key_get_level(state, KEY_SEMICOLON + 8, 0) == 0);
411     sym = xkb_state_key_get_one_sym(state, KEY_SEMICOLON + 8);
412     assert(sym == XKB_KEY_Eacute);
413     nsyms = xkb_state_key_get_syms(state, KEY_SEMICOLON + 8, &syms);
414     assert(nsyms == 1 && syms[0] == XKB_KEY_eacute);
415     xkb_state_update_key(state, KEY_LEFTSHIFT + 8, XKB_KEY_UP);
416     assert(xkb_state_mod_index_is_active(state, shift, XKB_STATE_MODS_EFFECTIVE) == 0);
417     xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_DOWN);
418     xkb_state_update_key(state, KEY_CAPSLOCK + 8, XKB_KEY_UP);
419 }
420
421 int
422 main(void)
423 {
424     struct xkb_context *context = test_get_context(0);
425     struct xkb_keymap *keymap;
426
427     assert(context);
428
429     /* Make sure these are allowed. */
430     xkb_context_unref(NULL);
431     xkb_keymap_unref(NULL);
432     xkb_state_unref(NULL);
433
434     keymap = test_compile_rules(context, "evdev", "pc104", "us,ru", NULL, "grp:menu_toggle");
435     assert(keymap);
436
437     test_update_key(keymap);
438     test_serialisation(keymap);
439     test_repeat(keymap);
440     test_consume(keymap);
441     test_range(keymap);
442
443     xkb_keymap_unref(keymap);
444     keymap = test_compile_rules(context, "evdev", NULL, "ch", "fr", NULL);
445     assert(keymap);
446
447     test_caps_keysym_transformation(keymap);
448
449     xkb_keymap_unref(keymap);
450     xkb_context_unref(context);
451 }