diff options
Diffstat (limited to 'src/plugins/platforms/qnx')
-rw-r--r-- | src/plugins/platforms/qnx/qqnxglcontext.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxglobal.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.cpp | 70 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.h | 22 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 45 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreeneventhandler.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreeneventthread.cpp | 156 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreeneventthread.h | 26 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxwindow.cpp | 23 |
9 files changed, 185 insertions, 167 deletions
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp index 2031de308c..1d030ba1aa 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.cpp +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -64,7 +64,7 @@ static QEGLPlatformContext::Flags makeFlags() { QEGLPlatformContext::Flags result = 0; - if (!QQnxIntegration::options().testFlag(QQnxIntegration::SurfacelessEGLContext)) + if (!QQnxIntegration::instance()->options().testFlag(QQnxIntegration::SurfacelessEGLContext)) result |= QEGLPlatformContext::NoSurfaceless; return result; diff --git a/src/plugins/platforms/qnx/qqnxglobal.cpp b/src/plugins/platforms/qnx/qqnxglobal.cpp index 6b3cc6bebf..c17f6a7546 100644 --- a/src/plugins/platforms/qnx/qqnxglobal.cpp +++ b/src/plugins/platforms/qnx/qqnxglobal.cpp @@ -45,9 +45,9 @@ QT_BEGIN_NAMESPACE void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool critical) { - if (!rc && (QQnxIntegration::options() & QQnxIntegration::AlwaysFlushScreenContext) - && QQnxIntegration::screenContext() != 0) { - rc = screen_flush_context(QQnxIntegration::screenContext(), 0); + if (!rc && (QQnxIntegration::instance()->options() & QQnxIntegration::AlwaysFlushScreenContext) + && QQnxIntegration::instance()->screenContext() != 0) { + rc = screen_flush_context(QQnxIntegration::instance()->screenContext(), 0); } if (Q_UNLIKELY(rc)) { diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index dc4ebdf699..8c8521325c 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -99,8 +99,7 @@ QT_BEGIN_NAMESPACE -QQnxWindowMapper QQnxIntegration::ms_windowMapper; -QMutex QQnxIntegration::ms_windowMapperMutex; +QQnxIntegration *QQnxIntegration::ms_instance; static inline QQnxIntegration::Options parseOptions(const QStringList ¶mList) { @@ -124,6 +123,22 @@ static inline QQnxIntegration::Options parseOptions(const QStringList ¶mList return options; } +static inline int getContextCapabilities(const QStringList ¶mList) +{ + QString contextCapabilitiesPrefix = QStringLiteral("screen-context-capabilities="); + int contextCapabilities = SCREEN_APPLICATION_CONTEXT; + for (const QString ¶m : paramList) { + if (param.startsWith(contextCapabilitiesPrefix)) { + QStringRef value = param.midRef(contextCapabilitiesPrefix.length()); + bool ok = false; + contextCapabilities = value.toInt(&ok, 0); + if (!ok) + contextCapabilities = SCREEN_APPLICATION_CONTEXT; + } + } + return contextCapabilities; +} + QQnxIntegration::QQnxIntegration(const QStringList ¶mList) : QPlatformIntegration() , m_screenEventThread(0) @@ -147,11 +162,15 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) , m_drag(new QSimpleDrag()) #endif { - ms_options = parseOptions(paramList); + ms_instance = this; + m_options = parseOptions(paramList); qIntegrationDebug(); + // Open connection to QNX composition manager - Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT), - "Failed to create screen context"); + if (screen_create_context(&m_screenContext, getContextCapabilities(paramList))) { + qFatal("%s - Screen: Failed to create screen context - Error: %s (%i)", + Q_FUNC_INFO, strerror(errno), errno); + } #if QT_CONFIG(qqnx_pps) // Create/start navigator event notifier @@ -168,7 +187,8 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) #endif // Create/start event thread - m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler); + m_screenEventThread = new QQnxScreenEventThread(m_screenContext); + m_screenEventHandler->setScreenEventThread(m_screenEventThread); m_screenEventThread->start(); #if QT_CONFIG(qqnx_pps) @@ -244,7 +264,7 @@ QQnxIntegration::~QQnxIntegration() destroyDisplays(); // Close connection to QNX composition manager - screen_destroy_context(ms_screenContext); + screen_destroy_context(m_screenContext); #if !defined(QT_NO_OPENGL) // Cleanup global OpenGL resources @@ -268,6 +288,8 @@ QQnxIntegration::~QQnxIntegration() // Destroy navigator interface delete m_navigator; + ms_instance = nullptr; + qIntegrationDebug("platform plugin shutdown end"); } @@ -296,10 +318,10 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const const bool needRootWindow = options() & RootWindow; switch (surfaceType) { case QSurface::RasterSurface: - return new QQnxRasterWindow(window, ms_screenContext, needRootWindow); + return new QQnxRasterWindow(window, m_screenContext, needRootWindow); #if !defined(QT_NO_OPENGL) case QSurface::OpenGLSurface: - return new QQnxEglWindow(window, ms_screenContext, needRootWindow); + return new QQnxEglWindow(window, m_screenContext, needRootWindow); #endif default: qFatal("QQnxWindow: unsupported window API"); @@ -433,7 +455,7 @@ QPlatformDrag *QQnxIntegration::drag() const QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const { qIntegrationDebug(); - if ((hint == ShowIsFullScreen) && (ms_options & FullScreenApplication)) + if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication)) return true; return QPlatformIntegration::styleHint(hint); @@ -447,25 +469,25 @@ QPlatformServices * QQnxIntegration::services() const QWindow *QQnxIntegration::window(screen_window_t qnxWindow) { qIntegrationDebug(); - QMutexLocker locker(&ms_windowMapperMutex); + QMutexLocker locker(&m_windowMapperMutex); Q_UNUSED(locker); - return ms_windowMapper.value(qnxWindow, 0); + return m_windowMapper.value(qnxWindow, 0); } void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window) { qIntegrationDebug(); - QMutexLocker locker(&ms_windowMapperMutex); + QMutexLocker locker(&m_windowMapperMutex); Q_UNUSED(locker); - ms_windowMapper.insert(qnxWindow, window); + m_windowMapper.insert(qnxWindow, window); } void QQnxIntegration::removeWindow(screen_window_t qnxWindow) { qIntegrationDebug(); - QMutexLocker locker(&ms_windowMapperMutex); + QMutexLocker locker(&m_windowMapperMutex); Q_UNUSED(locker); - ms_windowMapper.remove(qnxWindow); + m_windowMapper.remove(qnxWindow); } void QQnxIntegration::createDisplays() @@ -473,7 +495,7 @@ void QQnxIntegration::createDisplays() qIntegrationDebug(); // Query number of displays int displayCount = 0; - int result = screen_get_context_property_iv(ms_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, + int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount); Q_SCREEN_CRITICALERROR(result, "Failed to query display count"); @@ -484,7 +506,7 @@ void QQnxIntegration::createDisplays() // Get all displays screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount); - result = screen_get_context_property_pv(ms_screenContext, SCREEN_PROPERTY_DISPLAYS, + result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays); Q_SCREEN_CRITICALERROR(result, "Failed to query displays"); @@ -510,7 +532,7 @@ void QQnxIntegration::createDisplays() void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary) { - QQnxScreen *screen = new QQnxScreen(ms_screenContext, display, isPrimary); + QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary); m_screens.append(screen); screenAdded(screen); screen->adjustOrientation(); @@ -559,14 +581,14 @@ QQnxScreen *QQnxIntegration::primaryDisplay() const return m_screens.first(); } -QQnxIntegration::Options QQnxIntegration::options() +QQnxIntegration::Options QQnxIntegration::options() const { - return ms_options; + return m_options; } screen_context_t QQnxIntegration::screenContext() { - return ms_screenContext; + return m_screenContext; } QQnxNavigatorEventHandler *QQnxIntegration::navigatorEventHandler() @@ -574,10 +596,6 @@ QQnxNavigatorEventHandler *QQnxIntegration::navigatorEventHandler() return m_navigatorEventHandler; } -screen_context_t QQnxIntegration::ms_screenContext = 0; - -QQnxIntegration::Options QQnxIntegration::ms_options = 0; - bool QQnxIntegration::supportsNavigatorEvents() const { // If QQNX_PPS is defined then we have navigator diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index f844a7508c..2993607489 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -88,6 +88,8 @@ public: explicit QQnxIntegration(const QStringList ¶mList); ~QQnxIntegration(); + static QQnxIntegration *instance() { return ms_instance; } + bool hasCapability(QPlatformIntegration::Capability cap) const override; QPlatformWindow *createPlatformWindow(QWindow *window) const override; @@ -121,15 +123,15 @@ public: QPlatformServices *services() const override; - static QWindow *window(screen_window_t qnxWindow); + QWindow *window(screen_window_t qnxWindow); QQnxScreen *screenForNative(screen_display_t qnxScreen) const; void createDisplay(screen_display_t display, bool isPrimary); void removeDisplay(QQnxScreen *screen); QQnxScreen *primaryDisplay() const; - static Options options(); - static screen_context_t screenContext(); + Options options() const; + screen_context_t screenContext(); QQnxNavigatorEventHandler *navigatorEventHandler(); @@ -137,10 +139,10 @@ private: void createDisplays(); void destroyDisplays(); - static void addWindow(screen_window_t qnxWindow, QWindow *window); - static void removeWindow(screen_window_t qnxWindow); + void addWindow(screen_window_t qnxWindow, QWindow *window); + void removeWindow(screen_window_t qnxWindow); - static screen_context_t ms_screenContext; + screen_context_t m_screenContext; QQnxScreenEventThread *m_screenEventThread; QQnxNavigatorEventHandler *m_navigatorEventHandler; QQnxAbstractVirtualKeyboard *m_virtualKeyboard; @@ -162,10 +164,12 @@ private: #if QT_CONFIG(draganddrop) QSimpleDrag *m_drag; #endif - static QQnxWindowMapper ms_windowMapper; - static QMutex ms_windowMapperMutex; + QQnxWindowMapper m_windowMapper; + QMutex m_windowMapperMutex; + + Options m_options; - static Options ms_options; + static QQnxIntegration *ms_instance; friend class QQnxWindow; }; diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index ff1133aaa7..e4843cb438 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -218,36 +218,39 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread) { m_eventThread = eventThread; + connect(m_eventThread, &QQnxScreenEventThread::eventsPending, + this, &QQnxScreenEventHandler::processEvents); } -void QQnxScreenEventHandler::processEventsFromScreenThread() +void QQnxScreenEventHandler::processEvents() { if (!m_eventThread) return; - QQnxScreenEventArray *events = m_eventThread->lock(); + screen_event_t event = nullptr; + if (screen_create_event(&event) != 0) + return; - for (int i = 0; i < events->size(); ++i) { - screen_event_t event = events->at(i); - if (!event) - continue; - (*events)[i] = 0; + int count = 0; + for (;;) { + if (screen_get_event(m_eventThread->context(), event, 0) != 0) + break; - m_eventThread->unlock(); + int type = SCREEN_EVENT_NONE; + screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type); + if (type == SCREEN_EVENT_NONE) + break; + ++count; long result = 0; QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); bool handled = dispatcher && dispatcher->filterNativeEvent(QByteArrayLiteral("screen_event_t"), event, &result); if (!handled) handleEvent(event); - screen_destroy_event(event); - - m_eventThread->lock(); } - events->clear(); - - m_eventThread->unlock(); + m_eventThread->armEventsPending(count); + screen_destroy_event(event); } void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event) @@ -323,11 +326,11 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event) "Failed to query event wheel delta"); // Map window handle to top-level QWindow - QWindow *w = QQnxIntegration::window(qnxWindow); + QWindow *w = QQnxIntegration::instance()->window(qnxWindow); // Generate enter and leave events as needed. if (qnxWindow != m_lastMouseWindow) { - QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); + QWindow *wOld = QQnxIntegration::instance()->window(m_lastMouseWindow); if (wOld) { QWindowSystemInterface::handleLeaveEvent(wOld); @@ -435,11 +438,11 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) if (touchId < MaximumTouchPoints) { // Map window handle to top-level QWindow - QWindow *w = QQnxIntegration::window(qnxWindow); + QWindow *w = QQnxIntegration::instance()->window(qnxWindow); // Generate enter and leave events as needed. if (qnxWindow != m_lastMouseWindow) { - QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); + QWindow *wOld = QQnxIntegration::instance()->window(m_lastMouseWindow); if (wOld) { QWindowSystemInterface::handleLeaveEvent(wOld); @@ -529,7 +532,7 @@ void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event) Q_EMIT windowClosed(window); // Map window handle to top-level QWindow - QWindow *w = QQnxIntegration::window(window); + QWindow *w = QQnxIntegration::instance()->window(window); if (w != 0) QWindowSystemInterface::handleCloseEvent(w); } @@ -629,7 +632,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi if (Q_UNLIKELY(window && screen_get_window_property_iv(window, SCREEN_PROPERTY_FOCUS, &focus) != 0)) qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno); - QWindow *focusWindow = QQnxIntegration::window(window); + QWindow *focusWindow = QQnxIntegration::instance()->window(window); if (m_focusLostTimer != -1) { killTimer(m_focusLostTimer); @@ -655,7 +658,7 @@ void QQnxScreenEventHandler::handleGeometryPropertyEvent(screen_window_t window) } QRect rect(pos[0], pos[1], size[0], size[1]); - QWindow *qtWindow = QQnxIntegration::window(window); + QWindow *qtWindow = QQnxIntegration::instance()->window(window); if (qtWindow) { qtWindow->setGeometry(rect); QWindowSystemInterface::handleGeometryChange(qtWindow, rect); diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h index 40697b7a09..b35967610e 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h @@ -74,7 +74,7 @@ protected: void timerEvent(QTimerEvent *event) override; private Q_SLOTS: - void processEventsFromScreenThread(); + void processEvents(); private: void handleKeyboardEvent(screen_event_t event); diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp index c56d9a8da4..1b5f3b4954 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp @@ -1,5 +1,6 @@ /*************************************************************************** ** +** Copyright (C) 2017 QNX Software Systems. All rights reserved. ** Copyright (C) 2011 - 2012 Research In Motion ** Contact: https://www.qt.io/licensing/ ** @@ -55,116 +56,101 @@ #define qScreenEventThreadDebug QT_NO_QDEBUG_MACRO #endif -QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler) - : QThread(), - m_screenContext(context), - m_screenEventHandler(screenEventHandler), - m_quit(false) +static const int c_screenCode = _PULSE_CODE_MINAVAIL + 0; +static const int c_armCode = _PULSE_CODE_MINAVAIL + 1; +static const int c_quitCode = _PULSE_CODE_MINAVAIL + 2; + +QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context) + : QThread() + , m_screenContext(context) { - screenEventHandler->setScreenEventThread(this); - connect(this, SIGNAL(eventPending()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection); - connect(this, SIGNAL(finished()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection); + m_channelId = ChannelCreate(_NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK | _NTO_CHF_PRIVATE); + if (m_channelId == -1) { + qFatal("QQnxScreenEventThread: Can't continue without a channel"); + } + + m_connectionId = ConnectAttach(0, 0, m_channelId, _NTO_SIDE_CHANNEL, 0); + if (m_connectionId == -1) { + ChannelDestroy(m_channelId); + qFatal("QQnxScreenEventThread: Can't continue without a channel connection"); + } + + struct sigevent screenEvent; + SIGEV_PULSE_INIT(&screenEvent, m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_screenCode, 0); + + screen_notify(m_screenContext, SCREEN_NOTIFY_EVENT, nullptr, &screenEvent); } QQnxScreenEventThread::~QQnxScreenEventThread() { // block until thread terminates shutdown(); -} -void QQnxScreenEventThread::injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap) -{ - QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap); -} - -QQnxScreenEventArray *QQnxScreenEventThread::lock() -{ - m_mutex.lock(); - return &m_events; -} - -void QQnxScreenEventThread::unlock() -{ - m_mutex.unlock(); + ConnectDetach(m_connectionId); + ChannelDestroy(m_channelId); } void QQnxScreenEventThread::run() { qScreenEventThreadDebug("screen event thread started"); - int errorCounter = 0; - // loop indefinitely - while (!m_quit) { - screen_event_t event; - - // create screen event - Q_SCREEN_CHECKERROR(screen_create_event(&event), "Failed to create screen event"); - - // block until screen event is available - const int error = screen_get_event(m_screenContext, event, -1); - Q_SCREEN_CRITICALERROR(error, "Failed to get screen event"); - // Only allow 50 consecutive errors before we exit the thread - if (error) { - errorCounter++; - if (errorCounter > 50) - m_quit = true; - - screen_destroy_event(event); - continue; - } else { - errorCounter = 0; - } - - // process received event - // get the event type - int qnxType; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType), - "Failed to query screen event type"); - - if (qnxType == SCREEN_EVENT_USER) { - // treat all user events as shutdown requests - qScreenEventThreadDebug("QNX user screen event"); - m_quit = true; - } else { - m_mutex.lock(); - m_events << event; - m_mutex.unlock(); - emit eventPending(); - } + while (1) { + struct _pulse msg; + memset(&msg, 0, sizeof(msg)); + int receiveId = MsgReceive(m_channelId, &msg, sizeof(msg), nullptr); + if (receiveId == 0 && msg.code == c_quitCode) + break; + else if (receiveId == 0) + handlePulse(msg); + else if (receiveId > 0) + qWarning() << "Unexpected message" << msg.code; + else + qWarning() << "MsgReceive error" << strerror(errno); } qScreenEventThreadDebug("screen event thread stopped"); - - // cleanup - m_mutex.lock(); - Q_FOREACH (screen_event_t event, m_events) { - screen_destroy_event(event); - } - m_events.clear(); - m_mutex.unlock(); } -void QQnxScreenEventThread::shutdown() +void QQnxScreenEventThread::armEventsPending(int count) { - screen_event_t event; + MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_armCode, count); +} - // create screen event - Q_SCREEN_CHECKERROR(screen_create_event(&event), - "Failed to create screen event"); +void QQnxScreenEventThread::handleScreenPulse(const struct _pulse &msg) +{ + Q_UNUSED(msg); - // set the event type as user - int type = SCREEN_EVENT_USER; - Q_SCREEN_CHECKERROR(screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type), - "Failed to set screen type"); + ++m_screenPulsesSinceLastArmPulse; + if (m_emitNeededOnNextScreenPulse) { + m_emitNeededOnNextScreenPulse = false; + Q_EMIT eventsPending(); + } +} - // NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events +void QQnxScreenEventThread::handleArmPulse(const struct _pulse &msg) +{ + if (msg.value.sival_int == 0 && m_screenPulsesSinceLastArmPulse == 0) { + m_emitNeededOnNextScreenPulse = true; + } else { + m_screenPulsesSinceLastArmPulse = 0; + m_emitNeededOnNextScreenPulse = false; + Q_EMIT eventsPending(); + } +} - // post event to event loop so it will wake up and die - Q_SCREEN_CHECKERROR(screen_send_event(m_screenContext, event, getpid()), - "Failed to set screen event type"); +void QQnxScreenEventThread::handlePulse(const struct _pulse &msg) +{ + if (msg.code == c_screenCode) + handleScreenPulse(msg); + else if (msg.code == c_armCode) + handleArmPulse(msg); + else + qWarning() << "Unexpected pulse" << msg.code; +} - // cleanup - screen_destroy_event(event); +void QQnxScreenEventThread::shutdown() +{ + MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_quitCode, 0); qScreenEventThreadDebug("screen event thread shutdown begin"); diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.h b/src/plugins/platforms/qnx/qqnxscreeneventthread.h index 140f53aa50..3c8d197545 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventthread.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.h @@ -1,5 +1,6 @@ /*************************************************************************** ** +** Copyright (C) 2017 QNX Software Systems. All rights reserved. ** Copyright (C) 2011 - 2012 Research In Motion ** Contact: https://www.qt.io/licensing/ ** @@ -47,37 +48,34 @@ QT_BEGIN_NAMESPACE -class QQnxScreenEventHandler; - -typedef QVarLengthArray<screen_event_t, 64> QQnxScreenEventArray; - class QQnxScreenEventThread : public QThread { Q_OBJECT public: - QQnxScreenEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler); + QQnxScreenEventThread(screen_context_t context); ~QQnxScreenEventThread(); - static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - - QQnxScreenEventArray *lock(); - void unlock(); + screen_context_t context() const { return m_screenContext; } + void armEventsPending(int count); protected: void run() override; Q_SIGNALS: - void eventPending(); + void eventsPending(); private: + void handleScreenPulse(const struct _pulse &msg); + void handleArmPulse(const struct _pulse &msg); + void handlePulse(const struct _pulse &msg); void shutdown(); + int m_channelId; + int m_connectionId; screen_context_t m_screenContext; - QMutex m_mutex; - QQnxScreenEventArray m_events; - QQnxScreenEventHandler *m_screenEventHandler; - bool m_quit; + bool m_emitNeededOnNextScreenPulse = true; + int m_screenPulsesSinceLastArmPulse = 0; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 4a547aa158..5d9eaaa3ea 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -174,7 +174,9 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW // If a qnxInitialWindowGroup property is set on the window we'll take this as an // indication that we want to create a child window and join that window group. - const QVariant windowGroup = window->property("qnxInitialWindowGroup"); + QVariant windowGroup = window->property("qnxInitialWindowGroup"); + if (!windowGroup.isValid()) + windowGroup = window->property("_q_platform_qnxParentGroup"); if (window->type() == Qt::CoverWindow) { // Cover windows have to be top level to be accessible to window delegate (i.e. navigator) @@ -194,7 +196,12 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW if (window->type() == Qt::Desktop) // A desktop widget does not need a libscreen window return; - if (m_isTopLevel) { + QVariant type = window->property("_q_platform_qnxWindowType"); + if (type.isValid() && type.canConvert<int>()) { + Q_SCREEN_CHECKERROR( + screen_create_window_type(&m_window, m_screenContext, type.value<int>()), + "Could not create window"); + } else if (m_isTopLevel) { Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext), "Could not create top level window"); // Creates an application window if (window->type() != Qt::CoverWindow) { @@ -212,7 +219,9 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW // If the window has a qnxWindowId property, set this as the string id property. This generally // needs to be done prior to joining any group as it might be used by the owner of the // group to identify the window. - const QVariant windowId = window->property("qnxWindowId"); + QVariant windowId = window->property("qnxWindowId"); + if (!windowId.isValid()) + windowId = window->property("_q_platform_qnxWindowId"); if (windowId.isValid() && windowId.canConvert<QByteArray>()) { QByteArray id = windowId.toByteArray(); Q_SCREEN_CHECKERROR(screen_set_window_property_cv(m_window, SCREEN_PROPERTY_ID_STRING, @@ -262,7 +271,7 @@ QQnxWindow::~QQnxWindow() Q_ASSERT(m_childWindows.size() == 0); // Remove from plugin's window mapper - QQnxIntegration::removeWindow(m_window); + QQnxIntegration::instance()->removeWindow(m_window); // Remove from parent's Hierarchy. removeFromParent(); @@ -471,7 +480,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) qWindowDebug("Moving window to different screen"); m_screen->removeWindow(this); - if ((QQnxIntegration::options() & QQnxIntegration::RootWindow)) { + if ((QQnxIntegration::instance()->options() & QQnxIntegration::RootWindow)) { screen_leave_window_group(m_window); } } @@ -726,7 +735,7 @@ void QQnxWindow::initWindow() m_exposed = false; // Add window to plugin's window mapper - QQnxIntegration::addWindow(m_window, window()); + QQnxIntegration::instance()->addWindow(m_window, window()); // Qt never calls these setters after creating the window, so we need to do that ourselves here setWindowState(window()->windowState()); @@ -823,7 +832,7 @@ void QQnxWindow::windowPosted() bool QQnxWindow::shouldMakeFullScreen() const { return ((static_cast<QQnxScreen *>(screen())->rootWindow() == this) - && (QQnxIntegration::options() & QQnxIntegration::FullScreenApplication)); + && (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication)); } QT_END_NAMESPACE |