4 * i3 - an improved dynamic tiling window manager
6 * © 2009 Michael Stapelberg and contributors
8 * See file LICENSE for license information.
18 #include <xcb/xcb_keysyms.h>
20 #include <X11/keysym.h>
24 extern xcb_window_t root;
25 unsigned int xcb_numlock_mask;
28 * Returns the mask for Mode_switch (to be used for looking up keysymbols by
32 uint32_t get_mod_mask(xcb_connection_t *conn, uint32_t keycode) {
33 xcb_key_symbols_t *symbols = xcb_key_symbols_alloc(conn);
35 xcb_get_modifier_mapping_reply_t *modmap_r;
36 xcb_keycode_t *modmap, kc;
37 xcb_keycode_t *modeswitchcodes = xcb_key_symbols_get_keycode(symbols, keycode);
38 if (modeswitchcodes == NULL)
41 modmap_r = xcb_get_modifier_mapping_reply(conn, xcb_get_modifier_mapping(conn), NULL);
42 modmap = xcb_get_modifier_mapping_keycodes(modmap_r);
44 for (int i = 0; i < 8; i++)
45 for (int j = 0; j < modmap_r->keycodes_per_modifier; j++) {
46 kc = modmap[i * modmap_r->keycodes_per_modifier + j];
47 for (xcb_keycode_t *ktest = modeswitchcodes; *ktest; ktest++) {
51 free(modeswitchcodes);
61 * Opens the window we use for input/output and maps it
64 xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height) {
65 xcb_window_t win = xcb_generate_id(conn);
66 //xcb_cursor_t cursor_id = xcb_generate_id(conn);
69 /* Use the default cursor (left pointer) */
71 i3Font *cursor_font = load_font(conn, "cursor");
72 xcb_create_glyph_cursor(conn, cursor_id, cursor_font->id, cursor_font->id,
73 XCB_CURSOR_LEFT_PTR, XCB_CURSOR_LEFT_PTR + 1,
74 0, 0, 0, 65535, 65535, 65535);
81 mask |= XCB_CW_BACK_PIXEL;
84 mask |= XCB_CW_EVENT_MASK;
85 values[1] = XCB_EVENT_MASK_EXPOSURE |
86 XCB_EVENT_MASK_BUTTON_PRESS;
88 xcb_create_window(conn,
90 win, /* the window id */
91 root, /* parent == root */
92 490, 297, width, height, /* dimensions */
93 0, /* border = 0, we draw our own */
94 XCB_WINDOW_CLASS_INPUT_OUTPUT,
95 XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
101 xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, &cursor_id);
104 /* Map the window (= make it visible) */
105 xcb_map_window(conn, win);
111 * Returns the ID of the font matching the given pattern and stores the height
112 * of the font (in pixels) in *font_height. die()s if no font matches.
115 int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) {
116 xcb_void_cookie_t font_cookie;
117 xcb_list_fonts_with_info_cookie_t info_cookie;
119 /* Send all our requests first */
121 result = xcb_generate_id(conn);
122 font_cookie = xcb_open_font_checked(conn, result, strlen(pattern), pattern);
123 info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern);
125 xcb_generic_error_t *error = xcb_request_check(conn, font_cookie);
127 fprintf(stderr, "ERROR: Could not open font: %d\n", error->error_code);
131 /* Get information (height/name) for this font */
132 xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL);
134 errx(1, "Could not load font \"%s\"\n", pattern);
136 *font_height = reply->font_ascent + reply->font_descent;
142 * Finds out which modifier mask is the one for numlock, as the user may change this.
145 void xcb_get_numlock_mask(xcb_connection_t *conn) {
146 xcb_key_symbols_t *keysyms;
147 xcb_get_modifier_mapping_cookie_t cookie;
148 xcb_get_modifier_mapping_reply_t *reply;
149 xcb_keycode_t *modmap;
151 const int masks[8] = { XCB_MOD_MASK_SHIFT,
153 XCB_MOD_MASK_CONTROL,
160 /* Request the modifier map */
161 cookie = xcb_get_modifier_mapping_unchecked(conn);
163 /* Get the keysymbols */
164 keysyms = xcb_key_symbols_alloc(conn);
166 if ((reply = xcb_get_modifier_mapping_reply(conn, cookie, NULL)) == NULL) {
167 xcb_key_symbols_free(keysyms);
171 modmap = xcb_get_modifier_mapping_keycodes(reply);
173 /* Get the keycode for numlock */
174 #ifdef OLD_XCB_KEYSYMS_API
175 xcb_keycode_t numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
177 /* For now, we only use the first keysymbol. */
178 xcb_keycode_t *numlock_syms = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
179 if (numlock_syms == NULL)
181 xcb_keycode_t numlock = *numlock_syms;
185 /* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */
186 for (mask = 0; mask < 8; mask++)
187 for (i = 0; i < reply->keycodes_per_modifier; i++)
188 if (modmap[(mask * reply->keycodes_per_modifier) + i] == numlock)
189 xcb_numlock_mask = masks[mask];
191 xcb_key_symbols_free(keysyms);