Skip to content

Commit

Permalink
Made qtwayland compositor handle plain wayland clients.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Samuel Rødal committed Sep 22, 2012
1 parent cfe4d15 commit c999bcb
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
2 changes: 1 addition & 1 deletion libxkbcommon_sha1.txt
@@ -1,6 +1,6 @@
This version of Qt-Compositor is checked against the following sha1
from the libxkbcommon repository:
3fbc277bb8717d031f9c863935460b895c3d3beb
9aee332e9fd470580611d789d8265f983b199fde

During the qmake step a configuration test will be compiled to check
if libxkbcommon is available. If not, or it is an incompatible
Expand Down
9 changes: 9 additions & 0 deletions src/compositor/wayland_wrapper/wayland_wrapper.pri
Expand Up @@ -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
}
76 changes: 76 additions & 0 deletions src/compositor/wayland_wrapper/wlinputdevice.cpp
Expand Up @@ -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;
Expand All @@ -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()
Expand Down Expand Up @@ -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,
Expand Down
11 changes: 11 additions & 0 deletions src/compositor/wayland_wrapper/wlinputdevice.h
Expand Up @@ -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;
Expand Down Expand Up @@ -115,6 +119,13 @@ class InputDevice : public Object<struct wl_seat>
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,
Expand Down

0 comments on commit c999bcb

Please sign in to comment.