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 | |
12 | QT_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 | */ |
62 | QWaylandIviApplication::QWaylandIviApplication() |
63 | : QWaylandCompositorExtensionTemplate<QWaylandIviApplication>(*new QWaylandIviApplicationPrivate()) |
64 | { |
65 | } |
66 | |
67 | /*! |
68 | * Constructs a QWaylandIviApplication object for the provided \a compositor. |
69 | */ |
70 | QWaylandIviApplication::QWaylandIviApplication(QWaylandCompositor *compositor) |
71 | : QWaylandCompositorExtensionTemplate<QWaylandIviApplication>(compositor, *new QWaylandIviApplicationPrivate()) |
72 | { |
73 | } |
74 | |
75 | /*! |
76 | * Initializes the shell extension. |
77 | */ |
78 | void 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 | */ |
95 | const struct wl_interface *QWaylandIviApplication::interface() |
96 | { |
97 | return QWaylandIviApplicationPrivate::interface(); |
98 | } |
99 | |
100 | /*! |
101 | * \internal |
102 | */ |
103 | QByteArray 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 | |
140 | QWaylandIviApplicationPrivate::QWaylandIviApplicationPrivate() |
141 | { |
142 | } |
143 | |
144 | void QWaylandIviApplicationPrivate::unregisterIviSurface(QWaylandIviSurface *iviSurface) |
145 | { |
146 | m_iviSurfaces.remove(key: iviSurface->iviId()); |
147 | } |
148 | |
149 | void 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 | |
180 | QT_END_NAMESPACE |
181 | |
182 | #include "moc_qwaylandiviapplication.cpp" |
183 | |