[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
parent
0b0a48ca08
commit
46f2b252d8
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue