1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qwaylandiviapplication.h"
5#include "qwaylandiviapplication_p.h"
6
7#include <QtWaylandCompositor/QWaylandCompositor>
8#include <QtWaylandCompositor/QWaylandSurface>
9#include <QtWaylandCompositor/QWaylandIviSurface>
10#include <QtWaylandCompositor/QWaylandResource>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 * \qmltype IviApplication
16 * \instantiates QWaylandIviApplication
17 * \inqmlmodule QtWayland.Compositor.IviApplication
18 * \since 5.8
19 * \brief Provides a shell extension for embedded-style user interfaces.
20 *
21 * The IviApplication extension provides a way to associate an IviSurface
22 * with a regular Wayland surface. Using the IviSurface interface, the client can identify
23 * itself by giving an ivi id, and the compositor can ask the client to resize.
24 *
25 * IviApplication corresponds to the Wayland \c ivi_application interface.
26 *
27 * To provide the functionality of the shell extension in a compositor, create
28 * an instance of the IviApplication component and add it to the list of extensions
29 * supported by the compositor:
30 *
31 * \qml
32 * import QtWayland.Compositor.IviApplication
33 *
34 * WaylandCompositor {
35 * IviApplication {
36 * onIviSurfaceCreated: {
37 * if (iviSurface.iviId === navigationIviId) {
38 * // ...
39 * }
40 * }
41 * }
42 * }
43 * \endqml
44 */
45
46/*!
47 * \class QWaylandIviApplication
48 * \inmodule QtWaylandCompositor
49 * \since 5.8
50 * \brief The QWaylandIviApplication class is an extension for embedded-style user interfaces.
51 *
52 * The QWaylandIviApplication extension provides a way to associate an QWaylandIviSurface
53 * with a regular Wayland surface. Using the QWaylandIviSurface interface, the client can identify
54 * itself by giving an ivi id, and the compositor can ask the client to resize.
55 *
56 * QWaylandIviApplication corresponds to the Wayland \c ivi_application interface.
57 */
58
59/*!
60 * Constructs a QWaylandIviApplication object.
61 */
62QWaylandIviApplication::QWaylandIviApplication()
63 : QWaylandCompositorExtensionTemplate<QWaylandIviApplication>(*new QWaylandIviApplicationPrivate())
64{
65}
66
67/*!
68 * Constructs a QWaylandIviApplication object for the provided \a compositor.
69 */
70QWaylandIviApplication::QWaylandIviApplication(QWaylandCompositor *compositor)
71 : QWaylandCompositorExtensionTemplate<QWaylandIviApplication>(compositor, *new QWaylandIviApplicationPrivate())
72{
73}
74
75/*!
76 * Initializes the shell extension.
77 */
78void QWaylandIviApplication::initialize()
79{
80 Q_D(QWaylandIviApplication);
81 QWaylandCompositorExtensionTemplate::initialize();
82
83 QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
84 if (!compositor) {
85 qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandIviApplication";
86 return;
87 }
88
89 d->init(compositor->display(), 1);
90}
91
92/*!
93 * Returns the Wayland interface for the QWaylandIviApplication.
94 */
95const struct wl_interface *QWaylandIviApplication::interface()
96{
97 return QWaylandIviApplicationPrivate::interface();
98}
99
100/*!
101 * \internal
102 */
103QByteArray QWaylandIviApplication::interfaceName()
104{
105 return QWaylandIviApplicationPrivate::interfaceName();
106}
107
108/*!
109 * \qmlsignal void IviApplication::iviSurfaceRequested(WaylandSurface surface, int iviId, WaylandResource resource)
110 *
111 * This signal is emitted when the client has requested an \c ivi_surface to be associated
112 * with \a surface, which is identified by \a iviId. The handler for this signal is
113 * expected to create the ivi surface for \a resource and initialize it within the scope of the
114 * signal emission. If no ivi surface is created, a default one will be created instead.
115 *
116 */
117
118/*!
119 * \fn void QWaylandIviApplication::iviSurfaceRequested(QWaylandSurface *surface, uint iviId, const QWaylandResource &resource)
120 *
121 * This signal is emitted when the client has requested an \c ivi_surface to be associated
122 * with \a surface, which is identified by \a iviId. The handler for this signal is
123 * expected to create the ivi surface for \a resource and initialize it within the scope of the
124 * signal emission. If no ivi surface is created, a default one will be created instead.
125 */
126
127/*!
128 * \qmlsignal void IviApplication::iviSurfaceCreated(IviSurface *iviSurface)
129 *
130 * This signal is emitted when an IviSurface has been created. The supplied \a iviSurface is
131 * most commonly used to instantiate a ShellSurfaceItem.
132 */
133
134/*!
135 * \fn void QWaylandIviApplication::iviSurfaceCreated(QWaylandIviSurface *iviSurface)
136 *
137 * This signal is emitted when an IviSurface, \a iviSurface, has been created.
138 */
139
140QWaylandIviApplicationPrivate::QWaylandIviApplicationPrivate()
141{
142}
143
144void QWaylandIviApplicationPrivate::unregisterIviSurface(QWaylandIviSurface *iviSurface)
145{
146 m_iviSurfaces.remove(key: iviSurface->iviId());
147}
148
149void QWaylandIviApplicationPrivate::ivi_application_surface_create(QtWaylandServer::ivi_application::Resource *resource,
150 uint32_t ivi_id, wl_resource *surfaceResource, uint32_t id)
151{
152 Q_Q(QWaylandIviApplication);
153 QWaylandSurface *surface = QWaylandSurface::fromResource(resource: surfaceResource);
154
155 if (m_iviSurfaces.contains(key: ivi_id)) {
156 wl_resource_post_error(resource->handle, IVI_APPLICATION_ERROR_IVI_ID,
157 "Given ivi_id, %d, is already assigned to wl_surface@%d", ivi_id,
158 wl_resource_get_id(m_iviSurfaces[ivi_id]->surface()->resource()));
159 return;
160 }
161
162 if (!surface->setRole(role: QWaylandIviSurface::role(), errorResource: resource->handle, errorCode: IVI_APPLICATION_ERROR_ROLE))
163 return;
164
165 QWaylandResource iviSurfaceResource(wl_resource_create(resource->client(), &ivi_surface_interface,
166 wl_resource_get_version(resource->handle), id));
167
168 emit q->iviSurfaceRequested(surface, iviId: ivi_id, resource: iviSurfaceResource);
169
170 QWaylandIviSurface *iviSurface = QWaylandIviSurface::fromResource(resource: iviSurfaceResource.resource());
171
172 if (!iviSurface)
173 iviSurface = new QWaylandIviSurface(q, surface, ivi_id, iviSurfaceResource);
174
175 m_iviSurfaces.insert(key: ivi_id, value: iviSurface);
176
177 emit q->iviSurfaceCreated(iviSurface);
178}
179
180QT_END_NAMESPACE
181
182#include "moc_qwaylandiviapplication.cpp"
183

source code of qtwayland/src/compositor/extensions/qwaylandiviapplication.cpp