]> git.sur5r.net Git - i3/i3/commitdiff
Move get_mod_mask to libi3, use it in i3 and i3-config-wizard
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 23 Oct 2011 20:26:15 +0000 (21:26 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 23 Oct 2011 20:26:15 +0000 (21:26 +0100)
Also, the API changed a bit. There are two functions now, both assume you
already got the keysyms (which is the case for i3 and i3-config-wizard),
one gets the modifier mapping for you (aio_get_mod_mask_for) while the other
assumes you also got that. No roundtrips are required for the latter.

i3-config-wizard/main.c
i3-config-wizard/xcb.c
i3-config-wizard/xcb.h
include/libi3.h
include/xcb.h
libi3/get_mod_mask.c [new file with mode: 0644]
src/handlers.c
src/main.c
src/xcb.c

index 09320dfb0c2360679729bd1e20a49e202361e841..fb916daf8bf56b6cde7848e4b85be1a502d0776c 100644 (file)
@@ -57,7 +57,7 @@ enum { STEP_WELCOME, STEP_GENERATE } current_step = STEP_WELCOME;
 enum { MOD_Mod1, MOD_Mod4 } modifier = MOD_Mod4;
 
 static char *config_path;
-static xcb_connection_t *conn;
+xcb_connection_t *conn;
 static xcb_get_modifier_mapping_reply_t *modmap_reply;
 static uint32_t font_id;
 static uint32_t font_bold_id;
@@ -424,6 +424,7 @@ int main(int argc, char *argv[]) {
 
     xcb_get_modifier_mapping_cookie_t modmap_cookie;
     modmap_cookie = xcb_get_modifier_mapping(conn);
+    symbols = xcb_key_symbols_alloc(conn);
 
     /* Place requests for the atoms we need as soon as possible */
     #define xmacro(atom) \
@@ -437,11 +438,7 @@ int main(int argc, char *argv[]) {
     if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
         errx(EXIT_FAILURE, "Could not get modifier mapping\n");
 
-    /* XXX: we should refactor xcb_get_numlock_mask so that it uses the
-     * modifier mapping we already have */
-    xcb_get_numlock_mask(conn);
-
-    symbols = xcb_key_symbols_alloc(conn);
+    xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);
 
     font_id = get_font_id(conn, pattern, &font_height);
     font_bold_id = get_font_id(conn, patternbold, &font_bold_height);
index 4f8eb4da182496601ab73def382892e3383a9794..753568e3c6cd0409fcf1eed75a5996f16f70d3ed 100644 (file)
@@ -104,58 +104,3 @@ int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) {
 
         return result;
 }
-
-/*
- * Finds out which modifier mask is the one for numlock, as the user may change this.
- *
- */
-void xcb_get_numlock_mask(xcb_connection_t *conn) {
-    xcb_key_symbols_t *keysyms;
-    xcb_get_modifier_mapping_cookie_t cookie;
-    xcb_get_modifier_mapping_reply_t *reply;
-    xcb_keycode_t *modmap;
-    int mask, i;
-    const int masks[8] = { XCB_MOD_MASK_SHIFT,
-                           XCB_MOD_MASK_LOCK,
-                           XCB_MOD_MASK_CONTROL,
-                           XCB_MOD_MASK_1,
-                           XCB_MOD_MASK_2,
-                           XCB_MOD_MASK_3,
-                           XCB_MOD_MASK_4,
-                           XCB_MOD_MASK_5 };
-
-    /* Request the modifier map */
-    cookie = xcb_get_modifier_mapping_unchecked(conn);
-
-    /* Get the keysymbols */
-    keysyms = xcb_key_symbols_alloc(conn);
-
-    if ((reply = xcb_get_modifier_mapping_reply(conn, cookie, NULL)) == NULL) {
-        xcb_key_symbols_free(keysyms);
-        return;
-    }
-
-    modmap = xcb_get_modifier_mapping_keycodes(reply);
-
-    /* Get the keycode for numlock */
-#ifdef OLD_XCB_KEYSYMS_API
-    xcb_keycode_t numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
-#else
-    /* For now, we only use the first keysymbol. */
-    xcb_keycode_t *numlock_syms = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
-    if (numlock_syms == NULL)
-        return;
-    xcb_keycode_t numlock = *numlock_syms;
-    free(numlock_syms);
-#endif
-
-    /* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */
-    for (mask = 0; mask < 8; mask++)
-        for (i = 0; i < reply->keycodes_per_modifier; i++)
-            if (modmap[(mask * reply->keycodes_per_modifier) + i] == numlock)
-                xcb_numlock_mask = masks[mask];
-
-    xcb_key_symbols_free(keysyms);
-    free(reply);
-}
-
index c2ecedf8760a0c6d35247741e8fa39bc4e35addf..1e5d2d2a779ccfe33cfa976a2d890236d77958b4 100644 (file)
@@ -12,10 +12,5 @@ extern unsigned int xcb_numlock_mask;
 
 xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height);
 int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height);
-/**
- * Finds out which modifier mask is the one for numlock, as the user may change this.
- *
- */
-void xcb_get_numlock_mask(xcb_connection_t *conn);
 
 #endif
index f4cd2160747fecf2cfc44d11ba3ed97971b76ab3..ecb72cb5bfdf8b0947cfcd590ec00eef60b17ed7 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdarg.h>
 #include <xcb/xcb.h>
 #include <xcb/xproto.h>
+#include <xcb/xcb_keysyms.h>
 
 /**
  * Try to get the socket path from X11 and return NULL if it doesn’t work.
@@ -121,4 +122,25 @@ char *strndup(const char *str, size_t n);
 
 #endif
 
+/**
+ * All-in-one function which returns the modifier mask (XCB_MOD_MASK_*) for the
+ * given keysymbol, for example for XCB_NUM_LOCK (usually configured to mod2).
+ *
+ * This function initiates one round-trip. Use get_mod_mask_for() directly if
+ * you already have the modifier mapping and key symbols.
+ *
+ */
+uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols);
+
+/**
+ * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for
+ * example for XCB_NUM_LOCK (usually configured to mod2).
+ *
+ * This function does not initiate any round-trips.
+ *
+ */
+uint32_t get_mod_mask_for(uint32_t keysym,
+                           xcb_key_symbols_t *symbols,
+                           xcb_get_modifier_mapping_reply_t *modmap_reply);
+
 #endif
index 9660939dfb48bd9bffd7e58f8aaf7f906fa861a1..3670bbcd4b970223f6eb90931c650401fc74d152 100644 (file)
@@ -97,13 +97,6 @@ void fake_absolute_configure_notify(Con *con);
  */
 void send_take_focus(xcb_window_t window);
 
-/**
- * Finds out which modifier mask is the one for numlock, as the user may
- * change this.
- *
- */
-void xcb_get_numlock_mask(xcb_connection_t *conn);
-
 /**
  * Raises the given window (typically client->frame) above all other windows
  *
diff --git a/libi3/get_mod_mask.c b/libi3/get_mod_mask.c
new file mode 100644 (file)
index 0000000..7654922
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * vim:ts=4:sw=4:expandtab
+ *
+ * i3 - an improved dynamic tiling window manager
+ *
+ * © 2009-2011 Michael Stapelberg and contributors
+ *
+ * See file LICENSE for license information.
+ *
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_keysyms.h>
+
+#include "libi3.h"
+
+extern xcb_connection_t *conn;
+
+/*
+ * All-in-one function which returns the modifier mask (XCB_MOD_MASK_*) for the
+ * given keysymbol, for example for XCB_NUM_LOCK (usually configured to mod2).
+ *
+ * This function initiates one round-trip. Use get_mod_mask_for() directly if
+ * you already have the modifier mapping and key symbols.
+ *
+ */
+uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols) {
+    xcb_get_modifier_mapping_cookie_t cookie;
+    xcb_get_modifier_mapping_reply_t *modmap_r;
+
+    xcb_flush(conn);
+
+    /* Get the current modifier mapping (this is blocking!) */
+    cookie = xcb_get_modifier_mapping(conn);
+    if (!(modmap_r = xcb_get_modifier_mapping_reply(conn, cookie, NULL)))
+        return 0;
+
+    uint32_t result = get_mod_mask_for(keysym, symbols, modmap_r);
+    free(modmap_r);
+    return result;
+}
+
+/*
+ * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for
+ * example for XCB_NUM_LOCK (usually configured to mod2).
+ *
+ * This function does not initiate any round-trips.
+ *
+ */
+uint32_t get_mod_mask_for(uint32_t keysym,
+                           xcb_key_symbols_t *symbols,
+                           xcb_get_modifier_mapping_reply_t *modmap_reply) {
+    xcb_keycode_t *codes, *modmap;
+    xcb_keycode_t mod_code;
+
+    modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);
+
+    /* Get the list of keycodes for the given symbol */
+    if (!(codes = xcb_key_symbols_get_keycode(symbols, keysym)))
+        return 0;
+
+    /* Loop through all modifiers (Mod1-Mod5, Shift, Control, Lock) */
+    for (int mod = 0; mod < 8; mod++)
+        for (int j = 0; j < modmap_reply->keycodes_per_modifier; j++) {
+            /* Store the current keycode (for modifier 'mod') */
+            mod_code = modmap[(mod * modmap_reply->keycodes_per_modifier) + j];
+            /* Check if that keycode is in the list of previously resolved
+             * keycodes for our symbol. If so, return the modifier mask. */
+            for (xcb_keycode_t *code = codes; *code; code++) {
+                if (*code != mod_code)
+                    continue;
+
+                free(codes);
+                /* This corresponds to the XCB_MOD_MASK_* constants */
+                return (1 << mod);
+            }
+        }
+
+    return 0;
+}
index 0695f2d04dcc2d87453ab6efbd3b0e5c3de67622..29dcdc70936522b9c1e4fc003e8cbffb18d2afe9 100644 (file)
@@ -286,7 +286,7 @@ static int handle_mapping_notify(xcb_mapping_notify_event_t *event) {
     DLOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
     xcb_refresh_keyboard_mapping(keysyms, event);
 
-    xcb_get_numlock_mask(conn);
+    xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
 
     ungrab_all_keys(conn);
     translate_keysyms();
index 958ea65342f5e12619c0cd57b1b541dad4e0d58e..52c9e2cdab92027266daff06f57031470a39f4b9 100644 (file)
@@ -178,7 +178,7 @@ static void xkb_got_event(EV_P_ struct ev_io *w, int revents) {
     xcb_key_symbols_free(keysyms);
     keysyms = xcb_key_symbols_alloc(conn);
 
-    xcb_get_numlock_mask(conn);
+    xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
 
     ungrab_all_keys(conn);
     DLOG("Re-grabbing...\n");
@@ -520,7 +520,7 @@ int main(int argc, char *argv[]) {
 
     keysyms = xcb_key_symbols_alloc(conn);
 
-    xcb_get_numlock_mask(conn);
+    xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
 
     translate_keysyms();
     grab_all_keys(conn, false);
index 587f18b3e1bd1716c6e41a731bef789ec73a3768..d9891bfcc44f760006863f28f14da4e08910d595 100644 (file)
--- a/src/xcb.c
+++ b/src/xcb.c
@@ -173,60 +173,6 @@ void send_take_focus(xcb_window_t window) {
     free(event);
 }
 
-/*
- * Finds out which modifier mask is the one for numlock, as the user may change this.
- *
- */
-void xcb_get_numlock_mask(xcb_connection_t *conn) {
-    xcb_key_symbols_t *keysyms;
-    xcb_get_modifier_mapping_cookie_t cookie;
-    xcb_get_modifier_mapping_reply_t *reply;
-    xcb_keycode_t *modmap;
-    int mask, i;
-    const int masks[8] = { XCB_MOD_MASK_SHIFT,
-                           XCB_MOD_MASK_LOCK,
-                           XCB_MOD_MASK_CONTROL,
-                           XCB_MOD_MASK_1,
-                           XCB_MOD_MASK_2,
-                           XCB_MOD_MASK_3,
-                           XCB_MOD_MASK_4,
-                           XCB_MOD_MASK_5 };
-
-    /* Request the modifier map */
-    cookie = xcb_get_modifier_mapping(conn);
-
-    /* Get the keysymbols */
-    keysyms = xcb_key_symbols_alloc(conn);
-
-    if ((reply = xcb_get_modifier_mapping_reply(conn, cookie, NULL)) == NULL) {
-        xcb_key_symbols_free(keysyms);
-        return;
-    }
-
-    modmap = xcb_get_modifier_mapping_keycodes(reply);
-
-    /* Get the keycode for numlock */
-#ifdef OLD_XCB_KEYSYMS_API
-    xcb_keycode_t numlock = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
-#else
-    /* For now, we only use the first keysymbol. */
-    xcb_keycode_t *numlock_syms = xcb_key_symbols_get_keycode(keysyms, XCB_NUM_LOCK);
-    if (numlock_syms == NULL)
-        return;
-    xcb_keycode_t numlock = *numlock_syms;
-    free(numlock_syms);
-#endif
-
-    /* Check all modifiers (Mod1-Mod5, Shift, Control, Lock) */
-    for (mask = 0; mask < 8; mask++)
-        for (i = 0; i < reply->keycodes_per_modifier; i++)
-            if (modmap[(mask * reply->keycodes_per_modifier) + i] == numlock)
-                xcb_numlock_mask = masks[mask];
-
-    xcb_key_symbols_free(keysyms);
-    free(reply);
-}
-
 /*
  * Raises the given window (typically client->frame) above all other windows
  *