Move get_mod_mask to libi3, use it in i3 and i3-config-wizard
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.
This commit is contained in:
parent
a512b99a51
commit
91134f75c0
|
@ -57,7 +57,7 @@ enum { STEP_WELCOME, STEP_GENERATE } current_step = STEP_WELCOME;
|
||||||
enum { MOD_Mod1, MOD_Mod4 } modifier = MOD_Mod4;
|
enum { MOD_Mod1, MOD_Mod4 } modifier = MOD_Mod4;
|
||||||
|
|
||||||
static char *config_path;
|
static char *config_path;
|
||||||
static xcb_connection_t *conn;
|
xcb_connection_t *conn;
|
||||||
static xcb_get_modifier_mapping_reply_t *modmap_reply;
|
static xcb_get_modifier_mapping_reply_t *modmap_reply;
|
||||||
static uint32_t font_id;
|
static uint32_t font_id;
|
||||||
static uint32_t font_bold_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;
|
xcb_get_modifier_mapping_cookie_t modmap_cookie;
|
||||||
modmap_cookie = xcb_get_modifier_mapping(conn);
|
modmap_cookie = xcb_get_modifier_mapping(conn);
|
||||||
|
symbols = xcb_key_symbols_alloc(conn);
|
||||||
|
|
||||||
/* Place requests for the atoms we need as soon as possible */
|
/* Place requests for the atoms we need as soon as possible */
|
||||||
#define xmacro(atom) \
|
#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)))
|
if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
|
||||||
errx(EXIT_FAILURE, "Could not get modifier mapping\n");
|
errx(EXIT_FAILURE, "Could not get modifier mapping\n");
|
||||||
|
|
||||||
/* XXX: we should refactor xcb_get_numlock_mask so that it uses the
|
xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);
|
||||||
* modifier mapping we already have */
|
|
||||||
xcb_get_numlock_mask(conn);
|
|
||||||
|
|
||||||
symbols = xcb_key_symbols_alloc(conn);
|
|
||||||
|
|
||||||
font_id = get_font_id(conn, pattern, &font_height);
|
font_id = get_font_id(conn, pattern, &font_height);
|
||||||
font_bold_id = get_font_id(conn, patternbold, &font_bold_height);
|
font_bold_id = get_font_id(conn, patternbold, &font_bold_height);
|
||||||
|
|
|
@ -104,58 +104,3 @@ int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) {
|
||||||
|
|
||||||
return result;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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);
|
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
|
#endif
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xproto.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.
|
* 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
|
#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
|
#endif
|
||||||
|
|
|
@ -97,13 +97,6 @@ void fake_absolute_configure_notify(Con *con);
|
||||||
*/
|
*/
|
||||||
void send_take_focus(xcb_window_t window);
|
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
|
* Raises the given window (typically client->frame) above all other windows
|
||||||
*
|
*
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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");
|
DLOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
|
||||||
xcb_refresh_keyboard_mapping(keysyms, event);
|
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);
|
ungrab_all_keys(conn);
|
||||||
translate_keysyms();
|
translate_keysyms();
|
||||||
|
|
|
@ -178,7 +178,7 @@ static void xkb_got_event(EV_P_ struct ev_io *w, int revents) {
|
||||||
xcb_key_symbols_free(keysyms);
|
xcb_key_symbols_free(keysyms);
|
||||||
keysyms = xcb_key_symbols_alloc(conn);
|
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);
|
ungrab_all_keys(conn);
|
||||||
DLOG("Re-grabbing...\n");
|
DLOG("Re-grabbing...\n");
|
||||||
|
@ -520,7 +520,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
keysyms = xcb_key_symbols_alloc(conn);
|
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();
|
translate_keysyms();
|
||||||
grab_all_keys(conn, false);
|
grab_all_keys(conn, false);
|
||||||
|
|
54
src/xcb.c
54
src/xcb.c
|
@ -173,60 +173,6 @@ void send_take_focus(xcb_window_t window) {
|
||||||
free(event);
|
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
|
* Raises the given window (typically client->frame) above all other windows
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue