From 0d43606d405d99dcd968f7835d486ad3397338c3 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Fri, 21 Jun 2019 16:02:27 +0200 Subject: [PATCH] Proof of concept of a wayland protocol to allow the keystate dataengine to work Test Plan: Tested with both the lock screen and the keyboard indicator plasmoid Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, kde-frameworks-devel Tags: #frameworks Differential Revision: https://phabricator.kde.org/D20191 --- src/wayland/CMakeLists.txt | 7 +++ src/wayland/display.cpp | 8 +++ src/wayland/display.h | 5 ++ src/wayland/keystate_interface.cpp | 96 ++++++++++++++++++++++++++++++ src/wayland/keystate_interface.h | 71 ++++++++++++++++++++++ 5 files changed, 187 insertions(+) create mode 100644 src/wayland/keystate_interface.cpp create mode 100644 src/wayland/keystate_interface.h diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index cebdbe7347..c8860c3c71 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -16,6 +16,7 @@ set(SERVER_LIB_SRCS idleinhibit_interface_v1.cpp fakeinput_interface.cpp keyboard_interface.cpp + keystate_interface.cpp remote_access_interface.cpp outputconfiguration_interface.cpp outputchangeset.cpp @@ -208,6 +209,11 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS BASENAME eglstream-controller ) +ecm_add_wayland_server_protocol(SERVER_LIB_SRCS + PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/keystate.xml + BASENAME keystate +) + set(SERVER_GENERATED_SRCS ${CMAKE_CURRENT_BINARY_DIR}/wayland-output-management-client-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/wayland-output-management-server-protocol.h @@ -317,6 +323,7 @@ set(SERVER_LIB_HEADERS idle_interface.h idleinhibit_interface.h keyboard_interface.h + keystate_interface.h remote_access_interface.h outputdevice_interface.h outputchangeset.h diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp index 6862645c76..d9c3193eac 100644 --- a/src/wayland/display.cpp +++ b/src/wayland/display.cpp @@ -56,6 +56,7 @@ License along with this library. If not, see . #include "xdgoutput_interface.h" #include "xdgdecoration_interface.h" #include "eglstream_controller_interface.h" +#include "keystate_interface.h" #include #include @@ -522,6 +523,13 @@ EglStreamControllerInterface *Display::createEglStreamControllerInterface(QObjec return e; } +KeyStateInterface *Display::createKeyStateInterface(QObject *parent) +{ + auto d = new KeyStateInterface(this, parent); + connect(this, &Display::aboutToTerminate, d, [d] { delete d; }); + return d; +} + void Display::createShm() { Q_ASSERT(d->display); diff --git a/src/wayland/display.h b/src/wayland/display.h index d6a5f47891..40e9d3e8f2 100644 --- a/src/wayland/display.h +++ b/src/wayland/display.h @@ -91,6 +91,7 @@ class PlasmaVirtualDesktopManagementInterface; class XdgOutputManagerInterface; class XdgDecorationManagerInterface; class EglStreamControllerInterface; +class KeyStateInterface; /** * @brief Class holding the Wayland server display loop. @@ -203,6 +204,10 @@ public: ContrastManagerInterface *createContrastManager(QObject *parent = nullptr); SlideManagerInterface *createSlideManager(QObject *parent = nullptr); DpmsManagerInterface *createDpmsManager(QObject *parent = nullptr); + + /** @since 5.57 */ + KeyStateInterface *createKeyStateInterface(QObject *parent = nullptr); + /** * @since 5.6 **/ diff --git a/src/wayland/keystate_interface.cpp b/src/wayland/keystate_interface.cpp new file mode 100644 index 0000000000..576470b883 --- /dev/null +++ b/src/wayland/keystate_interface.cpp @@ -0,0 +1,96 @@ +/******************************************************************** +Copyright 2019 Aleix Pol Gonzalez + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#include "keystate_interface.h" +#include "global_p.h" +#include "display.h" + +#include +#include +#include +#include + +namespace KWayland +{ +namespace Server +{ + +class KeyStateInterface::Private : public Global::Private +{ +public: + Private(Display *d) + : Global::Private(d, &org_kde_kwin_keystate_interface, s_version) + {} + + void bind(wl_client * client, uint32_t version, uint32_t id) override { + auto c = display->getConnection(client); + wl_resource *resource = c->createResource(&org_kde_kwin_keystate_interface, qMin(version, s_version), id); + if (!resource) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(resource, &s_interface, this, unbind); + m_resources << resource; + } + + static void unbind(wl_resource *resource) { + auto *d = reinterpret_cast(wl_resource_get_user_data(resource)); + d->m_resources.removeAll(resource); + } + + + static void fetchStatesCallback(struct wl_client */*client*/, struct wl_resource *resource) { + auto s = reinterpret_cast(wl_resource_get_user_data(resource)); + + for (int i=0; im_keyStates.count(); ++i) + org_kde_kwin_keystate_send_stateChanged(resource, i, s->m_keyStates[i]); + } + + static const quint32 s_version; + QVector m_resources; + QVector m_keyStates = QVector(3, Unlocked); + static const struct org_kde_kwin_keystate_interface s_interface; +}; + +const quint32 KeyStateInterface::Private::s_version = 1; + +KeyStateInterface::KeyStateInterface(Display* d, QObject* parent) + : Global(new Private(d), parent) +{} + +KeyStateInterface::~KeyStateInterface() = default; + +const struct org_kde_kwin_keystate_interface KeyStateInterface::Private::s_interface = { + fetchStatesCallback +}; + +void KeyStateInterface::setState(KeyStateInterface::Key key, KeyStateInterface::State state) +{ + auto dptr = static_cast(d.data()); + dptr->m_keyStates[int(key)] = state; + + qDebug() << Q_FUNC_INFO << "xxxxxxxx setting state" << dptr->m_resources << key << state; + for(auto r : qAsConst(dptr->m_resources)) + org_kde_kwin_keystate_send_stateChanged(r, int(key), int(state)); +} + +} + +} diff --git a/src/wayland/keystate_interface.h b/src/wayland/keystate_interface.h new file mode 100644 index 0000000000..9ad1f3cb3a --- /dev/null +++ b/src/wayland/keystate_interface.h @@ -0,0 +1,71 @@ +/******************************************************************** +Copyright 2019 Aleix Pol Gonzalez + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#ifndef KWAYLAND_KEYSTATE_INTERFACE_H +#define KWAYLAND_KEYSTATE_INTERFACE_H + +#include +#include "global.h" +#include "resource.h" + +namespace KWayland +{ +namespace Server +{ + +class Display; + +/** + * @brief Exposes key states to wayland clients + * + * @since 5.58 + **/ +class KWAYLANDSERVER_EXPORT KeyStateInterface : public Global +{ + Q_OBJECT +public: + virtual ~KeyStateInterface(); + + enum class Key { + CapsLock = 0, + NumLock = 1, + ScrollLock = 2, + }; + Q_ENUM(Key); + enum State { + Unlocked = 0, + Latched = 1, + Locked = 2, + }; + Q_ENUM(State) + + void setState(Key k, State s); + +private: + explicit KeyStateInterface(Display *display, QObject *parent = nullptr); + friend class Display; + + class Private; +}; + +} +} + +#endif