aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-08-18 00:46:57 +0100
committerHarry Jeffery <harry@exec64.co.uk>2019-08-18 00:58:43 +0100
commiteaa2a69bd44179b024051f3d1a09143e17ad5df8 (patch)
treea6bfaa217621c5f9224709069c5fa0c1443110b1
parentc6ce270ee1e54fc7ae9c4029923bccedbcac5ad2 (diff)
downloadimv-eaa2a69bd44179b024051f3d1a09143e17ad5df8.tar.gz
x11_window: Use XCB to load keymap
-rw-r--r--.builds/archlinux.yml2
-rw-r--r--.builds/debian.yml2
-rw-r--r--.builds/fedora.yml2
-rw-r--r--.builds/freebsd.yml2
-rw-r--r--.builds/ubuntu.yml2
-rw-r--r--Makefile2
-rw-r--r--src/dummy_window.c2
-rw-r--r--src/imv.c2
-rw-r--r--src/window.h2
-rw-r--r--src/wl_window.c2
-rw-r--r--src/x11_window.c52
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 <X11/Xatom.h>
#include <X11/Xlib.h>
+#include <xcb/xcb.h>
+#include <xkbcommon/xkbcommon-x11.h>
+
+#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;
}