1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qwaylandnativeinterface_p.h"
5#include "qwaylanddisplay_p.h"
6#include "qwaylandwindow_p.h"
7#include "qwaylandshellintegration_p.h"
8#include "qwaylandsubsurface_p.h"
9#include "qwaylandintegration_p.h"
10#include "qwaylanddisplay_p.h"
11#include "qwaylandwindowmanagerintegration_p.h"
12#include "qwaylandscreen_p.h"
13#include "qwaylandinputdevice_p.h"
14#include <QtCore/private/qnativeinterface_p.h>
15#include <QtGui/private/qguiapplication_p.h>
16#include <QtGui/QScreen>
17#include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h>
18#if QT_CONFIG(vulkan)
19#include <QtWaylandClient/private/qwaylandvulkanwindow_p.h>
20#endif
21
22QT_BEGIN_NAMESPACE
23
24namespace QtWaylandClient {
25
26QWaylandNativeInterface::QWaylandNativeInterface(QWaylandIntegration *integration)
27 : m_integration(integration)
28{
29}
30
31void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
32{
33 QByteArray lowerCaseResource = resourceString.toLower();
34
35 if (lowerCaseResource == "display" || lowerCaseResource == "wl_display" || lowerCaseResource == "nativedisplay")
36 return m_integration->display()->wl_display();
37 if (lowerCaseResource == "compositor") {
38 if (auto compositor = m_integration->display()->compositor())
39 return compositor->object();
40 }
41 if (lowerCaseResource == "server_buffer_integration")
42 return m_integration->serverBufferIntegration();
43
44 if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())
45 return m_integration->clientBufferIntegration()->nativeResource(QWaylandClientBufferIntegration::EglDisplay);
46
47 if (lowerCaseResource == "wl_seat")
48 return m_integration->display()->defaultInputDevice()->wl_seat();
49 if (lowerCaseResource == "wl_keyboard") {
50 auto *keyboard = m_integration->display()->defaultInputDevice()->keyboard();
51 if (keyboard)
52 return keyboard->wl_keyboard();
53 return nullptr;
54 }
55 if (lowerCaseResource == "wl_pointer") {
56 auto *pointer = m_integration->display()->defaultInputDevice()->pointer();
57 if (pointer)
58 return pointer->wl_pointer();
59 return nullptr;
60 }
61 if (lowerCaseResource == "wl_touch") {
62 auto *touch = m_integration->display()->defaultInputDevice()->touch();
63 if (touch)
64 return touch->wl_touch();
65 return nullptr;
66 }
67 if (lowerCaseResource == "serial")
68 return reinterpret_cast<void *>(quintptr(m_integration->display()->defaultInputDevice()->serial()));
69
70 return nullptr;
71}
72
73wl_display *QtWaylandClient::QWaylandNativeInterface::display() const
74{
75 return m_integration->display()->wl_display();
76}
77
78wl_compositor *QtWaylandClient::QWaylandNativeInterface::compositor() const
79{
80 if (auto compositor = m_integration->display()->compositor())
81 return compositor->object();
82 return nullptr;
83}
84
85wl_seat *QtWaylandClient::QWaylandNativeInterface::seat() const
86{
87 if (auto inputDevice = m_integration->display()->defaultInputDevice()) {
88 return inputDevice->wl_seat();
89 }
90 return nullptr;
91}
92
93wl_keyboard *QtWaylandClient::QWaylandNativeInterface::keyboard() const
94{
95 if (auto inputDevice = m_integration->display()->defaultInputDevice())
96 if (auto keyboard = inputDevice->keyboard())
97 return keyboard->wl_keyboard();
98 return nullptr;
99}
100
101wl_pointer *QtWaylandClient::QWaylandNativeInterface::pointer() const
102{
103 if (auto inputDevice = m_integration->display()->defaultInputDevice())
104 if (auto pointer = inputDevice->pointer())
105 return pointer->wl_pointer();
106 return nullptr;
107}
108
109wl_touch *QtWaylandClient::QWaylandNativeInterface::touch() const
110{
111 if (auto inputDevice = m_integration->display()->defaultInputDevice())
112 if (auto touch = inputDevice->touch())
113 return touch->wl_touch();
114 return nullptr;
115}
116
117uint QtWaylandClient::QWaylandNativeInterface::lastInputSerial() const
118{
119 return m_integration->display()->lastInputSerial();
120}
121
122wl_seat *QtWaylandClient::QWaylandNativeInterface::lastInputSeat() const
123{
124 if (auto inputDevice = m_integration->display()->lastInputDevice())
125 return inputDevice->wl_seat();
126 return nullptr;
127}
128
129void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
130{
131 QByteArray lowerCaseResource = resourceString.toLower();
132
133 if (lowerCaseResource == "display")
134 return m_integration->display()->wl_display();
135 if (lowerCaseResource == "compositor") {
136 if (auto compositor = m_integration->display()->compositor())
137 return compositor->object();
138 }
139 if (lowerCaseResource == "surface") {
140 QWaylandWindow *w = static_cast<QWaylandWindow*>(window->handle());
141 return w ? w->wlSurface() : nullptr;
142 }
143
144 if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())
145 return m_integration->clientBufferIntegration()->nativeResource(QWaylandClientBufferIntegration::EglDisplay);
146
147#if QT_CONFIG(vulkan)
148 if (lowerCaseResource == "vksurface") {
149 if (window->surfaceType() == QSurface::VulkanSurface && window->handle()) {
150 // return a pointer to the VkSurfaceKHR value, not the value itself
151 return static_cast<QWaylandVulkanWindow *>(window->handle())->vkSurface();
152 }
153 }
154#endif
155
156 QWaylandWindow *platformWindow = static_cast<QWaylandWindow *>(window->handle());
157 if (platformWindow && platformWindow->shellIntegration())
158 return platformWindow->shellIntegration()->nativeResourceForWindow(resource: resourceString, window);
159
160 return nullptr;
161}
162
163void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourceString, QScreen *screen)
164{
165 QByteArray lowerCaseResource = resourceString.toLower();
166
167 if (lowerCaseResource == "output" && !screen->handle()->isPlaceholder())
168 return ((QWaylandScreen *) screen->handle())->output();
169
170 return nullptr;
171}
172
173#if QT_CONFIG(opengl)
174void *QWaylandNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
175{
176#if QT_CONFIG(opengl)
177 QByteArray lowerCaseResource = resource.toLower();
178
179 if (lowerCaseResource == "eglconfig" && m_integration->clientBufferIntegration())
180 return m_integration->clientBufferIntegration()->nativeResourceForContext(QWaylandClientBufferIntegration::EglConfig, context->handle());
181
182 if (lowerCaseResource == "eglcontext" && m_integration->clientBufferIntegration())
183 return m_integration->clientBufferIntegration()->nativeResourceForContext(QWaylandClientBufferIntegration::EglContext, context->handle());
184
185 if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())
186 return m_integration->clientBufferIntegration()->nativeResourceForContext(QWaylandClientBufferIntegration::EglDisplay, context->handle());
187#endif
188
189 return nullptr;
190}
191#endif // opengl
192
193QPlatformNativeInterface::NativeResourceForWindowFunction QWaylandNativeInterface::nativeResourceFunctionForWindow(const QByteArray &resource)
194{
195 QByteArray lowerCaseResource = resource.toLower();
196
197 if (lowerCaseResource == "setmargins") {
198 return NativeResourceForWindowFunction(reinterpret_cast<void *>(setWindowMargins));
199 }
200
201 return nullptr;
202}
203
204QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const
205{
206 QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
207 return waylandWindow->properties();
208}
209
210QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
211{
212 QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
213 return waylandWindow->property(name);
214}
215
216QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
217{
218 QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window);
219 return waylandWindow->property(name, defaultValue);
220}
221
222void QWaylandNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
223{
224 QWaylandWindow *wlWindow = static_cast<QWaylandWindow*>(window);
225 wlWindow->sendProperty(name, value);
226}
227
228void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window, const QString &name)
229{
230 emit windowPropertyChanged(window,propertyName: name);
231}
232
233void QWaylandNativeInterface::setWindowMargins(QWindow *window, const QMargins &margins)
234{
235 QWaylandWindow *wlWindow = static_cast<QWaylandWindow*>(window->handle());
236 wlWindow->setCustomMargins(margins);
237}
238
239}
240
241QT_END_NAMESPACE
242

source code of qtbase/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp