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