summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/qnx
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/qnx')
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp70
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h22
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp45
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp156
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.h26
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp23
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 &paramList)
{
@@ -124,6 +123,22 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
return options;
}
+static inline int getContextCapabilities(const QStringList &paramList)
+{
+ QString contextCapabilitiesPrefix = QStringLiteral("screen-context-capabilities=");
+ int contextCapabilities = SCREEN_APPLICATION_CONTEXT;
+ for (const QString &param : 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 &paramList)
: QPlatformIntegration()
, m_screenEventThread(0)
@@ -147,11 +162,15 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
, 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 &paramList)
#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 &paramList);
~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