Rename 'ctx' back to 'context' in external API
[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     xkb_group_index_t group;
43     xkb_mod_index_t mod;
44     xkb_led_index_t led;
45
46     if (!state->group && !state->mods && !state->leds) {
47         fprintf(stderr, "\tno state\n");
48         return;
49     }
50
51     for (group = 0; group < xkb_map_num_groups(state->keymap); group++) {
52         if (!xkb_state_group_index_is_active(state, group, XKB_STATE_EFFECTIVE))
53             continue;
54         fprintf(stderr, "\tgroup %s (%d): %s%s%s%s\n",
55                 xkb_map_group_get_name(state->keymap, group),
56                 group,
57                 xkb_state_group_index_is_active(state, group, XKB_STATE_EFFECTIVE) ?
58                     "effective " : "",
59                 xkb_state_group_index_is_active(state, group, XKB_STATE_DEPRESSED) ?
60                     "depressed " : "",
61                 xkb_state_group_index_is_active(state, group, XKB_STATE_LATCHED) ?
62                     "latched " : "",
63                 xkb_state_group_index_is_active(state, group, XKB_STATE_LOCKED) ?
64                     "locked " : "");
65     }
66
67     for (mod = 0; mod < xkb_map_num_mods(state->keymap); mod++) {
68         if (!xkb_state_mod_index_is_active(state, mod, XKB_STATE_EFFECTIVE))
69             continue;
70         fprintf(stderr, "\tmod %s (%d): %s%s%s\n",
71                 xkb_map_mod_get_name(state->keymap, mod),
72                 mod,
73                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_DEPRESSED) ?
74                     "depressed " : "",
75                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_LATCHED) ?
76                     "latched " : "",
77                 xkb_state_mod_index_is_active(state, mod, XKB_STATE_LOCKED) ?
78                     "locked " : "");
79     }
80
81     for (led = 0; led < xkb_map_num_leds(state->keymap); led++) {
82         if (!xkb_state_led_index_is_active(state, led))
83             continue;
84         fprintf(stderr, "\tled %s (%d): active\n",
85                 xkb_map_led_get_name(state->keymap, led),
86                 led);
87     }
88 }
89
90 static void
91 test_update_key(struct xkb_keymap *keymap)
92 {
93     struct xkb_state *state = xkb_state_new(keymap);
94     const xkb_keysym_t *syms;
95     int num_syms;
96
97     assert(state);
98
99     /* LCtrl down */
100     xkb_state_update_key(state, KEY_LEFTCTRL + EVDEV_OFFSET, XKB_KEY_DOWN);
101     fprintf(stderr, "dumping state for LCtrl down:\n");
102     print_state(state);
103     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
104                                         XKB_STATE_DEPRESSED));
105
106     /* LCtrl + RAlt down */
107     xkb_state_update_key(state, KEY_RIGHTALT + EVDEV_OFFSET, XKB_KEY_DOWN);
108     fprintf(stderr, "dumping state for LCtrl + RAlt down:\n");
109     print_state(state);
110     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
111                                         XKB_STATE_DEPRESSED));
112     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
113                                         XKB_STATE_DEPRESSED));
114     assert(xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
115                                           XKB_STATE_MATCH_ALL,
116                                           XKB_MOD_NAME_CTRL,
117                                           XKB_MOD_NAME_ALT,
118                                           NULL));
119     assert(!xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
120                                            XKB_STATE_MATCH_ALL,
121                                            XKB_MOD_NAME_ALT,
122                                            NULL));
123     assert(xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
124                                           (XKB_STATE_MATCH_ANY |
125                                            XKB_STATE_MATCH_NON_EXCLUSIVE),
126                                           XKB_MOD_NAME_ALT,
127                                           NULL));
128
129     /* RAlt down */
130     xkb_state_update_key(state, KEY_LEFTCTRL + EVDEV_OFFSET, XKB_KEY_UP);
131     fprintf(stderr, "dumping state for RAlt down:\n");
132     print_state(state);
133     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL,
134                                          XKB_STATE_EFFECTIVE));
135     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
136                                         XKB_STATE_DEPRESSED));
137     assert(xkb_state_mod_names_are_active(state, XKB_STATE_DEPRESSED,
138                                           XKB_STATE_MATCH_ANY,
139                                           XKB_MOD_NAME_CTRL,
140                                           XKB_MOD_NAME_ALT,
141                                           NULL));
142
143     /* none down */
144     xkb_state_update_key(state, KEY_RIGHTALT + EVDEV_OFFSET, XKB_KEY_UP);
145     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT,
146                                          XKB_STATE_EFFECTIVE));
147
148     /* Caps locked */
149     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
150     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
151     fprintf(stderr, "dumping state for Caps Lock:\n");
152     print_state(state);
153     assert(xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
154                                         XKB_STATE_LOCKED));
155     assert(xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS));
156     num_syms = xkb_key_get_syms(state, KEY_Q + EVDEV_OFFSET, &syms);
157     assert(num_syms == 1 && syms[0] == XKB_KEY_Q);
158
159     /* Caps unlocked */
160     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
161     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
162     assert(!xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CAPS,
163                                          XKB_STATE_EFFECTIVE));
164     assert(!xkb_state_led_name_is_active(state, XKB_LED_NAME_CAPS));
165     num_syms = xkb_key_get_syms(state, KEY_Q + EVDEV_OFFSET, &syms);
166     assert(num_syms == 1 && syms[0] == XKB_KEY_q);
167
168     xkb_state_unref(state);
169 }
170
171 static void
172 test_serialisation(struct xkb_keymap *keymap)
173 {
174     struct xkb_state *state = xkb_state_new(keymap);
175     xkb_mod_mask_t base_mods;
176     xkb_mod_mask_t latched_mods;
177     xkb_mod_mask_t locked_mods;
178     xkb_mod_mask_t effective_mods;
179     xkb_mod_index_t caps, shift, ctrl;
180     xkb_group_index_t base_group = 0;
181     xkb_group_index_t latched_group = 0;
182     xkb_group_index_t locked_group = 0;
183
184     assert(state);
185
186     caps = xkb_map_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
187     assert(caps != XKB_MOD_INVALID);
188     shift = xkb_map_mod_get_index(state->keymap, XKB_MOD_NAME_SHIFT);
189     assert(shift != XKB_MOD_INVALID);
190     ctrl = xkb_map_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL);
191     assert(ctrl != XKB_MOD_INVALID);
192
193     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_DOWN);
194     xkb_state_update_key(state, KEY_CAPSLOCK + EVDEV_OFFSET, XKB_KEY_UP);
195     base_mods = xkb_state_serialize_mods(state, XKB_STATE_DEPRESSED);
196     assert(base_mods == 0);
197     latched_mods = xkb_state_serialize_mods(state, XKB_STATE_LATCHED);
198     assert(latched_mods == 0);
199     locked_mods = xkb_state_serialize_mods(state, XKB_STATE_LOCKED);
200     assert(locked_mods == (1 << caps));
201     effective_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
202     assert(effective_mods == locked_mods);
203
204     xkb_state_update_key(state, KEY_LEFTSHIFT + EVDEV_OFFSET, XKB_KEY_DOWN);
205     base_mods = xkb_state_serialize_mods(state, XKB_STATE_DEPRESSED);
206     assert(base_mods == (1 << shift));
207     latched_mods = xkb_state_serialize_mods(state, XKB_STATE_LATCHED);
208     assert(latched_mods == 0);
209     locked_mods = xkb_state_serialize_mods(state, XKB_STATE_LOCKED);
210     assert(locked_mods == (1 << caps));
211     effective_mods = xkb_state_serialize_mods(state, XKB_STATE_EFFECTIVE);
212     assert(effective_mods == (base_mods | locked_mods));
213
214     base_mods |= (1 << ctrl);
215     xkb_state_update_mask(state, base_mods, latched_mods, locked_mods,
216                           base_group, latched_group, locked_group);
217
218     assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_DEPRESSED));
219     assert(xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_EFFECTIVE));
220
221     xkb_state_unref(state);
222 }
223
224 int
225 main(void)
226 {
227     struct xkb_context *context;
228     struct xkb_keymap *keymap;
229     struct xkb_rule_names rmlvo = {
230         .rules = "evdev",
231         .model = "pc104",
232         .layout = "us",
233         .variant = NULL,
234         .options = NULL,
235     };
236
237     context = xkb_context_new(0);
238     assert(context);
239
240     keymap = xkb_map_new_from_names(context, &rmlvo, 0);
241     assert(keymap);
242
243     test_update_key(keymap);
244     test_serialisation(keymap);
245
246     xkb_map_unref(keymap);
247     xkb_context_unref(context);
248 }