Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosplatformintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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 "private/qohosplatformtheme_p.h"
10#include "qohosjsmain.h"
23#include "qohosutils.h"
24
25#include <QtCore/qdebug.h>
26#include <QtCore/qthread.h>
27#include <QtCore/private/qnapi_p.h>
28#include <QtGui/private/qeglpbuffer_p.h>
29#include <QtGui/private/qrhibackingstore_p.h>
30#include <QtCore/private/qohoslogger_p.h>
31#include <QtGui/private/qguiapplication_p.h>
32#include <QtCore/qcoreapplication.h>
33#include <qohosdeviceinfo_p.h>
34#include <qohosplugincore.h>
35
37
38#include <qpa/qwindowsysteminterface.h>
39#include <qpa/qplatforminputcontextfactory_p.h>
40#include <QtCore/qset.h>
41#include <algorithm>
42#include <string>
43#include <utility>
44#include <vector>
45
46#if QT_CONFIG(vulkan)
47#include "qohosplatformvulkaninstance.h"
48#endif
49
50QT_BEGIN_NAMESPACE
51
52namespace {
53
54bool isInputDeviceOfType(QtOhos::JsState &jsState, std::uint32_t deviceId, const std::string &type)
55{
56 auto devSources = QNapi::getArrayElements<std::vector<std::string>, QNapi::String>(
57 jsState.eval<QNapi::Array>(
58 "@ohos.multimodalInput.inputDevice.getDeviceInfoSync(*).sources",
59 {deviceId}));
60 return std::find(devSources.begin(), devSources.end(), type) != devSources.end();
61}
62
63bool isInputDeviceWithTouchscreen(QtOhos::JsState &jsState, std::uint32_t deviceId)
64{
65 return isInputDeviceOfType(jsState, deviceId, "touchscreen");
66}
67
68bool isInputDeviceWithTouchpad(QtOhos::JsState &jsState, std::uint32_t deviceId)
69{
70 return isInputDeviceOfType(jsState, deviceId, "touchpad");
71}
72
74 QtOhos::JsState &jsState, const std::vector<std::uint32_t> &deviceIds,
75 const std::function<bool(QtOhos::JsState &, std::uint32_t)> &isDeviceTypeFunc)
76{
77 return std::any_of(
78 deviceIds.begin(), deviceIds.end(),
79 [&](std::uint32_t deviceId) {
80 return isDeviceTypeFunc(jsState, deviceId);
81 });
82}
83
85{
86 return QtOhos::evalInJsThreadWithConsumer<std::set<QInputDevice::DeviceType>>(
87 [](QtOhos::JsState &jsState, QOhosConsumer<std::set<QInputDevice::DeviceType>> resultConsumer) {
88 jsState.eval<QNapi::Promise>("@ohos.multimodalInput.inputDevice.getDeviceList()")
89 .withContext(std::move(resultConsumer))
90 .onThenWithContext(
91 [](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
92 auto deviceIdsJsArray = cbInfo.getFirstArg<QNapi::Array>(Q_FUNC_INFO);
93 auto deviceIds = QNapi::getArrayElements<std::vector<std::uint32_t>, QNapi::Number>(deviceIdsJsArray);
94 std::set<QInputDevice::DeviceType> deviceTypes;
95 if (isDeviceTypeInDeviceIds(cbInfo.jsState(), deviceIds, isInputDeviceWithTouchscreen))
96 deviceTypes.insert(QInputDevice::DeviceType::TouchScreen);
97 if (isDeviceTypeInDeviceIds(cbInfo.jsState(), deviceIds, isInputDeviceWithTouchpad))
98 deviceTypes.insert(QInputDevice::DeviceType::TouchPad);
99 resultConsumer(deviceTypes);
100 })
101 .onCatchWithContext(
102 [](const QtOhos::CallbackInfo &, auto &resultConsumer) {
103 qOhosPrintfError("Error while obtaining device list (@ohos.multimodalInput.inputDevice.getDeviceList())");
104 resultConsumer({});
105 });
106 });
107}
108
109}
110
111QScopedPointer<QOhosSystemLocale> QOhosPlatformIntegration::m_systemLocale;
114
116{
117 return static_cast<QOhosPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration());
118}
119
121{
122 Q_UNUSED(paramList);
123 auto __dbg = make_QCScopedDebug("QOhosPlatformIntegration::QOhosPlatformIntegration");
124 m_ohosPlatformNativeInterface.reset(new QOhosPlatformNativeInterface());
125
127 m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
128 if (Q_UNLIKELY(m_eglDisplay == EGL_NO_DISPLAY))
129 qOhosReportFatalErrorAndAbort("Could not open egl display");
130
131 EGLint major;
132 EGLint minor;
133 if (Q_UNLIKELY(!eglInitialize(m_eglDisplay, &major, &minor)))
134 qOhosReportFatalErrorAndAbort("Could not initialize egl display");
135
136 if (Q_UNLIKELY(!eglBindAPI(EGL_OPENGL_ES_API)))
137 qOhosReportFatalErrorAndAbort("Could not bind GL_ES API");
138 }
139
140 if (!QtOhos::isOhosNoUiChildMode())
141 m_screenManager = std::make_unique<QOhosScreenManager>();
142
143 m_mainThread = QThread::currentThread();
144
145 m_ohosFDB = std::make_unique<QOhosPlatformFontDatabase>();
146 m_ohosPlatformServices = std::make_unique<QOhosPlatformServices>();
147 if (!QtOhos::isOhosNoUiChildMode())
148 m_ohosInputMethodEventHandler = std::make_unique<QOhosInputMethodEventHandler>(getAvailableDeviceTypes());
149
150#ifndef QT_NO_CLIPBOARD
151 if (!QtOhos::isOhosNoUiChildMode())
152 m_platformClipboard = std::make_unique<QOhosPlatformClipboard>();
153#endif // QT_NO_CLIPBOARD
154
155#if QT_CONFIG(draganddrop)
156 if (!QtOhos::isOhosNoUiChildMode())
157 m_drag = makeQOhosPlatformDrag();
158#endif // QT_CONFIG(draganddrop)
159
160 // QCoreApplication::postEvent takes ownership of the created event.
161 QCoreApplication::postEvent(m_ohosPlatformNativeInterface.data(), new QEvent(QEvent::User));
162}
163
165{
166 return m_ohosInputMethodEventHandler.get();
167}
168
173
175{
176 if (hint == ShowIsMaximized)
177 return false;
178 return QPlatformIntegration::styleHint(hint);
179}
180
182{
183 // Don't maximize dialogs on Android
184 if ((flags & Qt::Dialog & ~Qt::Window) != 0)
185 return Qt::WindowNoState;
186
187 return QPlatformIntegration::defaultWindowState(flags);
188}
189
191{
192 auto __dbg = make_QCScopedDebug("QOhosPlatformIntegration::createPlatformWindow");
193
194 static const QSet<QString> nativeDialogClass = {
195 QString::fromUtf8("QFileDialogClassWindow"),
196 };
197 // FIXME: - System that decides the window class should be reworked
198 // For now this behaviour avoids potential crashes related to the lack of surface
199 if (window != nullptr && !nativeDialogClass.contains(window->objectName()))
200 return new QOhosFloatingWindow(window);
201 return new QOhosPlatformWindow(window);
202}
203
205{
206 return new QOhosForeignWindow(window, windowId);
207}
208
210{
211 return m_ohosFDB.get();
212}
213
214#ifndef QT_NO_CLIPBOARD
216{
217 return m_platformClipboard.get();
218}
219#endif
220
221#if QT_CONFIG(draganddrop)
222QPlatformDrag *QOhosPlatformIntegration::drag() const
223{
224 return m_drag.get();
225}
226#endif // QT_CONFIG(draganddrop)
227
229{
230 std::unique_ptr<QPlatformBackingStore> result;
231 switch (window->surfaceType()) {
232 case QSurface::RasterSurface:
233 // NOTE - This is temporary change done so that tests can be performed
234 // on the new implementation - if there are no problems
235 // a switch to it as the default will be made
236 result = QtOhos::isGlBackingStoreDefaultEnabled()
237 ? makeGlOhosPlatformBackingStore(window)
238 : std::make_unique<QOhosPlatformBackingStore>(
239 window,
240 QOhosPlatformBackingStore::CreateInfo{
241 .debugDrawFlushedRegion = QtOhos::isDebugDrawQtRasterBackingStoreFlushedRegionEnabled(),
242 .enableVsync = QtOhos::isVsyncOnSoftwareBackingStoreEnabled(),
243 });
244 break;
245 case QSurface::OpenGLSurface:
246 case QSurface::VulkanSurface:
247 result = std::make_unique<QRhiBackingStore>(window);
248 break;
249 case QSurface::OpenVGSurface:
250 case QSurface::MetalSurface:
251 case QSurface::Direct3DSurface:
252 qOhosReportFatalErrorAndAbort("Unsupported window surface type for backing store: %d", window->surfaceType());
253 break;
254 }
255
256 return result.release();
257}
258#ifndef QT_NO_OPENGL
260{
261 QSurfaceFormat format = context->format();
262 format.setRedBufferSize(8);
263 format.setGreenBufferSize(8);
264 format.setBlueBufferSize(8);
265 format.setAlphaBufferSize(8);
266 auto *eglCtx = new QOhosEGLPlatformContext(format, context->shareHandle(), m_eglDisplay);
267 return eglCtx;
268}
269
270QOpenGLContext *QOhosPlatformIntegration::createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const
271{
272 return QEGLPlatformContext::createFrom<QOhosEGLPlatformContext>(context, display, m_eglDisplay, shareContext);
273}
274#endif // QT_NO_OPENGL
275
276QPlatformOffscreenSurface *
278{
279 auto __dbg = make_QCScopedDebug("QOhosPlatformIntegration::createPlatformOffscreenSurface");
280 return new QEGLPbuffer(m_eglDisplay, surface->requestedFormat(), surface);
281}
282
283bool QOhosPlatformIntegration::hasCapability(Capability cap) const
284{
285 qOhosDebug(QtForOhos) << "QOhosPlatformIntegration::hasCapability:" << cap;
286
287 switch (cap) {
288 case ApplicationState: return true;
289 case ThreadedPixmaps: return true;
290 case ForeignWindows: return !QtOhos::isOhosNoUiChildMode();
291 case NativeWidgets: return !QtOhos::isOhosNoUiChildMode();
292 case OpenGL: return !QtOhos::isOhosNoUiChildMode();
293 case ThreadedOpenGL: return !QtOhos::isOhosNoUiChildMode();
294 case OffscreenSurface: return true;
295 // TODO: Enable the capability of OpenGLRasterSurface to have emulator
296 // working for OHOS. It doesn't work with other rendering options
297 case OpenGLOnRasterSurface: {
298 return (QOhosDeviceInfo::getProperty(QOhosDeviceInfo::Type::productModel).toString() == QString::fromUtf8("emulator"));
299 }
300 case MultipleWindows: return true;
301 case WindowManagement: return true;
302 case TopStackedNativeChildWindows: return false;
303 default:
304 return QPlatformIntegration::hasCapability(cap);
305 }
306}
307
309{
310 return m_platformInputContext.data();
311}
312
314{
315 auto d = make_QCScopedDebug("QOhosPlatformIntegration::initialize");
316 const auto requestedInputContext = QPlatformInputContextFactory::requested();
317 if (requestedInputContext.isEmpty()) {
319 m_platformInputContext.reset(context);
320 } else {
321 m_platformInputContext.reset(QPlatformInputContextFactory::create(requestedInputContext));
322 }
323
324 if (QWindowSystemInterfacePrivate::eventHandler != nullptr)
325 qOhosReportFatalErrorAndAbort("QWindowSystemInterfacePrivate::eventHandler was already registered.");
326
327 auto tracker = makeApplicationStateTracker();
328 QWindowSystemInterfacePrivate::installWindowSystemEventHandler(tracker.get());
329 m_applicationStateTracker = QtOhos::makeDestroyNotifier(
330 [tracker = std::move(tracker)]() {
331 QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(tracker.get());
332 });
333}
334
336{
337 if (QtOhos::isDebugUseBasicStyleAndThemeEnabled())
338 return std::make_unique<QPlatformTheme>().release();
339
340 if (name == QString::fromUtf8(ohosThemeName))
341 return new QOhosPlatformTheme();
342 return nullptr;
343}
344
346{
347 return {QString::fromUtf8(ohosThemeName)};
348}
349
351{
352 return m_systemLocale.data();
353}
354
356{
357 m_systemLocale.reset(systemLocale);
358}
359
365
370
372{
373 return m_ohosPlatformServices.get();
374}
375
377{
378 return m_ohosPlatformNativeInterface.get();
379}
380
382{
383 return m_screenManager.get();
384}
385
386#if QT_CONFIG(vulkan)
387
388QPlatformVulkanInstance *QOhosPlatformIntegration::createPlatformVulkanInstance(
389 QVulkanInstance *instance) const
390{
391 return new QOhosPlatformVulkanInstance(instance);
392}
393
394#endif // QT_CONFIG(vulkan)
395
396QT_END_NAMESPACE
static void setMainWindowGeometryPersistencePolicy(WindowGeometryPersistencePolicy policy)
QOhosScreenManager * screenManager() const
QPlatformOpenGLContext * createPlatformOpenGLContext(QOpenGLContext *context) const override
Factory function for QPlatformOpenGLContext.
QOhosPlatformClipboard * clipboard() const override
Accessor for the platform integration's clipboard.
QPlatformOffscreenSurface * createPlatformOffscreenSurface(QOffscreenSurface *surface) const override
Factory function for QOffscreenSurface.
bool hasCapability(Capability cap) const override
QPlatformInputContext * inputContext() const override
Returns the platforms input context.
QPlatformFontDatabase * fontDatabase() const override
Accessor for the platform integration's fontdatabase.
QPlatformServices * services() const override
QPlatformNativeInterface * nativeInterface() const override
QOpenGLContext * createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override
QPlatformWindow * createPlatformWindow(QWindow *window) const override
Factory function for QPlatformWindow.
static QOhosPlatformIntegration * instance()
QPlatformTheme * createPlatformTheme(const QString &name) const override
QVariant styleHint(StyleHint hint) const override
QStringList themeNames() const override
static WindowGeometryPersistencePolicy getMainWindowGeometryPersistencePolicy()
Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const override
QPlatformWindow * createForeignWindow(QWindow *, WId) const override
QOhosInputMethodEventHandler * inputMethodEventHandler() const
QPlatformBackingStore * createPlatformBackingStore(QWindow *window) const override
Factory function for QPlatformBackingStore.
QOhosPlatformIntegration(const QStringList &paramList)
QAbstractEventDispatcher * createEventDispatcher() const override
Factory function for the GUI event dispatcher.
void initialize() override
Performs initialization steps that depend on having an event dispatcher available.
static QOhosSystemLocale * systemLocale()
static void setSystemLocale(QOhosSystemLocale *systemLocale)
std::set< QInputDevice::DeviceType > getAvailableDeviceTypes()
bool isDeviceTypeInDeviceIds(QtOhos::JsState &jsState, const std::vector< std::uint32_t > &deviceIds, const std::function< bool(QtOhos::JsState &, std::uint32_t)> &isDeviceTypeFunc)
bool isInputDeviceWithTouchscreen(QtOhos::JsState &jsState, std::uint32_t deviceId)
bool isInputDeviceOfType(QtOhos::JsState &jsState, std::uint32_t deviceId, const std::string &type)
bool isInputDeviceWithTouchpad(QtOhos::JsState &jsState, std::uint32_t deviceId)
bool isOhosNoUiChildMode()