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 ThreadedPixmaps:
296 return true;
297#if !defined(QT_NO_OPENGL)
298 case OpenGL:
299 case ThreadedOpenGL:
300 case BufferQueueingOpenGL:
301 return true;
302#endif
303 default:
304 return QPlatformIntegration::hasCapability(cap);
305 }
306}
307
308QPlatformWindow *QQnxIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
309{
310 screen_window_t screenWindow = reinterpret_cast<screen_window_t>(nativeHandle);
311 if (this->window(screenWindow)) {
312 qWarning() << "QWindow already created for foreign window"
313 << screenWindow;
314 return nullptr;
315 }
316
317 return new QQnxForeignWindow(window, m_screenContext, screenWindow);
318}
319
321{
322 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
323 QSurface::SurfaceType surfaceType = window->surfaceType();
324 const bool needRootWindow = options() & RootWindow;
325 switch (surfaceType) {
326 case QSurface::RasterSurface:
327 return new QQnxRasterWindow(window, m_screenContext, needRootWindow);
328#if !defined(QT_NO_OPENGL)
329 case QSurface::OpenGLSurface:
330 return new QQnxEglWindow(window, m_screenContext, needRootWindow);
331#endif
332#if QT_CONFIG(vulkan)
333 case QSurface::VulkanSurface:
334 return new QQnxVulkanWindow(window, m_screenContext, needRootWindow);
335#endif
336 default:
337 qFatal("QQnxWindow: unsupported window API");
338 }
339 return 0;
340}
341
342#if QT_CONFIG(vulkan)
343QPlatformVulkanInstance *QQnxIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
344{
345 return new QQnxVulkanInstance(instance);
346}
347#endif
348
350{
351 QSurface::SurfaceType surfaceType = window->surfaceType();
352 qCDebug(lcQpaQnx) << Q_FUNC_INFO << surfaceType;
353 switch (surfaceType) {
354 case QSurface::RasterSurface:
355 return new QQnxRasterBackingStore(window);
356#if !defined(QT_NO_OPENGL)
357 // Return a QRhiBackingStore for non-raster surface windows
358 case QSurface::OpenGLSurface:
359 return new QRhiBackingStore(window);
360#endif
361#if QT_CONFIG(vulkan)
362 case QSurface::VulkanSurface:
363 return new QRhiBackingStore(window);
364#endif
365 default:
366 return nullptr;
367 }
368}
369
370#if !defined(QT_NO_OPENGL)
371QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
372{
373 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
374
375 // Get color channel sizes from window format
376 QSurfaceFormat format = context->format();
377 int alphaSize = format.alphaBufferSize();
378 int redSize = format.redBufferSize();
379 int greenSize = format.greenBufferSize();
380 int blueSize = format.blueBufferSize();
381
382 // Check if all channels are don't care
383 if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) {
384 // Set color channels based on depth of window's screen
385 QQnxScreen *screen = static_cast<QQnxScreen*>(context->screen()->handle());
386 int depth = screen->depth();
387 if (depth == 32) {
388 // SCREEN_FORMAT_RGBA8888
389 alphaSize = 8;
390 redSize = 8;
391 greenSize = 8;
392 blueSize = 8;
393 } else {
394 // SCREEN_FORMAT_RGB565
395 alphaSize = 0;
396 redSize = 5;
397 greenSize = 6;
398 blueSize = 5;
399 }
400 } else {
401 // Choose best match based on supported pixel formats
402 if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) {
403 // SCREEN_FORMAT_RGB565
404 alphaSize = 0;
405 redSize = 5;
406 greenSize = 6;
407 blueSize = 5;
408 } else {
409 // SCREEN_FORMAT_RGBA8888
410 alphaSize = 8;
411 redSize = 8;
412 greenSize = 8;
413 blueSize = 8;
414 }
415 }
416
417 // Update color channel sizes in window format
418 format.setAlphaBufferSize(alphaSize);
419 format.setRedBufferSize(redSize);
420 format.setGreenBufferSize(greenSize);
421 format.setBlueBufferSize(blueSize);
422 context->setFormat(format);
423
424 QQnxGLContext *ctx = new QQnxGLContext(context->format(), context->shareHandle());
425 return ctx;
426}
427#endif
428
430{
431 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
432 if (m_qpaInputContext)
433 return m_qpaInputContext;
434 return m_inputContext;
435}
436
437void QQnxIntegration::moveToScreen(QWindow *window, int screen)
438{
439 qCDebug(lcQpaQnx) << Q_FUNC_INFO << "w =" << window << ", s =" << screen;
440
441 // get platform window used by widget
442 QQnxWindow *platformWindow = static_cast<QQnxWindow *>(window->handle());
443
444 // lookup platform screen by index
445 QQnxScreen *platformScreen = m_screens.at(screen);
446
447 // move the platform window to the platform screen
448 platformWindow->setScreen(platformScreen);
449}
450
452{
453 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
454
455 // We transfer ownersip of the event-dispatcher to QtCoreApplication
456 QAbstractEventDispatcher *eventDispatcher = m_eventDispatcher;
457 m_eventDispatcher = 0;
458
459 return eventDispatcher;
460}
461
463{
464 return m_nativeInterface;
465}
466
467#if !defined(QT_NO_CLIPBOARD)
469{
470 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
471 if (!m_clipboard)
472 m_clipboard = new QQnxClipboard;
473
474 return m_clipboard;
475}
476#endif
477
478#if QT_CONFIG(draganddrop)
479QPlatformDrag *QQnxIntegration::drag() const
480{
481 return m_drag;
482}
483#endif
484
485QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
486{
487 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
488 if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
489 return true;
490
491 return QPlatformIntegration::styleHint(hint);
492}
493
494// QNX provides no native widget style, so without a platform theme the base
495// QPlatformTheme reports an empty StyleNames hint. QApplication then falls back
496// to the first available QStyleFactory key, which lets any deployed style
497// plugin (e.g. the labs StyleKit style) silently become the default widget
498// style. Declare a sensible default (Fusion, always built into QtWidgets),
499// matching what the generic Unix theme used by eglfs does.
500namespace {
501class QQnxTheme : public QPlatformTheme
502{
503public:
504 QVariant themeHint(ThemeHint hint) const override
505 {
506 if (hint == QPlatformTheme::StyleNames)
507 return QStringList{ QStringLiteral("Fusion") };
508 return QPlatformTheme::themeHint(hint);
509 }
510};
511} // unnamed namespace
512
514{
515 // Returning a non-empty name ensures createPlatformTheme() below is invoked
516 // (QGuiApplication only calls it for names reported here / via environment).
517 return QStringList{ QStringLiteral("qnx") };
518}
519
521{
522 // Return nullptr for non-matching names so that other theme names tried by
523 // QGuiApplication (e.g. from QT_QPA_PLATFORMTHEME) are not shadowed by a
524 // non-null base theme.
525 return name == "qnx"_L1 ? new QQnxTheme : nullptr;
526}
527
529{
530 // Create services handling class
531 if (m_navigator && !m_services)
532 m_services = new QQnxServices(m_navigator);
533
534 return m_services;
535}
536
537QWindow *QQnxIntegration::window(screen_window_t qnxWindow) const
538{
539 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
540 QMutexLocker locker(&m_windowMapperMutex);
541 Q_UNUSED(locker);
542 return m_windowMapper.value(qnxWindow, 0);
543}
544
545void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
546{
547 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
548 QMutexLocker locker(&m_windowMapperMutex);
549 Q_UNUSED(locker);
550 m_windowMapper.insert(qnxWindow, window);
551}
552
553void QQnxIntegration::removeWindow(screen_window_t qnxWindow)
554{
555 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
556 QMutexLocker locker(&m_windowMapperMutex);
557 Q_UNUSED(locker);
558 m_windowMapper.remove(qnxWindow);
559}
560
561/*!
562 Get display ID for given \a display
563
564 Returns -1 for failure, otherwise returns display ID
565 */
566static int getIdOfDisplay(screen_display_t display)
567{
568 int displayId;
569 if (screen_get_display_property_iv(display,
570 SCREEN_PROPERTY_ID,
571 &displayId) == 0) {
572 return displayId;
573 }
574 return -1;
575}
576
577/*!
578 Read JSON configuration file for the QNX display order
579
580 Returns true if file was read successfully and fills \a requestedDisplays
581 */
582static bool getRequestedDisplays(QJsonArray &requestedDisplays)
583{
584 // Check if display configuration file is provided
585 QByteArray json = qgetenv("QT_QPA_QNX_DISPLAY_CONFIG");
586 if (json.isEmpty())
587 return false;
588
589 // Check if configuration file exists
590 QFile file(QString::fromUtf8(json));
591 if (!file.open(QFile::ReadOnly)) {
592 qWarning() << "Could not open config file" << json << "for reading";
593 return false;
594 }
595
596 // Read config file and check it's json
597 const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
598 if (!doc.isObject()) {
599 qWarning() << "Invalid config file" << json
600 << "- no top-level JSON object";
601 return false;
602 }
603
604 // Read the requested display order
605 const QJsonObject object = doc.object();
606 requestedDisplays = object.value("displayOrder"_L1).toArray();
607
608 return true;
609}
610
611/*!
612 Match \a availableDisplays with display order defined in a json file
613 pointed to by QT_QPA_QNX_DISPLAY_CONFIG. Display order must use same
614 identifiers as defined for displays in graphics.conf. Number of
615 available displays must be specified in \a displayCount
616
617 An example configuration is below:
618 \badcode
619 {
620 "displayOrder": [ 3, 1 ]
621 }
622 \endcode
623
624 Returns ordered list of displays. If no order was specified, returns
625 displays in the same order as in the original list.
626*/
627QList<screen_display_t *> QQnxIntegration::sortDisplays(screen_display_t *availableDisplays, int displayCount)
628{
629 // Intermediate list for sorting
630 QList<screen_display_t *> allDisplays;
631 for (int i = 0; i < displayCount; i++)
632 allDisplays.append(&availableDisplays[i]);
633
634 // Read requested display order if available
635 QJsonArray requestedDisplays;
636 if (!getRequestedDisplays(requestedDisplays))
637 return allDisplays;
638
639 // Go through all the requested displays IDs
640 QList<screen_display_t *> orderedDisplays;
641 for (const QJsonValue &value : std::as_const(requestedDisplays)) {
642 int requestedValue = value.toInt();
643
644 // Move all displays with matching ID from the intermediate list
645 // to the beginning of the ordered list
646 for (auto it = allDisplays.begin(), end = allDisplays.end(); it != end; ++it) {
647 screen_display_t *display = *it;
648 if (getIdOfDisplay(*display) == requestedValue) {
649 orderedDisplays.append(display);
650 allDisplays.erase(it);
651 break;
652 }
653 }
654 }
655
656 // Place all unordered displays to the end of list
657 orderedDisplays.append(allDisplays);
658
659 return orderedDisplays;
660}
661
662void QQnxIntegration::createDisplays()
663{
664 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
665 // Query number of displays
666 int displayCount = 0;
667 int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
668 &displayCount);
669 Q_SCREEN_CRITICALERROR(result, "Failed to query display count");
670
671 if (Q_UNLIKELY(displayCount < 1)) {
672 // Never happens, even if there's no display, libscreen returns 1
673 qFatal("QQnxIntegration: displayCount=%d", displayCount);
674 }
675
676 // Get all displays
677 screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
678 result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS,
679 (void **)displays);
680 QList<screen_display_t *> orderedDisplays = sortDisplays(displays, displayCount);
681 Q_SCREEN_CRITICALERROR(result, "Failed to query displays");
682
683 // If it's primary, we create a QScreen for it even if it's not attached
684 // since Qt will dereference QGuiApplication::primaryScreen()
685 createDisplay(*orderedDisplays[0], /*isPrimary=*/true);
686
687 for (int i=1; i<displayCount; i++) {
688 int isAttached = 1;
689 result = screen_get_display_property_iv(*orderedDisplays[i], SCREEN_PROPERTY_ATTACHED,
690 &isAttached);
691 Q_SCREEN_CHECKERROR(result, "Failed to query display attachment");
692
693 if (!isAttached) {
694 qCDebug(lcQpaQnx) << "Skipping non-attached display " << i;
695 continue;
696 }
697
698 qCDebug(lcQpaQnx) << "Creating screen for display " << i;
699
700 createDisplay(*orderedDisplays[i], /*isPrimary=*/false);
701 } // of displays iteration
702}
703
704void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary)
705{
706 QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
707 m_screens.append(screen);
708 QWindowSystemInterface::handleScreenAdded(screen);
710
711 QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void*)),
712 screen, SLOT(newWindowCreated(void*)));
713 QObject::connect(m_screenEventHandler, SIGNAL(windowClosed(void*)),
714 screen, SLOT(windowClosed(void*)));
715
716 QObject::connect(m_navigatorEventHandler, SIGNAL(rotationChanged(int)), screen, SLOT(setRotation(int)));
717 QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupActivated(QByteArray)), screen, SLOT(activateWindowGroup(QByteArray)));
718 QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupDeactivated(QByteArray)), screen, SLOT(deactivateWindowGroup(QByteArray)));
719 QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupStateChanged(QByteArray,Qt::WindowState)),
720 screen, SLOT(windowGroupStateChanged(QByteArray,Qt::WindowState)));
721}
722
724{
725 Q_CHECK_PTR(screen);
726 Q_ASSERT(m_screens.contains(screen));
727 m_screens.removeAll(screen);
728 QWindowSystemInterface::handleScreenRemoved(screen);
729}
730
731void QQnxIntegration::destroyDisplays()
732{
733 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
734
735 Q_FOREACH (QQnxScreen *screen, m_screens) {
736 QWindowSystemInterface::handleScreenRemoved(screen);
737 }
738 m_screens.clear();
739}
740
741QQnxScreen *QQnxIntegration::screenForNative(screen_display_t qnxScreen) const
742{
743 Q_FOREACH (QQnxScreen *screen, m_screens) {
744 if (screen->nativeDisplay() == qnxScreen)
745 return screen;
746 }
747
748 return 0;
749}
750
752{
753 return m_screens.first();
754}
755
757{
758 return m_options;
759}
760
762{
763 return m_screenContext;
764}
765
767{
768 return m_screenContextId;
769}
770
772{
773 return m_navigatorEventHandler;
774}
775
777{
778 // If QQNX_PPS is defined then we have navigator
779 return m_navigator != 0;
780}
781
782#if QT_CONFIG(opengl)
783void QQnxIntegration::createEglDisplay()
784{
785 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
786
787 // Initialize connection to EGL
788 m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
789 if (Q_UNLIKELY(m_eglDisplay == EGL_NO_DISPLAY))
790 qFatal("QQnxiIntegration: failed to obtain EGL display: %x", eglGetError());
791
792 EGLBoolean eglResult = eglInitialize(m_eglDisplay, 0, 0);
793 if (Q_UNLIKELY(eglResult != EGL_TRUE))
794 qFatal("QQnxIntegration: failed to initialize EGL display, err=%d", eglGetError());
795}
796
797void QQnxIntegration::destroyEglDisplay()
798{
799 qCDebug(lcQpaQnx) << Q_FUNC_INFO;
800
801 // Close connection to EGL
802 eglTerminate(m_eglDisplay);
803}
804#endif
805
806QT_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)