]> git.sur5r.net Git - i3/i3/blob - libi3/get_mod_mask.c
Move get_mod_mask to libi3, use it in i3 and i3-config-wizard
[i3/i3] / libi3 / get_mod_mask.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  *
6  * © 2009-2011 Michael Stapelberg and contributors
7  *
8  * See file LICENSE for license information.
9  *
10  */
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <xcb/xcb.h>
14 #include <xcb/xcb_keysyms.h>
15
16 #include "libi3.h"
17
18 extern xcb_connection_t *conn;
19
20 /*
21  * All-in-one function which returns the modifier mask (XCB_MOD_MASK_*) for the
22  * given keysymbol, for example for XCB_NUM_LOCK (usually configured to mod2).
23  *
24  * This function initiates one round-trip. Use get_mod_mask_for() directly if
25  * you already have the modifier mapping and key symbols.
26  *
27  */
28 uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols) {
29     xcb_get_modifier_mapping_cookie_t cookie;
30     xcb_get_modifier_mapping_reply_t *modmap_r;
31
32     xcb_flush(conn);
33
34     /* Get the current modifier mapping (this is blocking!) */
35     cookie = xcb_get_modifier_mapping(conn);
36     if (!(modmap_r = xcb_get_modifier_mapping_reply(conn, cookie, NULL)))
37         return 0;
38
39     uint32_t result = get_mod_mask_for(keysym, symbols, modmap_r);
40     free(modmap_r);
41     return result;
42 }
43
44 /*
45  * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for
46  * example for XCB_NUM_LOCK (usually configured to mod2).
47  *
48  * This function does not initiate any round-trips.
49  *
50  */
51 uint32_t get_mod_mask_for(uint32_t keysym,
52                            xcb_key_symbols_t *symbols,
53                            xcb_get_modifier_mapping_reply_t *modmap_reply) {
54     xcb_keycode_t *codes, *modmap;
55     xcb_keycode_t mod_code;
56
57     modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);
58
59     /* Get the list of keycodes for the given symbol */
60     if (!(codes = xcb_key_symbols_get_keycode(symbols, keysym)))
61         return 0;
62
63     /* Loop through all modifiers (Mod1-Mod5, Shift, Control, Lock) */
64     for (int mod = 0; mod < 8; mod++)
65         for (int j = 0; j < modmap_reply->keycodes_per_modifier; j++) {
66             /* Store the current keycode (for modifier 'mod') */
67             mod_code = modmap[(mod * modmap_reply->keycodes_per_modifier) + j];
68             /* Check if that keycode is in the list of previously resolved
69              * keycodes for our symbol. If so, return the modifier mask. */
70             for (xcb_keycode_t *code = codes; *code; code++) {
71                 if (*code != mod_code)
72                     continue;
73
74                 free(codes);
75                 /* This corresponds to the XCB_MOD_MASK_* constants */
76                 return (1 << mod);
77             }
78         }
79
80     return 0;
81 }