diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -24,6 +24,7 @@ idle.cpp idleinhibit.cpp keyboard.cpp + keystate.cpp remote_access.cpp outputconfiguration.cpp outputmanagement.cpp @@ -189,6 +190,10 @@ BASENAME xdg-decoration-unstable-v1 ) +ecm_add_wayland_client_protocol(CLIENT_LIB_SRCS + PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/keystate.xml + BASENAME keystate +) set(CLIENT_GENERATED_FILES ${CMAKE_CURRENT_BINARY_DIR}/wayland-fullscreen-shell-client-protocol.h @@ -268,6 +273,7 @@ idle.h idleinhibit.h keyboard.h + keystate.h remote_access.h outputconfiguration.h outputmanagement.h diff --git a/src/client/keystate.h b/src/client/keystate.h new file mode 100644 --- /dev/null +++ b/src/client/keystate.h @@ -0,0 +1,81 @@ +/******************************************************************** +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 WAYLAND_KEYSTATE_H +#define WAYLAND_KEYSTATE_H + +#include + +#include + +struct org_kde_kwin_keystate; + +namespace KWayland +{ +namespace Client +{ +class EventQueue; + +class KWAYLANDCLIENT_EXPORT Keystate : public QObject +{ + Q_OBJECT +public: + enum class Key { + CapsLock = 0, + NumLock = 1, + ScrollLock = 2, + }; + Q_ENUM(Key); + enum State { + Unlocked = 0, + Latched = 1, + Locked = 2, + }; + Q_ENUM(State) + + Keystate(QObject* parent); + ~Keystate() override; + + void setEventQueue(EventQueue *queue); + + void destroy(); + void setup(org_kde_kwin_keystate* keystate); + + void fetchStates(); + +Q_SIGNALS: + /** + * State of the @p key changed to @p state + */ + void stateChanged(Key key, State state); + + /** + * The corresponding global for this interface on the Registry got removed. + **/ + void removed(); + +private: + class Private; + QScopedPointer d; +}; + +} +} + +#endif diff --git a/src/client/keystate.cpp b/src/client/keystate.cpp new file mode 100644 --- /dev/null +++ b/src/client/keystate.cpp @@ -0,0 +1,81 @@ +/******************************************************************** +Copyright 2014 Martin Gräßlin + +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.h" +#include "wayland_pointer_p.h" +#include +#include +#include +#include + +namespace KWayland +{ +namespace Client +{ + +class Q_DECL_HIDDEN Keystate::Private +{ +public: + Private() {} + + WaylandPointer keystate; + + static void org_kde_kwin_keystate_stateChanged(void *data, struct org_kde_kwin_keystate */*keystate*/, uint32_t k, uint32_t s) { + auto q = static_cast(data); + q->stateChanged(Key(k), State(s)); + } + + static const org_kde_kwin_keystate_listener s_listener; +}; + +const org_kde_kwin_keystate_listener Keystate::Private::s_listener = { + org_kde_kwin_keystate_stateChanged +}; + +Keystate::Keystate(QObject *parent) + : QObject(parent) + , d(new Private()) +{ +} + +Keystate::~Keystate() = default; + +void Keystate::fetchStates() +{ + org_kde_kwin_keystate_fetchStates(d->keystate); +} + +void Keystate::setup(org_kde_kwin_keystate* keystate) +{ + d->keystate.setup(keystate); + org_kde_kwin_keystate_add_listener(keystate, &Keystate::Private::s_listener, this); +} + +void Keystate::destroy() +{ + d->keystate.destroy(); +} + +void Keystate::setEventQueue(KWayland::Client::EventQueue* /*queue*/) +{ +} + + +} +} diff --git a/src/client/protocols/keystate.xml b/src/client/protocols/keystate.xml new file mode 100644 --- /dev/null +++ b/src/client/protocols/keystate.xml @@ -0,0 +1,43 @@ + + + + + This program 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) 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . + ]]> + + + + xxxxxxxxxxxxxxx + + + + + + + + + + + + + + + + + + + + + diff --git a/src/client/registry.h b/src/client/registry.h --- a/src/client/registry.h +++ b/src/client/registry.h @@ -43,6 +43,7 @@ struct org_kde_kwin_outputdevice; struct org_kde_kwin_fake_input; struct org_kde_kwin_idle; +struct org_kde_kwin_keystate; struct org_kde_kwin_remote_access_manager; struct org_kde_kwin_dpms_manager; struct org_kde_kwin_shadow_manager; @@ -83,6 +84,7 @@ class OutputDevice; class Idle; class IdleInhibitManager; +class Keystate; class RemoteAccessManager; class Output; class PlasmaShell; @@ -185,6 +187,7 @@ XdgOutputUnstableV1, ///refers to zxdg_output_v1, @since 5.47 XdgShellStable, ///refers to xdg_wm_base @since 5.48 XdgDecorationUnstableV1, ///refers to zxdg_decoration_manager_v1, @since 5.54 + Keystate,/// #include #include +#include /***** * How to add another interface: @@ -377,6 +379,13 @@ &zxdg_decoration_manager_v1_interface, &Registry::xdgDecorationAnnounced, &Registry::xdgDecorationRemoved + }}, + {Registry::Interface::Keystate, { + 1, + QByteArrayLiteral("org_kde_kwin_keystate"), + &org_kde_kwin_keystate_interface, + &Registry::keystateAnnounced, + &Registry::keystateRemoved }} }; @@ -684,6 +693,7 @@ BIND(XdgExporterUnstableV2, zxdg_exporter_v2) BIND(XdgImporterUnstableV2, zxdg_importer_v2) BIND(IdleInhibitManagerUnstableV1, zwp_idle_inhibit_manager_v1) +BIND(Keystate, org_kde_kwin_keystate) BIND2(ShadowManager, Shadow, org_kde_kwin_shadow_manager) BIND2(BlurManager, Blur, org_kde_kwin_blur_manager) BIND2(ContrastManager, Contrast, org_kde_kwin_contrast_manager) @@ -745,6 +755,7 @@ CREATE(ServerSideDecorationManager) CREATE2(ShmPool, Shm) CREATE(AppMenuManager) +CREATE(Keystate) CREATE(ServerSideDecorationPaletteManager) #undef CREATE diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -16,6 +16,7 @@ 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 @@ 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 @@ 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/server/display.h b/src/server/display.h --- a/src/server/display.h +++ b/src/server/display.h @@ -91,6 +91,7 @@ class XdgOutputManagerInterface; class XdgDecorationManagerInterface; class EglStreamControllerInterface; +class KeyStateInterface; /** * @brief Class holding the Wayland server display loop. @@ -203,6 +204,10 @@ 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/server/display.cpp b/src/server/display.cpp --- a/src/server/display.cpp +++ b/src/server/display.cpp @@ -56,6 +56,7 @@ #include "xdgoutput_interface.h" #include "xdgdecoration_interface.h" #include "eglstream_controller_interface.h" +#include "keystate_interface.h" #include #include @@ -522,6 +523,13 @@ 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/server/keystate_interface.h b/src/server/keystate_interface.h new file mode 100644 --- /dev/null +++ b/src/server/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 diff --git a/src/server/keystate_interface.cpp b/src/server/keystate_interface.cpp new file mode 100644 --- /dev/null +++ b/src/server/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)); +} + +} + +}