From 85a654b02b13b87a590de2d54a7888358d2363fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 9 Jun 2015 02:48:56 +0200 Subject: [PATCH] [server] Add bindings for PlasmaShell interface --- src/wayland/CMakeLists.txt | 7 + src/wayland/display.cpp | 8 + src/wayland/display.h | 2 + src/wayland/plasmashell_interface.cpp | 258 ++++++++++++++++++++++++++ src/wayland/plasmashell_interface.h | 90 +++++++++ 5 files changed, 365 insertions(+) create mode 100644 src/wayland/plasmashell_interface.cpp create mode 100644 src/wayland/plasmashell_interface.h diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 466363466f..25f42634b6 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -12,6 +12,7 @@ set(SERVER_LIB_SRCS logging.cpp output_interface.cpp pointer_interface.cpp + plasmashell_interface.cpp region_interface.cpp resource.cpp seat_interface.cpp @@ -21,6 +22,11 @@ set(SERVER_LIB_SRCS touch_interface.cpp ) +ecm_add_wayland_server_protocol(SERVER_LIB_SRCS + PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/plasma-shell.xml + BASENAME plasma-shell +) + add_library(KF5WaylandServer ${SERVER_LIB_SRCS}) generate_export_header(KF5WaylandServer BASE_NAME @@ -68,6 +74,7 @@ install(FILES keyboard_interface.h output_interface.h pointer_interface.h + plasmashell_interface.h region_interface.h resource.h seat_interface.h diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp index 1796f53f9e..fd985f8eb3 100644 --- a/src/wayland/display.cpp +++ b/src/wayland/display.cpp @@ -22,6 +22,7 @@ License along with this library. If not, see . #include "datadevicemanager_interface.h" #include "logging_p.h" #include "output_interface.h" +#include "plasmashell_interface.h" #include "seat_interface.h" #include "shell_interface.h" #include "subcompositor_interface.h" @@ -223,6 +224,13 @@ DataDeviceManagerInterface *Display::createDataDeviceManager(QObject *parent) return m; } +PlasmaShellInterface *Display::createPlasmaShell(QObject* parent) +{ + auto s = new PlasmaShellInterface(this, parent); + connect(this, &Display::aboutToTerminate, s, [this, s] { delete s; }); + return s; +} + void Display::createShm() { Q_ASSERT(d->display); diff --git a/src/wayland/display.h b/src/wayland/display.h index 74865992df..ea004e316a 100644 --- a/src/wayland/display.h +++ b/src/wayland/display.h @@ -39,6 +39,7 @@ namespace Server class CompositorInterface; class DataDeviceManagerInterface; class OutputInterface; +class PlasmaShellInterface; class SeatInterface; class ShellInterface; class SubCompositorInterface; @@ -114,6 +115,7 @@ public: SeatInterface *createSeat(QObject *parent = nullptr); SubCompositorInterface *createSubCompositor(QObject *parent = nullptr); DataDeviceManagerInterface *createDataDeviceManager(QObject *parent = nullptr); + PlasmaShellInterface *createPlasmaShell(QObject *parent = nullptr); /** * Gets the ClientConnection for the given @p client. diff --git a/src/wayland/plasmashell_interface.cpp b/src/wayland/plasmashell_interface.cpp new file mode 100644 index 0000000000..4bf4f785e2 --- /dev/null +++ b/src/wayland/plasmashell_interface.cpp @@ -0,0 +1,258 @@ +/******************************************************************** +Copyright 2015 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 "plasmashell_interface.h" +#include "global_p.h" +#include "resource_p.h" +#include "display.h" +#include "surface_interface.h" + +#include + +#include +#include + +namespace KWayland +{ +namespace Server +{ + +static const quint32 s_version = 1; + +class PlasmaShellInterface::Private : public Global::Private +{ +public: + Private(PlasmaShellInterface *q, Display *d); + + QList surfaces; + +private: + static void createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface); + void bind(wl_client *client, uint32_t version, uint32_t id) override; + void createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource); + + PlasmaShellInterface *q; + static const struct org_kde_plasma_shell_interface s_interface; +}; + +PlasmaShellInterface::Private::Private(PlasmaShellInterface *q, Display *d) + : Global::Private(d, &org_kde_plasma_shell_interface, s_version) + , q(q) +{ +} + +const struct org_kde_plasma_shell_interface PlasmaShellInterface::Private::s_interface = { + createSurfaceCallback +}; + + + +class PlasmaShellSurfaceInterface::Private : public Resource::Private +{ +public: + Private(PlasmaShellSurfaceInterface *q, PlasmaShellInterface *shell, SurfaceInterface *surface, wl_resource *parentResource); + + SurfaceInterface *surface; + QPoint m_globalPos; + Role m_role; + bool m_positionSet = false; + +private: + // interface callbacks + static void destroyCallback(wl_client *client, wl_resource *resource); + static void setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output); + static void setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y); + static void setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role); + + void setPosition(const QPoint &globalPos); + void setRole(uint32_t role); + + PlasmaShellSurfaceInterface *q_func() { + return reinterpret_cast(q); + } + + static const struct org_kde_plasma_surface_interface s_interface; +}; + +PlasmaShellInterface::PlasmaShellInterface(Display *display, QObject *parent) + : Global(new Private(this, display), parent) +{ +} + +PlasmaShellInterface::~PlasmaShellInterface() = default; + +void PlasmaShellInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id) +{ + auto c = display->getConnection(client); + wl_resource *shell = c->createResource(&org_kde_plasma_shell_interface, qMin(version, s_version), id); + if (!shell) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(shell, &s_interface, this, nullptr); +} + +void PlasmaShellInterface::Private::createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface) +{ + auto s = reinterpret_cast(wl_resource_get_user_data(resource)); + s->createSurface(client, wl_resource_get_version(resource), id, SurfaceInterface::get(surface), resource); +} + +void PlasmaShellInterface::Private::createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface, wl_resource *parentResource) +{ + auto it = std::find_if(surfaces.constBegin(), surfaces.constEnd(), + [surface](PlasmaShellSurfaceInterface *s) { + return surface == s->surface(); + } + ); + if (it != surfaces.constEnd()) { + wl_resource_post_error(surface->resource(), WL_DISPLAY_ERROR_INVALID_OBJECT, "PlasmaShellSurface already created"); + return; + } + PlasmaShellSurfaceInterface *shellSurface = new PlasmaShellSurfaceInterface(q, surface, parentResource); + surfaces << shellSurface; + QObject::connect(shellSurface, &PlasmaShellSurfaceInterface::destroyed, q, + [this, shellSurface] { + surfaces.removeAll(shellSurface); + } + ); + shellSurface->d->create(display->getConnection(client), version, id); + emit q->surfaceCreated(shellSurface); +} + +/********************************* + * ShellSurfaceInterface + *********************************/ +PlasmaShellSurfaceInterface::Private::Private(PlasmaShellSurfaceInterface *q, PlasmaShellInterface *shell, SurfaceInterface *surface, wl_resource *parentResource) + : Resource::Private(q, shell, parentResource, &org_kde_plasma_surface_interface, &s_interface) + , surface(surface) +{ +} + +const struct org_kde_plasma_surface_interface PlasmaShellSurfaceInterface::Private::s_interface = { + destroyCallback, + setOutputCallback, + setPositionCallback, + setRoleCallback +}; + +PlasmaShellSurfaceInterface::PlasmaShellSurfaceInterface(PlasmaShellInterface *shell, SurfaceInterface *parent, wl_resource *parentResource) + : Resource(new Private(this, shell, parent, parentResource), parent) +{ +} + +PlasmaShellSurfaceInterface::~PlasmaShellSurfaceInterface() = default; + +SurfaceInterface *PlasmaShellSurfaceInterface::surface() const { + Q_D(); + return d->surface; +} + +PlasmaShellInterface *PlasmaShellSurfaceInterface::shell() const { + Q_D(); + return reinterpret_cast(d->global); +} + +PlasmaShellSurfaceInterface::Private *PlasmaShellSurfaceInterface::d_func() const +{ + return reinterpret_cast(d.data()); +} + +void PlasmaShellSurfaceInterface::Private::destroyCallback(wl_client *client, wl_resource *resource) +{ + Q_UNUSED(client) + wl_resource_destroy(resource); +} + +void PlasmaShellSurfaceInterface::Private::setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output) +{ + Q_UNUSED(client) + Q_UNUSED(resource) + Q_UNUSED(output) + // TODO: implement +} + +void PlasmaShellSurfaceInterface::Private::setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y) +{ + auto s = cast(resource); + Q_ASSERT(client == *s->client); + s->setPosition(QPoint(x, y)); +} + +void PlasmaShellSurfaceInterface::Private::setPosition(const QPoint &globalPos) +{ + if (m_globalPos == globalPos && m_positionSet) { + return; + } + m_positionSet = true; + m_globalPos = globalPos; + Q_Q(PlasmaShellSurfaceInterface); + emit q->positionChanged(); +} + +void PlasmaShellSurfaceInterface::Private::setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role) +{ + auto s = cast(resource); + Q_ASSERT(client == *s->client); + s->setRole(role); +} + +void PlasmaShellSurfaceInterface::Private::setRole(uint32_t role) +{ + Role r = Role::Normal; + switch (role) { + case ORG_KDE_PLASMA_SURFACE_ROLE_DESKTOP: + r = Role::Desktop; + break; + case ORG_KDE_PLASMA_SURFACE_ROLE_PANEL: + r = Role::Panel; + break; + case ORG_KDE_PLASMA_SURFACE_ROLE_NORMAL: + default: + r = Role::Normal; + break; + } + if (r == m_role) { + return; + } + m_role = r; + Q_Q(PlasmaShellSurfaceInterface); + emit q->roleChanged(); +} + +QPoint PlasmaShellSurfaceInterface::position() const +{ + Q_D(); + return d->m_globalPos; +} + +PlasmaShellSurfaceInterface::Role PlasmaShellSurfaceInterface::role() const +{ + Q_D(); + return d->m_role; +} + +bool PlasmaShellSurfaceInterface::isPositionSet() const +{ + Q_D(); + return d->m_positionSet; +} + +} +} diff --git a/src/wayland/plasmashell_interface.h b/src/wayland/plasmashell_interface.h new file mode 100644 index 0000000000..2e07a52594 --- /dev/null +++ b/src/wayland/plasmashell_interface.h @@ -0,0 +1,90 @@ +/******************************************************************** +Copyright 2015 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 . +*********************************************************************/ +#ifndef WAYLAND_SERVER_PLASMA_SHELL_INTERFACE_H +#define WAYLAND_SERVER_PLASMA_SHELL_INTERFACE_H + +#include + +#include + +#include "global.h" +#include "resource.h" + +class QSize; +struct wl_resource; + +namespace KWayland +{ +namespace Server +{ + +class Display; +class SurfaceInterface; +class PlasmaShellSurfaceInterface; + +class KWAYLANDSERVER_EXPORT PlasmaShellInterface : public Global +{ + Q_OBJECT +public: + virtual ~PlasmaShellInterface(); + +Q_SIGNALS: + void surfaceCreated(KWayland::Server::PlasmaShellSurfaceInterface*); + +private: + friend class Display; + explicit PlasmaShellInterface(Display *display, QObject *parent); + class Private; +}; + +class KWAYLANDSERVER_EXPORT PlasmaShellSurfaceInterface : public Resource +{ + Q_OBJECT +public: + virtual ~PlasmaShellSurfaceInterface(); + + SurfaceInterface *surface() const; + PlasmaShellInterface *shell() const; + + QPoint position() const; + bool isPositionSet() const; + + enum class Role { + Normal, + Desktop, + Panel + }; + Role role() const; + +Q_SIGNALS: + void positionChanged(); + void roleChanged(); + +private: + friend class PlasmaShellInterface; + explicit PlasmaShellSurfaceInterface(PlasmaShellInterface *shell, SurfaceInterface *parent, wl_resource *parentResource); + class Private; + Private *d_func() const; +}; + +} +} + +#endif