Change copyrights from Nokia to Digia
[profile/ivi/qtwayland.git] / src / compositor / compositor_api / waylandsurface.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Compositor.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #include "waylandsurface.h"
42
43 #include <private/qobject_p.h>
44
45 #include "wayland_wrapper/wlsurface.h"
46 #include "wayland_wrapper/wlextendedsurface.h"
47 #include "wayland_wrapper/wlsubsurface.h"
48 #include "wayland_wrapper/wlcompositor.h"
49 #include "wayland_wrapper/wlshellsurface.h"
50
51 #include "waylandcompositor.h"
52 #include "waylandwindowmanagerintegration.h"
53
54 #include <QtGui/QGuiApplication>
55 #include <QtGui/QScreen>
56
57 #ifdef QT_COMPOSITOR_QUICK
58 #include "waylandsurfaceitem.h"
59 #endif
60
61 class WaylandSurfacePrivate : public QObjectPrivate
62 {
63 public:
64     WaylandSurfacePrivate(Wayland::Surface *srfc)
65         : surface(srfc)
66 #ifdef QT_COMPOSITOR_QUICK
67         , surface_item(0)
68 #endif
69     {}
70
71     ~WaylandSurfacePrivate()
72     {
73 #ifdef QT_COMPOSITOR_QUICK
74         if (surface_item)
75             surface_item->setSurface(0);
76 #endif
77     }
78
79     Wayland::Surface *surface;
80 #ifdef QT_COMPOSITOR_QUICK
81     WaylandSurfaceItem *surface_item;
82 #endif
83 };
84
85 WaylandSurface::WaylandSurface(Wayland::Surface *surface)
86     : QObject(*new WaylandSurfacePrivate(surface))
87 {
88     connect(this, SIGNAL(windowOrientationChanged()), this, SIGNAL(windowRotationChanged()));
89 }
90
91 WaylandClient *WaylandSurface::client() const
92 {
93     Q_D(const WaylandSurface);
94     return d->surface->base()->resource.client;
95 }
96
97 WaylandSurface *WaylandSurface::parentSurface() const
98 {
99     Q_D(const WaylandSurface);
100     if (d->surface->subSurface() && d->surface->subSurface()->parent()) {
101         return d->surface->subSurface()->parent()->waylandSurface();
102     }
103     return 0;
104 }
105
106 QLinkedList<WaylandSurface *> WaylandSurface::subSurfaces() const
107 {
108     Q_D(const WaylandSurface);
109     if (d->surface->subSurface()) {
110         return d->surface->subSurface()->subSurfaces();
111     }
112     return QLinkedList<WaylandSurface *>();
113 }
114
115 WaylandSurface::Type WaylandSurface::type() const
116 {
117     Q_D(const WaylandSurface);
118     return d->surface->type();
119 }
120
121 bool WaylandSurface::isYInverted() const
122 {
123     Q_D(const WaylandSurface);
124     return d->surface->isYInverted();
125 }
126
127 bool WaylandSurface::visible() const
128 {
129     Q_D(const WaylandSurface);
130     return d->surface->visible();
131 }
132
133 QPointF WaylandSurface::pos() const
134 {
135     Q_D(const WaylandSurface);
136     return d->surface->pos();
137 }
138
139 void WaylandSurface::setPos(const QPointF &pos)
140 {
141     Q_D(WaylandSurface);
142     d->surface->setPos(pos);
143 }
144
145 QSize WaylandSurface::size() const
146 {
147     Q_D(const WaylandSurface);
148     return d->surface->size();
149 }
150
151 void WaylandSurface::setSize(const QSize &size)
152 {
153     Q_D(WaylandSurface);
154     d->surface->setSize(size);
155 }
156
157 void WaylandSurface::sendConfigure(const QSize &size)
158 {
159     Q_D(WaylandSurface);
160     if (d->surface->shellSurface())
161         d->surface->shellSurface()->sendConfigure(WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, size.width(), size.height());
162 }
163
164 Qt::ScreenOrientations WaylandSurface::orientationUpdateMask() const
165 {
166     Q_D(const WaylandSurface);
167     return d->surface->compositor()->orientationUpdateMaskForClient(static_cast<wl_client *>(client()));
168 }
169
170 Qt::ScreenOrientation WaylandSurface::contentOrientation() const
171 {
172     Q_D(const WaylandSurface);
173     if (!d->surface->extendedSurface())
174         return Qt::PrimaryOrientation;
175     return d->surface->extendedSurface()->contentOrientation();
176 }
177
178 Qt::ScreenOrientation WaylandSurface::windowOrientation() const
179 {
180     Q_D(const WaylandSurface);
181     if (!d->surface->extendedSurface())
182         return Qt::PrimaryOrientation;
183     return d->surface->extendedSurface()->windowOrientation();
184 }
185
186 /*!
187    \property windowRotation
188
189    Convenience property to get the rotation required to map the surface to the screen
190    based on its windowOrientation.
191  */
192 int WaylandSurface::windowRotation() const
193 {
194     QRect geometry = compositor()->outputGeometry();
195     Qt::ScreenOrientation compositorOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
196     Qt::ScreenOrientation wOrientation = windowOrientation();
197
198     if (wOrientation == Qt::PrimaryOrientation)
199         return 0;
200
201     return QGuiApplication::primaryScreen()->angleBetween(wOrientation, compositorOrientation);
202 }
203
204 WaylandSurface::WindowFlags WaylandSurface::windowFlags() const
205 {
206     Q_D(const WaylandSurface);
207     if (!d->surface->extendedSurface())
208         return WaylandSurface::WindowFlags(0);
209     return d->surface->extendedSurface()->windowFlags();
210 }
211
212
213 QImage WaylandSurface::image() const
214 {
215     Q_D(const WaylandSurface);
216     return d->surface->image();
217 }
218
219 #ifdef QT_COMPOSITOR_WAYLAND_GL
220 GLuint WaylandSurface::texture(QOpenGLContext *context) const
221 {
222     Q_D(const WaylandSurface);
223     return d->surface->textureId(context);
224 }
225 #else //QT_COMPOSITOR_WAYLAND_GL
226 uint WaylandSurface::texture(QOpenGLContext *) const
227 {
228     return 0;
229 }
230 #endif
231
232 Wayland::Surface * WaylandSurface::handle() const
233 {
234     Q_D(const WaylandSurface);
235     return d->surface;
236 }
237
238 #ifdef QT_COMPOSITOR_QUICK
239 WaylandSurfaceItem *WaylandSurface::surfaceItem() const
240 {
241     Q_D(const WaylandSurface);
242     return d->surface_item;
243 }
244
245 void WaylandSurface::setSurfaceItem(WaylandSurfaceItem *surfaceItem)
246 {
247     Q_D(WaylandSurface);
248     d->surface_item = surfaceItem;
249 }
250 #endif //QT_COMPOSITOR_QUICK
251
252 qint64 WaylandSurface::processId() const
253 {
254     Q_D(const WaylandSurface);
255     WindowManagerServerIntegration *wmIntegration = d->surface->compositor()->windowManagerIntegration();
256     if (!wmIntegration) {
257         return 0;
258     }
259
260     WaylandManagedClient *mcl = wmIntegration->managedClient(d->surface->base()->resource.client);
261     return mcl ? mcl->processId() : 0;
262 }
263
264 QByteArray WaylandSurface::authenticationToken() const
265 {
266     Q_D(const WaylandSurface);
267     WindowManagerServerIntegration *wmIntegration = d->surface->compositor()->windowManagerIntegration();
268     if (!wmIntegration) {
269         return QByteArray();
270     }
271
272     WaylandManagedClient *mcl = wmIntegration->managedClient(d->surface->base()->resource.client);
273     return mcl ? mcl->authenticationToken() : QByteArray();
274 }
275
276 QVariantMap WaylandSurface::windowProperties() const
277 {
278     Q_D(const WaylandSurface);
279     if (!d->surface->extendedSurface())
280         return QVariantMap();
281
282     return d->surface->extendedSurface()->windowProperties();
283 }
284
285 void WaylandSurface::setWindowProperty(const QString &name, const QVariant &value)
286 {
287     Q_D(WaylandSurface);
288     if (!d->surface->extendedSurface())
289         return;
290
291     d->surface->extendedSurface()->setWindowProperty(name, value);
292 }
293
294 QPointF WaylandSurface::mapToParent(const QPointF &pos) const
295 {
296     return pos + this->pos();
297 }
298
299 QPointF WaylandSurface::mapTo(WaylandSurface *parent, const QPointF &pos) const
300 {
301     QPointF p = pos;
302     if (parent) {
303         const WaylandSurface * surface = this;
304         while (surface != parent) {
305             Q_ASSERT_X(surface, "WaylandSurface::mapTo(WaylandSurface *parent, const QPoint &pos)",
306                        "parent must be in parent hierarchy");
307             p = surface->mapToParent(p);
308             surface = surface->parentSurface();
309         }
310     }
311     return p;
312 }
313
314 WaylandCompositor *WaylandSurface::compositor() const
315 {
316     Q_D(const WaylandSurface);
317     return d->surface->compositor()->waylandCompositor();
318 }
319
320 void WaylandSurface::frameFinished()
321 {
322     Q_D(WaylandSurface);
323     d->surface->frameFinished();
324 }
325
326 WaylandSurface *WaylandSurface::transientParent() const
327 {
328     Q_D(const WaylandSurface);
329     if (d->surface->shellSurface() && d->surface->shellSurface()->transientParent())
330         return d->surface->shellSurface()->transientParent()->surface()->waylandSurface();
331     return 0;
332 }
333
334 void WaylandSurface::sendOnScreenVisibilityChange(bool visible)
335 {
336     Q_D(WaylandSurface);
337     if (d->surface->extendedSurface())
338         d->surface->extendedSurface()->sendOnScreenVisibility(visible);
339 }
340
341 QString WaylandSurface::title() const
342 {
343     Q_D(const WaylandSurface);
344     return d->surface->title();
345 }
346
347 /*!
348  * \return True if WL_SHELL_SURFACE_TRANSIENT_INACTIVE was set for this surface, meaning it should not receive keyboard focus.
349  */
350 bool WaylandSurface::transientInactive() const
351 {
352     Q_D(const WaylandSurface);
353     return d->surface->transientInactive();
354 }