server_decoration_interface.cpp 7.46 KB
Newer Older
1
2
/*
    SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
3

4
5
    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
6
7
#include "server_decoration_interface.h"
#include "display.h"
8
#include "logging.h"
9
10
11
12
#include "surface_interface.h"

#include <QVector>

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
13
#include <qwayland-server-server-decoration.h>
14

15
namespace KWaylandServer
16
17
{

18
class ServerSideDecorationManagerInterfacePrivate : public QtWaylandServer::org_kde_kwin_server_decoration_manager
19
20
{
public:
21
22
    ServerSideDecorationManagerInterfacePrivate(ServerSideDecorationManagerInterface *_q, Display *display);
    void setDefaultMode(ServerSideDecorationManagerInterface::Mode mode);
23

24
25
    ServerSideDecorationManagerInterface::Mode defaultMode = ServerSideDecorationManagerInterface::Mode::None;
    
26
27
28
29
private:
    ServerSideDecorationManagerInterface *q;
    static const quint32 s_version;

30
31
32
protected:
    void org_kde_kwin_server_decoration_manager_bind_resource(Resource *resource) override;
    void org_kde_kwin_server_decoration_manager_create(Resource *resource, uint32_t id, wl_resource *surface) override;
33
34
35

};

36
const quint32 ServerSideDecorationManagerInterfacePrivate::s_version = 1;
37

38
39
40
41
static uint32_t modeWayland(ServerSideDecorationManagerInterface::Mode mode)
{
    switch (mode) {
    case ServerSideDecorationManagerInterface::Mode::None:
42
        return ServerSideDecorationManagerInterfacePrivate::mode_None;
43
    case ServerSideDecorationManagerInterface::Mode::Client:
44
        return ServerSideDecorationManagerInterfacePrivate::mode_Client;
45
    case ServerSideDecorationManagerInterface::Mode::Server:
46
        return ServerSideDecorationManagerInterfacePrivate::mode_Server;
47
48
49
50
51
    default:
        Q_UNREACHABLE();
    }
}

52
void ServerSideDecorationManagerInterfacePrivate::org_kde_kwin_server_decoration_manager_create(Resource *resource, uint32_t id, wl_resource *surface)
53
{
54
55
56
    SurfaceInterface *s = SurfaceInterface::get(surface);
    if (!s) {
        wl_resource_post_error(resource->handle, 0, "Invalid  surface");
57
58
        return;
    }
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
    wl_resource *decorationResource = wl_resource_create(resource->client(), &org_kde_kwin_server_decoration_interface, resource->version(), id);
    if (!decorationResource) {
        wl_client_post_no_memory(resource->client());
        return;
    }
    auto decoration = new ServerSideDecorationInterface(s, decorationResource);
    decoration->setMode(defaultMode);
    emit q->decorationCreated(decoration);
}

void ServerSideDecorationManagerInterfacePrivate::setDefaultMode(ServerSideDecorationManagerInterface::Mode mode)
{
    defaultMode = mode;
    const uint32_t wlMode = modeWayland(mode);
74

75
76
77
78
79
80
81
82
83
84
    const auto clientResources = resourceMap();
    for (Resource *resource : clientResources) {
        send_default_mode(resource->handle, wlMode);
    }
}

ServerSideDecorationManagerInterfacePrivate::ServerSideDecorationManagerInterfacePrivate(ServerSideDecorationManagerInterface *_q, Display *display)
    : QtWaylandServer::org_kde_kwin_server_decoration_manager(*display, s_version)
    , q(_q)
{
85
86
}

87
void ServerSideDecorationManagerInterfacePrivate::org_kde_kwin_server_decoration_manager_bind_resource(Resource *resource)
88
{
89
    send_default_mode(resource->handle, modeWayland(defaultMode));
90
91
}

92

93
ServerSideDecorationManagerInterface::ServerSideDecorationManagerInterface(Display *display, QObject *parent)
94
95
    : QObject(parent)
    , d(new ServerSideDecorationManagerInterfacePrivate(this, display))
96
97
98
99
100
{
}

ServerSideDecorationManagerInterface::~ServerSideDecorationManagerInterface() = default;

101
void ServerSideDecorationManagerInterface::setDefaultMode(Mode mode)
102
{
103
    d->setDefaultMode(mode);
104
105
}

106
ServerSideDecorationManagerInterface::Mode ServerSideDecorationManagerInterface::defaultMode() const
107
{
108
    return d->defaultMode;
109
110
}

111
class ServerSideDecorationInterfacePrivate : public QtWaylandServer::org_kde_kwin_server_decoration
112
113
{
public:
114
115
116
117
118
    ServerSideDecorationInterfacePrivate(ServerSideDecorationInterface *_q, SurfaceInterface *surface,  wl_resource *resource);
    ~ServerSideDecorationInterfacePrivate();

    static ServerSideDecorationInterface *get(SurfaceInterface *surface);
    void setMode(ServerSideDecorationManagerInterface::Mode mode);
119
120
121
122
123

    ServerSideDecorationManagerInterface::Mode mode = ServerSideDecorationManagerInterface::Mode::None;
    SurfaceInterface *surface;

private:
124
125
    ServerSideDecorationInterface *q;
    static QVector<ServerSideDecorationInterfacePrivate*> s_all;
126

127
128
129
130
protected:
    void org_kde_kwin_server_decoration_destroy_resource(Resource *resource) override;
    void org_kde_kwin_server_decoration_release(Resource *resource) override;
    void org_kde_kwin_server_decoration_request_mode(Resource *resource, uint32_t mode) override;
131
132
};

133
134
135
QVector<ServerSideDecorationInterfacePrivate*> ServerSideDecorationInterfacePrivate::s_all;

void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_request_mode(Resource *resource, uint32_t mode)
136
{
137
    Q_UNUSED(resource)
138
139
    ServerSideDecorationManagerInterface::Mode m = ServerSideDecorationManagerInterface::Mode::None;
    switch (mode) {
140
    case ServerSideDecorationManagerInterfacePrivate::mode_None:
141
142
        m = ServerSideDecorationManagerInterface::Mode::None;
        break;
143
    case ServerSideDecorationManagerInterfacePrivate::mode_Client:
144
145
        m = ServerSideDecorationManagerInterface::Mode::Client;
        break;
146
    case ServerSideDecorationManagerInterfacePrivate::mode_Server:
147
148
149
150
151
152
153
        m = ServerSideDecorationManagerInterface::Mode::Server;
        break;
    default:
        // invalid mode
        qCWarning(KWAYLAND_SERVER) << "Invalid mode:" << mode;
        return;
    }
154
155
156
157
158
159
160
161
162
163
164
165
    emit q->modeRequested(m);
}

void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_release(Resource *resource)
{
    wl_resource_destroy(resource->handle);
}

void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_destroy_resource(Resource *resource)
{
    Q_UNUSED(resource)
    delete q;
166
167
}

168
ServerSideDecorationInterface *ServerSideDecorationInterfacePrivate::get(SurfaceInterface *surface)
169
{
170
171
172
173
    for (ServerSideDecorationInterfacePrivate *decoration : qAsConst(s_all)) {
        if (decoration->surface == surface) {
            return decoration->q;
        }
174
    }
175
    return nullptr;
176
177
}

178
179
ServerSideDecorationInterfacePrivate::ServerSideDecorationInterfacePrivate(ServerSideDecorationInterface *_q, SurfaceInterface *surface, wl_resource *resource)
    : QtWaylandServer::org_kde_kwin_server_decoration(resource)
180
    , surface(surface)
181
    , q(_q)
182
183
184
185
{
    s_all << this;
}

186
ServerSideDecorationInterfacePrivate::~ServerSideDecorationInterfacePrivate()
187
188
189
190
{
    s_all.removeAll(this);
}

191
192
void ServerSideDecorationInterfacePrivate::setMode(ServerSideDecorationManagerInterface::Mode mode)
{
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
193
    this->mode = mode;
194
195
196
197
198
199
    send_mode(modeWayland(mode));
}

ServerSideDecorationInterface::ServerSideDecorationInterface(SurfaceInterface *surface, wl_resource *resource)
    : QObject()
    , d(new ServerSideDecorationInterfacePrivate(this, surface, resource))
200
201
202
203
204
205
206
{
}

ServerSideDecorationInterface::~ServerSideDecorationInterface() = default;

void ServerSideDecorationInterface::setMode(ServerSideDecorationManagerInterface::Mode mode)
{
207
    d->setMode(mode);
208
209
210
211
212
213
214
215
216
217
218
219
}

ServerSideDecorationManagerInterface::Mode ServerSideDecorationInterface::mode() const
{
    return d->mode;
}

SurfaceInterface *ServerSideDecorationInterface::surface() const
{
    return d->surface;
}

220
ServerSideDecorationInterface *ServerSideDecorationInterface::get(SurfaceInterface *surface)
221
{
222
    return ServerSideDecorationInterfacePrivate::get(surface);
223
224
225
}

}