author | Andrea Scarpino
<andrea@archlinux.org> 2015-01-25 12:20:57 UTC |
committer | Andrea Scarpino
<andrea@archlinux.org> 2015-01-25 12:20:57 UTC |
parent | b1f1d2d325cebe2d0df626658869f58f1317ce76 |
PKGBUILD | +3 | -5 |
screenlocker-input.patch | +0 | -705 |
diff --git a/PKGBUILD b/PKGBUILD index d88a70e..baf9977 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -4,7 +4,7 @@ pkgname=plasma-workspace pkgver=5.1.2 -pkgrel=4 +pkgrel=5 pkgdesc='KDE Plasma Workspace' arch=('i686' 'x86_64') url='https://projects.kde.org/projects/kde/workspace/plasma-workspace' @@ -12,7 +12,7 @@ license=('LGPL') depends=('knewstuff' 'baloo-frameworks' 'kjsembed' 'knotifyconfig' 'libxcursor' 'libksysguard' 'libkscreen-frameworks' 'ktexteditor' 'libqalculate' 'qt5-tools' 'kded' 'kde-cli-tools' 'kio-extras' 'milou' 'breeze' - 'xorg-xrdb' 'xorg-xsetroot' 'xorg-xmessage') + 'xorg-xrdb' 'xorg-xsetroot' 'xorg-xmessage' 'xorg-xprop') makedepends=('extra-cmake-modules' 'kdoctools' 'kwin' 'gpsd') optdepends=('plasma-workspace-wallpapers: additional wallpapers' 'gpsd: GPS support for geolocation') @@ -21,10 +21,9 @@ groups=('plasma-next') options=('!buildflags') source=("http://download.kde.org/stable/plasma/${pkgver}/$pkgname-$pkgver.tar.xz" 'kde.pam' - 'screenlocker-input.patch' 'screenlocker-network.patch' 'dbus.patch') + 'screenlocker-network.patch' 'dbus.patch') md5sums=('8a01835179b25e3a7ff644fd7e52ec96' '929b182dec8a096206ad493477c09d2c' - '7e426d07806d8887879d932791bba869' 'd67e504422a7e80a91b7adf3f41563f5' '45f12d6fec8a5e08ce1080f5efb8fb21') @@ -32,7 +31,6 @@ prepare() { mkdir -p build cd ${pkgname}-${pkgver} - #patch -p1 -i ../screenlocker-input.patch patch -p1 -i ../screenlocker-network.patch patch -p1 -i ../dbus.patch } diff --git a/screenlocker-input.patch b/screenlocker-input.patch deleted file mode 100644 index d4417f2..0000000 --- a/screenlocker-input.patch +++ /dev/null @@ -1,705 +0,0 @@ -commit 0ac34dca5d6a6ea8fc5c06e1dae96fb1ad4ce7c9 -Author: Martin Gräßlin <mgraesslin@kde.org> -Date: Wed Dec 10 13:22:49 2014 +0100 - - Use out-of-band communication between ksld and greeter - - The screenlocker_greet needs to tell the parent ksld process which - windows it created. Ksld sends input events to these windows. So - far this was based on an X property on the window. Unfortunately - ksld didn't validate whether the windows tagged with this property - belong to the screenlocker_greet process it started. - - With this change the communication for announcing windows is moved - away from the X11 protocol and instead a custom Wayland protocol is - used. - - Ksld starts a KWaylandServer when the greet process gets started. It - creates anonymous unix sockets for the connection and passes one - filedescriptor to the started greeter process. - - The check for the X property is removed in ksld and instead only - windows ids passed through the Wayland socket connection are - accepted. - - REVIEW: 121429 - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index c6d89c1..227eace 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -74,6 +74,16 @@ if(X11_FOUND AND XCB_XCB_FOUND) - set(HAVE_X11 1) - endif() - -+find_package(KF5Wayland CONFIG) -+set_package_properties(KF5Wayland PROPERTIES -+ TYPE REQUIRED -+ PURPOSE "Required for building screenlocker") -+find_package(WaylandScanner) -+find_package(Wayland 1.3 COMPONENTS Client Server) -+set_package_properties(Wayland PROPERTIES -+ TYPE REQUIRED -+ PURPOSE "Required for building screenlocker") -+ - include(ConfigureChecks.cmake) - - include_directories("${CMAKE_CURRENT_BINARY_DIR}") -diff --git a/ksmserver/screenlocker/CMakeLists.txt b/ksmserver/screenlocker/CMakeLists.txt -index 5378a10..83a5b39 100644 ---- a/ksmserver/screenlocker/CMakeLists.txt -+++ b/ksmserver/screenlocker/CMakeLists.txt -@@ -1,6 +1,9 @@ - remove_definitions(-DTRANSLATION_DOMAIN=\"ksmserver\") - add_definitions(-DTRANSLATION_DOMAIN=\"kscreenlocker\") - -+# adjusting CMAKE_C_FLAGS to get wayland protocols to compile -+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90") -+ - add_definitions(-DKDE_DEFAULT_DEBUG_AREA=1223) - add_subdirectory(kcheckpass) - add_subdirectory(greeter) -@@ -17,6 +20,7 @@ set(ksld_SRCS - interface.cpp - lockwindow.cpp - logind.cpp -+ waylandserver.cpp - ) - qt5_add_dbus_adaptor(ksld_SRCS ${screensaver_dbusXML} interface.h ScreenLocker::Interface) - qt5_add_dbus_adaptor(ksld_SRCS ${kscreensaver_dbusXML} interface.h ScreenLocker::Interface kscreensaveradaptor KScreenSaverAdaptor) -@@ -24,6 +28,11 @@ kconfig_add_kcfg_files(ksld_SRCS kcfg/kscreensaversettings.kcfgc) - qt5_add_dbus_interface(ksld_SRCS ${ksmserver_xml} ksmserver_interface) - qt5_add_dbus_interface(ksld_SRCS ${powerdevilpolicyagent_xml} powerdevilpolicyagent) - -+ecm_add_wayland_server_protocol(ksld_SRCS -+ PROTOCOL protocols/ksld.xml -+ BASENAME ksld -+) -+ - add_library(screenlocker_static STATIC ${ksld_SRCS}) - - target_link_libraries(screenlocker_static -@@ -39,6 +48,8 @@ target_link_libraries(screenlocker_static - ${X11_LIBRARIES} - ${X11_Xcursor_LIB} - XCB::XCB -+ KF5::WaylandServer -+ Wayland::Server - ) - - # Needed to compile on Arm target. -diff --git a/ksmserver/screenlocker/greeter/CMakeLists.txt b/ksmserver/screenlocker/greeter/CMakeLists.txt -index 10c4734..14a34f0 100644 ---- a/ksmserver/screenlocker/greeter/CMakeLists.txt -+++ b/ksmserver/screenlocker/greeter/CMakeLists.txt -@@ -18,6 +18,11 @@ set(kscreenlocker_greet_SRCS - qt5_add_resources(kscreenlocker_greet_SRCS fallbacktheme.qrc) - kconfig_add_kcfg_files(kscreenlocker_greet_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../kcfg/kscreensaversettings.kcfgc) - -+ecm_add_wayland_client_protocol(kscreenlocker_greet_SRCS -+ PROTOCOL ../protocols/ksld.xml -+ BASENAME ksld -+) -+ - add_executable(kscreenlocker_greet ${kscreenlocker_greet_SRCS}) - - target_link_libraries(kscreenlocker_greet -@@ -36,6 +41,8 @@ target_link_libraries(kscreenlocker_greet - Qt5::X11Extras - ${X11_LIBRARIES} - KF5::KDELibs4Support -+ KF5::WaylandClient -+ Wayland::Client - ) - - install(TARGETS kscreenlocker_greet DESTINATION ${LIBEXEC_INSTALL_DIR}) -diff --git a/ksmserver/screenlocker/greeter/greeterapp.cpp b/ksmserver/screenlocker/greeter/greeterapp.cpp -index f2e7ab9..824ba60 100644 ---- a/ksmserver/screenlocker/greeter/greeterapp.cpp -+++ b/ksmserver/screenlocker/greeter/greeterapp.cpp -@@ -33,10 +33,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. - #include <Plasma/Package> - #include <Plasma/PackageStructure> - #include <Plasma/PluginLoader> -+// KWayland -+#include <KWayland/Client/connection_thread.h> -+#include <KWayland/Client/event_queue.h> -+#include <KWayland/Client/registry.h> - // Qt - #include <QtCore/QTimer> - #include <QtGui/QKeyEvent> - #include <qscreen.h> -+#include <QThread> - - #include <QQuickView> - #include <QQuickItem> -@@ -45,6 +50,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. - #include <QQmlProperty> - - #include <QX11Info> -+// Wayland -+#include <wayland-client.h> -+#include <wayland-ksld-client-protocol.h> - // X11 - #include <X11/Xatom.h> - #include <X11/Xlib.h> -@@ -77,6 +85,18 @@ UnlockApp::UnlockApp(int &argc, char **argv) - UnlockApp::~UnlockApp() - { - qDeleteAll(m_views); -+ -+ if (m_ksldInterface) { -+ org_kde_ksld_destroy(m_ksldInterface); -+ } -+ if (m_ksldRegistry) { -+ delete m_ksldRegistry; -+ } -+ if (m_ksldConnection) { -+ m_ksldConnection->deleteLater(); -+ m_ksldConnectionThread->quit(); -+ m_ksldConnectionThread->wait(); -+ } - } - - void UnlockApp::initialize() -@@ -146,6 +166,12 @@ void UnlockApp::desktopResized() - view->setFlags(Qt::X11BypassWindowManagerHint); - } - -+ if (m_ksldInterface) { -+ view->create(); -+ org_kde_ksld_x11window(m_ksldInterface, view->winId()); -+ wl_display_flush(m_ksldConnection->display()); -+ } -+ - // engine stuff - QQmlContext* context = view->engine()->rootContext(); - const KUser user; -@@ -390,5 +416,43 @@ void UnlockApp::setNoLock(bool noLock) - m_noLock = noLock; - } - -+void UnlockApp::setKsldSocket(int socket) -+{ -+ using namespace KWayland::Client; -+ m_ksldConnection = new ConnectionThread; -+ m_ksldConnection->setSocketFd(socket); -+ -+ m_ksldRegistry = new Registry(); -+ EventQueue *queue = new EventQueue(m_ksldRegistry); -+ -+ connect(m_ksldRegistry, &Registry::interfaceAnnounced, this, -+ [this, queue] (QByteArray interface, quint32 name, quint32 version) { -+ if (interface != QByteArrayLiteral("org_kde_ksld")) { -+ return; -+ } -+ m_ksldInterface = reinterpret_cast<org_kde_ksld*>(wl_registry_bind(*m_ksldRegistry, name, &org_kde_ksld_interface, version)); -+ queue->addProxy(m_ksldInterface); -+ for (auto v : m_views) { -+ org_kde_ksld_x11window(m_ksldInterface, v->winId()); -+ wl_display_flush(m_ksldConnection->display()); -+ } -+ } -+ ); -+ -+ connect(m_ksldConnection, &ConnectionThread::connected, this, -+ [this, queue] { -+ m_ksldRegistry->create(m_ksldConnection); -+ queue->setup(m_ksldConnection); -+ m_ksldRegistry->setEventQueue(queue); -+ m_ksldRegistry->setup(); -+ wl_display_flush(m_ksldConnection->display()); -+ }, Qt::QueuedConnection); -+ -+ m_ksldConnectionThread = new QThread(this); -+ m_ksldConnection->moveToThread(m_ksldConnectionThread); -+ m_ksldConnectionThread->start(); -+ m_ksldConnection->initConnection(); -+} -+ - } // namespace - -diff --git a/ksmserver/screenlocker/greeter/greeterapp.h b/ksmserver/screenlocker/greeter/greeterapp.h -index b92b13b..4a90faf 100644 ---- a/ksmserver/screenlocker/greeter/greeterapp.h -+++ b/ksmserver/screenlocker/greeter/greeterapp.h -@@ -29,8 +29,17 @@ namespace Plasma { - class Package; - }; - -+namespace KWayland { -+namespace Client { -+ class ConnectionThread; -+ class Registry; -+} -+} -+ - class Authenticator; - -+struct org_kde_ksld; -+ - namespace ScreenLocker - { - class Unlocker; -@@ -47,6 +56,7 @@ public: - void lockImmediately(); - void setGraceTime(int milliseconds); - void setNoLock(bool noLock); -+ void setKsldSocket(int socket); - - public Q_SLOTS: - void desktopResized(); -@@ -78,6 +88,11 @@ private: - Authenticator *m_authenticator; - int m_graceTime; - bool m_noLock; -+ -+ KWayland::Client::ConnectionThread *m_ksldConnection = nullptr; -+ KWayland::Client::Registry *m_ksldRegistry = nullptr; -+ QThread *m_ksldConnectionThread = nullptr; -+ org_kde_ksld *m_ksldInterface = nullptr; - }; - } // namespace - -diff --git a/ksmserver/screenlocker/greeter/main.cpp b/ksmserver/screenlocker/greeter/main.cpp -index 12e5701..4477363 100644 ---- a/ksmserver/screenlocker/greeter/main.cpp -+++ b/ksmserver/screenlocker/greeter/main.cpp -@@ -80,11 +80,15 @@ int main(int argc, char* argv[]) - QStringLiteral("0")); - QCommandLineOption nolockOption(QStringLiteral("nolock"), - i18n("Don't show any lock user interface.")); -+ QCommandLineOption waylandFdOption(QStringLiteral("ksldfd"), -+ i18n("File descriptor for connecting to ksld."), -+ QStringLiteral("fd")); - - parser.addOption(testingOption); - parser.addOption(immediateLockOption); - parser.addOption(graceTimeOption); - parser.addOption(nolockOption); -+ parser.addOption(waylandFdOption); - parser.process(app); - - if (parser.isSet(testingOption)) { -@@ -94,11 +98,20 @@ int main(int argc, char* argv[]) - app.setImmediateLock(parser.isSet(immediateLockOption)); - } - app.setNoLock(parser.isSet(nolockOption)); -+ - bool ok = false; - int graceTime = parser.value(graceTimeOption).toInt(&ok); - if (ok) { - app.setGraceTime(graceTime); - } -+ -+ if (parser.isSet(waylandFdOption)) { -+ ok = false; -+ const int fd = parser.value(waylandFdOption).toInt(&ok); -+ if (ok) { -+ app.setKsldSocket(fd); -+ } -+ } - app.desktopResized(); - - // This allow ksmserver to know when the applicaion has actually finished setting itself up. -diff --git a/ksmserver/screenlocker/ksldapp.cpp b/ksmserver/screenlocker/ksldapp.cpp -index 94eccd4..addf49e 100644 ---- a/ksmserver/screenlocker/ksldapp.cpp -+++ b/ksmserver/screenlocker/ksldapp.cpp -@@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. - #include "logind.h" - #include "kscreensaversettings.h" - #include <config-ksmserver.h> -+#include "waylandserver.h" - // workspace - #include <kdisplaymanager.h> - // KDE -@@ -68,6 +69,7 @@ KSldApp::KSldApp(QObject * parent) - , m_lockState(Unlocked) - , m_lockProcess(NULL) - , m_lockWindow(NULL) -+ , m_waylandServer(new WaylandServer(this)) - , m_lockedTimer(QElapsedTimer()) - , m_idleId(0) - , m_lockGrace(0) -@@ -330,6 +332,7 @@ void KSldApp::doUnlock() - m_lockedTimer.invalidate(); - endGraceTime(); - KDisplayManager().setLock(false); -+ m_waylandServer->stop(); - emit unlocked(); - // KNotification::event( QLatin1String("unlocked")); - } -@@ -347,12 +350,25 @@ bool KSldApp::startLockProcess(EstablishLock establishLock) - if (m_lockGrace == -1) { - args << "--nolock"; - } -+ -+ // start the Wayland server -+ int fd = m_waylandServer->start(); -+ if (fd == -1) { -+ return false; -+ } -+ -+ args << "--ksldfd"; -+ args << QString::number(fd); -+ - m_lockProcess->start(QStringLiteral(KSCREENLOCKER_GREET_BIN), args); - // we wait one minute - if (!m_lockProcess->waitForStarted(60000)) { - m_lockProcess->kill(); -+ m_waylandServer->stop(); -+ close(fd); - return false; - } -+ close(fd); - - return true; - } -@@ -369,6 +385,7 @@ void KSldApp::showLockWindow() - }, - Qt::QueuedConnection - ); -+ connect(m_waylandServer, &WaylandServer::x11WindowAdded, m_lockWindow, &LockWindow::addAllowedWindow); - } - m_lockWindow->showLockWindow(); - XSync(QX11Info::display(), False); -diff --git a/ksmserver/screenlocker/ksldapp.h b/ksmserver/screenlocker/ksldapp.h -index 095424c..a606aa8 100644 ---- a/ksmserver/screenlocker/ksldapp.h -+++ b/ksmserver/screenlocker/ksldapp.h -@@ -40,6 +40,7 @@ enum class EstablishLock { - }; - - class LockWindow; -+class WaylandServer; - - class KSldApp : public QObject - { -@@ -104,6 +105,7 @@ private: - LockState m_lockState; - QProcess *m_lockProcess; - LockWindow *m_lockWindow; -+ WaylandServer *m_waylandServer; - /** - * Timer to measure how long the screen is locked. - * This information is required by DBus Interface. -diff --git a/ksmserver/screenlocker/lockwindow.cpp b/ksmserver/screenlocker/lockwindow.cpp -index 3aa963a..99245e7 100644 ---- a/ksmserver/screenlocker/lockwindow.cpp -+++ b/ksmserver/screenlocker/lockwindow.cpp -@@ -158,6 +158,7 @@ void LockWindow::hideLockWindow() - gVRoot = 0; - } - XSync(QX11Info::display(), False); -+ m_allowedWindows.clear(); - } - - //--------------------------------------------------------------------------- -@@ -370,7 +371,7 @@ bool LockWindow::nativeEventFilter(const QByteArray &eventType, void *message, l - m_windowInfo[ index ].viewable = true; - else - qDebug() << "Unknown toplevel for MapNotify"; -- if (isLockWindow(xm->window)) { -+ if (m_allowedWindows.contains(xm->window)) { - if (m_lockWindows.contains(xm->window)) { - qDebug() << "uhoh! duplicate!"; - } else { -@@ -497,28 +498,6 @@ void LockWindow::stayOnTop() - XRestackWindows( QX11Info::display(), stack.data(), count ); - } - --bool LockWindow::isLockWindow(Window id) --{ -- Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False); -- Atom actualType; -- int actualFormat; -- unsigned long nitems, remaining; -- unsigned char *data = 0; -- Display *display = QX11Info::display(); -- -- int result = XGetWindowProperty(display, id, tag, 0, 1, False, tag, &actualType, -- &actualFormat, &nitems, &remaining, &data); -- -- bool lockWindow = false; -- if (result == Success && actualType == tag) { -- lockWindow = true; -- } -- if (data) { -- XFree(data); -- } -- return lockWindow; --} -- - void LockWindow::updateGeo() - { - QDesktopWidget *desktop = QApplication::desktop(); -@@ -530,6 +509,29 @@ void LockWindow::paintEvent(QPaintEvent* ) - QPainter p(this); - p.setBrush(QBrush(Qt::black)); - p.drawRect(geometry()); -+ stayOnTop(); -+} -+ -+void LockWindow::addAllowedWindow(quint32 window) -+{ -+ m_allowedWindows << window; -+ // test whether it's to show -+ const int index = findWindowInfo( window ); -+ if (index == -1 || !m_windowInfo[ index ].viewable) { -+ return; -+ } -+ if (m_lockWindows.contains(window)) { -+ qDebug() << "uhoh! duplicate!"; -+ } else { -+ if (!isVisible()) { -+ // not yet shown and we have a lock window, so we show our own window -+ show(); -+ setCursor(Qt::ArrowCursor); -+ } -+ m_lockWindows.prepend(window); -+ fakeFocusIn(window); -+ stayOnTop(); -+ } - } - - } -diff --git a/ksmserver/screenlocker/lockwindow.h b/ksmserver/screenlocker/lockwindow.h -index 9938d20..cad62ed 100644 ---- a/ksmserver/screenlocker/lockwindow.h -+++ b/ksmserver/screenlocker/lockwindow.h -@@ -41,6 +41,8 @@ public: - void showLockWindow(); - void hideLockWindow(); - -+ void addAllowedWindow(quint32 window); -+ - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; - - Q_SIGNALS: -@@ -59,7 +61,6 @@ private: - void removeVRoot(Window win); - int findWindowInfo(Window w); - void stayOnTop(); -- bool isLockWindow(Window w); - struct WindowInfo - { - Window window; -@@ -67,6 +68,7 @@ private: - }; - QList<WindowInfo> m_windowInfo; - QList<WId> m_lockWindows; -+ QList<quint32> m_allowedWindows; - }; - } - -diff --git a/ksmserver/screenlocker/protocols/ksld.xml b/ksmserver/screenlocker/protocols/ksld.xml -new file mode 100644 -index 0000000..bfb3219 ---- /dev/null -+++ b/ksmserver/screenlocker/protocols/ksld.xml -@@ -0,0 +1,9 @@ -+<?xml version="1.0" encoding="UTF-8"?> -+<protocol name="ksld"> -+ <interface name="org_kde_ksld" version="1"> -+ <request name="x11window"> -+ <arg name="id" type="uint"/> -+ </request> -+ </interface> -+</protocol> -+ -diff --git a/ksmserver/screenlocker/waylandserver.cpp b/ksmserver/screenlocker/waylandserver.cpp -new file mode 100644 -index 0000000..746032e ---- /dev/null -+++ b/ksmserver/screenlocker/waylandserver.cpp -@@ -0,0 +1,119 @@ -+/******************************************************************** -+ KSld - the KDE Screenlocker Daemon -+ 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 "waylandserver.h" -+// ksld -+#include <config-ksmserver.h> -+#include <wayland-ksld-server-protocol.h> -+// KWayland -+#include <KWayland/Server/display.h> -+// Wayland -+#include <wayland-server.h> -+// system -+#include <unistd.h> -+#include <fcntl.h> -+#include <sys/types.h> -+#include <sys/socket.h> -+ -+namespace ScreenLocker -+{ -+ -+WaylandServer::WaylandServer(QObject *parent) -+ : QObject(parent) -+{ -+} -+ -+WaylandServer::~WaylandServer() -+{ -+ stop(); -+} -+ -+int WaylandServer::start() -+{ -+ stop(); -+ m_display.reset(new KWayland::Server::Display); -+ m_display->start(KWayland::Server::Display::StartMode::ConnectClientsOnly); -+ if (!m_display->isRunning()) { -+ // failed to start the Wayland server -+ return -1; -+ } -+ int socketPair[2]; -+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketPair) == -1) { -+ // failed creating socket -+ return -1; -+ } -+ fcntl(socketPair[0], F_SETFD, FD_CLOEXEC); -+ m_allowedClient = m_display->createClient(socketPair[0]); -+ if (!m_allowedClient) { -+ // failed creating the Wayland client -+ stop(); -+ close(socketPair[0]); -+ close(socketPair[1]); -+ return -1; -+ } -+ m_interface = wl_global_create(*m_display.data(), &org_kde_ksld_interface, 1, this, bind); -+ return socketPair[1]; -+} -+ -+void WaylandServer::stop() -+{ -+ if (m_interface) { -+ wl_global_destroy(m_interface); -+ m_interface = nullptr; -+ } -+ m_display.reset(); -+ m_allowedClient = nullptr; -+} -+ -+void WaylandServer::bind(wl_client *client, void *data, uint32_t version, uint32_t id) -+{ -+ auto s = reinterpret_cast<WaylandServer*>(data); -+ if (client != s->m_allowedClient->client()) { -+ // a proper error would be better -+ wl_client_post_no_memory(client); -+ return; -+ } -+ wl_resource *r = s->m_allowedClient->createResource(&org_kde_ksld_interface, qMin(version, 1u), id); -+ if (!r) { -+ wl_client_post_no_memory(client); -+ return; -+ } -+ -+ static const struct org_kde_ksld_interface s_interface = { -+ x11WindowCallback -+ }; -+ wl_resource_set_implementation(r, &s_interface, s, unbind); -+ s->m_allowedClient->flush(); -+} -+ -+void WaylandServer::unbind(wl_resource *resource) -+{ -+ Q_UNUSED(resource) -+} -+ -+void WaylandServer::x11WindowCallback(wl_client *client, wl_resource *resource, uint32_t id) -+{ -+ auto s = reinterpret_cast<WaylandServer*>(wl_resource_get_user_data(resource)); -+ if (s->m_allowedClient->client() != client) { -+ return; -+ } -+ emit s->x11WindowAdded(id); -+} -+ -+} -diff --git a/ksmserver/screenlocker/waylandserver.h b/ksmserver/screenlocker/waylandserver.h -new file mode 100644 -index 0000000..5a8ed22 ---- /dev/null -+++ b/ksmserver/screenlocker/waylandserver.h -@@ -0,0 +1,64 @@ -+/******************************************************************** -+ KSld - the KDE Screenlocker Daemon -+ 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 SCREENLOCKER_WAYLANDSERVER_H -+#define SCREENLOCKER_WAYLANDSERVER_H -+ -+#include <QObject> -+ -+struct wl_client; -+struct wl_global; -+struct wl_resource; -+ -+namespace KWayland -+{ -+namespace Server -+{ -+class ClientConnection; -+class Display; -+} -+} -+ -+namespace ScreenLocker -+{ -+ -+class WaylandServer : public QObject -+{ -+ Q_OBJECT -+public: -+ explicit WaylandServer(QObject *parent = nullptr); -+ virtual ~WaylandServer(); -+ int start(); -+ void stop(); -+ -+Q_SIGNALS: -+ void x11WindowAdded(quint32 window); -+ -+private: -+ static void bind(wl_client *client, void *data, uint32_t version, uint32_t id); -+ static void unbind(wl_resource *resource); -+ static void x11WindowCallback(wl_client *client, wl_resource *resource, uint32_t id); -+ QScopedPointer<KWayland::Server::Display> m_display; -+ KWayland::Server::ClientConnection *m_allowedClient = nullptr; -+ wl_global *m_interface = nullptr; -+}; -+ -+} -+ -+#endif