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
qqnxintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2013 BlackBerry Limited. All rights reserved.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
6
7#include "qqnxglobal.h"
8
13#include "qqnxscreen.h"
15#include "qqnxwindow.h"
19#include "qqnxservices.h"
20
23#if !defined(QT_NO_OPENGL)
24#include "qqnxeglwindow.h"
25#endif
26
27#if QT_CONFIG(vulkan)
28#include "qqnxvulkanwindow.h"
29#include "qqnxvulkaninstance.h"
30#endif
31
32#if QT_CONFIG(qqnx_pps)
33#include "qqnxnavigatorpps.h"
34#include "qqnxnavigatoreventnotifier.h"
35#include "qqnxvirtualkeyboardpps.h"
36#endif
37
38#if QT_CONFIG(qqnx_pps)
39# include "qqnxbuttoneventnotifier.h"
40#endif
41
42#if QT_CONFIG(qqnx_imf)
43# include "qqnxinputcontext_imf.h"
44#else
46#endif
47
48#if !defined(QT_NO_CLIPBOARD)
49# include "qqnxclipboard.h"
50#endif
51
52#include <qpa/qplatforminputcontextfactory_p.h>
53#include <qpa/qplatforminputcontext.h>
54#include <qpa/qplatformtheme.h>
55
56#include "private/qgenericunixfontdatabase_p.h"
57#include "private/qgenericunixeventdispatcher_p.h"
58
59#include <qpa/qplatformwindow.h>
60#include <qpa/qwindowsysteminterface.h>
61
62#include <QtGui/private/qguiapplication_p.h>
63#include <QtGui/private/qrhibackingstore_p.h>
64
65#if !defined(QT_NO_OPENGL)
66#include "qqnxglcontext.h"
67#include <QtGui/QOpenGLContext>
68#endif
69
70#include <private/qsimpledrag_p.h>
71
72#include <QtCore/QDebug>
73#include <QtCore/QJsonDocument>
74#include <QtCore/QJsonObject>
75#include <QtCore/QJsonArray>
76#include <QtCore/QFile>
77#include <errno.h>
78
79QT_BEGIN_NAMESPACE
80
81using namespace Qt::StringLiterals;
82
84
85static inline QQnxIntegration::Options parseOptions(const QStringList &paramList)
86{
87 QQnxIntegration::Options options = QQnxIntegration::NoOptions;
88 if (!paramList.contains("no-fullscreen"_L1)) {
90 }
91
92 if (paramList.contains("flush-screen-context"_L1)) {
94 }
95
96 if (paramList.contains("rootwindow"_L1)) {
98 }
99
100 if (!paramList.contains("disable-EGL_KHR_surfaceless_context"_L1)) {
102 }
103
104 if (paramList.contains("desktop"_L1)) {
105 options |= QQnxIntegration::Desktop;
106 }
107
108 return options;
109}
110
111static inline int getContextCapabilities(const QStringList &paramList)
112{
113 constexpr auto contextCapabilitiesPrefix = "screen-context-capabilities="_L1;
114 int contextCapabilities = SCREEN_APPLICATION_CONTEXT;
115 for (const QString &param : paramList) {
116 if (param.startsWith(contextCapabilitiesPrefix)) {
117 auto value = QStringView{param}.mid(contextCapabilitiesPrefix.length());
118 bool ok = false;
119 contextCapabilities = value.toInt(&ok, 0);
120 if (!ok)
121 contextCapabilities = SCREEN_APPLICATION_CONTEXT;
122 }
123 }
124 return contextCapabilities;
125}
126
127QQnxIntegration::QQnxIntegration(const QStringList &paramList)
128 : QPlatformIntegration()
129 , m_screenContextId(256, 0)
130 , m_screenEventThread(0)
131 , m_navigatorEventHandler(new QQnxNavigatorEventHandler())
132 , m_virtualKeyboard(0)
133 , m_inputContext(0)
134#if QT_CONFIG(qqnx_pps)
135 , m_navigatorEventNotifier(0)
136 , m_buttonsNotifier(new QQnxButtonEventNotifier())
137#endif
138 , m_qpaInputContext(0)
139 , m_fontDatabase(new QGenericUnixFontDatabase())
140 , m_eventDispatcher(createUnixEventDispatcher())
141 , m_nativeInterface(new QQnxNativeInterface(this))
142 , m_screenEventHandler(new QQnxScreenEventHandler(this))
143#if !defined(QT_NO_CLIPBOARD)
144 , m_clipboard(0)
145#endif
146 , m_navigator(0)
147#if QT_CONFIG(draganddrop)
148 , m_drag(new QSimpleDrag())
149#endif
150#if QT_CONFIG(opengl)
151 , m_eglDisplay(EGL_NO_DISPLAY)
152#endif
153{
154 ms_instance = this;
155 m_options = parseOptions(paramList);
156 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
157
158 // Open connection to QNX composition manager
159 if (screen_create_context(&m_screenContext, getContextCapabilities(paramList))) {
160 qFatal("%s - Screen: Failed to create screen context - Error: %s (%i)",
161 Q_FUNC_INFO, strerror(errno), errno);
162 }
163 screen_get_context_property_cv(m_screenContext,
164 SCREEN_PROPERTY_ID,
165 m_screenContextId.size(),
166 m_screenContextId.data());
167 m_screenContextId.resize(strlen(m_screenContextId.constData()));
168
169#if QT_CONFIG(qqnx_pps)
170 // Create/start navigator event notifier
171 m_navigatorEventNotifier = new QQnxNavigatorEventNotifier(m_navigatorEventHandler);
172
173 // delay invocation of start() to the time the event loop is up and running
174 // needed to have the QThread internals of the main thread properly initialized
175 QMetaObject::invokeMethod(m_navigatorEventNotifier, "start", Qt::QueuedConnection);
176#endif
177
178#if QT_CONFIG(opengl)
179 createEglDisplay();
180#endif
181
182 // Create/start event thread
183 m_screenEventThread = new QQnxScreenEventThread(m_screenContext);
184 m_screenEventHandler->setScreenEventThread(m_screenEventThread);
185 m_screenEventThread->start();
186
187 m_qpaInputContext = QPlatformInputContextFactory::create();
188
189#if QT_CONFIG(qqnx_pps)
190 if (!m_qpaInputContext) {
191 // Create/start the keyboard class.
192 m_virtualKeyboard = new QQnxVirtualKeyboardPps();
193
194 // delay invocation of start() to the time the event loop is up and running
195 // needed to have the QThread internals of the main thread properly initialized
196 QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection);
197 }
198#endif
199
200#if QT_CONFIG(qqnx_pps)
201 m_navigator = new QQnxNavigatorPps();
202#endif
203
204 createDisplays();
205
206 if (m_virtualKeyboard) {
207 // TODO check if we need to do this for all screens or only the primary one
208 QObject::connect(m_virtualKeyboard, SIGNAL(heightChanged(int)),
209 primaryDisplay(), SLOT(keyboardHeightChanged(int)));
210
211#if QT_CONFIG(qqnx_pps)
212 // Set up the input context
213 m_inputContext = new QQnxInputContext(this, *m_virtualKeyboard);
214#if QT_CONFIG(qqnx_imf)
215 m_screenEventHandler->addScreenEventFilter(m_inputContext);
216#endif
217#endif
218 }
219
220#if QT_CONFIG(qqnx_pps)
221 // delay invocation of start() to the time the event loop is up and running
222 // needed to have the QThread internals of the main thread properly initialized
223 QMetaObject::invokeMethod(m_buttonsNotifier, "start", Qt::QueuedConnection);
224#endif
225}
226
228{
229 qCDebug(lcQpaQnx) << "Platform plugin shutdown begin";
230 delete m_nativeInterface;
231
232#if QT_CONFIG(draganddrop)
233 // Destroy the drag object
234 delete m_drag;
235#endif
236
237#if !defined(QT_NO_CLIPBOARD)
238 // Delete the clipboard
239 delete m_clipboard;
240#endif
241
242 // Stop/destroy navigator event notifier
243#if QT_CONFIG(qqnx_pps)
244 delete m_navigatorEventNotifier;
245#endif
246 delete m_navigatorEventHandler;
247
248 // Stop/destroy screen event thread
249 delete m_screenEventThread;
250
251 // In case the event-dispatcher was never transferred to QCoreApplication
252 delete m_eventDispatcher;
253
254 delete m_screenEventHandler;
255
256 // Destroy all displays
257 destroyDisplays();
258
259 // Close connection to QNX composition manager
260 screen_destroy_context(m_screenContext);
261
262#if QT_CONFIG(opengl)
263 destroyEglDisplay();
264#endif
265
266#if QT_CONFIG(qqnx_pps)
267 // Destroy the hardware button notifier
268 delete m_buttonsNotifier;
269
270 // Destroy input context
271 delete m_inputContext;
272#endif
273 delete m_qpaInputContext;
274
275 // Destroy the keyboard class.
276 delete m_virtualKeyboard;
277
278 // Destroy services class
279 delete m_services;
280
281 // Destroy navigator interface
282 delete m_navigator;
283
284 ms_instance = nullptr;
285
286 qCDebug(lcQpaQnx) << "Platform plugin shutdown end";
287}
288
289bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const
290{
291 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
292 switch (cap) {
293 case MultipleWindows:
294 case ForeignWindows:
295 case ChildWindows:
296 case ThreadedPixmaps:
297 return true;
298#if !defined(QT_NO_OPENGL)
299 case OpenGL:
300 case ThreadedOpenGL:
301 case BufferQueueingOpenGL:
302 return true;
303#endif
304 default:
305 return QPlatformIntegration::hasCapability(cap);
306 }
307}
308
309QPlatformWindow *QQnxIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
310{
311 screen_window_t screenWindow = reinterpret_cast<screen_window_t>(nativeHandle);
312 if (this->window(screenWindow)) {
313 qWarning() << "QWindow already created for foreign window"
314 << screenWindow;
315 return nullptr;
316 }
317
318 return new QQnxForeignWindow(window, m_screenContext, screenWindow);
319}
320
322{
323 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
324 QSurface::SurfaceType surfaceType = window->surfaceType();
325 const bool needRootWindow = options() & RootWindow;
326 switch (surfaceType) {
327 case QSurface::RasterSurface:
328 return new QQnxRasterWindow(window, m_screenContext, needRootWindow);
329#if !defined(QT_NO_OPENGL)
330 case QSurface::OpenGLSurface:
331 return new QQnxEglWindow(window, m_screenContext, needRootWindow);
332#endif
333#if QT_CONFIG(vulkan)
334 case QSurface::VulkanSurface:
335 return new QQnxVulkanWindow(window, m_screenContext, needRootWindow);
336#endif
337 default:
338 qFatal("QQnxWindow: unsupported window API");
339 }
340 return 0;
341}
342
343#if QT_CONFIG(vulkan)
344QPlatformVulkanInstance *QQnxIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
345{
346 return new QQnxVulkanInstance(instance);
347}
348#endif
349
351{
352 QSurface::SurfaceType surfaceType = window->surfaceType();
353 qCDebug(lcQpaQnx) << Q_FUNC_INFO << surfaceType;
354 switch (surfaceType) {
355 case QSurface::RasterSurface:
356 return new QQnxRasterBackingStore(window);
357#if !defined(QT_NO_OPENGL)
358 // Return a QRhiBackingStore for non-raster surface windows
359 case QSurface::OpenGLSurface:
360 return new QRhiBackingStore(window);
361#endif
362#if QT_CONFIG(vulkan)
363 case QSurface::VulkanSurface:
364 return new QRhiBackingStore(window);
365#endif
366 default:
367 return nullptr;
368 }
369}
370
371#if !defined(QT_NO_OPENGL)
372QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
373{
374 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
375
376 // Get color channel sizes from window format
377 QSurfaceFormat format = context->format();
378 int alphaSize = format.alphaBufferSize();
379 int redSize = format.redBufferSize();
380 int greenSize = format.greenBufferSize();
381 int blueSize = format.blueBufferSize();
382
383 // Check if all channels are don't care
384 if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) {
385 // Set color channels based on depth of window's screen
386 QQnxScreen *screen = static_cast<QQnxScreen*>(context->screen()->handle());
387 int depth = screen->depth();
388 if (depth == 32) {
389 // SCREEN_FORMAT_RGBA8888
390 alphaSize = 8;
391 redSize = 8;
392 greenSize = 8;
393 blueSize = 8;
394 } else {
395 // SCREEN_FORMAT_RGB565
396 alphaSize = 0;
397 redSize = 5;
398 greenSize = 6;
399 blueSize = 5;
400 }
401 } else {
402 // Choose best match based on supported pixel formats
403 if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) {
404 // SCREEN_FORMAT_RGB565
405 alphaSize = 0;
406 redSize = 5;
407 greenSize = 6;
408 blueSize = 5;
409 } else {
410 // SCREEN_FORMAT_RGBA8888
411 alphaSize = 8;
412 redSize = 8;
413 greenSize = 8;
414 blueSize = 8;
415 }
416 }
417
418 // Update color channel sizes in window format
419 format.setAlphaBufferSize(alphaSize);
420 format.setRedBufferSize(redSize);
421 format.setGreenBufferSize(greenSize);
422 format.setBlueBufferSize(blueSize);
423 context->setFormat(format);
424
425 QQnxGLContext *ctx = new QQnxGLContext(context->format(), context->shareHandle());
426 return ctx;
427}
428#endif
429
431{
432 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
433 if (m_qpaInputContext)
434 return m_qpaInputContext;
435 return m_inputContext;
436}
437
438void QQnxIntegration::moveToScreen(QWindow *window, int screen)
439{
440 qCDebug(lcQpaQnx) << Q_FUNC_INFO << "w =" << window << ", s =" << screen;
441
442 // get platform window used by widget
443 QQnxWindow *platformWindow = static_cast<QQnxWindow *>(window->handle());
444
445 // lookup platform screen by index
446 QQnxScreen *platformScreen = m_screens.at(screen);
447
448 // move the platform window to the platform screen
449 platformWindow->setScreen(platformScreen);
450}
451
453{
454 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
455
456 // We transfer ownersip of the event-dispatcher to QtCoreApplication
457 QAbstractEventDispatcher *eventDispatcher = m_eventDispatcher;
458 m_eventDispatcher = 0;
459
460 return eventDispatcher;
461}
462
464{
465 return m_nativeInterface;
466}
467
468#if !defined(QT_NO_CLIPBOARD)
470{
471 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
472 if (!m_clipboard)
473 m_clipboard = new QQnxClipboard;
474
475 return m_clipboard;
476}
477#endif
478
479#if QT_CONFIG(draganddrop)
480QPlatformDrag *QQnxIntegration::drag() const
481{
482 return m_drag;
483}
484#endif
485
486QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
487{
488 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
489 if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
490 return true;
491
492 return QPlatformIntegration::styleHint(hint);
493}
494
495// QNX provides no native widget style, so without a platform theme the base
496// QPlatformTheme reports an empty StyleNames hint. QApplication then falls back
497// to the first available QStyleFactory key, which lets any deployed style
498// plugin (e.g. the labs StyleKit style) silently become the default widget
499// style. Declare a sensible default (Fusion, always built into QtWidgets),
500// matching what the generic Unix theme used by eglfs does.
501namespace {
502class QQnxTheme : public QPlatformTheme
503{
504public:
505 QVariant themeHint(ThemeHint hint) const override
506 {
507 if (hint == QPlatformTheme::StyleNames)
508 return QStringList{ QStringLiteral("Fusion") };
509 return QPlatformTheme::themeHint(hint);
510 }
511};
512} // unnamed namespace
513
515{
516 // Returning a non-empty name ensures createPlatformTheme() below is invoked
517 // (QGuiApplication only calls it for names reported here / via environment).
518 return QStringList{ QStringLiteral("qnx") };
519}
520
522{
523 // Return nullptr for non-matching names so that other theme names tried by
524 // QGuiApplication (e.g. from QT_QPA_PLATFORMTHEME) are not shadowed by a
525 // non-null base theme.
526 return name == "qnx"_L1 ? new QQnxTheme : nullptr;
527}
528
530{
531 // Create services handling class
532 if (m_navigator && !m_services)
533 m_services = new QQnxServices(m_navigator);
534
535 return m_services;
536}
537
538QWindow *QQnxIntegration::window(screen_window_t qnxWindow) const
539{
540 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
541 QMutexLocker locker(&m_windowMapperMutex);
542 Q_UNUSED(locker);
543 return m_windowMapper.value(qnxWindow, 0);
544}
545
546void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
547{
548 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
549 QMutexLocker locker(&m_windowMapperMutex);
550 Q_UNUSED(locker);
551 m_windowMapper.insert(qnxWindow, window);
552}
553
554void QQnxIntegration::removeWindow(screen_window_t qnxWindow)
555{
556 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
557 QMutexLocker locker(&m_windowMapperMutex);
558 Q_UNUSED(locker);
559 m_windowMapper.remove(qnxWindow);
560}
561
562/*!
563 Get display ID for given \a display
564
565 Returns -1 for failure, otherwise returns display ID
566 */
567static int getIdOfDisplay(screen_display_t display)
568{
569 int displayId;
570 if (screen_get_display_property_iv(display,
571 SCREEN_PROPERTY_ID,
572 &displayId) == 0) {
573 return displayId;
574 }
575 return -1;
576}
577
578/*!
579 Read JSON configuration file for the QNX display order
580
581 Returns true if file was read successfully and fills \a requestedDisplays
582 */
583static bool getRequestedDisplays(QJsonArray &requestedDisplays)
584{
585 // Check if display configuration file is provided
586 QByteArray json = qgetenv("QT_QPA_QNX_DISPLAY_CONFIG");
587 if (json.isEmpty())
588 return false;
589
590 // Check if configuration file exists
591 QFile file(QString::fromUtf8(json));
592 if (!file.open(QFile::ReadOnly)) {
593 qWarning() << "Could not open config file" << json << "for reading";
594 return false;
595 }
596
597 // Read config file and check it's json
598 const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
599 if (!doc.isObject()) {
600 qWarning() << "Invalid config file" << json
601 << "- no top-level JSON object";
602 return false;
603 }
604
605 // Read the requested display order
606 const QJsonObject object = doc.object();
607 requestedDisplays = object.value("displayOrder"_L1).toArray();
608
609 return true;
610}
611
612/*!
613 Match \a availableDisplays with display order defined in a json file
614 pointed to by QT_QPA_QNX_DISPLAY_CONFIG. Display order must use same
615 identifiers as defined for displays in graphics.conf. Number of
616 available displays must be specified in \a displayCount
617
618 An example configuration is below:
619 \badcode
620 {
621 "displayOrder": [ 3, 1 ]
622 }
623 \endcode
624
625 Returns ordered list of displays. If no order was specified, returns
626 displays in the same order as in the original list.
627*/
628QList<screen_display_t *> QQnxIntegration::sortDisplays(screen_display_t *availableDisplays, int displayCount)
629{
630 // Intermediate list for sorting
631 QList<screen_display_t *> allDisplays;
632 for (int i = 0; i < displayCount; i++)
633 allDisplays.append(&availableDisplays[i]);
634
635 // Read requested display order if available
636 QJsonArray requestedDisplays;
637 if (!getRequestedDisplays(requestedDisplays))
638 return allDisplays;
639
640 // Go through all the requested displays IDs
641 QList<screen_display_t *> orderedDisplays;
642 for (const QJsonValue &value : std::as_const(requestedDisplays)) {
643 int requestedValue = value.toInt();
644
645 // Move all displays with matching ID from the intermediate list
646 // to the beginning of the ordered list
647 for (auto it = allDisplays.begin(), end = allDisplays.end(); it != end; ++it) {
648 screen_display_t *display = *it;
649 if (getIdOfDisplay(*display) == requestedValue) {
650 orderedDisplays.append(display);
651 allDisplays.erase(it);
652 break;
653 }
654 }
655 }
656
657 // Place all unordered displays to the end of list
658 orderedDisplays.append(allDisplays);
659
660 return orderedDisplays;
661}
662
663void QQnxIntegration::createDisplays()
664{
665 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
666 // Query number of displays
667 int displayCount = 0;
668 int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
669 &displayCount);
670 Q_SCREEN_CRITICALERROR(result, "Failed to query display count");
671
672 if (Q_UNLIKELY(displayCount < 1)) {
673 // Never happens, even if there's no display, libscreen returns 1
674 qFatal("QQnxIntegration: displayCount=%d", displayCount);
675 }
676
677 // Get all displays
678 screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
679 result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS,
680 (void **)displays);
681 QList<screen_display_t *> orderedDisplays = sortDisplays(displays, displayCount);
682 Q_SCREEN_CRITICALERROR(result, "Failed to query displays");
683
684 // If it's primary, we create a QScreen for it even if it's not attached
685 // since Qt will dereference QGuiApplication::primaryScreen()
686 createDisplay(*orderedDisplays[0], /*isPrimary=*/true);
687
688 for (int i=1; i<displayCount; i++) {
689 int isAttached = 1;
690 result = screen_get_display_property_iv(*orderedDisplays[i], SCREEN_PROPERTY_ATTACHED,
691 &isAttached);
692 Q_SCREEN_CHECKERROR(result, "Failed to query display attachment");
693
694 if (!isAttached) {
695 qCDebug(lcQpaQnx) << "Skipping non-attached display " << i;
696 continue;
697 }
698
699 qCDebug(lcQpaQnx) << "Creating screen for display " << i;
700
701 createDisplay(*orderedDisplays[i], /*isPrimary=*/false);
702 } // of displays iteration
703}
704
705void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary)
706{
707 QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
708 m_screens.append(screen);
709 QWindowSystemInterface::handleScreenAdded(screen);
711
712 QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void*)),
713 screen, SLOT(newWindowCreated(void*)));
714 QObject::connect(m_screenEventHandler, SIGNAL(windowClosed(void*)),
715 screen, SLOT(windowClosed(void*)));
716
717 QObject::connect(m_navigatorEventHandler, SIGNAL(rotationChanged(int)), screen, SLOT(setRotation(int)));
718 QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupActivated(QByteArray)), screen, SLOT(activateWindowGroup(QByteArray)));
719 QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupDeactivated(QByteArray)), screen, SLOT(deactivateWindowGroup(QByteArray)));
720 QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupStateChanged(QByteArray,Qt::WindowState)),
721 screen, SLOT(windowGroupStateChanged(QByteArray,Qt::WindowState)));
722}
723
725{
726 Q_CHECK_PTR(screen);
727 Q_ASSERT(m_screens.contains(screen));
728 m_screens.removeAll(screen);
729 QWindowSystemInterface::handleScreenRemoved(screen);
730}
731
732void QQnxIntegration::destroyDisplays()
733{
734 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
735
736 Q_FOREACH (QQnxScreen *screen, m_screens) {
737 QWindowSystemInterface::handleScreenRemoved(screen);
738 }
739 m_screens.clear();
740}
741
742QQnxScreen *QQnxIntegration::screenForNative(screen_display_t qnxScreen) const
743{
744 Q_FOREACH (QQnxScreen *screen, m_screens) {
745 if (screen->nativeDisplay() == qnxScreen)
746 return screen;
747 }
748
749 return 0;
750}
751
753{
754 return m_screens.first();
755}
756
758{
759 return m_options;
760}
761
763{
764 return m_screenContext;
765}
766
768{
769 return m_screenContextId;
770}
771
773{
774 return m_navigatorEventHandler;
775}
776
778{
779 // If QQNX_PPS is defined then we have navigator
780 return m_navigator != 0;
781}
782
783#if QT_CONFIG(opengl)
784void QQnxIntegration::createEglDisplay()
785{
786 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
787
788 // Initialize connection to EGL
789 m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
790 if (Q_UNLIKELY(m_eglDisplay == EGL_NO_DISPLAY))
791 qFatal("QQnxiIntegration: failed to obtain EGL display: %x", eglGetError());
792
793 EGLBoolean eglResult = eglInitialize(m_eglDisplay, 0, 0);
794 if (Q_UNLIKELY(eglResult != EGL_TRUE))
795 qFatal("QQnxIntegration: failed to initialize EGL display, err=%d", eglGetError());
796}
797
798void QQnxIntegration::destroyEglDisplay()
799{
800 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
801
802 // Close connection to EGL
803 eglTerminate(m_eglDisplay);
804}
805#endif
806
807QT_END_NAMESPACE
QAbstractEventDispatcher * createEventDispatcher() const override
Factory function for the GUI event dispatcher.
bool hasCapability(QPlatformIntegration::Capability cap) const override
QPlatformNativeInterface * nativeInterface() const override
QQnxNavigatorEventHandler * navigatorEventHandler()
QPlatformBackingStore * createPlatformBackingStore(QWindow *window) const override
Factory function for QPlatformBackingStore.
QPlatformWindow * createPlatformWindow(QWindow *window) const override
Factory function for QPlatformWindow.
QPlatformWindow * createForeignWindow(QWindow *window, WId nativeHandle) const override
QStringList themeNames() const override
Options options() const
QQnxScreen * primaryDisplay() const
QPlatformTheme * createPlatformTheme(const QString &name) const override
void removeDisplay(QQnxScreen *screen)
QVariant styleHint(StyleHint hint) const override
QPlatformServices * services() const override
void moveToScreen(QWindow *window, int screen)
QPlatformInputContext * inputContext() const override
Returns the platforms input context.
QByteArray screenContextId()
QQnxScreen * screenForNative(screen_display_t qnxScreen) const
void createDisplay(screen_display_t display, bool isPrimary)
screen_context_t screenContext()
QWindow * window(screen_window_t qnxWindow) const
QPlatformClipboard * clipboard() const override
Accessor for the platform integration's clipboard.
bool supportsNavigatorEvents() const
QQnxNativeInterface(QQnxIntegration *integration)
void setScreenEventThread(QQnxScreenEventThread *eventThread)
int depth() const override
Reimplement in subclass to return current depth of the screen.
void adjustOrientation()
QQnxServices(QQnxAbstractNavigator *navigator)
The QQnxWindow is the base class of the various classes used as instances of QPlatformWindow in the Q...
Definition qqnxwindow.h:32
void setScreen(QQnxScreen *platformScreen)
#define Q_SCREEN_CRITICALERROR(x, message)
Definition qqnxglobal.h:20
#define Q_SCREEN_CHECKERROR(x, message)
Definition qqnxglobal.h:17
static bool getRequestedDisplays(QJsonArray &requestedDisplays)
Read JSON configuration file for the QNX display order.
static int getIdOfDisplay(screen_display_t display)
Get display ID for given display.
static int getContextCapabilities(const QStringList &paramList)
static QQnxIntegration::Options parseOptions(const QStringList &paramList)