summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@digia.com>2012-09-22 01:12:38 +0200
committerSamuel Rødal <samuel.rodal@digia.com>2012-09-22 12:55:57 +0200
commitc999bcb9a5cb4fb30ff5753d704507225eb43ce1 (patch)
treebd491155b13d78cb53f7cad6be94a9f53ed53b68 /src
parentcfe4d1589f17cb23a149c3cbec2b4e416bc8a18c (diff)
Made qtwayland compositor handle plain wayland clients.
Wayland clients now expect to receive a compiled xkb keymap from the compositor. Update libxkbcommon_sha1.txt to newest and send a keymap to the clients (for now just evdev/pc105/us). Change-Id: I89e99f05d8a98a7de83b8985a370de4fa39074a6 Reviewed-by: Arvid Picciani <aep@exys.org> Reviewed-by: Jørgen Lind <jorgen.lind@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri9
-rw-r--r--src/compositor/wayland_wrapper/wlinputdevice.cpp76
-rw-r--r--src/compositor/wayland_wrapper/wlinputdevice.h11
3 files changed, 96 insertions, 0 deletions
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index 96b02f4ce..d64a2351b 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -49,3 +49,12 @@ SOURCES += \
INCLUDEPATH += $$PWD
INCLUDEPATH += $$PWD/../../shared
+config_xkbcommon {
+ !contains(QT_CONFIG, no-pkg-config) {
+ PKGCONFIG += xkbcommon
+ } else {
+ LIBS += -lxkbcommon
+ }
+} else {
+ DEFINES += QT_NO_WAYLAND_XKB
+}
diff --git a/src/compositor/wayland_wrapper/wlinputdevice.cpp b/src/compositor/wayland_wrapper/wlinputdevice.cpp
index 41cbc3806..12d90db31 100644
--- a/src/compositor/wayland_wrapper/wlinputdevice.cpp
+++ b/src/compositor/wayland_wrapper/wlinputdevice.cpp
@@ -49,6 +49,17 @@
#include <QtGui/QTouchEvent>
+#ifndef QT_NO_WAYLAND_XKB
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#endif
+
namespace Wayland {
static QImage *currentCursor;
@@ -63,12 +74,72 @@ InputDevice::InputDevice(WaylandInputDevice *handle, Compositor *compositor)
&wl_seat_interface,
this,
InputDevice::bind_func);
+
+#ifndef QT_NO_WAYLAND_XKB
+ xkb_rule_names xkb_names;
+ xkb_context *context = xkb_context_new(xkb_context_flags(0));
+
+ memset(&xkb_names, 0, sizeof(xkb_names));
+ xkb_names.rules = strdup("evdev");
+ xkb_names.model = strdup("pc105");
+ xkb_names.layout = strdup("us");
+
+ xkb_keymap *keymap = xkb_map_new_from_names(context, &xkb_names, xkb_map_compile_flags(0));
+ if (!keymap)
+ qFatal("Failed to compile global XKB keymap");
+
+ char *keymap_str_data = xkb_map_get_as_string(keymap);
+ QByteArray keymap_str = keymap_str_data;
+ m_keymap_size = keymap_str.size() + 1;
+ free(keymap_str_data);
+
+ const char *path = getenv("XDG_RUNTIME_DIR");
+ if (!path)
+ qFatal("XDG_RUNTIME_DIR not set");
+
+ QByteArray name = QByteArray(path) + "/qtwayland-xkb-map-XXXXXX";
+
+ int fd = mkstemp(name.data());
+ if (fd >= 0) {
+ long flags = fcntl(fd, F_GETFD);
+ if (flags == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
+ close(fd);
+ qFatal("Failed to set FD_CLOEXEC on anonymous file");
+ }
+ unlink(name.data());
+ } else {
+ qFatal("Failed to create anonymous file with name %s", name.constData());
+ }
+
+ if (ftruncate(fd, m_keymap_size) < 0)
+ qFatal("Failed to create anonymous file of size %d", m_keymap_size);
+
+ m_keymap_fd = fd;
+
+ m_keymap_area = (char *)mmap(0, m_keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_keymap_fd, 0);
+ if (m_keymap_area == MAP_FAILED) {
+ close(m_keymap_fd);
+ qFatal("Failed to map shared memory segment");
+ }
+
+ strcpy(m_keymap_area, keymap_str.constData());
+
+ free((char *)xkb_names.rules);
+ free((char *)xkb_names.model);
+ free((char *)xkb_names.layout);
+ xkb_map_unref(keymap);
+ xkb_context_unref(context);
+#endif
}
InputDevice::~InputDevice()
{
qDeleteAll(m_data_devices);
releaseDevices();
+
+ if (m_keymap_area)
+ munmap(m_keymap_area, m_keymap_size);
+ close(m_keymap_fd);
}
void InputDevice::initDevices()
@@ -198,6 +269,11 @@ void InputDevice::get_keyboard(struct wl_client *client,
keyboard);
wl_list_insert(&keyboard->resource_list, &clientResource->link);
clientResource->destroy = InputDevice::destroy_device_resource;
+
+#ifndef QT_NO_WAYLAND_XKB
+ wl_keyboard_send_keymap(clientResource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+ inputDevice->m_keymap_fd, inputDevice->m_keymap_size);
+#endif
}
void InputDevice::get_touch(struct wl_client *client,
diff --git a/src/compositor/wayland_wrapper/wlinputdevice.h b/src/compositor/wayland_wrapper/wlinputdevice.h
index 58f450294..8bd28789d 100644
--- a/src/compositor/wayland_wrapper/wlinputdevice.h
+++ b/src/compositor/wayland_wrapper/wlinputdevice.h
@@ -48,6 +48,10 @@
#include <QtCore/QList>
#include <QtCore/QPoint>
+#ifndef QT_NO_WAYLAND_XKB
+#include <xkbcommon/xkbcommon.h>
+#endif
+
class QKeyEvent;
class QTouchEvent;
class WaylandInputDevice;
@@ -115,6 +119,13 @@ private:
wl_touch touch;
} m_device_interfaces;
+#ifndef QT_NO_WAYLAND_XKB
+ struct xkb_keymap *m_keymap;
+ int m_keymap_fd;
+ size_t m_keymap_size;
+ char *m_keymap_area;
+#endif
+
uint32_t toWaylandButton(Qt::MouseButton button);
static void bind_func(struct wl_client *client, void *data,