diff options
-rw-r--r-- | src/plugins/platforms/qnx/qqnxnativeinterface.cpp | 9 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxnativeinterface.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreen.cpp | 77 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreen.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxwindow.cpp | 37 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxwindow.h | 10 |
6 files changed, 125 insertions, 10 deletions
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index 4dd3444832..8958a5c1e2 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -42,6 +42,7 @@ #include "qqnxnativeinterface.h" #include "qqnxscreen.h" +#include "qqnxwindow.h" #include <QtGui/QScreen> #include <QtGui/QWindow> @@ -70,4 +71,12 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q 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..b61f6a56cc 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.h +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h @@ -51,6 +51,7 @@ class QQnxNativeInterface : public QPlatformNativeInterface public: void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen); + void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index dd8cf2131a..3dab2b3bc9 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -119,6 +119,38 @@ 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), @@ -585,6 +617,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 +655,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. // - // Assume that if a foreign window already has a Z-Order both negative and + // 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. + // + // 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 +697,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) diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index e11030ea0a..014f7905f3 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -119,6 +119,7 @@ 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; diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 3969a09098..749a336fcc 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -77,7 +77,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) 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; @@ -489,6 +490,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) @@ -583,17 +600,25 @@ void QQnxWindow::initWindow() 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..52d22235a2 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -99,6 +99,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,6 +110,10 @@ public: void minimize(); + QString mmRendererWindowName() const { return m_mmRendererWindowName; } + + screen_window_t mmRendererWindow() const { return m_mmRendererWindow; } + virtual WindowType windowType() const = 0; protected: virtual int pixelFormat() const = 0; @@ -123,6 +130,7 @@ private: 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; @@ -135,6 +143,8 @@ private: bool m_exposed; QRect m_unmaximizedGeometry; Qt::WindowState m_windowState; + QString m_mmRendererWindowName; + screen_window_t m_mmRendererWindow; }; QT_END_NAMESPACE |