- DLOG("Ungrabbing all keys\n");
- xcb_ungrab_key(conn, XCB_GRAB_ANY, root, XCB_BUTTON_MASK_ANY);
-}
-
-static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint32_t keycode) {
- DLOG("Grabbing %d\n", keycode);
- /* Grab the key in all combinations */
- #define GRAB_KEY(modifier) \
- do { \
- xcb_grab_key(conn, 0, root, modifier, keycode, \
- XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); \
- } while (0)
- int mods = bind->mods;
- if ((bind->mods & BIND_MODE_SWITCH) != 0) {
- mods &= ~BIND_MODE_SWITCH;
- if (mods == 0)
- mods = XCB_MOD_MASK_ANY;
- }
- GRAB_KEY(mods);
- GRAB_KEY(mods | xcb_numlock_mask);
- GRAB_KEY(mods | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
-}
-
-/*
- * Returns a pointer to the Binding with the specified modifiers and keycode
- * or NULL if no such binding exists.
- *
- */
-Binding *get_binding(uint16_t modifiers, xcb_keycode_t keycode) {
- Binding *bind;
-
- TAILQ_FOREACH(bind, bindings, bindings) {
- /* First compare the modifiers */
- if (bind->mods != modifiers)
- continue;
-
- /* If a symbol was specified by the user, we need to look in
- * the array of translated keycodes for the event’s keycode */
- if (bind->symbol != NULL) {
- if (memmem(bind->translated_to,
- bind->number_keycodes * sizeof(xcb_keycode_t),
- &keycode, sizeof(xcb_keycode_t)) != NULL)
- break;
- } else {
- /* This case is easier: The user specified a keycode */
- if (bind->keycode == keycode)
- break;
- }
- }
-
- return (bind == TAILQ_END(bindings) ? NULL : bind);
-}
-
-/*
- * Translates keysymbols to keycodes for all bindings which use keysyms.
- *
- */
-void translate_keysyms() {
- Binding *bind;
- TAILQ_FOREACH(bind, bindings, bindings) {
- if (bind->keycode > 0)
- continue;
-
- /* We need to translate the symbol to a keycode */
- xcb_keysym_t keysym = XStringToKeysym(bind->symbol);
- if (keysym == NoSymbol) {
- ELOG("Could not translate string to key symbol: \"%s\"\n", bind->symbol);
- continue;
- }
-
- uint32_t last_keycode = 0;
- xcb_keycode_t *keycodes = xcb_key_symbols_get_keycode(keysyms, keysym);
- if (keycodes == NULL) {
- DLOG("Could not translate symbol \"%s\"\n", bind->symbol);
- continue;
- }
-
- bind->number_keycodes = 0;
-
- for (xcb_keycode_t *walk = keycodes; *walk != 0; walk++) {
- /* We hope duplicate keycodes will be returned in order
- * and skip them */
- if (last_keycode == *walk)
- continue;
- last_keycode = *walk;
- bind->number_keycodes++;
- }
- DLOG("Translated symbol \"%s\" to %d keycode\n", bind->symbol, bind->number_keycodes);
- bind->translated_to = smalloc(bind->number_keycodes * sizeof(xcb_keycode_t));
- memcpy(bind->translated_to, keycodes, bind->number_keycodes * sizeof(xcb_keycode_t));
- free(keycodes);
- }
-}
-
-/*
- * Grab the bound keys (tell X to send us keypress events for those keycodes)
- *
- */
-void grab_all_keys(xcb_connection_t *conn, bool bind_mode_switch) {
- Binding *bind;
- TAILQ_FOREACH(bind, bindings, bindings) {
- if ((bind_mode_switch && (bind->mods & BIND_MODE_SWITCH) == 0) ||
- (!bind_mode_switch && (bind->mods & BIND_MODE_SWITCH) != 0))
- continue;
-
- /* The easy case: the user specified a keycode directly. */
- if (bind->keycode > 0) {
- grab_keycode_for_binding(conn, bind, bind->keycode);
- continue;
- }
-
- xcb_keycode_t *walk = bind->translated_to;
- for (int i = 0; i < bind->number_keycodes; i++)
- grab_keycode_for_binding(conn, bind, *walk++);
- }