summaryrefslogtreecommitdiff
path: root/i3lock.c
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2014-01-18 17:13:59 +0100
committerMichael Stapelberg <michael@stapelberg.de>2014-06-21 16:32:18 +0200
commit0beb9a47b1cfaf868c3610b2748d0fa6988c658e (patch)
tree033a25b073ab6be6590eaddf2c8ef269564f4bb8 /i3lock.c
parent6191590e5c207803df211b74a714daf92c69c28f (diff)
use libxkbcommon-x11 instead of libX11
Diffstat (limited to 'i3lock.c')
-rw-r--r--i3lock.c88
1 files changed, 30 insertions, 58 deletions
diff --git a/i3lock.c b/i3lock.c
index 682f162..f81ea18 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -17,14 +17,12 @@
#include <err.h>
#include <assert.h>
#include <security/pam_appl.h>
-#include <X11/Xlib-xcb.h>
#include <getopt.h>
#include <string.h>
#include <ev.h>
#include <sys/mman.h>
-#include <X11/XKBlib.h>
-#include <X11/extensions/XKBfile.h>
#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-x11.h>
#include <cairo.h>
#include <cairo/cairo-xcb.h>
@@ -44,7 +42,6 @@
typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents);
/* We need this for libxkbfile */
-static Display *display;
char color[7] = "ffffff";
int inactivity_timeout = 30;
uint32_t last_resolution[2];
@@ -70,6 +67,8 @@ extern pam_state_t pam_state;
static struct xkb_state *xkb_state;
static struct xkb_context *xkb_context;
static struct xkb_keymap *xkb_keymap;
+static uint8_t xkb_base_event;
+static uint8_t xkb_base_error;
cairo_surface_t *img = NULL;
bool tile = false;
@@ -102,77 +101,44 @@ static void turn_monitors_off(void) {
* Necessary so that we can properly let xkbcommon track the keyboard state and
* translate keypresses to utf-8.
*
- * Ideally, xkbcommon would ship something like this itself, but as of now
- * (version 0.2.0), it doesn’t.
- *
- * TODO: Once xcb-xkb is enabled by default and released, we should port this
- * code to xcb-xkb. See also https://github.com/xkbcommon/libxkbcommon/issues/1
- *
*/
static bool load_keymap(void) {
- bool ret = false;
- XkbFileInfo result;
- memset(&result, '\0', sizeof(result));
- result.xkb = XkbGetKeyboard(display, XkbAllMapComponentsMask, XkbUseCoreKbd);
- if (result.xkb == NULL) {
- fprintf(stderr, "[i3lock] XKB: XkbGetKeyboard failed\n");
- return false;
- }
-
- FILE *temp = tmpfile();
- if (temp == NULL) {
- fprintf(stderr, "[i3lock] could not create tempfile\n");
- return false;
- }
-
- bool ok = XkbWriteXKBKeymap(temp, &result, false, false, NULL, NULL);
- if (!ok) {
- fprintf(stderr, "[i3lock] XkbWriteXKBKeymap failed\n");
- goto out;
- }
-
- rewind(temp);
-
if (xkb_context == NULL) {
if ((xkb_context = xkb_context_new(0)) == NULL) {
fprintf(stderr, "[i3lock] could not create xkbcommon context\n");
- goto out;
+ return false;
}
}
if (xkb_keymap != NULL)
xkb_keymap_unref(xkb_keymap);
- if ((xkb_keymap = xkb_keymap_new_from_file(xkb_context, temp, XKB_KEYMAP_FORMAT_TEXT_V1, 0)) == NULL) {
- fprintf(stderr, "[i3lock] xkb_keymap_new_from_file failed\n");
- goto out;
+ int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn);
+ DEBUG("device = %d\n", device_id);
+ if ((xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL) {
+ fprintf(stderr, "[i3lock] xkb_x11_keymap_new_from_device failed\n");
+ return false;
}
- struct xkb_state *new_state = xkb_state_new(xkb_keymap);
+ struct xkb_state *new_state =
+ xkb_x11_state_new_from_device(xkb_keymap, conn, device_id);
if (new_state == NULL) {
- fprintf(stderr, "[i3lock] xkb_state_new failed\n");
- goto out;
+ fprintf(stderr, "[i3lock] xkb_x11_state_new_from_device failed\n");
+ return false;
}
/* Get the initial modifier state to be in sync with the X server.
* See https://github.com/xkbcommon/libxkbcommon/issues/1 for why we ignore
* the base and latched fields. */
- XkbStateRec state_rec;
- XkbGetState(display, XkbUseCoreKbd, &state_rec);
-
- xkb_state_update_mask(new_state,
- 0, 0, state_rec.locked_mods,
- 0, 0, state_rec.locked_group);
+ //xkb_state_update_mask(new_state,
+ // 0, 0, new_state->components.locked_mods,
+ // 0, 0, new_state->components.locked_group);
if (xkb_state != NULL)
xkb_state_unref(xkb_state);
xkb_state = new_state;
- ret = true;
-out:
- XkbFreeKeyboard(result.xkb, XkbAllComponentsMask, true);
- fclose(temp);
- return ret;
+ return true;
}
/*
@@ -772,16 +738,22 @@ int main(int argc, char *argv[]) {
err(EXIT_FAILURE, "Could not lock page in memory, check RLIMIT_MEMLOCK");
#endif
- /* Initialize connection to X11 */
- if ((display = XOpenDisplay(NULL)) == NULL)
- errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?");
- XSetEventQueueOwner(display, XCBOwnsEventQueue);
- conn = XGetXCBConnection(display);
-
/* Double checking that connection is good and operatable with xcb */
- if (xcb_connection_has_error(conn))
+ int screennr;
+ if ((conn = xcb_connect(NULL, &screennr)) == NULL ||
+ xcb_connection_has_error(conn))
errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set DISPLAY?");
+ if (xkb_x11_setup_xkb_extension(conn,
+ XKB_X11_MIN_MAJOR_XKB_VERSION,
+ XKB_X11_MIN_MINOR_XKB_VERSION,
+ 0,
+ NULL,
+ NULL,
+ &xkb_base_event,
+ &xkb_base_error) != 1)
+ errx(EXIT_FAILURE, "Could not setup XKB extension.");
+
/* When we cannot initially load the keymap, we better exit */
if (!load_keymap())
errx(EXIT_FAILURE, "Could not load keymap");