[kwin_wayland] Create dedicated classes for Seat, Keyboard and Pointer

Split out from wayland_backend. So far no unit test as there is no proper
way to simulate input events.
icc-effect-5.14.5
Martin Gräßlin 2014-08-21 11:20:03 +02:00
parent 0b0a48ca08
commit 46f2b252d8
9 changed files with 770 additions and 174 deletions

View File

@ -431,7 +431,10 @@ if(Wayland_Client_FOUND AND XKB_FOUND)
wayland_client/connection_thread.cpp
wayland_client/registry.cpp
wayland_client/fullscreen_shell.cpp
wayland_client/keyboard.cpp
wayland_client/output.cpp
wayland_client/pointer.cpp
wayland_client/seat.cpp
wayland_client/shell.cpp
wayland_client/shm_pool.cpp
wayland_client/surface.cpp

View File

@ -26,8 +26,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_client/compositor.h"
#include "wayland_client/connection_thread.h"
#include "wayland_client/fullscreen_shell.h"
#include "wayland_client/keyboard.h"
#include "wayland_client/output.h"
#include "wayland_client/pointer.h"
#include "wayland_client/registry.h"
#include "wayland_client/seat.h"
#include "wayland_client/shell.h"
#include "wayland_client/shm_pool.h"
#include "wayland_client/surface.h"
@ -49,127 +52,6 @@ namespace KWin
namespace Wayland
{
static void seatHandleCapabilities(void *data, wl_seat *seat, uint32_t capabilities)
{
WaylandSeat *s = reinterpret_cast<WaylandSeat*>(data);
if (seat != s->seat()) {
return;
}
s->changed(capabilities);
}
static void pointerHandleEnter(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy)
{
Q_UNUSED(data)
Q_UNUSED(pointer)
Q_UNUSED(surface)
Q_UNUSED(sx)
Q_UNUSED(sy)
WaylandSeat *seat = reinterpret_cast<WaylandSeat*>(data);
seat->pointerEntered(serial);
}
static void pointerHandleLeave(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface)
{
Q_UNUSED(data)
Q_UNUSED(pointer)
Q_UNUSED(serial)
Q_UNUSED(surface)
}
static void pointerHandleMotion(void *data, wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
{
Q_UNUSED(data)
Q_UNUSED(pointer)
input()->processPointerMotion(QPoint(wl_fixed_to_double(sx), wl_fixed_to_double(sy)), time);
}
static void pointerHandleButton(void *data, wl_pointer *pointer, uint32_t serial, uint32_t time,
uint32_t button, uint32_t state)
{
Q_UNUSED(data)
Q_UNUSED(pointer)
Q_UNUSED(serial)
input()->processPointerButton(button, static_cast<InputRedirection::PointerButtonState>(state), time);
}
static void pointerHandleAxis(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
{
Q_UNUSED(data)
Q_UNUSED(pointer)
input()->processPointerAxis(static_cast<InputRedirection::PointerAxis>(axis), wl_fixed_to_double(value), time);
}
static void keyboardHandleKeymap(void *data, wl_keyboard *keyboard,
uint32_t format, int fd, uint32_t size)
{
Q_UNUSED(data)
Q_UNUSED(keyboard)
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
return;
}
input()->processKeymapChange(fd, size);
}
static void keyboardHandleEnter(void *data, wl_keyboard *keyboard,
uint32_t serial, wl_surface *surface,
wl_array *keys)
{
Q_UNUSED(data)
Q_UNUSED(keyboard)
Q_UNUSED(serial)
Q_UNUSED(surface)
Q_UNUSED(keys)
}
static void keyboardHandleLeave(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface)
{
Q_UNUSED(data)
Q_UNUSED(keyboard)
Q_UNUSED(serial)
Q_UNUSED(surface)
}
static void keyboardHandleKey(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time,
uint32_t key, uint32_t state)
{
Q_UNUSED(data)
Q_UNUSED(keyboard)
Q_UNUSED(serial)
input()->processKeyboardKey(key, static_cast<InputRedirection::KeyboardKeyState>(state), time);
}
static void keyboardHandleModifiers(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t modsDepressed,
uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
{
Q_UNUSED(data)
Q_UNUSED(keyboard)
Q_UNUSED(serial)
input()->processKeyboardModifiers(modsDepressed, modsLatched, modsLocked, group);
}
// handlers
static const struct wl_pointer_listener s_pointerListener = {
pointerHandleEnter,
pointerHandleLeave,
pointerHandleMotion,
pointerHandleButton,
pointerHandleAxis
};
static const struct wl_keyboard_listener s_keyboardListener = {
keyboardHandleKeymap,
keyboardHandleEnter,
keyboardHandleLeave,
keyboardHandleKey,
keyboardHandleModifiers,
};
static const struct wl_seat_listener s_seatListener = {
seatHandleCapabilities
};
CursorData::CursorData()
: m_valid(init())
{
@ -264,7 +146,7 @@ void X11CursorTracker::resetCursor()
WaylandSeat::WaylandSeat(wl_seat *seat, WaylandBackend *backend)
: QObject(NULL)
, m_seat(seat)
, m_seat(new Seat(this))
, m_pointer(NULL)
, m_keyboard(NULL)
, m_cursor(NULL)
@ -273,58 +155,109 @@ WaylandSeat::WaylandSeat(wl_seat *seat, WaylandBackend *backend)
, m_cursorTracker()
, m_backend(backend)
{
if (m_seat) {
wl_seat_add_listener(m_seat, &s_seatListener, this);
}
m_seat->setup(seat);
connect(m_seat, &Seat::hasKeyboardChanged, this,
[this](bool hasKeyboard) {
if (hasKeyboard) {
m_keyboard = m_seat->createKeyboard(this);
connect(m_keyboard, &Keyboard::keyChanged, this,
[this](quint32 key, Keyboard::KeyState state, quint32 time) {
auto toState = [state] {
switch (state) {
case Keyboard::KeyState::Pressed:
return InputRedirection::KeyboardKeyPressed;
case Keyboard::KeyState::Released:
return InputRedirection::KeyboardKeyReleased;
}
abort();
};
input()->processKeyboardKey(key, toState(), time);
}
);
connect(m_keyboard, &Keyboard::modifiersChanged, this,
[this](quint32 depressed, quint32 latched, quint32 locked, quint32 group) {
input()->processKeyboardModifiers(depressed, latched, locked, group);
}
);
connect(m_keyboard, &Keyboard::keymapChanged, this,
[this](int fd, quint32 size) {
input()->processKeymapChange(fd, size);
}
);
} else {
destroyKeyboard();
}
}
);
connect(m_seat, &Seat::hasPointerChanged, this,
[this](bool hasPointer) {
if (hasPointer && !m_pointer) {
m_pointer = m_seat->createPointer(this);
connect(m_pointer, &Pointer::entered, this,
[this](quint32 serial) {
m_enteredSerial = serial;
}
);
connect(m_pointer, &Pointer::motion, this,
[this](const QPointF &relativeToSurface, quint32 time) {
input()->processPointerMotion(relativeToSurface.toPoint(), time);
}
);
connect(m_pointer, &Pointer::buttonStateChanged, this,
[this](quint32 serial, quint32 time, quint32 button, Pointer::ButtonState state) {
Q_UNUSED(serial)
auto toState = [state] {
switch (state) {
case Pointer::ButtonState::Pressed:
return InputRedirection::PointerButtonPressed;
case Pointer::ButtonState::Released:
return InputRedirection::PointerButtonReleased;
}
abort();
};
input()->processPointerButton(button, toState(), time);
}
);
connect(m_pointer, &Pointer::axisChanged, this,
[this](quint32 time, Pointer::Axis axis, qreal delta) {
auto toAxis = [axis] {
switch (axis) {
case Pointer::Axis::Horizontal:
return InputRedirection::PointerAxisHorizontal;
case Pointer::Axis::Vertical:
return InputRedirection::PointerAxisVertical;
}
abort();
};
input()->processPointerAxis(toAxis(), delta, time);
}
);
m_cursorTracker.reset(new X11CursorTracker(this, m_backend));
} else {
destroyPointer();
}
}
);
}
WaylandSeat::~WaylandSeat()
{
destroyPointer();
destroyKeyboard();
if (m_seat) {
wl_seat_destroy(m_seat);
}
destroyTheme();
}
void WaylandSeat::destroyPointer()
{
if (m_pointer) {
wl_pointer_destroy(m_pointer);
m_pointer = NULL;
m_cursorTracker.reset();
}
delete m_pointer;
m_pointer = nullptr;
m_cursorTracker.reset();
}
void WaylandSeat::destroyKeyboard()
{
if (m_keyboard) {
wl_keyboard_destroy(m_keyboard);
m_keyboard = NULL;
}
}
void WaylandSeat::changed(uint32_t capabilities)
{
if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && !m_pointer) {
m_pointer = wl_seat_get_pointer(m_seat);
wl_pointer_add_listener(m_pointer, &s_pointerListener, this);
m_cursorTracker.reset(new X11CursorTracker(this, m_backend));
} else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER)) {
destroyPointer();
}
if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
m_keyboard = wl_seat_get_keyboard(m_seat);
wl_keyboard_add_listener(m_keyboard, &s_keyboardListener, this);
} else if (!(capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
destroyKeyboard();
}
}
void WaylandSeat::pointerEntered(uint32_t serial)
{
m_enteredSerial = serial;
delete m_keyboard;
m_keyboard = nullptr;
}
void WaylandSeat::resetCursor()
@ -336,7 +269,7 @@ void WaylandSeat::resetCursor()
void WaylandSeat::installCursorImage(wl_buffer *image, const QSize &size, const QPoint &hotSpot)
{
if (!m_pointer) {
if (!m_pointer || !m_pointer->isValid()) {
return;
}
if (!m_cursor) {
@ -345,7 +278,7 @@ void WaylandSeat::installCursorImage(wl_buffer *image, const QSize &size, const
if (!m_cursor || !m_cursor->isValid()) {
return;
}
wl_pointer_set_cursor(m_pointer, m_enteredSerial, *m_cursor, hotSpot.x(), hotSpot.y());
wl_pointer_set_cursor(*m_pointer, m_enteredSerial, *m_cursor, hotSpot.x(), hotSpot.y());
m_cursor->attachBuffer(image);
m_cursor->damage(QRect(QPoint(0,0), size));
m_cursor->commit(Surface::CommitFlag::None);
@ -546,7 +479,7 @@ void WaylandBackend::initConnection()
void WaylandBackend::createSeat(uint32_t name)
{
m_seat.reset(new WaylandSeat(m_registry->bindSeat(name, 1), this));
m_seat.reset(new WaylandSeat(m_registry->bindSeat(name, 2), this));
}
void WaylandBackend::installCursorImage(Qt::CursorShape shape)

View File

@ -48,8 +48,11 @@ class WaylandSeat;
class Compositor;
class ConnectionThread;
class FullscreenShell;
class Keyboard;
class Output;
class Pointer;
class Registry;
class Seat;
class Shell;
class ShellSurface;
class Surface;
@ -94,9 +97,6 @@ public:
WaylandSeat(wl_seat *seat, WaylandBackend *backend);
virtual ~WaylandSeat();
void changed(uint32_t capabilities);
wl_seat *seat();
void pointerEntered(uint32_t serial);
void resetCursor();
void installCursorImage(wl_buffer *image, const QSize &size, const QPoint &hotspot);
void installCursorImage(Qt::CursorShape shape);
@ -106,9 +106,9 @@ private:
void destroyPointer();
void destroyKeyboard();
void destroyTheme();
wl_seat *m_seat;
wl_pointer *m_pointer;
wl_keyboard *m_keyboard;
Seat *m_seat;
Pointer *m_pointer;
Keyboard *m_keyboard;
Surface *m_cursor;
wl_cursor_theme *m_theme;
uint32_t m_enteredSerial;
@ -184,12 +184,6 @@ const QImage &CursorData::cursor() const
return m_cursor;
}
inline
wl_seat *WaylandSeat::seat()
{
return m_seat;
}
inline
wl_display *WaylandBackend::display()
{

117
wayland_client/keyboard.cpp Normal file
View File

@ -0,0 +1,117 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "keyboard.h"
namespace KWin
{
namespace Wayland
{
const wl_keyboard_listener Keyboard::s_listener = {
keymapCallback,
enterCallback,
leaveCallback,
keyCallback,
modifiersCallback
};
Keyboard::Keyboard(QObject *parent)
: QObject(parent)
, m_keyboard(nullptr)
{
}
Keyboard::~Keyboard()
{
release();
}
void Keyboard::release()
{
if (!m_keyboard) {
return;
}
wl_keyboard_destroy(m_keyboard);
m_keyboard = nullptr;
}
void Keyboard::setup(wl_keyboard *keyboard)
{
Q_ASSERT(keyboard);
Q_ASSERT(!m_keyboard);
m_keyboard = keyboard;
wl_keyboard_add_listener(m_keyboard, &Keyboard::s_listener, this);
}
void Keyboard::enterCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys)
{
// ignore
Q_UNUSED(data)
Q_UNUSED(keyboard)
Q_UNUSED(serial)
Q_UNUSED(surface)
Q_UNUSED(keys)
}
void Keyboard::leaveCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface)
{
// ignore
Q_UNUSED(data)
Q_UNUSED(keyboard)
Q_UNUSED(serial)
Q_UNUSED(surface)
}
void Keyboard::keyCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
{
Q_UNUSED(serial)
Keyboard *k = reinterpret_cast<Keyboard*>(data);
Q_ASSERT(k->m_keyboard == keyboard);
auto toState = [state] {
if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
return KeyState::Released;
} else {
return KeyState::Pressed;
}
};
emit k->keyChanged(key, toState(), time);
}
void Keyboard::keymapCallback(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size)
{
Keyboard *k = reinterpret_cast<Keyboard*>(data);
Q_ASSERT(k->m_keyboard == keyboard);
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
return;
}
emit k->keymapChanged(fd, size);
}
void Keyboard::modifiersCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t modsDepressed,
uint32_t modsLatched, uint32_t modsLocked, uint32_t group)
{
Q_UNUSED(serial)
Keyboard *k = reinterpret_cast<Keyboard*>(data);
Q_ASSERT(k->m_keyboard == keyboard);
emit k->modifiersChanged(modsDepressed, modsLatched, modsLocked, group);
}
}
}

77
wayland_client/keyboard.h Normal file
View File

@ -0,0 +1,77 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_WAYLAND_KEYBOARD_H
#define KWIN_WAYLAND_KEYBOARD_H
#include <QObject>
#include <wayland-client-protocol.h>
namespace KWin
{
namespace Wayland
{
class Keyboard : public QObject
{
Q_OBJECT
public:
enum class KeyState {
Released,
Pressed
};
explicit Keyboard(QObject *parent = nullptr);
virtual ~Keyboard();
bool isValid() const {
return m_keyboard != nullptr;
}
void setup(wl_keyboard *keyboard);
void release();
operator wl_keyboard*() {
return m_keyboard;
}
operator wl_keyboard*() const {
return m_keyboard;
}
static void keymapCallback(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size);
static void enterCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys);
static void leaveCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface);
static void keyCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
static void modifiersCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t modsDepressed,
uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
Q_SIGNALS:
void keymapChanged(int fd, quint32 size);
void keyChanged(quint32 key, KeyState state, quint32 time);
void modifiersChanged(quint32 depressed, quint32 latched, quint32 locked, quint32 group);
private:
wl_keyboard *m_keyboard;
static const wl_keyboard_listener s_listener;
};
}
}
Q_DECLARE_METATYPE(KWin::Wayland::Keyboard::KeyState)
#endif

118
wayland_client/pointer.cpp Normal file
View File

@ -0,0 +1,118 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "pointer.h"
#include <QPointF>
namespace KWin
{
namespace Wayland
{
const wl_pointer_listener Pointer::s_listener = {
Pointer::enterCallback,
Pointer::leaveCallback,
Pointer::motionCallback,
Pointer::buttonCallback,
Pointer::axisCallback
};
Pointer::Pointer(QObject *parent)
: QObject(parent)
, m_pointer(nullptr)
{
}
Pointer::~Pointer()
{
release();
}
void Pointer::release()
{
if (!m_pointer) {
return;
}
wl_pointer_destroy(m_pointer);
m_pointer = nullptr;
}
void Pointer::setup(wl_pointer *pointer)
{
Q_ASSERT(pointer);
Q_ASSERT(!m_pointer);
m_pointer = pointer;
wl_pointer_add_listener(m_pointer, &Pointer::s_listener, this);
}
void Pointer::enterCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy)
{
Q_UNUSED(surface)
Pointer *p = reinterpret_cast<Pointer*>(data);
Q_ASSERT(p->m_pointer == pointer);
emit p->entered(serial, QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy)));
}
void Pointer::leaveCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface)
{
Q_UNUSED(surface)
Pointer *p = reinterpret_cast<Pointer*>(data);
Q_ASSERT(p->m_pointer == pointer);
emit p->left(serial);
}
void Pointer::motionCallback(void *data, wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
{
Pointer *p = reinterpret_cast<Pointer*>(data);
Q_ASSERT(p->m_pointer == pointer);
emit p->motion(QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy)), time);
}
void Pointer::buttonCallback(void *data, wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
{
Pointer *p = reinterpret_cast<Pointer*>(data);
Q_ASSERT(p->m_pointer == pointer);
auto toState = [state] {
if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
return ButtonState::Released;
} else {
return ButtonState::Pressed;
}
};
emit p->buttonStateChanged(serial, time, button, toState());
}
void Pointer::axisCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
{
Pointer *p = reinterpret_cast<Pointer*>(data);
Q_ASSERT(p->m_pointer == pointer);
auto toAxis = [axis] {
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
return Axis::Horizontal;
} else {
return Axis::Vertical;
}
};
emit p->axisChanged(time, toAxis(), wl_fixed_to_double(value));
}
}
}

84
wayland_client/pointer.h Normal file
View File

@ -0,0 +1,84 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_WAYLAND_POINTER_H
#define KWIN_WAYLAND_POINTER_H
#include <QObject>
#include <wayland-client-protocol.h>
namespace KWin
{
namespace Wayland
{
class Pointer : public QObject
{
Q_OBJECT
public:
enum class ButtonState {
Released,
Pressed
};
enum class Axis {
Vertical,
Horizontal
};
explicit Pointer(QObject *parent = nullptr);
virtual ~Pointer();
bool isValid() const {
return m_pointer;
}
void setup(wl_pointer *pointer);
void release();
operator wl_pointer*() {
return m_pointer;
}
operator wl_pointer*() const {
return m_pointer;
}
static void enterCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface,
wl_fixed_t sx, wl_fixed_t sy);
static void leaveCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface);
static void motionCallback(void *data, wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy);
static void buttonCallback(void *data, wl_pointer *pointer, uint32_t serial, uint32_t time,
uint32_t button, uint32_t state);
static void axisCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value);
Q_SIGNALS:
void entered(quint32 serial, const QPointF &relativeToSurface);
void left(quint32 serial);
void motion(const QPointF &relativeToSurface, quint32 time);
void buttonStateChanged(quint32 serial, quint32 time, quint32 button, ButtonState state);
void axisChanged(quint32 time, Axis axis, qreal delta);
private:
wl_pointer *m_pointer;
static const wl_pointer_listener s_listener;
};
}
}
Q_DECLARE_METATYPE(KWin::Wayland::Pointer::ButtonState)
#endif

167
wayland_client/seat.cpp Normal file
View File

@ -0,0 +1,167 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "seat.h"
#include "keyboard.h"
#include "pointer.h"
namespace KWin
{
namespace Wayland
{
const wl_seat_listener Seat::s_listener = {
Seat::capabilitiesCallback,
Seat::nameCallback
};
Seat::Seat(QObject *parent)
: QObject(parent)
, m_seat(nullptr)
, m_capabilityKeyboard(false)
, m_capabilityPointer(false)
, m_capabilityTouch(false)
{
}
Seat::~Seat()
{
release();
}
void Seat::release()
{
if (!m_seat) {
return;
}
wl_seat_destroy(m_seat);
m_seat = nullptr;
resetSeat();
}
void Seat::destroy()
{
if (!m_seat) {
return;
}
free(m_seat);
m_seat = nullptr;
resetSeat();
}
void Seat::resetSeat()
{
setHasKeyboard(false);
setHasPointer(false);
setHasTouch(false);
setName(QString());
}
void Seat::setHasKeyboard(bool has)
{
if (m_capabilityKeyboard == has) {
return;
}
m_capabilityKeyboard = has;
emit hasKeyboardChanged(m_capabilityKeyboard);
}
void Seat::setHasPointer(bool has)
{
if (m_capabilityPointer == has) {
return;
}
m_capabilityPointer = has;
emit hasPointerChanged(m_capabilityPointer);
}
void Seat::setHasTouch(bool has)
{
if (m_capabilityTouch == has) {
return;
}
m_capabilityTouch = has;
emit hasTouchChanged(m_capabilityTouch);
}
void Seat::setup(wl_seat *seat)
{
Q_ASSERT(seat);
Q_ASSERT(!m_seat);
m_seat = seat;
wl_seat_add_listener(m_seat, &Seat::s_listener, this);
}
void Seat::capabilitiesCallback(void *data, wl_seat *seat, uint32_t capabilities)
{
Seat *s = reinterpret_cast<Seat*>(data);
Q_ASSERT(s->m_seat == seat);
s->capabilitiesChanged(capabilities);
}
void Seat::nameCallback(void *data, wl_seat *seat, const char *name)
{
Seat *s = reinterpret_cast<Seat*>(data);
Q_ASSERT(s->m_seat == seat);
s->setName(QString::fromUtf8(name));
}
void Seat::capabilitiesChanged(uint32_t capabilities)
{
setHasKeyboard(capabilities & WL_SEAT_CAPABILITY_KEYBOARD);
setHasPointer(capabilities & WL_SEAT_CAPABILITY_POINTER);
setHasTouch(capabilities & WL_SEAT_CAPABILITY_TOUCH);
}
Keyboard *Seat::createKeyboard(QObject *parent)
{
Q_ASSERT(isValid());
Q_ASSERT(m_capabilityKeyboard);
Keyboard *k = new Keyboard(parent);
k->setup(wl_seat_get_keyboard(m_seat));
return k;
}
Pointer *Seat::createPointer(QObject *parent)
{
Q_ASSERT(isValid());
Q_ASSERT(m_capabilityPointer);
Pointer *p = new Pointer(parent);
p->setup(wl_seat_get_pointer(m_seat));
return p;
}
wl_touch *Seat::createTouch()
{
Q_ASSERT(isValid());
Q_ASSERT(m_capabilityTouch);
return wl_seat_get_touch(m_seat);
}
void Seat::setName(const QString &name)
{
if (m_name == name) {
return;
}
m_name = name;
emit nameChanged(m_name);
}
}
}

103
wayland_client/seat.h Normal file
View File

@ -0,0 +1,103 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_WAYLAND_SEAT_H
#define KWIN_WAYLAND_SEAT_H
#include <QObject>
#include <wayland-client-protocol.h>
namespace KWin
{
namespace Wayland
{
class Keyboard;
class Pointer;
class Seat : public QObject
{
Q_OBJECT
Q_PROPERTY(bool keyboard READ hasKeyboard NOTIFY hasKeyboardChanged)
Q_PROPERTY(bool pointer READ hasPointer NOTIFY hasPointerChanged)
Q_PROPERTY(bool touch READ hasTouch NOTIFY hasTouchChanged)
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
public:
explicit Seat(QObject *parent = nullptr);
virtual ~Seat();
bool isValid() const {
return m_seat != nullptr;
}
void setup(wl_seat *seat);
void release();
void destroy();
bool hasKeyboard() const {
return m_capabilityKeyboard;
}
bool hasPointer() const {
return m_capabilityPointer;
}
bool hasTouch() const {
return m_capabilityTouch;
}
const QString &name() const {
return m_name;
}
operator wl_seat*() {
return m_seat;
}
operator wl_seat*() const {
return m_seat;
}
Keyboard *createKeyboard(QObject *parent = nullptr);
Pointer *createPointer(QObject *parent = nullptr);
wl_touch *createTouch();
static void capabilitiesCallback(void *data, wl_seat *seat, uint32_t capabilities);
static void nameCallback(void *data, wl_seat *wl_seat, const char *name);
Q_SIGNALS:
void hasKeyboardChanged(bool);
void hasPointerChanged(bool);
void hasTouchChanged(bool);
void nameChanged(const QString &name);
private:
void resetSeat();
void setHasKeyboard(bool has);
void setHasPointer(bool has);
void setHasTouch(bool has);
void capabilitiesChanged(uint32_t capabilities);
void setName(const QString &name);
wl_seat *m_seat;
bool m_capabilityKeyboard;
bool m_capabilityPointer;
bool m_capabilityTouch;
QString m_name;
static const wl_seat_listener s_listener;
};
}
}
#endif