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/qnx.pro19
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp29
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h6
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp19
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h5
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp19
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.cpp16
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.h7
-rw-r--r--src/plugins/platforms/qnx/qqnxrootwindow.cpp268
-rw-r--r--src/plugins/platforms/qnx/qqnxrootwindow.h85
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp151
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h10
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp108
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h17
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp40
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.h13
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp182
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h32
20 files changed, 505 insertions, 525 deletions
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index e2c25add0b..100db54a5c 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -5,18 +5,7 @@ QT += platformsupport-private core-private gui-private
# Uncomment this to build with support for IMF once it becomes available in the BBNDK
#CONFIG += qqnx_imf
-# Uncomment this to build with support for PPS based platform integration
-#CONFIG += qqnx_pps
-
-CONFIG(blackberry) {
- CONFIG += qqnx_pps
-
- # Uncomment following line to enable screen event
- # handling through a dedicated thread.
- # CONFIG += qqnx_screeneventthread
-} else {
- CONFIG += qqnx_screeneventthread
-}
+!blackberry:CONFIG += qqnx_screeneventthread
# Uncomment these to enable debugging output for various aspects of the plugin
#DEFINES += QQNXBPSEVENTFILTER_DEBUG
@@ -33,7 +22,6 @@ CONFIG(blackberry) {
#DEFINES += QQNXNAVIGATOREVENTNOTIFIER_DEBUG
#DEFINES += QQNXNAVIGATOR_DEBUG
#DEFINES += QQNXRASTERBACKINGSTORE_DEBUG
-#DEFINES += QQNXROOTWINDOW_DEBUG
#DEFINES += QQNXSCREENEVENTTHREAD_DEBUG
#DEFINES += QQNXSCREENEVENT_DEBUG
#DEFINES += QQNXSCREEN_DEBUG
@@ -50,7 +38,6 @@ SOURCES = main.cpp \
qqnxscreen.cpp \
qqnxwindow.cpp \
qqnxrasterbackingstore.cpp \
- qqnxrootwindow.cpp \
qqnxscreeneventhandler.cpp \
qqnxnativeinterface.cpp \
qqnxnavigatoreventhandler.cpp \
@@ -67,7 +54,6 @@ HEADERS = main.h \
qqnxscreen.h \
qqnxwindow.h \
qqnxrasterbackingstore.h \
- qqnxrootwindow.h \
qqnxscreeneventhandler.h \
qqnxnativeinterface.h \
qqnxnavigatoreventhandler.h \
@@ -144,7 +130,8 @@ CONFIG(qqnx_pps) {
qqnxclipboard.h \
qqnxbuttoneventnotifier.h
- LIBS += -lpps -lclipboard
+ LIBS += -lpps
+ !contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard
CONFIG(qqnx_imf) {
DEFINES += QQNX_IMF
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index e8fcdd692b..b57227a60b 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -42,6 +42,7 @@
#include "qqnxeglwindow.h"
#include "qqnxscreen.h"
+#include "qqnxglcontext.h"
#include <QDebug>
@@ -55,14 +56,15 @@
QT_BEGIN_NAMESPACE
-QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context) :
- QQnxWindow(window, context),
- m_requestedBufferSize(window->geometry().size()),
+QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
+ QQnxWindow(window, context, needRootWindow),
m_platformOpenGLContext(0),
m_newSurfaceRequested(true),
m_eglSurface(EGL_NO_SURFACE)
{
initWindow();
+ m_requestedBufferSize = screen()->rootWindow() == this ?
+ screen()->geometry().size() : window->geometry().size();
}
QQnxEglWindow::~QQnxEglWindow()
@@ -98,8 +100,6 @@ void QQnxEglWindow::createEGLSurface()
QQnxGLContext::checkEGLError("eglCreateWindowSurface");
qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
}
-
- screen()->onWindowPost(0);
}
void QQnxEglWindow::destroyEGLSurface()
@@ -146,6 +146,9 @@ EGLSurface QQnxEglWindow::getSurface()
void QQnxEglWindow::setGeometry(const QRect &rect)
{
+ //If this is the root window, it has to be shown fullscreen
+ const QRect &newGeometry = screen()->rootWindow() == this ? screen()->geometry() : rect;
+
//We need to request that the GL context updates
// the EGLsurface on which it is rendering.
{
@@ -153,11 +156,11 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
// setting m_requestedBufferSize and therefore extended the scope to include
// that test.
const QMutexLocker locker(&m_mutex);
- m_requestedBufferSize = rect.size();
- if (m_platformOpenGLContext != 0 && bufferSize() != rect.size())
+ m_requestedBufferSize = newGeometry.size();
+ if (m_platformOpenGLContext != 0 && bufferSize() != newGeometry.size())
m_newSurfaceRequested.testAndSetRelease(false, true);
}
- QQnxWindow::setGeometry(rect);
+ QQnxWindow::setGeometry(newGeometry);
}
QSize QQnxEglWindow::requestedBufferSize() const
@@ -166,6 +169,13 @@ QSize QQnxEglWindow::requestedBufferSize() const
return m_requestedBufferSize;
}
+void QQnxEglWindow::adjustBufferSize()
+{
+ const QSize windowSize = window()->size();
+ if (windowSize != bufferSize())
+ setBufferSize(windowSize);
+}
+
void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
{
// This function does not take ownership of the platform gl context.
@@ -175,6 +185,9 @@ void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContex
int QQnxEglWindow::pixelFormat() const
{
+ if (!m_platformOpenGLContext) //The platform GL context was not set yet
+ return -1;
+
const QSurfaceFormat format = m_platformOpenGLContext->format();
// Extract size of color channels from window format
const int redSize = format.redBufferSize();
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index e7dae6a458..fc53afcd7a 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -43,8 +43,6 @@
#define QQNXEGLWINDOW_H
#include "qqnxwindow.h"
-#include "qqnxglcontext.h"
-
#include <QtCore/QMutex>
QT_BEGIN_NAMESPACE
@@ -54,7 +52,7 @@ class QQnxGLContext;
class QQnxEglWindow : public QQnxWindow
{
public:
- QQnxEglWindow(QWindow *window, screen_context_t context);
+ QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow);
~QQnxEglWindow();
void createEGLSurface();
@@ -70,7 +68,7 @@ public:
// Called by QQnxGLContext::createSurface()
QSize requestedBufferSize() const;
- WindowType windowType() const Q_DECL_OVERRIDE { return EGL; }
+ void adjustBufferSize();
protected:
int pixelFormat() const;
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index ff57861498..2b12657da9 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -75,6 +75,8 @@ public:
static EGLDisplay getEglDisplay();
EGLConfig getEglConfig() const { return m_eglConfig;}
+ EGLContext getEglContext() const { return m_eglContext; }
+
private:
//Can be static because different displays returne the same handle
static EGLDisplay ms_eglDisplay;
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 09054b9eb9..5695ef433a 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -122,6 +122,17 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
if (!paramList.contains(QLatin1String("no-fullscreen"))) {
options |= QQnxIntegration::FullScreenApplication;
}
+
+// On Blackberry the first window is treated as a root window
+#ifdef Q_OS_BLACKBERRY
+ if (!paramList.contains(QLatin1String("no-rootwindow"))) {
+ options |= QQnxIntegration::RootWindow;
+ }
+#else
+ if (paramList.contains(QLatin1String("rootwindow"))) {
+ options |= QQnxIntegration::RootWindow;
+ }
+#endif
return options;
}
@@ -326,9 +337,10 @@ bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
qIntegrationDebug() << Q_FUNC_INFO;
switch (cap) {
+ case MultipleWindows:
case ThreadedPixmaps:
return true;
-#if defined(QT_OPENGL_ES)
+#if !defined(QT_NO_OPENGL)
case OpenGL:
case ThreadedOpenGL:
case BufferQueueingOpenGL:
@@ -343,12 +355,13 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
{
qIntegrationDebug() << Q_FUNC_INFO;
QSurface::SurfaceType surfaceType = window->surfaceType();
+ const bool needRootWindow = options() & RootWindow;
switch (surfaceType) {
case QSurface::RasterSurface:
- return new QQnxRasterWindow(window, m_screenContext);
+ return new QQnxRasterWindow(window, m_screenContext, needRootWindow);
#if !defined(QT_NO_OPENGL)
case QSurface::OpenGLSurface:
- return new QQnxEglWindow(window, m_screenContext);
+ return new QQnxEglWindow(window, m_screenContext, needRootWindow);
#endif
default:
qFatal("QQnxWindow: unsupported window API");
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index ab0d6a3156..8b5614fe4f 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -84,7 +84,8 @@ class QQnxIntegration : public QPlatformIntegration
public:
enum Option { // Options to be passed on command line.
NoOptions = 0x0,
- FullScreenApplication = 0x1
+ FullScreenApplication = 0x1,
+ RootWindow = 0x2
};
Q_DECLARE_FLAGS(Options, Option)
explicit QQnxIntegration(const QStringList &paramList);
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index 4dd3444832..6e7fc35a82 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -41,8 +41,11 @@
#include "qqnxnativeinterface.h"
+#include "qqnxglcontext.h"
#include "qqnxscreen.h"
+#include "qqnxwindow.h"
+#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
@@ -70,4 +73,20 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
return 0;
}
+void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ if (resource == "eglcontext" && context)
+ return static_cast<QQnxGLContext*>(context->handle())->getEglContext();
+
+ return 0;
+}
+
+void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
+{
+ if (name == QStringLiteral("mmRendererWindowName")) {
+ QQnxWindow *qnxWindow = static_cast<QQnxWindow*>(window);
+ qnxWindow->setMMRendererWindowName(value.toString());
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h
index 6692da2576..dfd386214e 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.h
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h
@@ -51,6 +51,8 @@ class QQnxNativeInterface : public QPlatformNativeInterface
public:
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
index 16ff9d7519..1f974b268d 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
@@ -54,8 +54,8 @@
QT_BEGIN_NAMESPACE
-QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context) :
- QQnxWindow(window, context),
+QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
+ QQnxWindow(window, context, needRootWindow),
m_currentBufferIndex(-1),
m_previousBufferIndex(-1)
{
@@ -115,9 +115,6 @@ void QQnxRasterWindow::post(const QRegion &dirty)
// Save modified region and clear scrolled region
m_previousDirty = dirty;
m_scrolled = QRegion();
- // Notify screen that window posted
- if (screen() != 0)
- screen()->onWindowPost(this);
if (m_cover)
m_cover->updateCover();
@@ -169,6 +166,15 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer()
return m_buffers[m_currentBufferIndex];
}
+void QQnxRasterWindow::adjustBufferSize()
+{
+ // When having a raster window we don't need any buffers, since
+ // Qt will draw to the parent TLW backing store.
+ const QSize windowSize = m_parentWindow ? QSize(1,1) : window()->size();
+ if (windowSize != bufferSize())
+ setBufferSize(windowSize);
+}
+
int QQnxRasterWindow::pixelFormat() const
{
return screen()->nativeFormat();
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.h b/src/plugins/platforms/qnx/qqnxrasterwindow.h
index 8bd42bc320..ad34b3ccf2 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.h
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.h
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
class QQnxRasterWindow : public QQnxWindow
{
public:
- QQnxRasterWindow(QWindow *window, screen_context_t context);
+ QQnxRasterWindow(QWindow *window, screen_context_t context, bool needRootWindow);
void post(const QRegion &dirty);
@@ -60,7 +60,7 @@ public:
bool hasBuffers() const { return !bufferSize().isEmpty(); }
- WindowType windowType() const Q_DECL_OVERRIDE { return Raster; }
+ void adjustBufferSize();
protected:
int pixelFormat() const;
@@ -69,6 +69,9 @@ protected:
// Copies content from the previous buffer (back buffer) to the current buffer (front buffer)
void blitPreviousToCurrent(const QRegion &region, int dx, int dy, bool flush=false);
+ void blitHelper(QQnxBuffer &source, QQnxBuffer &target, const QPoint &sourceOffset,
+ const QPoint &targetOffset, const QRegion &region, bool flush = false);
+
private:
QRegion m_previousDirty;
QRegion m_scrolled;
diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.cpp b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
deleted file mode 100644
index b3f5c87176..0000000000
--- a/src/plugins/platforms/qnx/qqnxrootwindow.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2011 - 2012 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxrootwindow.h"
-
-#include "qqnxscreen.h"
-
-#include <QtCore/QUuid>
-#include <QtCore/QDebug>
-
-#if defined(QQNXROOTWINDOW_DEBUG)
-#define qRootWindowDebug qDebug
-#else
-#define qRootWindowDebug QT_NO_QDEBUG_MACRO
-#endif
-
-#include <errno.h>
-#include <unistd.h>
-
-static const int MAGIC_ZORDER_FOR_NO_NAV = 10;
-
-QQnxRootWindow::QQnxRootWindow(const QQnxScreen *screen)
- : m_screen(screen),
- m_window(0),
- m_windowGroupName(),
- m_translucent(false)
-{
- qRootWindowDebug() << Q_FUNC_INFO;
- // Create one top-level QNX window to act as a container for child windows
- // since navigator only supports one application window
- errno = 0;
- int result = screen_create_window(&m_window, m_screen->nativeContext());
- int val[2];
- if (result != 0)
- qFatal("QQnxRootWindow: failed to create window, errno=%d", errno);
-
- // Move window to proper display
- errno = 0;
- screen_display_t display = m_screen->nativeDisplay();
- result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window display, errno=%d", errno);
-
- // Make sure window is above navigator but below keyboard if running as root
- // since navigator won't automatically set our z-order in this case
- if (getuid() == 0) {
- errno = 0;
- val[0] = MAGIC_ZORDER_FOR_NO_NAV;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window z-order, errno=%d", errno);
- }
-
- // Window won't be visible unless it has some buffers so make one dummy buffer that is 1x1
- errno = 0;
- val[0] = SCREEN_USAGE_NATIVE;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window buffer usage, errno=%d", errno);
-
- errno = 0;
- val[0] = m_screen->nativeFormat();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window pixel format, errno=%d", errno);
-
- errno = 0;
- val[0] = 1;
- val[1] = 1;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window buffer size, errno=%d", errno);
-
- errno = 0;
- result = screen_create_window_buffers(m_window, 1);
- if (result != 0)
- qFatal("QQNX: failed to create window buffer, errno=%d", errno);
-
- // Window is always the size of the display
- errno = 0;
- QRect geometry = m_screen->geometry();
- val[0] = geometry.width();
- val[1] = geometry.height();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window size, errno=%d", errno);
-
- // Fill the window with solid black. Note that the LSB of the pixel value
- // 0x00000000 just happens to be 0x00, so if and when this root window's
- // alpha blending mode is changed from None to Source-Over, it will then
- // be interpreted as transparent.
- errno = 0;
- val[0] = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_COLOR, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window colour, errno=%d", errno);
-
- // Make the window opaque
- errno = 0;
- val[0] = SCREEN_TRANSPARENCY_NONE;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window transparency, errno=%d", errno);
-
- // Set the swap interval to 1
- errno = 0;
- val[0] = 1;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window swap interval, errno=%d", errno);
-
- // Set viewport size equal to window size but move outside buffer so the fill colour is used exclusively
- errno = 0;
- val[0] = geometry.width();
- val[1] = geometry.height();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window source size, errno=%d", errno);
-
- errno = 0;
- val[0] = 0;
- val[1] = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_POSITION, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window source position, errno=%d", errno);
-
- // Optionally disable the screen power save
- bool ok = false;
- const int disablePowerSave = qgetenv("QQNX_DISABLE_POWER_SAVE").toInt(&ok);
- if (ok && disablePowerSave) {
- const int mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_IDLE_MODE, &mode);
- if (result != 0)
- qWarning("QQnxRootWindow: failed to disable power saving mode");
- }
-
- createWindowGroup();
-
- // Don't post yet. This will be lazily done from QQnxScreen upon first posting of
- // a child window. Doing it now pre-emptively would create a flicker if one of
- // the QWindow's about to be created sets its Qt::WA_TranslucentBackground flag
- // and immediately triggers the buffer re-creation in makeTranslucent().
-}
-
-void QQnxRootWindow::makeTranslucent()
-{
- if (m_translucent)
- return;
-
- int result;
-
- errno = 0;
- const int val = SCREEN_TRANSPARENCY_DISCARD;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val);
- if (result != 0) {
- qFatal("QQnxRootWindow: failed to set window transparency, errno=%d", errno);
- }
-
- m_translucent = true;
- post();
-}
-
-QQnxRootWindow::~QQnxRootWindow()
-{
- // Cleanup top-level QNX window
- screen_destroy_window(m_window);
-}
-
-void QQnxRootWindow::post() const
-{
- qRootWindowDebug() << Q_FUNC_INFO;
- errno = 0;
- screen_buffer_t buffer;
- int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&buffer);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to query window buffer, errno=%d", errno);
-
- errno = 0;
- int dirtyRect[] = {0, 0, 1, 1};
- result = screen_post_window(m_window, buffer, 1, dirtyRect, 0);
- if (result != 0)
- qFatal("QQNX: failed to post window buffer, errno=%d", errno);
-}
-
-void QQnxRootWindow::flush() const
-{
- qRootWindowDebug() << Q_FUNC_INFO;
- // Force immediate display update
- errno = 0;
- int result = screen_flush_context(m_screen->nativeContext(), 0);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to flush context, errno=%d", errno);
-}
-
-void QQnxRootWindow::setRotation(int rotation)
-{
- qRootWindowDebug() << Q_FUNC_INFO << "angle =" << rotation;
- errno = 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno);
-}
-
-void QQnxRootWindow::resize(const QSize &size)
-{
- errno = 0;
- int val[] = {size.width(), size.height()};
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window size, errno=%d", errno);
-
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window source size, errno=%d", errno);
-
- // NOTE: display will update when child windows relayout and repaint
-}
-
-void QQnxRootWindow::createWindowGroup()
-{
- // Generate a random window group name
- m_windowGroupName = QUuid::createUuid().toString().toLatin1();
-
- // Create window group so child windows can be parented by container window
- errno = 0;
- int result = screen_create_window_group(m_window, m_windowGroupName.constData());
- if (result != 0)
- qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno);
-}
diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.h b/src/plugins/platforms/qnx/qqnxrootwindow.h
deleted file mode 100644
index ea7c7faace..0000000000
--- a/src/plugins/platforms/qnx/qqnxrootwindow.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2011 - 2012 Research In Motion
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXROOTWINDOW_H
-#define QQNXROOTWINDOW_H
-
-#include <QtCore/QByteArray>
-#include <QtCore/QRect>
-
-#include <screen/screen.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQnxScreen;
-
-class QQnxRootWindow
-{
-public:
- QQnxRootWindow(const QQnxScreen *screen);
- ~QQnxRootWindow();
-
- screen_window_t nativeHandle() const { return m_window; }
-
- void post() const;
- void flush() const;
-
- void setRotation(int rotation);
-
- void resize(const QSize &size);
-
- void makeTranslucent();
-
- QByteArray groupName() const { return m_windowGroupName; }
-
-private:
- void createWindowGroup();
-
- const QQnxScreen *m_screen;
- screen_window_t m_window;
- QByteArray m_windowGroupName;
-
- bool m_translucent;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXROOTWINDOW_H
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index dd8cf2131a..a09d6ce1f5 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -119,11 +119,43 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
#endif
}
+static QQnxWindow *findMultimediaWindow(const QList<QQnxWindow*> windows,
+ const QByteArray &mmWindowId)
+{
+ Q_FOREACH (QQnxWindow *sibling, windows) {
+ if (sibling->mmRendererWindowName() == mmWindowId)
+ return sibling;
+
+ QQnxWindow *mmWindow = findMultimediaWindow(sibling->children(), mmWindowId);
+
+ if (mmWindow)
+ return mmWindow;
+ }
+
+ return 0;
+}
+
+static QQnxWindow *findMultimediaWindow(const QList<QQnxWindow*> windows,
+ screen_window_t mmWindowId)
+{
+ Q_FOREACH (QQnxWindow *sibling, windows) {
+ if (sibling->mmRendererWindow() == mmWindowId)
+ return sibling;
+
+ QQnxWindow *mmWindow = findMultimediaWindow(sibling->children(), mmWindowId);
+
+ if (mmWindow)
+ return mmWindow;
+ }
+
+ return 0;
+}
+
QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen)
: m_screenContext(screenContext),
m_display(display),
+ m_rootWindow(0),
m_primaryScreen(primaryScreen),
- m_posted(false),
m_keyboardHeight(0),
m_nativeOrientation(Qt::PrimaryOrientation),
m_coverWindow(0),
@@ -260,7 +292,8 @@ void QQnxScreen::setRotation(int rotation)
{
qScreenDebug() << Q_FUNC_INFO << "orientation =" << rotation;
// Check if rotation changed
- if (m_currentRotation != rotation) {
+ // We only want to rotate if we are the primary screen
+ if (m_currentRotation != rotation && isPrimaryScreen()) {
// Update rotation of root window
if (rootWindow())
rootWindow()->setRotation(rotation);
@@ -280,15 +313,13 @@ void QQnxScreen::setRotation(int rotation)
if (isOrthogonal(m_currentRotation, rotation)) {
qScreenDebug() << Q_FUNC_INFO << "resize, size =" << m_currentGeometry.size();
if (rootWindow())
- rootWindow()->resize(m_currentGeometry.size());
+ rootWindow()->setGeometry(QRect(QPoint(0,0), m_currentGeometry.size()));
- if (m_primaryScreen)
- resizeWindows(previousScreenGeometry);
+ resizeWindows(previousScreenGeometry);
} else {
// TODO: Find one global place to flush display updates
// Force immediate display update if no geometry changes required
- if (rootWindow())
- rootWindow()->flush();
+ screen_flush_context(nativeContext(), 0);
}
// Save new rotation
@@ -458,6 +489,8 @@ void QQnxScreen::removeWindow(QQnxWindow *window)
if (window != m_coverWindow) {
const int numWindowsRemoved = m_childWindows.removeAll(window);
+ if (window == m_rootWindow) //We just removed the root window
+ m_rootWindow = 0; //TODO we need a new root window ;)
if (numWindowsRemoved > 0)
updateHierarchy();
} else {
@@ -493,13 +526,15 @@ void QQnxScreen::updateHierarchy()
QList<QQnxWindow*>::const_iterator it;
int result;
- int topZorder;
+ int topZorder = 0;
errno = 0;
- if (isPrimaryScreen()) {
+ if (rootWindow()) {
result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder);
- if (result != 0)
- qFatal("QQnxScreen: failed to query root window z-order, errno=%d", errno);
+ if (result != 0) { //This can happen if we use winId in QWidgets
+ topZorder = 10;
+ qWarning("QQnxScreen: failed to query root window z-order, errno=%d", errno);
+ }
} else {
topZorder = 0; //We do not need z ordering on the secondary screen, because only one window
//is supported there
@@ -507,16 +542,17 @@ void QQnxScreen::updateHierarchy()
topZorder++; // root window has the lowest z-order in the windowgroup
+ int underlayZorder = -1;
// Underlays sit immediately above the root window in the z-ordering
Q_FOREACH (screen_window_t underlay, m_underlays) {
// Do nothing when this fails. This can happen if we have stale windows in m_underlays,
// which in turn can happen because a window was removed but we didn't get a notification
// yet.
- screen_set_window_property_iv(underlay, SCREEN_PROPERTY_ZORDER, &topZorder);
- topZorder++;
+ screen_set_window_property_iv(underlay, SCREEN_PROPERTY_ZORDER, &underlayZorder);
+ underlayZorder--;
}
- // Normal Qt windows come next above underlays in the z-ordering
+ // Normal Qt windows come next above the root window z-ordering
for (it = m_childWindows.constBegin(); it != m_childWindows.constEnd(); ++it)
(*it)->updateZorder(topZorder);
@@ -532,20 +568,6 @@ void QQnxScreen::updateHierarchy()
screen_flush_context( m_screenContext, 0 );
}
-void QQnxScreen::onWindowPost(QQnxWindow *window)
-{
- qScreenDebug() << Q_FUNC_INFO;
- Q_UNUSED(window)
-
- // post app window (so navigator will show it) after first child window
- // has posted; this only needs to happen once as the app window's content
- // never changes
- if (!m_posted && rootWindow()) {
- rootWindow()->post();
- m_posted = true;
- }
-}
-
void QQnxScreen::adjustOrientation()
{
if (!m_primaryScreen)
@@ -585,6 +607,19 @@ void QQnxScreen::addUnderlayWindow(screen_window_t window)
updateHierarchy();
}
+void QQnxScreen::addMultimediaWindow(const QByteArray &id, screen_window_t window)
+{
+ // find the QnxWindow this mmrenderer window is related to
+ QQnxWindow *mmWindow = findMultimediaWindow(m_childWindows, id);
+
+ if (!mmWindow)
+ return;
+
+ mmWindow->setMMRendererWindow(window);
+
+ updateHierarchy();
+}
+
void QQnxScreen::removeOverlayOrUnderlayWindow(screen_window_t window)
{
const int numRemoved = m_overlays.removeAll(window) + m_underlays.removeAll(window);
@@ -610,17 +645,35 @@ void QQnxScreen::newWindowCreated(void *window)
zorder = 0;
}
+ char windowNameBuffer[256] = { 0 };
+ QByteArray windowName;
+
+ if (screen_get_window_property_cv(windowHandle, SCREEN_PROPERTY_ID_STRING,
+ sizeof(windowNameBuffer) - 1, windowNameBuffer) != 0) {
+ qWarning("QQnx: Failed to get id for window, errno=%d", errno);
+ }
+
+ windowName = QByteArray(windowNameBuffer);
+
if (display == nativeDisplay()) {
// A window was created on this screen. If we don't know about this window yet, it means
// it was not created by Qt, but by some foreign library like the multimedia renderer, which
// creates an overlay window when playing a video.
//
- // Treat all foreign windows as overlays or underlays here.
+ // Treat all foreign windows as overlays, underlays or as windows
+ // created by the BlackBerry QtMultimedia plugin.
+ //
+ // In the case of the BlackBerry QtMultimedia plugin, we need to
+ // "attach" the foreign created mmrenderer window to the correct
+ // platform window (usually the one belonging to QVideoWidget) to
+ // ensure proper z-ordering.
//
- // Assume that if a foreign window already has a Z-Order both negative and
+ // Otherwise, assume that if a foreign window already has a Z-Order both negative and
// less than the default Z-Order installed by mmrender on windows it creates,
// the windows should be treated as an underlay. Otherwise, we treat it as an overlay.
- if (!findWindow(windowHandle)) {
+ if (!windowName.isEmpty() && windowName.startsWith("BbVideoWindowControl")) {
+ addMultimediaWindow(windowName, windowHandle);
+ } else if (!findWindow(windowHandle)) {
if (zorder <= MAX_UNDERLAY_ZORDER)
addUnderlayWindow(windowHandle);
else
@@ -634,7 +687,13 @@ void QQnxScreen::windowClosed(void *window)
{
Q_ASSERT(thread() == QThread::currentThread());
const screen_window_t windowHandle = reinterpret_cast<screen_window_t>(window);
- removeOverlayOrUnderlayWindow(windowHandle);
+
+ QQnxWindow *mmWindow = findMultimediaWindow(m_childWindows, windowHandle);
+
+ if (mmWindow)
+ mmWindow->clearMMRendererWindow();
+ else
+ removeOverlayOrUnderlayWindow(windowHandle);
}
void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState state)
@@ -644,7 +703,7 @@ void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState s
if (!rootWindow() || id != rootWindow()->groupName())
return;
- QWindow * const window = topMostChildWindow();
+ QWindow * const window = rootWindow()->window();
if (!window)
return;
@@ -659,7 +718,7 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id)
if (!rootWindow() || id != rootWindow()->groupName())
return;
- QWindow * const window = topMostChildWindow();
+ QWindow * const window = rootWindow()->window();
if (!window)
return;
@@ -686,18 +745,28 @@ void QQnxScreen::deactivateWindowGroup(const QByteArray &id)
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setExposed(false);
- QWindowSystemInterface::handleWindowActivated(0);
+ QWindowSystemInterface::handleWindowActivated(rootWindow()->window());
}
-QSharedPointer<QQnxRootWindow> QQnxScreen::rootWindow() const
+QQnxWindow *QQnxScreen::rootWindow() const
{
- // We only create the root window if we are the primary display.
- if (m_primaryScreen && !m_rootWindow)
- m_rootWindow = QSharedPointer<QQnxRootWindow>(new QQnxRootWindow(this));
-
return m_rootWindow;
}
+void QQnxScreen::setRootWindow(QQnxWindow *window)
+{
+ // Optionally disable the screen power save
+ bool ok = false;
+ const int disablePowerSave = qgetenv("QQNX_DISABLE_POWER_SAVE").toInt(&ok);
+ if (ok && disablePowerSave) {
+ const int mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
+ int result = screen_set_window_property_iv(window->nativeHandle(), SCREEN_PROPERTY_IDLE_MODE, &mode);
+ if (result != 0)
+ qWarning("QQnxRootWindow: failed to disable power saving mode");
+ }
+ m_rootWindow = window;
+}
+
QWindow * QQnxScreen::topMostChildWindow() const
{
if (!m_childWindows.isEmpty()) {
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index e11030ea0a..61c47e6c72 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -44,7 +44,7 @@
#include <qpa/qplatformscreen.h>
-#include "qqnxrootwindow.h"
+#include "qqnxwindow.h"
#include <QtCore/QObject>
#include <QtCore/QScopedPointer>
@@ -91,10 +91,10 @@ public:
void lowerWindow(QQnxWindow *window);
void updateHierarchy();
- void onWindowPost(QQnxWindow *window);
void adjustOrientation();
- QSharedPointer<QQnxRootWindow> rootWindow() const;
+ QQnxWindow *rootWindow() const;
+ void setRootWindow(QQnxWindow*);
QPlatformCursor *cursor() const;
@@ -119,15 +119,15 @@ private:
void resizeWindows(const QRect &previousScreenGeometry);
void addOverlayWindow(screen_window_t window);
void addUnderlayWindow(screen_window_t window);
+ void addMultimediaWindow(const QByteArray &id, screen_window_t window);
void removeOverlayOrUnderlayWindow(screen_window_t window);
QWindow *topMostChildWindow() const;
screen_context_t m_screenContext;
screen_display_t m_display;
- mutable QSharedPointer<QQnxRootWindow> m_rootWindow;
+ QQnxWindow *m_rootWindow;
const bool m_primaryScreen;
- bool m_posted;
int m_initialRotation;
int m_currentRotation;
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index a5d6db0985..37071d825c 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include "qqnxscreeneventhandler.h"
+#if defined(QQNX_SCREENEVENTTHREAD)
+#include "qqnxscreeneventthread.h"
+#endif
#include "qqnxintegration.h"
#include "qqnxkeytranslator.h"
#include "qqnxscreen.h"
@@ -64,6 +67,9 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
, m_lastButtonState(Qt::NoButton)
, m_lastMouseWindow(0)
, m_touchDevice(0)
+#if defined(QQNX_SCREENEVENTTHREAD)
+ , m_eventThread(0)
+#endif
{
// Create a touch device
m_touchDevice = new QTouchDevice;
@@ -136,6 +142,10 @@ bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
handleDisplayEvent(event);
break;
+ case SCREEN_EVENT_PROPERTY:
+ handlePropertyEvent(event);
+ break;
+
default:
// event ignored
qScreenEventDebug() << Q_FUNC_INFO << "unknown event" << qnxType;
@@ -189,6 +199,43 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie
}
}
+#if defined(QQNX_SCREENEVENTTHREAD)
+void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread)
+{
+ m_eventThread = eventThread;
+}
+
+void QQnxScreenEventHandler::processEventsFromScreenThread()
+{
+ if (!m_eventThread)
+ return;
+
+ QQnxScreenEventArray *events = m_eventThread->lock();
+
+ for (int i = 0; i < events->size(); ++i) {
+ screen_event_t event = events->at(i);
+ if (!event)
+ continue;
+ (*events)[i] = 0;
+
+ m_eventThread->unlock();
+
+ 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();
+}
+#endif
+
void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
{
// get flags of key event
@@ -412,11 +459,20 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
if (w) {
// get size of screen which contains window
QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w);
- QSizeF screenSize = platformScreen->physicalSize();
+ QSizeF screenSize = platformScreen->geometry().size();
// update cached position of current touch point
- m_touchPoints[touchId].normalPosition = QPointF( static_cast<qreal>(pos[0]) / screenSize.width(), static_cast<qreal>(pos[1]) / screenSize.height() );
- m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 );
+ m_touchPoints[touchId].normalPosition =
+ QPointF(static_cast<qreal>(pos[0]) / screenSize.width(),
+ static_cast<qreal>(pos[1]) / screenSize.height());
+
+ m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0],
+ w->geometry().top() + windowPos[1], 0.0, 0.0);
+ QWindow *parent = w->parent();
+ while (parent) {
+ m_touchPoints[touchId].area.translate(parent->geometry().topLeft());
+ parent = parent->parent();
+ }
// determine event type and update state of current touch point
QEvent::Type type = QEvent::None;
@@ -451,8 +507,8 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
// inject event into Qt
QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList);
qScreenEventDebug() << Q_FUNC_INFO << "Qt touch, w =" << w
- << ", p=(" << pos[0] << "," << pos[1]
- << "), t=" << type;
+ << ", p=" << m_touchPoints[touchId].area.topLeft()
+ << ", t=" << type;
}
}
}
@@ -523,6 +579,48 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event)
}
}
+void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
+{
+ errno = 0;
+ int objectType;
+ if (screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType) != 0)
+ qFatal("QQNX: failed to query object type property, errno=%d", errno);
+
+ if (objectType != SCREEN_OBJECT_TYPE_WINDOW)
+ return;
+
+ errno = 0;
+ screen_window_t window = 0;
+ if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
+ qFatal("QQnx: failed to query window property, errno=%d", errno);
+
+ errno = 0;
+ int property;
+ if (screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0)
+ qFatal("QQnx: failed to query window property, errno=%d", errno);
+
+ switch (property) {
+ case SCREEN_PROPERTY_KEYBOARD_FOCUS:
+ handleKeyboardFocusPropertyEvent(window);
+ break;
+ default:
+ // event ignored
+ qScreenEventDebug() << Q_FUNC_INFO << "Ignore property event for property: " << property;
+ }
+}
+
+void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t window)
+{
+ errno = 0;
+ int focus = 0;
+ if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0)
+ qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno);
+
+ QWindow *w = focus ? QQnxIntegration::window(window) : 0;
+
+ QWindowSystemInterface::handleWindowActivated(w);
+}
+
#include "moc_qqnxscreeneventhandler.cpp"
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index af0b086eb8..a7bcd449ee 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -50,6 +50,9 @@ QT_BEGIN_NAMESPACE
class QQnxIntegration;
class QQnxScreenEventFilter;
+#if defined(QQNX_SCREENEVENTTHREAD)
+class QQnxScreenEventThread;
+#endif
class QQnxScreenEventHandler : public QObject
{
@@ -65,10 +68,19 @@ public:
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
+#if defined(QQNX_SCREENEVENTTHREAD)
+ void setScreenEventThread(QQnxScreenEventThread *eventThread);
+#endif
+
Q_SIGNALS:
void newWindowCreated(void *window);
void windowClosed(void *window);
+#if defined(QQNX_SCREENEVENTTHREAD)
+private Q_SLOTS:
+ void processEventsFromScreenThread();
+#endif
+
private:
void handleKeyboardEvent(screen_event_t event);
void handlePointerEvent(screen_event_t event);
@@ -76,6 +88,8 @@ private:
void handleCloseEvent(screen_event_t event);
void handleCreateEvent(screen_event_t event);
void handleDisplayEvent(screen_event_t event);
+ void handlePropertyEvent(screen_event_t event);
+ void handleKeyboardFocusPropertyEvent(screen_window_t window);
private:
enum {
@@ -90,6 +104,9 @@ private:
QTouchDevice *m_touchDevice;
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
QList<QQnxScreenEventFilter*> m_eventFilters;
+#if defined(QQNX_SCREENEVENTTHREAD)
+ QQnxScreenEventThread *m_eventThread;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index f3f660bc03..25a597bab9 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -61,6 +61,9 @@ QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context, QQnxScree
m_screenEventHandler(screenEventHandler),
m_quit(false)
{
+ screenEventHandler->setScreenEventThread(this);
+ connect(this, SIGNAL(eventPending()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection);
+ connect(this, SIGNAL(finished()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection);
}
QQnxScreenEventThread::~QQnxScreenEventThread()
@@ -74,20 +77,31 @@ void QQnxScreenEventThread::injectKeyboardEvent(int flags, int sym, int mod, int
QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap);
}
-void QQnxScreenEventThread::run()
+QQnxScreenEventArray *QQnxScreenEventThread::lock()
{
- screen_event_t event;
+ m_mutex.lock();
+ return &m_events;
+}
- // create screen event
- errno = 0;
- int result = screen_create_event(&event);
- if (result)
- qFatal("QQNX: failed to create screen event, errno=%d", errno);
+void QQnxScreenEventThread::unlock()
+{
+ m_mutex.unlock();
+}
+void QQnxScreenEventThread::run()
+{
qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread started";
// loop indefinitely
while (!m_quit) {
+ screen_event_t event;
+
+ // create screen event
+ errno = 0;
+ int result = screen_create_event(&event);
+ if (result)
+ qFatal("QQNX: failed to create screen event, errno=%d", errno);
+
// block until screen event is available
errno = 0;
@@ -108,14 +122,22 @@ void QQnxScreenEventThread::run()
qScreenEventThreadDebug() << Q_FUNC_INFO << "QNX user screen event";
m_quit = true;
} else {
- m_screenEventHandler->handleEvent(event, qnxType);
+ m_mutex.lock();
+ m_events << event;
+ m_mutex.unlock();
+ emit eventPending();
}
}
qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread stopped";
// cleanup
- screen_destroy_event(event);
+ m_mutex.lock();
+ Q_FOREACH (screen_event_t event, m_events) {
+ screen_destroy_event(event);
+ }
+ m_events.clear();
+ m_mutex.unlock();
}
void QQnxScreenEventThread::shutdown()
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.h b/src/plugins/platforms/qnx/qqnxscreeneventthread.h
index 5e931819be..cbdb505b3b 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.h
@@ -43,6 +43,7 @@
#define QQNXSCREENEVENTTHREAD_H
#include <QtCore/QThread>
+#include <QtCore/QMutex>
#include <screen/screen.h>
@@ -50,21 +51,33 @@ 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();
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
+ QQnxScreenEventArray *lock();
+ void unlock();
+
protected:
void run();
+Q_SIGNALS:
+ void eventPending();
+
private:
void shutdown();
screen_context_t m_screenContext;
+ QMutex m_mutex;
+ QQnxScreenEventArray m_events;
QQnxScreenEventHandler *m_screenEventHandler;
bool m_quit;
};
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 3969a09098..b25c0b5b29 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,15 +40,16 @@
****************************************************************************/
#include "qqnxwindow.h"
-#if !defined(QT_NO_OPENGL)
-#include "qqnxglcontext.h"
-#endif
#include "qqnxintegration.h"
#include "qqnxscreen.h"
+#include <QUuid>
+
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
+#include "private/qguiapplication_p.h"
+
#include <QtCore/QDebug>
#if defined(Q_OS_BLACKBERRY)
@@ -69,26 +70,36 @@
QT_BEGIN_NAMESPACE
-QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
+QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow)
: QPlatformWindow(window),
m_screenContext(context),
+ m_parentWindow(0),
m_window(0),
m_screen(0),
- m_parentWindow(0),
m_visible(false),
m_exposed(true),
- m_windowState(Qt::WindowNoState)
+ m_windowState(Qt::WindowNoState),
+ m_mmRendererWindow(0)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
int result;
- // Create child QNX window
+ QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle());
+
+ m_isTopLevel = ( needRootWindow && !platformScreen->rootWindow())
+ || (!needRootWindow && !parent())
+ || window->type() == Qt::CoverWindow;
+
errno = 0;
- if (static_cast<QQnxScreen *>(window->screen()->handle())->isPrimaryScreen()
- && window->type() != Qt::CoverWindow) {
- result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ if (m_isTopLevel) {
+ result = screen_create_window(&m_window, m_screenContext); // Creates an application window
+ if (window->type() != Qt::CoverWindow) {
+ if (needRootWindow)
+ platformScreen->setRootWindow(this);
+ createWindowGroup();
+ }
} else {
- result = screen_create_window(&m_window, m_screenContext);
+ result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
}
if (result != 0)
qFatal("QQnxWindow: failed to create window, errno=%d", errno);
@@ -115,20 +126,24 @@ QQnxWindow::~QQnxWindow()
void QQnxWindow::setGeometry(const QRect &rect)
{
- const QRect oldGeometry = setGeometryHelper(rect);
+ QRect newGeometry = rect;
+ if (screen()->rootWindow() == this) //If this is the root window, it has to be shown fullscreen
+ newGeometry = screen()->geometry();
+
+ const QRect oldGeometry = setGeometryHelper(newGeometry);
// Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget).
// Calling flushWindowSystemEvents() here would flush input events which
// could result in re-entering QQnxWindow::setGeometry() again.
QWindowSystemInterface::setSynchronousWindowsSystemEvents(true);
- QWindowSystemInterface::handleGeometryChange(window(), rect);
- QWindowSystemInterface::handleExposeEvent(window(), rect);
+ QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
+ QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
// Now move all children.
if (!oldGeometry.isEmpty()) {
- const QPoint offset = rect.topLeft() - oldGeometry.topLeft();
+ const QPoint offset = newGeometry.topLeft() - oldGeometry.topLeft();
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setOffset(offset);
}
@@ -262,16 +277,6 @@ bool QQnxWindow::isExposed() const
return m_visible && m_exposed;
}
-void QQnxWindow::adjustBufferSize()
-{
- if (m_parentWindow)
- return;
-
- const QSize windowSize = window()->size();
- if (windowSize != bufferSize())
- setBufferSize(windowSize);
-}
-
void QQnxWindow::setBufferSize(const QSize &size)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
@@ -290,6 +295,8 @@ void QQnxWindow::setBufferSize(const QSize &size)
// Create window buffers if they do not exist
if (m_bufferSize.isEmpty()) {
val[0] = pixelFormat();
+ if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede
+ return;
errno = 0;
result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
@@ -303,12 +310,6 @@ void QQnxWindow::setBufferSize(const QSize &size)
qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno);
}
- // If the child window has been configured for transparency, lazily create
- // a full-screen buffer to back the root window.
- if (window()->requestedFormat().hasAlpha()) {
- m_screen->rootWindow()->makeTranslucent();
- }
-
// check if there are any buffers available
int bufferCount = 0;
result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount);
@@ -333,6 +334,9 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (platformScreen == 0) { // The screen has been destroyed
m_screen = 0;
+ Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
+ childWindow->setScreen(0);
+ }
return;
}
@@ -342,26 +346,36 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (m_screen) {
qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen";
m_screen->removeWindow(this);
- screen_leave_window_group(m_window);
+ QQnxIntegration *platformIntegration = static_cast<QQnxIntegration*>(QGuiApplicationPrivate::platformIntegration());
+
+ if ((platformIntegration->options() & QQnxIntegration::RootWindow)) {
+ screen_leave_window_group(m_window);
+ }
}
- platformScreen->addWindow(this);
m_screen = platformScreen;
-
- // Move window to proper screen/display
- errno = 0;
- screen_display_t display = platformScreen->nativeDisplay();
- int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
-
-
- if (m_screen->isPrimaryScreen() && window()->type() != Qt::CoverWindow) {
- // Add window to display's window group
+ if (!m_parentWindow) {
+ platformScreen->addWindow(this);
+ }
+ if (m_isTopLevel) {
+ // Move window to proper screen/display
errno = 0;
- result = screen_join_window_group(m_window, platformScreen->windowGroupName());
+ screen_display_t display = platformScreen->nativeDisplay();
+ int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
+ qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
+ } else {
+ errno = 0;
+ int result;
+ if (!parent()) {
+ result = screen_join_window_group(m_window, platformScreen->windowGroupName());
+ if (result != 0)
+ qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
+ } else {
+ result = screen_join_window_group(m_window, static_cast<QQnxWindow*>(parent())->groupName().constData());
+ if (result != 0)
+ qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
+ }
Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
// Only subwindows and tooltips need necessarily be moved to another display with the window.
@@ -405,20 +419,12 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
setScreen(m_parentWindow->m_screen);
m_parentWindow->m_childWindows.push_back(this);
-
- // we don't need any buffers, since
- // Qt will draw to the parent TLW
- // backing store.
- setBufferSize(QSize(1, 1));
} else {
m_screen->addWindow(this);
-
- // recreate buffers, in case the
- // window has been reparented and
- // becomes a TLW
- adjustBufferSize();
}
+ adjustBufferSize();
+
m_screen->updateHierarchy();
}
@@ -489,6 +495,22 @@ void QQnxWindow::gainedFocus()
QWindowSystemInterface::handleWindowActivated(window());
}
+void QQnxWindow::setMMRendererWindowName(const QString &name)
+{
+ m_mmRendererWindowName = name;
+}
+
+void QQnxWindow::setMMRendererWindow(screen_window_t handle)
+{
+ m_mmRendererWindow = handle;
+}
+
+void QQnxWindow::clearMMRendererWindow()
+{
+ m_mmRendererWindowName.clear();
+ m_mmRendererWindow = 0;
+}
+
QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle)
{
if (m_window == windowHandle)
@@ -524,6 +546,15 @@ void QQnxWindow::minimize()
#endif
}
+void QQnxWindow::setRotation(int rotation)
+{
+ qWindowDebug() << Q_FUNC_INFO << "angle =" << rotation;
+ errno = 0;
+ int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation);
+ if (result != 0)
+ qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno);
+}
+
void QQnxWindow::initWindow()
{
// Alpha channel is always pre-multiplied if present
@@ -577,23 +608,48 @@ void QQnxWindow::initWindow()
setWindowState(window()->windowState());
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
- setGeometryHelper(window()->geometry());
+
+ if (screen()->rootWindow() == this) {
+ setGeometryHelper(screen()->geometry());
+ QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry());
+ } else {
+ setGeometryHelper(window()->geometry());
+ }
}
+void QQnxWindow::createWindowGroup()
+{
+ // Generate a random window group name
+ m_windowGroupName = QUuid::createUuid().toString().toLatin1();
+
+ // Create window group so child windows can be parented by container window
+ errno = 0;
+ int result = screen_create_window_group(m_window, m_windowGroupName.constData());
+ if (result != 0)
+ qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno);
+}
void QQnxWindow::updateZorder(int &topZorder)
{
- errno = 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder);
- topZorder++;
+ updateZorder(m_window, topZorder);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window);
+ if (m_mmRendererWindow)
+ updateZorder(m_mmRendererWindow, topZorder);
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->updateZorder(topZorder);
}
+void QQnxWindow::updateZorder(screen_window_t window, int &topZorder)
+{
+ errno = 0;
+ int result = screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder);
+ topZorder++;
+
+ if (result != 0)
+ qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, window);
+}
+
void QQnxWindow::applyWindowState()
{
switch (m_windowState) {
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index f96280848a..3c8070b0be 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -66,12 +66,7 @@ class QQnxWindow : public QPlatformWindow
{
friend class QQnxScreen;
public:
- enum WindowType {
- EGL,
- Raster
- };
-
- QQnxWindow(QWindow *window, screen_context_t context);
+ QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow);
virtual ~QQnxWindow();
void setGeometry(const QRect &rect);
@@ -83,7 +78,7 @@ public:
WId winId() const { return (WId)m_window; }
screen_window_t nativeHandle() const { return m_window; }
- void adjustBufferSize();
+ virtual void adjustBufferSize() = 0;
void setBufferSize(const QSize &size);
QSize bufferSize() const { return m_bufferSize; }
@@ -99,6 +94,9 @@ public:
void propagateSizeHints();
void gainedFocus();
+ void setMMRendererWindowName(const QString &name);
+ void setMMRendererWindow(screen_window_t handle);
+ void clearMMRendererWindow();
QQnxScreen *screen() const { return m_screen; }
const QList<QQnxWindow*>& children() const { return m_childWindows; }
@@ -107,7 +105,14 @@ public:
void minimize();
- virtual WindowType windowType() const = 0;
+ QString mmRendererWindowName() const { return m_mmRendererWindowName; }
+
+ screen_window_t mmRendererWindow() const { return m_mmRendererWindow; }
+
+ void setRotation(int rotation);
+
+ QByteArray groupName() const { return m_windowGroupName; }
+
protected:
virtual int pixelFormat() const = 0;
virtual void resetBuffers() = 0;
@@ -117,12 +122,16 @@ protected:
screen_context_t m_screenContext;
QScopedPointer<QQnxAbstractCover> m_cover;
+ QQnxWindow *m_parentWindow;
+
private:
+ void createWindowGroup();
QRect setGeometryHelper(const QRect &rect);
void removeFromParent();
void setOffset(const QPoint &setOffset);
void updateVisibility(bool parentVisible);
void updateZorder(int &topZorder);
+ void updateZorder(screen_window_t window, int &zOrder);
void applyWindowState();
screen_window_t m_window;
@@ -130,11 +139,16 @@ private:
QQnxScreen *m_screen;
QList<QQnxWindow*> m_childWindows;
- QQnxWindow *m_parentWindow;
bool m_visible;
bool m_exposed;
QRect m_unmaximizedGeometry;
Qt::WindowState m_windowState;
+ QString m_mmRendererWindowName;
+ screen_window_t m_mmRendererWindow;
+
+ QByteArray m_windowGroupName;
+
+ bool m_isTopLevel;
};
QT_END_NAMESPACE