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