From eaa2a69bd44179b024051f3d1a09143e17ad5df8 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Sun, 18 Aug 2019 00:46:57 +0100 Subject: x11_window: Use XCB to load keymap --- .builds/archlinux.yml | 2 ++ .builds/debian.yml | 2 ++ .builds/fedora.yml | 2 ++ .builds/freebsd.yml | 2 +- .builds/ubuntu.yml | 2 ++ Makefile | 2 +- src/dummy_window.c | 2 +- src/imv.c | 2 +- src/window.h | 2 +- src/wl_window.c | 2 +- src/x11_window.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++--- 11 files changed, 63 insertions(+), 9 deletions(-) diff --git a/.builds/archlinux.yml b/.builds/archlinux.yml index e8eba80..27db21f 100644 --- a/.builds/archlinux.yml +++ b/.builds/archlinux.yml @@ -8,7 +8,9 @@ packages: - librsvg - libtiff - libx11 + - libxcb - libxkbcommon + - libxkbcommon-x11 - pango - wayland sources: diff --git a/.builds/debian.yml b/.builds/debian.yml index 08c583f..d11ceef 100644 --- a/.builds/debian.yml +++ b/.builds/debian.yml @@ -12,7 +12,9 @@ packages: - libturbojpeg-dev - libwayland-dev - libx11-dev + - libxcb1-dev - libxkbcommon-dev + - libxkbcommon-x11-dev - mesa-common-dev sources: - https://git.sr.ht/~exec64/imv diff --git a/.builds/fedora.yml b/.builds/fedora.yml index b2f8745..4bcec48 100644 --- a/.builds/fedora.yml +++ b/.builds/fedora.yml @@ -7,7 +7,9 @@ packages: - libpng-devel - librsvg2-devel - libtiff-devel + - libxcb-devel - libxkbcommon-devel + - libxkbcommon-x11-devel - mesa-libEGL-devel - mesa-libGL-devel - mesa-libGLU-devel diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index 2d2565c..449b84d 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -10,7 +10,7 @@ packages: - graphics/tiff - sysutils/cmocka - x11-toolkits/pango - - x11/libxkbcommon + - x11/libxcb - x11/libxkbcommon sources: - https://git.sr.ht/~exec64/imv diff --git a/.builds/ubuntu.yml b/.builds/ubuntu.yml index 9e0eb39..3e8b080 100644 --- a/.builds/ubuntu.yml +++ b/.builds/ubuntu.yml @@ -12,7 +12,9 @@ packages: - libturbojpeg-dev - libwayland-dev - libx11-dev + - libxcb1-dev - libxkbcommon-dev + - libxkbcommon-x11-dev - mesa-common-dev sources: - https://git.sr.ht/~exec64/imv diff --git a/Makefile b/Makefile index 31effa5..dcb38f5 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ WL_SOURCES = src/wl_window.c src/xdg-shell-protocol.c WL_LIBS = -lwayland-client -lwayland-egl -lEGL X11_SOURCES = src/x11_window.c -X11_LIBS = -lX11 -lGL -lGLU +X11_LIBS = -lX11 -lGL -lGLU -lxcb -lxkbcommon-x11 MSG_SOURCES = src/imv_msg.c src/ipc_common.c MSG_LIBS = diff --git a/src/dummy_window.c b/src/dummy_window.c index 937262b..e6ce54d 100644 --- a/src/dummy_window.c +++ b/src/dummy_window.c @@ -95,7 +95,7 @@ void imv_window_pump_events(struct imv_window *window, imv_event_handler handler (void)data; } -const char *imv_window_keymap(struct imv_window *window) +const char *imv_window_get_keymap(struct imv_window *window) { (void)window; return NULL; diff --git a/src/imv.c b/src/imv.c index 991de70..fd2bf1f 100644 --- a/src/imv.c +++ b/src/imv.c @@ -1090,7 +1090,7 @@ static bool setup_window(struct imv *imv) imv->keyboard = imv_keyboard_create(); assert(imv->keyboard); - const char *keymap = imv_window_keymap(imv->window); + const char *keymap = imv_window_get_keymap(imv->window); if (keymap) { imv_keyboard_set_keymap(imv->keyboard, keymap); } diff --git a/src/window.h b/src/window.h index 7db1125..a496655 100644 --- a/src/window.h +++ b/src/window.h @@ -73,6 +73,6 @@ typedef void (*imv_event_handler)(void *data, const struct imv_event *e); void imv_window_pump_events(struct imv_window *window, imv_event_handler handler, void *data); -const char *imv_window_keymap(struct imv_window *window); +const char *imv_window_get_keymap(struct imv_window *window); #endif diff --git a/src/wl_window.c b/src/wl_window.c index e0fa251..ace66f0 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -827,7 +827,7 @@ void imv_window_pump_events(struct imv_window *window, imv_event_handler handler } } -const char *imv_window_keymap(struct imv_window *window) +const char *imv_window_get_keymap(struct imv_window *window) { return window->keymap; } diff --git a/src/x11_window.c b/src/x11_window.c index 1b7f724..315f600 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -13,6 +13,11 @@ #include #include +#include +#include + +#include "log.h" + struct imv_window { Display *x_display; Window x_window; @@ -32,6 +37,7 @@ struct imv_window { } pointer; int pipe_fds[2]; + char *keymap; }; static void set_nonblocking(int fd) @@ -43,6 +49,44 @@ static void set_nonblocking(int fd) assert(rc != -1); } +static void setup_keymap(struct imv_window *window) +{ + xcb_connection_t *conn = xcb_connect(NULL, NULL); + if (xcb_connection_has_error(conn)) { + imv_log(IMV_ERROR, "x11_window: Failed to load keymap. Could not connect via xcb."); + return; + } + + if (!xkb_x11_setup_xkb_extension(conn, + XKB_X11_MIN_MAJOR_XKB_VERSION, + XKB_X11_MIN_MINOR_XKB_VERSION, + 0, NULL, NULL, NULL, NULL)) { + xcb_disconnect(conn); + imv_log(IMV_ERROR, "x11_window: Failed to load keymap. xkb extension not supported by server."); + return; + } + + int32_t device = xkb_x11_get_core_keyboard_device_id(conn); + + struct xkb_context *context = xkb_context_new(0); + if (!context) { + xcb_disconnect(conn); + imv_log(IMV_ERROR, "x11_window: Failed to load keymap. Failed to initialise xkb context."); + return; + } + + struct xkb_keymap *keymap = + xkb_x11_keymap_new_from_device(context, conn, device, 0); + if (keymap) { + window->keymap = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_USE_ORIGINAL_FORMAT); + } else { + imv_log(IMV_ERROR, "x11_window: Failed to load keymap. xkb_x11_keymap_new_from_device returned NULL."); + } + xkb_context_unref(context); + + xcb_disconnect(conn); +} + struct imv_window *imv_window_create(int w, int h, const char *title) { /* Ensure event writes will always be atomic */ @@ -93,6 +137,8 @@ struct imv_window *imv_window_create(int w, int h, const char *title) assert(window->x_glc); glXMakeCurrent(window->x_display, window->x_window, window->x_glc); + setup_keymap(window); + return window; } @@ -102,6 +148,7 @@ void imv_window_free(struct imv_window *window) close(window->pipe_fds[1]); glXDestroyContext(window->x_display, window->x_glc); XCloseDisplay(window->x_display); + free(window->keymap); free(window); } @@ -336,8 +383,7 @@ void imv_window_pump_events(struct imv_window *window, imv_event_handler handler } } -const char *imv_window_keymap(struct imv_window *window) +const char *imv_window_get_keymap(struct imv_window *window) { - (void)window; - return NULL; + return window->keymap; } -- cgit v1.2.3