From 3ca1a2c28ec710183a3853432fe97224fffcdfbf Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 8 Mar 2012 12:49:49 +0100 Subject: Defer window activation if the window hasn't beenn mapped yet. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I60d616fc60d3be9b55ab2599abadede5f7c11f93 Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbwindow.cpp | 8 +++++++- src/plugins/platforms/xcb/qxcbwindow.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 542d7ab69f..055defde08 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -143,6 +143,7 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_syncCounter(0) , m_mapped(false) , m_transparent(false) + , m_deferredActivation(false) , m_netWmUserTimeWindow(XCB_NONE) #if defined(XCB_USE_EGL) , m_eglSurface(0) @@ -1178,8 +1179,11 @@ void QXcbWindow::propagateSizeHints() void QXcbWindow::requestActivateWindow() { - if (!m_mapped) + if (!m_mapped) { + m_deferredActivation = true; return; + } + m_deferredActivation = false; updateNetWmUserTime(connection()->time()); @@ -1334,6 +1338,8 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event) { if (event->window == m_window) { m_mapped = true; + if (m_deferredActivation) + requestActivateWindow(); QWindowSystemInterface::handleMapEvent(window()); } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 6ae55e77e6..c212095e98 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -154,6 +154,7 @@ private: bool m_mapped; bool m_transparent; + bool m_deferredActivation; xcb_window_t m_netWmUserTimeWindow; QSurfaceFormat m_format; -- cgit v1.2.3 From c35d65e27d9232452d2e57973cdb132181440bbf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 8 Mar 2012 16:13:28 +0100 Subject: Windows: Fix flag handling. Fix a typo that caused a variable to be hidden such that the Qt::WindowFlags were not used. Change-Id: Iea4456b0cd4c968e0fbfdd53e5006ffee0298b24 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1edb243f4e..fa3661db22 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -441,17 +441,17 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange) const { if (desktop || !hwnd) return; - UINT flags = SWP_NOMOVE | SWP_NOSIZE; + UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE; if (frameChange) - flags |= SWP_FRAMECHANGED; + swpFlags |= SWP_FRAMECHANGED; if (topLevel) { - flags |= SWP_NOACTIVATE; + swpFlags |= SWP_NOACTIVATE; if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) { - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, swpFlags); if (flags & Qt::WindowStaysOnBottomHint) qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time"; } else if (flags & Qt::WindowStaysOnBottomHint) { - SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, flags); + SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, swpFlags); } if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) { HMENU systemMenu = GetSystemMenu(hwnd, FALSE); @@ -461,7 +461,7 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange) const EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED); } } else { // child. - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags); } } -- cgit v1.2.3 From a0933f4d7485d22f38b80c67f79b8d3f721b19a2 Mon Sep 17 00:00:00 2001 From: Rick Stockton Date: Wed, 7 Mar 2012 16:38:37 -0800 Subject: BlackBerry Plugin: support 8 mouse buttons, instead of just 3. The mask of possible mouse buttons in QNX provides tracking for the up/down State of up to 8 mouse buttons. This update adds support for the 5 buttons which we previously ignored in Qt on this Platform. Task-number: QTBUG-24682 Change-Id: I8c1d2b2a5d0deb3b857fb387c242c3792e21ff95 Reviewed-by: Kevin Krammer Reviewed-by: Robin Burchell --- src/plugins/platforms/blackberry/qbbeventthread.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/blackberry/qbbeventthread.cpp b/src/plugins/platforms/blackberry/qbbeventthread.cpp index 547428d1c4..6951921fe9 100644 --- a/src/plugins/platforms/blackberry/qbbeventthread.cpp +++ b/src/plugins/platforms/blackberry/qbbeventthread.cpp @@ -380,13 +380,26 @@ void QBBEventThread::handlePointerEvent(screen_event_t event) QPoint localPoint(windowPos[0], windowPos[1]); // Convert buttons. + // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit, + // so we may receive events as shown. (If this is wrong, the fix is easy.) + // QNX Button mask is 8 buttons wide, with a maximum value of x080. Qt::MouseButtons buttons = Qt::NoButton; - if (buttonState & 1) + if (buttonState & 0x01) buttons |= Qt::LeftButton; - if (buttonState & 2) + if (buttonState & 0x02) buttons |= Qt::MidButton; - if (buttonState & 4) + if (buttonState & 0x04) buttons |= Qt::RightButton; + if (buttonState & 0x08) + buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton' + if (buttonState & 0x10) + buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton' + if (buttonState & 0x20) + buttons |= Qt::ExtraButton3; + if (buttonState & 0x40) + buttons |= Qt::ExtraButton4; + if (buttonState & 0x80) + buttons |= Qt::ExtraButton5; if (w) { // Inject mouse event into Qt only if something has changed. -- cgit v1.2.3 From 4ba895a863a3468db2fe67beaa7e8b0b386b01dd Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Thu, 8 Mar 2012 11:58:32 +0100 Subject: Fix platforms.pro to match new qnx mkspec name Change-Id: Ib159b519d11c9b88979f0f47b87801552586abc0 Reviewed-by: Friedemann Kleint Reviewed-by: Sean Harmer Reviewed-by: Robin Burchell --- src/plugins/platforms/platforms.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 8f728a5fb0..52d3d83bbc 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -12,6 +12,6 @@ mac { win32: SUBDIRS += windows -blackberry-armv7le-qcc { +qnx-*-qcc { SUBDIRS += blackberry } -- cgit v1.2.3 From d26ef66a660fb7d3e1cb94c863c4076a2ecd8199 Mon Sep 17 00:00:00 2001 From: Donald Carr Date: Tue, 6 Mar 2012 22:35:30 +0000 Subject: Remove widgets dependency from eglfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit eglfs uses the (old) OpenGL paint engine for paint operations. This drags in a QWidget dependency and hence everything bar the kitchen sink. This change gets eglfs buildable without widget support although anything which relies on a QPaintDevice will end up rendering nothing to the screen. (Similar to the QWS simplegl driver) Change-Id: If7fcdb79038ef7568e771402fd1667bc0318ff5f Reviewed-by: Jørgen Lind Reviewed-by: Girish Ramakrishnan --- src/plugins/platforms/eglfs/eglfs.pro | 6 +++++- src/plugins/platforms/eglfs/qeglfsbackingstore.cpp | 21 +++++++++++++++------ src/plugins/platforms/eglfs/qeglfsbackingstore.h | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 8675dc164e..291e09d6ed 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -2,7 +2,11 @@ TARGET = qeglfs TEMPLATE = lib CONFIG += plugin -QT += opengl core-private gui-private opengl-private platformsupport-private widgets-private +QT += core-private gui-private platformsupport-private + +!contains(QT_CONFIG, no-widgets) { + QT += opengl opengl-private widgets-private +} DESTDIR = $$QT.gui.plugins/platforms diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp index 331b768a93..d2e4a47e56 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp @@ -39,17 +39,19 @@ ** ****************************************************************************/ -#include - #include "qeglfsbackingstore.h" +#ifndef QT_NO_WIDGETS +#include +#include +#endif //QT_NO_WIDGETS + #include #include -#include - QT_BEGIN_NAMESPACE +#ifndef QT_NO_WIDGETS class QEglFSPaintDevice : public QGLPaintDevice { public: @@ -73,15 +75,20 @@ private: QEglFSScreen *m_screen; QGLContext *m_context; }; - +#endif //QT_NO_WIDGETS QEglFSBackingStore::QEglFSBackingStore(QWindow *window) - : QPlatformBackingStore(window) + : QPlatformBackingStore(window), + m_paintDevice(0) { #ifdef QEGL_EXTRA_DEBUG qWarning("QEglBackingStore %p, %p", window, window->screen()); #endif +#ifdef QT_NO_WIDGETS + m_paintDevice = new QImage(0,0); +#else m_paintDevice = new QEglFSPaintDevice(static_cast(window->screen()->handle())); +#endif //QT_NO_WIDGETS } void QEglFSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) @@ -92,7 +99,9 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo #ifdef QEGL_EXTRA_DEBUG qWarning("QEglBackingStore::flush %p", window); #endif +#ifndef QT_NO_WIDGETS static_cast(m_paintDevice)->context()->swapBuffers(); +#endif //QT_NO_WIDGETS } void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents) diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h index 5623a96004..1ae3ecdc61 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h @@ -53,7 +53,7 @@ class QEglFSBackingStore : public QPlatformBackingStore { public: QEglFSBackingStore(QWindow *window); - ~QEglFSBackingStore() {} + ~QEglFSBackingStore() { delete m_paintDevice; } QPaintDevice *paintDevice() { return m_paintDevice; } void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); -- cgit v1.2.3 From bbc97c38d5917d8a403719531454ee24cde9c4fe Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 7 Mar 2012 09:57:39 +0100 Subject: misc: Fix some random typos and grammar while reading code. Typos: recieve -> receive descrived -> describe Grammar: this types -> these types Change-Id: Iedacc51a6322996f423ac9472af0a597424a4fed Reviewed-by: Casper van Donderen --- src/plugins/platforms/kms/qkmsdevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp index 01bf1d12be..8d42871401 100644 --- a/src/plugins/platforms/kms/qkmsdevice.cpp +++ b/src/plugins/platforms/kms/qkmsdevice.cpp @@ -127,7 +127,7 @@ void QKmsDevice::createScreens() void QKmsDevice::handlePageFlipCompleted() { - //qDebug() << "Display signal recieved"; + //qDebug() << "Display signal received"; drmEventContext eventContext; memset(&eventContext, 0, sizeof eventContext); -- cgit v1.2.3 From 5368ad604c958fc95683a72631ac47f59316fc26 Mon Sep 17 00:00:00 2001 From: Kevin Krammer Date: Fri, 9 Mar 2012 12:59:48 +0100 Subject: Use qt_safe_read to read from low-level file descriptor Change-Id: I7c7bc379a423be4de471c5972cb98101c90bab8c Reviewed-by: Robin Burchell --- src/plugins/platforms/blackberry/qbbnavigatorthread.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp b/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp index 65cbb77d31..03cf458b80 100644 --- a/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp +++ b/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -257,7 +258,7 @@ void QBBNavigatorThread::readData() // attempt to read pps data errno = 0; - int bytes = read(m_fd, buffer, ppsBufferSize - 1); + int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1); if (bytes == -1) { qFatal("QBB: failed to read navigator pps, errno=%d", errno); } -- cgit v1.2.3 From 472cc7ac27ea552a254b9a56663a8e94082b137a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Mar 2012 14:35:11 +0100 Subject: XCB: Implement native events for for windows. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iacea1231b49ebe57da96f4012d3f314e1b037105 Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbconnection.cpp | 16 ++++++++++++---- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 6 ++++-- src/plugins/platforms/xcb/qxcbnativeinterface.h | 2 ++ 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 367b24da9d..76979bf05f 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -235,16 +235,24 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id) #define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \ { \ event_t *e = (event_t *)event; \ - if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) \ - platformWindow->handler(e); \ + if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) { \ + long result = 0; \ + handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ + if (!handled) \ + platformWindow->handler(e); \ + } \ } \ break; #define HANDLE_KEYBOARD_EVENT(event_t, handler) \ { \ event_t *e = (event_t *)event; \ - if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) \ - m_keyboard->handler(platformWindow, e); \ + if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \ + long result = 0; \ + handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ + if (!handled) \ + m_keyboard->handler(platformWindow, e); \ + } \ } \ break; diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index f56072f9d7..fc320ee69c 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -76,7 +76,9 @@ public: Q_GLOBAL_STATIC(QXcbResourceMap, qXcbResourceMap) -QXcbNativeInterface::QXcbNativeInterface() +QXcbNativeInterface::QXcbNativeInterface() : + m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t")) + { qFill(m_eventFilters, m_eventFilters + EventFilterCount, EventFilter(0)); } @@ -134,7 +136,7 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr QPlatformNativeInterface::EventFilter QXcbNativeInterface::setEventFilter(const QByteArray &eventType, QPlatformNativeInterface::EventFilter filter) { int type = -1; - if (eventType == QByteArrayLiteral("xcb_generic_event_t")) + if (eventType == m_genericEventFilterType) type = GenericEventFilter; if (type == -1) { qWarning("QXcbNativeInterface: %s: Attempt to set invalid event filter type '%s'.", diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 6f6130d3e9..c6835ff9e0 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -71,6 +71,7 @@ public: void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context); void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); + inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; } EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter); EventFilter eventFilter(EventFilterType type) const { return m_eventFilters[type]; } @@ -83,6 +84,7 @@ public: void *eglContextForContext(QOpenGLContext *context); private: + const QByteArray m_genericEventFilterType; EventFilter m_eventFilters[EventFilterCount]; static QXcbScreen *qPlatformScreenForWindow(QWindow *window); -- cgit v1.2.3 From 61692bfefec3f15a2be219bdb29893872a7feadf Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 7 Mar 2012 20:48:06 +0100 Subject: Remove QAccessible2::TableModelChange. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was never a good idea since it has issues: It doesn't really work with more than one update without the client fetching the data. The same is unlikely to work reliable since it involves two ipc roundtrips. Instead we should have an extended QAccessibleEvent that contains the data so that the bridges can decide how to pass on the data if needed. Change-Id: Iaf6b74f49586f7155909a6fe1a17137b71b31175 Reviewed-by: Jan-Arve Sæther --- src/plugins/accessible/widgets/itemviews.cpp | 64 ---------------------------- src/plugins/accessible/widgets/itemviews.h | 11 ----- 2 files changed, 75 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index a9f3a858d2..a2fe2cb7fd 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -156,63 +156,6 @@ QHeaderView *QAccessibleTable::verticalHeader() const return header; } -void QAccessibleTable::modelReset() -{} - -void QAccessibleTable::rowsInserted(const QModelIndex &, int first, int last) -{ - lastChange.firstRow = first; - lastChange.lastRow = last; - lastChange.firstColumn = 0; - lastChange.lastColumn = 0; - lastChange.type = QAccessible2::TableModelChangeInsert; -} - -void QAccessibleTable::rowsRemoved(const QModelIndex &, int first, int last) -{ - lastChange.firstRow = first; - lastChange.lastRow = last; - lastChange.firstColumn = 0; - lastChange.lastColumn = 0; - lastChange.type = QAccessible2::TableModelChangeDelete; -} - -void QAccessibleTable::columnsInserted(const QModelIndex &, int first, int last) -{ - lastChange.firstRow = 0; - lastChange.lastRow = 0; - lastChange.firstColumn = first; - lastChange.lastColumn = last; - lastChange.type = QAccessible2::TableModelChangeInsert; -} - -void QAccessibleTable::columnsRemoved(const QModelIndex &, int first, int last) -{ - lastChange.firstRow = 0; - lastChange.lastRow = 0; - lastChange.firstColumn = first; - lastChange.lastColumn = last; - lastChange.type = QAccessible2::TableModelChangeDelete; -} - -void QAccessibleTable::rowsMoved( const QModelIndex &, int, int, const QModelIndex &, int) -{ - lastChange.firstRow = 0; - lastChange.lastRow = 0; - lastChange.firstColumn = 0; - lastChange.lastColumn = 0; - lastChange.type = QAccessible2::TableModelChangeUpdate; -} - -void QAccessibleTable::columnsMoved( const QModelIndex &, int, int, const QModelIndex &, int) -{ - lastChange.firstRow = 0; - lastChange.lastRow = 0; - lastChange.firstColumn = 0; - lastChange.lastColumn = 0; - lastChange.type = QAccessible2::TableModelChangeUpdate; -} - QAccessibleTableCell *QAccessibleTable::cell(const QModelIndex &index) const { if (index.isValid()) @@ -349,13 +292,6 @@ bool QAccessibleTable::unselectColumn(int column) return true; } -QAccessible2::TableModelChange QAccessibleTable::modelChange() const -{ - QAccessible2::TableModelChange change; - // FIXME - return change; -} - QAccessible::Role QAccessibleTable::role() const { return m_role; diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index 3d852a2377..2672cd4a16 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -88,7 +88,6 @@ public: virtual QString rowDescription(int row) const; virtual int columnCount() const; virtual int rowCount() const; - virtual QAccessible2::TableModelChange modelChange() const; // selection virtual int selectedCellCount() const; @@ -104,18 +103,8 @@ public: virtual bool unselectRow(int row); virtual bool unselectColumn(int column); -protected: - virtual void modelReset(); - virtual void rowsInserted(const QModelIndex &parent, int first, int last); - virtual void rowsRemoved(const QModelIndex &parent, int first, int last); - virtual void columnsInserted(const QModelIndex &parent, int first, int last); - virtual void columnsRemoved(const QModelIndex &parent, int first, int last); - virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row); - virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column); - protected: QAbstractItemView* view; - QAccessible2::TableModelChange lastChange; inline QAccessibleTableCell *cell(const QModelIndex &index) const; inline QAccessible::Role cellRole() const { switch (m_role) { -- cgit v1.2.3 From 9a81e371079d6aab20f6c4a43031857f4172688c Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Fri, 9 Mar 2012 17:21:22 +0000 Subject: Rename blackberry QPA plugin to QNX Changing the naming scheme from Blackberry to QNX in line with pattern of using platform names. Change-Id: I048a6a18010bc932311d63c8dde19ccab97894c8 Reviewed-by: Robin Burchell Reviewed-by: Nicolas Arnaud-Cormos --- src/plugins/platforms/blackberry/blackberry.pro | 71 - src/plugins/platforms/blackberry/main.cpp | 72 - src/plugins/platforms/blackberry/qbbbuffer.cpp | 165 -- src/plugins/platforms/blackberry/qbbbuffer.h | 74 - src/plugins/platforms/blackberry/qbbclipboard.cpp | 244 --- src/plugins/platforms/blackberry/qbbclipboard.h | 66 - .../platforms/blackberry/qbbeventthread.cpp | 572 ------- src/plugins/platforms/blackberry/qbbeventthread.h | 90 -- .../platforms/blackberry/qbbglbackingstore.cpp | 189 --- .../platforms/blackberry/qbbglbackingstore.h | 95 -- src/plugins/platforms/blackberry/qbbglcontext.cpp | 356 ---- src/plugins/platforms/blackberry/qbbglcontext.h | 93 -- .../platforms/blackberry/qbbinputcontext_imf.cpp | 1696 -------------------- .../platforms/blackberry/qbbinputcontext_imf.h | 132 -- .../platforms/blackberry/qbbinputcontext_noimf.cpp | 187 --- .../platforms/blackberry/qbbinputcontext_noimf.h | 84 - .../platforms/blackberry/qbbintegration.cpp | 293 ---- src/plugins/platforms/blackberry/qbbintegration.h | 119 -- .../platforms/blackberry/qbbkeytranslator.h | 269 ---- .../platforms/blackberry/qbbnavigatorthread.cpp | 280 ---- .../platforms/blackberry/qbbnavigatorthread.h | 78 - .../platforms/blackberry/qbbrasterbackingstore.cpp | 166 -- .../platforms/blackberry/qbbrasterbackingstore.h | 81 - src/plugins/platforms/blackberry/qbbrootwindow.cpp | 257 --- src/plugins/platforms/blackberry/qbbrootwindow.h | 81 - src/plugins/platforms/blackberry/qbbscreen.cpp | 315 ---- src/plugins/platforms/blackberry/qbbscreen.h | 121 -- .../platforms/blackberry/qbbvirtualkeyboard.cpp | 500 ------ .../platforms/blackberry/qbbvirtualkeyboard.h | 130 -- src/plugins/platforms/blackberry/qbbwindow.cpp | 665 -------- src/plugins/platforms/blackberry/qbbwindow.h | 133 -- src/plugins/platforms/platforms.pro | 2 +- src/plugins/platforms/qnx/main.cpp | 72 + src/plugins/platforms/qnx/qnx.pro | 71 + src/plugins/platforms/qnx/qqnxbuffer.cpp | 165 ++ src/plugins/platforms/qnx/qqnxbuffer.h | 74 + src/plugins/platforms/qnx/qqnxclipboard.cpp | 244 +++ src/plugins/platforms/qnx/qqnxclipboard.h | 66 + src/plugins/platforms/qnx/qqnxeventthread.cpp | 572 +++++++ src/plugins/platforms/qnx/qqnxeventthread.h | 90 ++ src/plugins/platforms/qnx/qqnxglbackingstore.cpp | 189 +++ src/plugins/platforms/qnx/qqnxglbackingstore.h | 95 ++ src/plugins/platforms/qnx/qqnxglcontext.cpp | 356 ++++ src/plugins/platforms/qnx/qqnxglcontext.h | 93 ++ src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp | 1696 ++++++++++++++++++++ src/plugins/platforms/qnx/qqnxinputcontext_imf.h | 132 ++ .../platforms/qnx/qqnxinputcontext_noimf.cpp | 187 +++ src/plugins/platforms/qnx/qqnxinputcontext_noimf.h | 84 + src/plugins/platforms/qnx/qqnxintegration.cpp | 293 ++++ src/plugins/platforms/qnx/qqnxintegration.h | 119 ++ src/plugins/platforms/qnx/qqnxkeytranslator.h | 269 ++++ src/plugins/platforms/qnx/qqnxnavigatorthread.cpp | 280 ++++ src/plugins/platforms/qnx/qqnxnavigatorthread.h | 78 + .../platforms/qnx/qqnxrasterbackingstore.cpp | 166 ++ src/plugins/platforms/qnx/qqnxrasterbackingstore.h | 81 + src/plugins/platforms/qnx/qqnxrootwindow.cpp | 257 +++ src/plugins/platforms/qnx/qqnxrootwindow.h | 81 + src/plugins/platforms/qnx/qqnxscreen.cpp | 315 ++++ src/plugins/platforms/qnx/qqnxscreen.h | 121 ++ src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp | 500 ++++++ src/plugins/platforms/qnx/qqnxvirtualkeyboard.h | 130 ++ src/plugins/platforms/qnx/qqnxwindow.cpp | 665 ++++++++ src/plugins/platforms/qnx/qqnxwindow.h | 133 ++ 63 files changed, 7675 insertions(+), 7675 deletions(-) delete mode 100644 src/plugins/platforms/blackberry/blackberry.pro delete mode 100644 src/plugins/platforms/blackberry/main.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbbuffer.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbbuffer.h delete mode 100644 src/plugins/platforms/blackberry/qbbclipboard.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbclipboard.h delete mode 100644 src/plugins/platforms/blackberry/qbbeventthread.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbeventthread.h delete mode 100644 src/plugins/platforms/blackberry/qbbglbackingstore.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbglbackingstore.h delete mode 100644 src/plugins/platforms/blackberry/qbbglcontext.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbglcontext.h delete mode 100644 src/plugins/platforms/blackberry/qbbinputcontext_imf.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbinputcontext_imf.h delete mode 100644 src/plugins/platforms/blackberry/qbbinputcontext_noimf.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbinputcontext_noimf.h delete mode 100644 src/plugins/platforms/blackberry/qbbintegration.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbintegration.h delete mode 100644 src/plugins/platforms/blackberry/qbbkeytranslator.h delete mode 100644 src/plugins/platforms/blackberry/qbbnavigatorthread.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbnavigatorthread.h delete mode 100644 src/plugins/platforms/blackberry/qbbrasterbackingstore.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbrasterbackingstore.h delete mode 100644 src/plugins/platforms/blackberry/qbbrootwindow.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbrootwindow.h delete mode 100644 src/plugins/platforms/blackberry/qbbscreen.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbscreen.h delete mode 100644 src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbvirtualkeyboard.h delete mode 100644 src/plugins/platforms/blackberry/qbbwindow.cpp delete mode 100644 src/plugins/platforms/blackberry/qbbwindow.h create mode 100644 src/plugins/platforms/qnx/main.cpp create mode 100644 src/plugins/platforms/qnx/qnx.pro create mode 100644 src/plugins/platforms/qnx/qqnxbuffer.cpp create mode 100644 src/plugins/platforms/qnx/qqnxbuffer.h create mode 100644 src/plugins/platforms/qnx/qqnxclipboard.cpp create mode 100644 src/plugins/platforms/qnx/qqnxclipboard.h create mode 100644 src/plugins/platforms/qnx/qqnxeventthread.cpp create mode 100644 src/plugins/platforms/qnx/qqnxeventthread.h create mode 100644 src/plugins/platforms/qnx/qqnxglbackingstore.cpp create mode 100644 src/plugins/platforms/qnx/qqnxglbackingstore.h create mode 100644 src/plugins/platforms/qnx/qqnxglcontext.cpp create mode 100644 src/plugins/platforms/qnx/qqnxglcontext.h create mode 100644 src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp create mode 100644 src/plugins/platforms/qnx/qqnxinputcontext_imf.h create mode 100644 src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp create mode 100644 src/plugins/platforms/qnx/qqnxinputcontext_noimf.h create mode 100644 src/plugins/platforms/qnx/qqnxintegration.cpp create mode 100644 src/plugins/platforms/qnx/qqnxintegration.h create mode 100644 src/plugins/platforms/qnx/qqnxkeytranslator.h create mode 100644 src/plugins/platforms/qnx/qqnxnavigatorthread.cpp create mode 100644 src/plugins/platforms/qnx/qqnxnavigatorthread.h create mode 100644 src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp create mode 100644 src/plugins/platforms/qnx/qqnxrasterbackingstore.h create mode 100644 src/plugins/platforms/qnx/qqnxrootwindow.cpp create mode 100644 src/plugins/platforms/qnx/qqnxrootwindow.h create mode 100644 src/plugins/platforms/qnx/qqnxscreen.cpp create mode 100644 src/plugins/platforms/qnx/qqnxscreen.h create mode 100644 src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp create mode 100644 src/plugins/platforms/qnx/qqnxvirtualkeyboard.h create mode 100644 src/plugins/platforms/qnx/qqnxwindow.cpp create mode 100644 src/plugins/platforms/qnx/qqnxwindow.h (limited to 'src/plugins') diff --git a/src/plugins/platforms/blackberry/blackberry.pro b/src/plugins/platforms/blackberry/blackberry.pro deleted file mode 100644 index 94b9c5dbc8..0000000000 --- a/src/plugins/platforms/blackberry/blackberry.pro +++ /dev/null @@ -1,71 +0,0 @@ -TARGET = blackberry -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms -QT += opengl opengl-private platformsupport platformsupport-private widgets-private - -# Uncomment this to build with support for IMF once it becomes available in the BBNDK -#CONFIG += qbb_imf - -# Uncomment these to enable debugging output for various aspects of the plugin -#DEFINES += QBBBUFFER_DEBUG -#DEFINES += QBBCLIPBOARD_DEBUG -#DEFINES += QBBEVENTTHREAD_DEBUG -#DEFINES += QBBGLBACKINGSTORE_DEBUG -#DEFINES += QBBGLCONTEXT_DEBUG -#DEFINES += QBBINPUTCONTEXT_DEBUG -#DEFINES += QBBINPUTCONTEXT_IMF_EVENT_DEBUG -#DEFINES += QBBINTEGRATION_DEBUG -#DEFINES += QBBNAVIGATORTHREAD_DEBUG -#DEFINES += QBBRASTERBACKINGSTORE_DEBUG -#DEFINES += QBBROOTWINDOW_DEBUG -#DEFINES += QBBSCREEN_DEBUG -#DEFINES += QBBVIRTUALKEYBOARD_DEBUG -#DEFINES += QBBWINDOW_DEBUG - -SOURCES = main.cpp \ - qbbbuffer.cpp \ - qbbeventthread.cpp \ - qbbglcontext.cpp \ - qbbglbackingstore.cpp \ - qbbintegration.cpp \ - qbbnavigatorthread.cpp \ - qbbscreen.cpp \ - qbbwindow.cpp \ - qbbrasterbackingstore.cpp \ - qbbvirtualkeyboard.cpp \ - qbbclipboard.cpp \ - qbbrootwindow.cpp - -HEADERS = qbbbuffer.h \ - qbbeventthread.h \ - qbbkeytranslator.h \ - qbbintegration.h \ - qbbnavigatorthread.h \ - qbbglcontext.h \ - qbbglbackingstore.h \ - qbbscreen.h \ - qbbwindow.h \ - qbbrasterbackingstore.h \ - qbbvirtualkeyboard.h \ - qbbclipboard.h \ - qbbrootwindow.h - -CONFIG(qbb_imf) { - DEFINES += QBB_IMF - HEADERS += qbbinputcontext_imf.h - SOURCES += qbbinputcontext_imf.cpp -} else { - HEADERS += qbbinputcontext_noimf.h - SOURCES += qbbinputcontext_noimf.cpp -} - -QMAKE_CXXFLAGS += -I./private - -LIBS += -lpps -lscreen -lEGL -lclipboard - -include (../../../platformsupport/eglconvenience/eglconvenience.pri) -include (../../../platformsupport/fontdatabases/fontdatabases.pri) - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/platforms/blackberry/main.cpp b/src/plugins/platforms/blackberry/main.cpp deleted file mode 100644 index b9e09c0384..0000000000 --- a/src/plugins/platforms/blackberry/main.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "qbbintegration.h" - -QT_BEGIN_NAMESPACE - -class QBBIntegrationPlugin : public QPlatformIntegrationPlugin -{ -public: - QStringList keys() const; - QPlatformIntegration *create(const QString&, const QStringList&); -}; - -QStringList QBBIntegrationPlugin::keys() const -{ - QStringList list; - list << QLatin1String("blackberry"); - return list; -} - -QPlatformIntegration *QBBIntegrationPlugin::create(const QString& system, const QStringList& paramList) -{ - Q_UNUSED(paramList); - if (system.toLower() == QLatin1String("blackberry")) - return new QBBIntegration; - - return 0; -} - -Q_EXPORT_PLUGIN2(blackberry, QBBIntegrationPlugin) - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbbuffer.cpp b/src/plugins/platforms/blackberry/qbbbuffer.cpp deleted file mode 100644 index c4ac04898d..0000000000 --- a/src/plugins/platforms/blackberry/qbbbuffer.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbbuffer.h" - -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -QBBBuffer::QBBBuffer() - : m_buffer(0) -{ -#if defined(QBBBUFFER_DEBUG) - qDebug() << "QBBBuffer::QBBBuffer - empty"; -#endif -} - -QBBBuffer::QBBBuffer(screen_buffer_t buffer) - : m_buffer(buffer) -{ -#if defined(QBBBUFFER_DEBUG) - qDebug() << "QBBBuffer::QBBBuffer - normal"; -#endif - - // Get size of buffer - errno = 0; - int size[2]; - int result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size); - if (result != 0) { - qFatal("QBB: failed to query buffer size, errno=%d", errno); - } - - // Get stride of buffer - errno = 0; - int stride; - result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride); - if (result != 0) { - qFatal("QBB: failed to query buffer stride, errno=%d", errno); - } - - // Get access to buffer's data - errno = 0; - uchar *dataPtr = 0; - result = screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr); - if (result != 0) { - qFatal("QBB: failed to query buffer pointer, errno=%d", errno); - } - if (dataPtr == NULL) { - qFatal("QBB: buffer pointer is NULL, errno=%d", errno); - } - - // Get format of buffer - errno = 0; - int screenFormat; - result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat); - if (result != 0) { - qFatal("QBB: failed to query buffer format, errno=%d", errno); - } - - // Convert screen format to QImage format - QImage::Format imageFormat = QImage::Format_Invalid; - switch (screenFormat) { - case SCREEN_FORMAT_RGBX4444: - imageFormat = QImage::Format_RGB444; - break; - case SCREEN_FORMAT_RGBA4444: - imageFormat = QImage::Format_ARGB4444_Premultiplied; - break; - case SCREEN_FORMAT_RGBX5551: - imageFormat = QImage::Format_RGB555; - break; - case SCREEN_FORMAT_RGB565: - imageFormat = QImage::Format_RGB16; - break; - case SCREEN_FORMAT_RGBX8888: - imageFormat = QImage::Format_RGB32; - break; - case SCREEN_FORMAT_RGBA8888: - imageFormat = QImage::Format_ARGB32_Premultiplied; - break; - default: - qFatal("QBB: unsupported buffer format, format=%d", screenFormat); - } - - // wrap buffer in an image - m_image = QImage(dataPtr, size[0], size[1], stride, imageFormat); -} - -QBBBuffer::QBBBuffer(const QBBBuffer &other) - : m_buffer(other.m_buffer), - m_image(other.m_image) -{ -#if defined(QBBBUFFER_DEBUG) - qDebug() << "QBBBuffer::QBBBuffer - copy"; -#endif -} - -QBBBuffer::~QBBBuffer() -{ -#if defined(QBBBUFFER_DEBUG) - qDebug() << "QBBBuffer::~QBBBuffer"; -#endif -} - -void QBBBuffer::invalidateInCache() -{ -#if defined(QBBBUFFER_DEBUG) - qDebug() << "QBBBuffer::invalidateInCache"; -#endif - - // Verify native buffer exists - if (m_buffer == 0) { - qFatal("QBB: can't invalidate cache for null buffer"); - } - - // Evict buffer's data from cache - errno = 0; - int result = msync(m_image.bits(), m_image.height() * m_image.bytesPerLine(), MS_INVALIDATE | MS_CACHE_ONLY); - if (result != 0) { - qFatal("QBB: failed to invalidate cache, errno=%d", errno); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbbuffer.h b/src/plugins/platforms/blackberry/qbbbuffer.h deleted file mode 100644 index 45cedb21a8..0000000000 --- a/src/plugins/platforms/blackberry/qbbbuffer.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBBUFFER_H -#define QBBBUFFER_H - -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBBuffer -{ -public: - QBBBuffer(); - QBBBuffer(screen_buffer_t buffer); - QBBBuffer(const QBBBuffer &other); - virtual ~QBBBuffer(); - - screen_buffer_t nativeBuffer() const { return m_buffer; } - const QImage *image() const { return (m_buffer != NULL) ? &m_image : NULL; } - QImage *image() { return (m_buffer != NULL) ? &m_image : NULL; } - - QRect rect() const { return m_image.rect(); } - - void invalidateInCache(); - -private: - screen_buffer_t m_buffer; - QImage m_image; -}; - -QT_END_NAMESPACE - -#endif // QBBBUFFER_H diff --git a/src/plugins/platforms/blackberry/qbbclipboard.cpp b/src/plugins/platforms/blackberry/qbbclipboard.cpp deleted file mode 100644 index 293a0c771b..0000000000 --- a/src/plugins/platforms/blackberry/qbbclipboard.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_CLIPBOARD - -#include "qbbclipboard.h" - -#include - -#include -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -// null terminated array -static const char *typeList[] = {"text/html", "text/plain", "image/png", "image/jpeg", "application/x-color", 0}; - -static QByteArray readClipboardBuff(const char *type) -{ - char *pbuffer; - if (is_clipboard_format_present(type) == 0) { - int size = get_clipboard_data(type, &pbuffer); - if (size != -1 && pbuffer) { - const QByteArray result = QByteArray(pbuffer, size); - free(pbuffer); - return result; - } - } - - return QByteArray(); -} - -class QBBClipboard::MimeData : public QMimeData -{ - Q_OBJECT -public: - MimeData(QBBClipboard *clipboard) - : QMimeData(), - m_clipboard(clipboard), - m_userMimeData(0) - { - Q_ASSERT(clipboard); - - for (int i = 0; typeList[i] != 0; ++i) { - m_formatsToCheck << QString::fromUtf8(typeList[i]); - } - } - - ~MimeData() - { - delete m_userMimeData; - } - - void addFormatToCheck(const QString &format) { - m_formatsToCheck << format; - -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << Q_FUNC_INFO << "formats=" << m_formatsToCheck; -#endif - } - - bool hasFormat(const QString &mimetype) const - { - const bool result = is_clipboard_format_present(mimetype.toUtf8().constData()) == 0; -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "result=" << result; -#endif - return result; - } - - QStringList formats() const - { - QStringList result; - - Q_FOREACH (const QString &format, m_formatsToCheck) { - if (is_clipboard_format_present(format.toUtf8().constData()) == 0) - result << format; - } - -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << Q_FUNC_INFO << "result=" << result; -#endif - return result; - } - - void setUserMimeData(QMimeData *userMimeData) - { - delete m_userMimeData; - m_userMimeData = userMimeData; - - // system clipboard API doesn't allow detection of changes by other applications - // simulate an owner change through delayed invocation - // basically transfer ownership of data to the system clipboard once event processing resumes - if (m_userMimeData) - QMetaObject::invokeMethod(this, "releaseOwnership", Qt::QueuedConnection); - } - - QMimeData *userMimeData() - { - return m_userMimeData; - } - -protected: - QVariant retrieveData(const QString &mimetype, QVariant::Type preferredType) const - { -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "preferredType=" << preferredType; -#endif - if (is_clipboard_format_present(mimetype.toUtf8().constData()) != 0) - return QMimeData::retrieveData(mimetype, preferredType); - - const QByteArray data = readClipboardBuff(mimetype.toUtf8().constData()); - return qVariantFromValue(data); - } - -private Q_SLOTS: - void releaseOwnership() - { - if (m_userMimeData) { -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << Q_FUNC_INFO << "user data formats=" << m_userMimeData->formats() << "system formats=" << formats(); -#endif - delete m_userMimeData; - m_userMimeData = 0; - m_clipboard->emitChanged(QClipboard::Clipboard); - } - } - -private: - QBBClipboard * const m_clipboard; - - QSet m_formatsToCheck; - QMimeData *m_userMimeData; -}; - -QBBClipboard::QBBClipboard() - : m_mimeData(new MimeData(this)) -{ -} - -QBBClipboard::~QBBClipboard() -{ - delete m_mimeData; -} - -void QBBClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) -{ - if (mode != QClipboard::Clipboard) - return; - - if (data == m_mimeData || data == m_mimeData->userMimeData()) - return; - - empty_clipboard(); - - m_mimeData->clear(); - m_mimeData->setUserMimeData(data); - - if (data == 0) - return; - - const QStringList formats = data->formats(); -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << Q_FUNC_INFO << "formats=" << formats; -#endif - - Q_FOREACH (const QString &format, formats) { - const QByteArray buf = data->data(format); - - if (buf.isEmpty()) - continue; - - int ret = set_clipboard_data(format.toUtf8().data(), buf.size(), buf.data()); -#if defined(QBBCLIPBOARD_DEBUG) - qDebug() << "QBB: set " << format << "to clipboard, size=" << buf.size() << ";ret=" << ret; -#endif - if (ret) - m_mimeData->addFormatToCheck(format); - } - - emitChanged(QClipboard::Clipboard); -} - -QMimeData *QBBClipboard::mimeData(QClipboard::Mode mode) -{ - if (mode != QClipboard::Clipboard) - return 0; - - if (m_mimeData->userMimeData()) - return m_mimeData->userMimeData(); - - m_mimeData->clear(); - - return m_mimeData; -} - -QT_END_NAMESPACE - -#include "qbbclipboard.moc" - -#endif //QT_NO_CLIPBOARD diff --git a/src/plugins/platforms/blackberry/qbbclipboard.h b/src/plugins/platforms/blackberry/qbbclipboard.h deleted file mode 100644 index 11a36ba8e5..0000000000 --- a/src/plugins/platforms/blackberry/qbbclipboard.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBCLIPBOARD_H -#define QBBCLIPBOARD_H - -#ifndef QT_NO_CLIPBOARD -#include - -QT_BEGIN_NAMESPACE - -class QBBClipboard : public QPlatformClipboard -{ -public: - QBBClipboard(); - virtual ~QBBClipboard(); - virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); - virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); - -private: - class MimeData; - MimeData *m_mimeData; -}; - -QT_END_NAMESPACE - -#endif //QT_NO_CLIPBOARD -#endif //QBBCLIPBOARD_H diff --git a/src/plugins/platforms/blackberry/qbbeventthread.cpp b/src/plugins/platforms/blackberry/qbbeventthread.cpp deleted file mode 100644 index 6951921fe9..0000000000 --- a/src/plugins/platforms/blackberry/qbbeventthread.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbeventthread.h" -#include "qbbintegration.h" -#include "qbbkeytranslator.h" - -#if defined(QBB_IMF) -#include "qbbinputcontext_imf.h" -#else -#include "qbbinputcontext_noimf.h" -#endif - -#include -#include -#include - -#include - -#include -#include -#include - -#include - -QBBEventThread::QBBEventThread(screen_context_t context, QPlatformScreen& screen) - : QThread(), - m_screenContext(context), - m_platformScreen(screen), - m_quit(false), - m_lastButtonState(Qt::NoButton), - m_lastMouseWindow(0) -{ - // Create a touch device - m_touchDevice = new QTouchDevice; - m_touchDevice->setType(QTouchDevice::TouchScreen); - m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); - QWindowSystemInterface::registerTouchDevice(m_touchDevice); - - // initialize array of touch points - for (int i = 0; i < MaximumTouchPoints; i++) { - - // map array index to id - m_touchPoints[i].id = i; - - // pressure is not supported - use default - m_touchPoints[i].pressure = 1.0; - - // nothing touching - m_touchPoints[i].state = Qt::TouchPointReleased; - } -} - -QBBEventThread::~QBBEventThread() -{ - // block until thread terminates - shutdown(); -} - -void QBBEventThread::run() -{ - screen_event_t event; - - // create screen event - errno = 0; - int result = screen_create_event(&event); - if (result) { - qFatal("QBB: failed to create event, errno=%d", errno); - } - -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: event loop started"; -#endif - - // loop indefinitely - while (!m_quit) { - - // block until screen event is available - errno = 0; - result = screen_get_event(m_screenContext, event, -1); - if (result) { - qFatal("QBB: failed to get event, errno=%d", errno); - } - - // process received event - dispatchEvent(event); - } - -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: event loop stopped"; -#endif - - // cleanup - screen_destroy_event(event); -} - -void QBBEventThread::shutdown() -{ - screen_event_t event; - - // create screen event - errno = 0; - int result = screen_create_event(&event); - if (result) { - qFatal("QBB: failed to create event, errno=%d", errno); - } - - // set the event type as user - errno = 0; - int type = SCREEN_EVENT_USER; - result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type); - if (result) { - qFatal("QBB: failed to set event type, errno=%d", errno); - } - - // NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events - - // post event to event loop so it will wake up and die - errno = 0; - result = screen_send_event(m_screenContext, event, getpid()); - if (result) { - qFatal("QBB: failed to set event type, errno=%d", errno); - } - - // cleanup - screen_destroy_event(event); - -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: event loop shutdown begin"; -#endif - - // block until thread terminates - wait(); - -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: event loop shutdown end"; -#endif -} - -void QBBEventThread::dispatchEvent(screen_event_t event) -{ - // get the event type - errno = 0; - int qnxType; - int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType); - if (result) { - qFatal("QBB: failed to query event type, errno=%d", errno); - } - - switch (qnxType) { - case SCREEN_EVENT_MTOUCH_TOUCH: - case SCREEN_EVENT_MTOUCH_MOVE: - case SCREEN_EVENT_MTOUCH_RELEASE: - handleTouchEvent(event, qnxType); - break; - - case SCREEN_EVENT_KEYBOARD: - handleKeyboardEvent(event); - break; - - case SCREEN_EVENT_POINTER: - handlePointerEvent(event); - break; - - case SCREEN_EVENT_CLOSE: - handleCloseEvent(event); - break; - - case SCREEN_EVENT_USER: - // treat all user events as shutdown requests -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: QNX user event"; -#endif - m_quit = true; - break; - - default: - // event ignored -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: QNX unknown event"; -#endif - break; - } -} - -void QBBEventThread::handleKeyboardEvent(screen_event_t event) -{ - // get flags of key event - errno = 0; - int flags; - int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags); - if (result) { - qFatal("QBB: failed to query event flags, errno=%d", errno); - } - - // get key code - errno = 0; - int sym; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym); - if (result) { - qFatal("QBB: failed to query event sym, errno=%d", errno); - } - - int modifiers; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers); - if (result) { - qFatal("QBB: failed to query event modifiers, errno=%d", errno); - } - - int scan; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan); - if (result) { - qFatal("QBB: failed to query event modifiers, errno=%d", errno); - } - - int cap; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap); - if (result) { - qFatal("QBB: failed to query event cap, errno=%d", errno); - } - - injectKeyboardEvent(flags, sym, modifiers, scan, cap); -} - -void QBBEventThread::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap) -{ - Q_UNUSED(scan); - - Qt::KeyboardModifiers qtMod = Qt::NoModifier; - if (modifiers & KEYMOD_SHIFT) - qtMod |= Qt::ShiftModifier; - if (modifiers & KEYMOD_CTRL) - qtMod |= Qt::ControlModifier; - if (modifiers & KEYMOD_ALT) - qtMod |= Qt::AltModifier; - - // determine event type - QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease; - - // Check if the key cap is valid - if (flags & KEY_CAP_VALID) { - Qt::Key key; - QString keyStr; - - if (cap >= 0x20 && cap <= 0x0ff) { - key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case. - - if ( qtMod & Qt::ControlModifier ) { - keyStr = QChar((int)(key & 0x3f)); - } else { - if (flags & KEY_SYM_VALID) { - keyStr = QChar(sym); - } - } - } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) { - key = (Qt::Key)cap; - keyStr = QChar(sym); - } else { - if (isKeypadKey(cap)) - qtMod |= Qt::KeypadModifier; // Is this right? - key = keyTranslator(cap); - } - - QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, keyStr); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt key t=" << type << ", k=" << key << ", s=" << keyStr; -#endif - } -} - -void QBBEventThread::handlePointerEvent(screen_event_t event) -{ - errno = 0; - - // Query the window that was clicked - screen_window_t qnxWindow; - void *handle; - int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); - if (result) { - qFatal("QBB: failed to query event window, errno=%d", errno); - } - qnxWindow = static_cast(handle); - - // Query the button states - int buttonState = 0; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState); - if (result) { - qFatal("QBB: failed to query event button state, errno=%d", errno); - } - - // Query the window position - int windowPos[2]; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); - if (result) { - qFatal("QBB: failed to query event window position, errno=%d", errno); - } - - // Query the screen position - int pos[2]; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); - if (result) { - qFatal("QBB: failed to query event position, errno=%d", errno); - } - - // Query the wheel delta - int wheelDelta = 0; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta); - if (result) { - qFatal("QBB: failed to query event wheel delta, errno=%d", errno); - } - - // Map window handle to top-level QWindow - QWindow *w = QBBIntegration::window(qnxWindow); - - // Generate enter and leave events as needed. - if (qnxWindow != m_lastMouseWindow) { - QWindow *wOld = QBBIntegration::window(m_lastMouseWindow); - - if (wOld) { - QWindowSystemInterface::handleLeaveEvent(wOld); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt leave, w=" << wOld; -#endif - } - - if (w) { - QWindowSystemInterface::handleEnterEvent(w); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt enter, w=" << w; -#endif - } - } - m_lastMouseWindow = qnxWindow; - - // Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale - // this via a system preference at some point. But for now this is a sane value and makes - // the wheel usable. - wheelDelta *= -10; - - // convert point to local coordinates - QPoint globalPoint(pos[0], pos[1]); - QPoint localPoint(windowPos[0], windowPos[1]); - - // Convert buttons. - // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit, - // so we may receive events as shown. (If this is wrong, the fix is easy.) - // QNX Button mask is 8 buttons wide, with a maximum value of x080. - Qt::MouseButtons buttons = Qt::NoButton; - if (buttonState & 0x01) - buttons |= Qt::LeftButton; - if (buttonState & 0x02) - buttons |= Qt::MidButton; - if (buttonState & 0x04) - buttons |= Qt::RightButton; - if (buttonState & 0x08) - buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton' - if (buttonState & 0x10) - buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton' - if (buttonState & 0x20) - buttons |= Qt::ExtraButton3; - if (buttonState & 0x40) - buttons |= Qt::ExtraButton4; - if (buttonState & 0x80) - buttons |= Qt::ExtraButton5; - - if (w) { - // Inject mouse event into Qt only if something has changed. - if (m_lastGlobalMousePoint != globalPoint || - m_lastLocalMousePoint != localPoint || - m_lastButtonState != buttons) { - QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast(buttons); -#endif - } - - if (wheelDelta) { - // Screen only supports a single wheel, so we will assume Vertical orientation for - // now since that is pretty much standard. - QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast(wheelDelta); -#endif - } - } - - m_lastGlobalMousePoint = globalPoint; - m_lastLocalMousePoint = localPoint; - m_lastButtonState = buttons; -} - -void QBBEventThread::handleTouchEvent(screen_event_t event, int qnxType) -{ - // get display coordinates of touch - errno = 0; - int pos[2]; - int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); - if (result) { - qFatal("QBB: failed to query event position, errno=%d", errno); - } - - // get window coordinates of touch - errno = 0; - int windowPos[2]; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); - if (result) { - qFatal("QBB: failed to query event window position, errno=%d", errno); - } - - // determine which finger touched - errno = 0; - int touchId; - result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId); - if (result) { - qFatal("QBB: failed to query event touch id, errno=%d", errno); - } - - // determine which window was touched - errno = 0; - void *handle; - result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); - if (result) { - qFatal("QBB: failed to query event window, errno=%d", errno); - } - screen_window_t qnxWindow = static_cast(handle); - - // check if finger is valid - if (touchId < MaximumTouchPoints) { - - // Map window handle to top-level QWindow - QWindow *w = QBBIntegration::window(qnxWindow); - - // Generate enter and leave events as needed. - if (qnxWindow != m_lastMouseWindow) { - QWindow *wOld = QBBIntegration::window(m_lastMouseWindow); - - if (wOld) { - QWindowSystemInterface::handleLeaveEvent(wOld); - #if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt leave, w=" << wOld; - #endif - } - - if (w) { - QWindowSystemInterface::handleEnterEvent(w); - #if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt enter, w=" << w; - #endif - } - } - m_lastMouseWindow = qnxWindow; - - if (w) { - // convert primary touch to mouse event - if (touchId == 0) { - - // convert point to local coordinates - QPoint globalPoint(pos[0], pos[1]); - QPoint localPoint(windowPos[0], windowPos[1]); - - // map touch state to button state - Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton; - - // inject event into Qt - QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons; -#endif - } - - // get size of screen which contains window - QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w); - QSizeF screenSize = platformScreen->physicalSize(); - - // update cached position of current touch point - m_touchPoints[touchId].normalPosition = QPointF( static_cast(pos[0]) / screenSize.width(), static_cast(pos[1]) / screenSize.height() ); - m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 ); - - // determine event type and update state of current touch point - QEvent::Type type = QEvent::None; - switch (qnxType) { - case SCREEN_EVENT_MTOUCH_TOUCH: - m_touchPoints[touchId].state = Qt::TouchPointPressed; - type = QEvent::TouchBegin; - break; - case SCREEN_EVENT_MTOUCH_MOVE: - m_touchPoints[touchId].state = Qt::TouchPointMoved; - type = QEvent::TouchUpdate; - break; - case SCREEN_EVENT_MTOUCH_RELEASE: - m_touchPoints[touchId].state = Qt::TouchPointReleased; - type = QEvent::TouchEnd; - break; - } - - // build list of active touch points - QList pointList; - for (int i = 0; i < MaximumTouchPoints; i++) { - if (i == touchId) { - // current touch point is always active - pointList.append(m_touchPoints[i]); - } else if (m_touchPoints[i].state != Qt::TouchPointReleased) { - // finger is down but did not move - m_touchPoints[i].state = Qt::TouchPointStationary; - pointList.append(m_touchPoints[i]); - } - } - - // inject event into Qt - QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList); -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type; -#endif - } - } -} - -void QBBEventThread::handleCloseEvent(screen_event_t event) -{ - // Query the window that was closed - void *handle; - int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); - if (result != 0) { - qFatal("QBB: failed to query event window, errno=%d", errno); - } - screen_window_t qnxWindow = static_cast(handle); - - // Map window handle to top-level QWindow - QWindow *w = QBBIntegration::window(qnxWindow); - if (w != 0) { - QWindowSystemInterface::handleCloseEvent(w); - } -} - diff --git a/src/plugins/platforms/blackberry/qbbeventthread.h b/src/plugins/platforms/blackberry/qbbeventthread.h deleted file mode 100644 index afa738830c..0000000000 --- a/src/plugins/platforms/blackberry/qbbeventthread.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBEVENTTHREAD_H -#define QBBEVENTTHREAD_H - -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBEventThread : public QThread -{ -public: - QBBEventThread(screen_context_t context, QPlatformScreen& screen); - virtual ~QBBEventThread(); - - static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - -protected: - virtual void run(); - -private: - enum { - MaximumTouchPoints = 10 - }; - - void shutdown(); - void dispatchEvent(screen_event_t event); - void handleKeyboardEvent(screen_event_t event); - void handlePointerEvent(screen_event_t event); - void handleTouchEvent(screen_event_t event, int type); - void handleCloseEvent(screen_event_t event); - - screen_context_t m_screenContext; - QPlatformScreen& m_platformScreen; - bool m_quit; - QPoint m_lastGlobalMousePoint; - QPoint m_lastLocalMousePoint; - Qt::MouseButtons m_lastButtonState; - screen_window_t m_lastMouseWindow; - QTouchDevice *m_touchDevice; - QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints]; -}; - -QT_END_NAMESPACE - -#endif // QBBEVENTTHREAD_H diff --git a/src/plugins/platforms/blackberry/qbbglbackingstore.cpp b/src/plugins/platforms/blackberry/qbbglbackingstore.cpp deleted file mode 100644 index 91b07770e1..0000000000 --- a/src/plugins/platforms/blackberry/qbbglbackingstore.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbglbackingstore.h" -#include "qbbglcontext.h" -#include "qbbwindow.h" -#include "qbbscreen.h" - -#include - -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -QBBGLPaintDevice::QBBGLPaintDevice(QWindow *window) - : QGLPaintDevice(), - m_window(0), - m_glContext(0) -{ - m_window = static_cast(window->handle()); - - // Extract the QPlatformOpenGLContext from the window - QPlatformOpenGLContext *platformOpenGLContext = m_window->platformOpenGLContext(); - - // Convert this to a QGLContext - m_glContext = QGLContext::fromOpenGLContext(platformOpenGLContext->context()); -} - -QBBGLPaintDevice::~QBBGLPaintDevice() -{ - // Cleanup GL context - delete m_glContext; -} - -QPaintEngine *QBBGLPaintDevice::paintEngine() const -{ - // Select a paint engine based on configued OpenGL version - return qt_qgl_paint_engine(); -} - -QSize QBBGLPaintDevice::size() const -{ - // Get size of EGL surface - return m_window->geometry().size(); -} - - -QBBGLBackingStore::QBBGLBackingStore(QWindow *window) - : QPlatformBackingStore(window), - m_openGLContext(0), - m_paintDevice(0), - m_requestedSize(), - m_size() -{ -#if defined(QBBGLBACKINGSTORE_DEBUG) - qDebug() << "QBBGLBackingStore::QBBGLBackingStore - w=" << window; -#endif - - // Create an OpenGL paint device which in turn creates a QGLContext for us - m_paintDevice = new QBBGLPaintDevice(window); - m_openGLContext = m_paintDevice->context()->contextHandle(); -} - -QBBGLBackingStore::~QBBGLBackingStore() -{ -#if defined(QBBGLBACKINGSTORE_DEBUG) - qDebug() << "QBBGLBackingStore::~QBBGLBackingStore - w=" << window(); -#endif - - // cleanup OpenGL paint device - delete m_paintDevice; -} - -void QBBGLBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(region); - Q_UNUSED(offset); - -#if defined(QBBGLBACKINGSTORE_DEBUG) - qDebug() << "QBBGLBackingStore::flush - w=" << window; -#endif - - // update the display with newly rendered content - m_openGLContext->swapBuffers(window); -} - -void QBBGLBackingStore::resize(const QSize &size, const QRegion &staticContents) -{ - Q_UNUSED(staticContents); -#if defined(QBBGLBACKINGSTORE_DEBUG) - qDebug() << "QBBGLBackingStore::resize - w=" << window() << ", s=" << size; -#endif - // NOTE: defer resizing window buffers until next paint as - // resize() can be called multiple times before a paint occurs - m_requestedSize = size; -} - -void QBBGLBackingStore::beginPaint(const QRegion ®ion) -{ - Q_UNUSED(region); - -#if defined(QBBGLBACKINGSTORE_DEBUG) - qDebug() << "QBBGLBackingStore::beginPaint - w=" << window(); -#endif - - // resize EGL surface if window surface resized - if (m_size != m_requestedSize) { - resizeSurface(m_requestedSize); - } -} - -void QBBGLBackingStore::endPaint(const QRegion ®ion) -{ - Q_UNUSED(region); -#if defined(QBBGLBACKINGSTORE_DEBUG) - qDebug() << "QBBGLBackingStore::endPaint - w=" << window(); -#endif -} - -void QBBGLBackingStore::resizeSurface(const QSize &size) -{ - // need to destroy surface so make sure its not current - bool restoreCurrent = false; - QBBGLContext *platformContext = static_cast(m_openGLContext->handle()); - if (platformContext->isCurrent()) { - m_openGLContext->doneCurrent(); - restoreCurrent = true; - } - - // destroy old EGL surface - platformContext->destroySurface(); - - // resize window's buffers - static_cast(window()->handle())->setBufferSize(size); - - // re-create EGL surface with new size - m_size = size; - platformContext->createSurface(window()->handle()); - - // make context current again - if (restoreCurrent) { - m_openGLContext->makeCurrent(window()); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbglbackingstore.h b/src/plugins/platforms/blackberry/qbbglbackingstore.h deleted file mode 100644 index 5455c5767c..0000000000 --- a/src/plugins/platforms/blackberry/qbbglbackingstore.h +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBGLBACKINGSTORE_H -#define QBBGLBACKINGSTORE_H - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QGLContext; -class QBBGLContext; -class QBBScreen; -class QBBWindow; - -class QBBGLPaintDevice : public QGLPaintDevice -{ -public: - QBBGLPaintDevice(QWindow *window); - virtual ~QBBGLPaintDevice(); - - virtual QPaintEngine *paintEngine() const; - virtual QSize size() const; - virtual QGLContext *context() const { return m_glContext; } - -private: - QBBWindow *m_window; - QGLContext *m_glContext; -}; - -class QBBGLBackingStore : public QPlatformBackingStore -{ -public: - QBBGLBackingStore(QWindow *window); - virtual ~QBBGLBackingStore(); - - virtual QPaintDevice *paintDevice() { return m_paintDevice; } - virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); - virtual void resize(const QSize &size, const QRegion &staticContents); - virtual void beginPaint(const QRegion ®ion); - virtual void endPaint(const QRegion ®ion); - - void resizeSurface(const QSize &size); - -private: - QOpenGLContext *m_openGLContext; - QBBGLPaintDevice *m_paintDevice; - QSize m_requestedSize; - QSize m_size; -}; - -QT_END_NAMESPACE - -#endif // QBBGLBACKINGSTORE_H diff --git a/src/plugins/platforms/blackberry/qbbglcontext.cpp b/src/plugins/platforms/blackberry/qbbglcontext.cpp deleted file mode 100644 index fb74fdb5d2..0000000000 --- a/src/plugins/platforms/blackberry/qbbglcontext.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbglcontext.h" -#include "qbbrootwindow.h" -#include "qbbscreen.h" -#include "qbbwindow.h" - -#include "private/qeglconvenience_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -EGLDisplay QBBGLContext::ms_eglDisplay = EGL_NO_DISPLAY; - -static EGLenum checkEGLError(const char *msg) -{ - static const char *errmsg[] = - { - "EGL function succeeded", - "EGL is not initialized, or could not be initialized, for the specified display", - "EGL cannot access a requested resource", - "EGL failed to allocate resources for the requested operation", - "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list", - "EGLConfig argument does not name a valid EGLConfig", - "EGLContext argument does not name a valid EGLContext", - "EGL current surface of the calling thread is no longer valid", - "EGLDisplay argument does not name a valid EGLDisplay", - "EGL arguments are inconsistent", - "EGLNativePixmapType argument does not refer to a valid native pixmap", - "EGLNativeWindowType argument does not refer to a valid native window", - "EGL one or more argument values are invalid", - "EGLSurface argument does not name a valid surface configured for rendering", - "EGL power management event has occurred", - }; - EGLenum error = eglGetError(); - fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]); - return error; -} - -QBBGLContext::QBBGLContext(QOpenGLContext *glContext) - : QPlatformOpenGLContext(), - m_glContext(glContext), - m_eglSurface(EGL_NO_SURFACE) -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - QSurfaceFormat format = m_glContext->format(); - - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to set EGL API, err=%d", eglGetError()); - } - - // Get colour channel sizes from window format - int alphaSize = format.alphaBufferSize(); - int redSize = format.redBufferSize(); - int greenSize = format.greenBufferSize(); - int blueSize = format.blueBufferSize(); - - // Check if all channels are don't care - if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) { - // Set colour channels based on depth of window's screen - QBBScreen *screen = static_cast(QBBScreen::screens().first()); - int depth = screen->depth(); - if (depth == 32) { - // SCREEN_FORMAT_RGBA8888 - alphaSize = 8; - redSize = 8; - greenSize = 8; - blueSize = 8; - } else { - // SCREEN_FORMAT_RGB565 - alphaSize = 0; - redSize = 5; - greenSize = 6; - blueSize = 5; - } - } else { - // Choose best match based on supported pixel formats - if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) { - // SCREEN_FORMAT_RGB565 - alphaSize = 0; - redSize = 5; - greenSize = 6; - blueSize = 5; - } else { - // SCREEN_FORMAT_RGBA8888 - alphaSize = 8; - redSize = 8; - greenSize = 8; - blueSize = 8; - } - } - - // Update colour channel sizes in window format - format.setAlphaBufferSize(alphaSize); - format.setRedBufferSize(redSize); - format.setGreenBufferSize(greenSize); - format.setBlueBufferSize(blueSize); - format.setSamples(2); - - // Select EGL config based on requested window format - m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format); - if (m_eglConfig == 0) { - qFatal("QBB: failed to find EGL config"); - } - - m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs()); - if (m_eglContext == EGL_NO_CONTEXT) { - checkEGLError("eglCreateContext"); - qFatal("QBB: failed to create EGL context, err=%d", eglGetError()); - } - - // Query/cache window format of selected EGL config - m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig); -} - -QBBGLContext::~QBBGLContext() -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - // Cleanup EGL context if it exists - if (m_eglContext != EGL_NO_CONTEXT) { - eglDestroyContext(ms_eglDisplay, m_eglContext); - } - - // Cleanup EGL surface if it exists - destroySurface(); -} - -void QBBGLContext::initialize() -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Initialize connection to EGL - ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (ms_eglDisplay == EGL_NO_DISPLAY) { - checkEGLError("eglGetDisplay"); - qFatal("QBB: failed to obtain EGL display"); - } - - EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0); - if (eglResult != EGL_TRUE) { - checkEGLError("eglInitialize"); - qFatal("QBB: failed to initialize EGL display, err=%d", eglGetError()); - } -} - -void QBBGLContext::shutdown() -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Close connection to EGL - eglTerminate(ms_eglDisplay); -} - -bool QBBGLContext::makeCurrent(QPlatformSurface *surface) -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to set EGL API, err=%d", eglGetError()); - } - - if (m_eglSurface == EGL_NO_SURFACE) - createSurface(surface); - - eglResult = eglMakeCurrent(ms_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); - if (eglResult != EGL_TRUE) { - checkEGLError("eglMakeCurrent"); - qFatal("QBB: failed to set current EGL context, err=%d", eglGetError()); - } - return (eglResult == EGL_TRUE); -} - -void QBBGLContext::doneCurrent() -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to set EGL API, err=%d", eglGetError()); - } - - // clear curent EGL context and unbind EGL surface - eglResult = eglMakeCurrent(ms_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to clear current EGL context, err=%d", eglGetError()); - } -} - -void QBBGLContext::swapBuffers(QPlatformSurface *surface) -{ - Q_UNUSED(surface); -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to set EGL API, err=%d", eglGetError()); - } - - // Post EGL surface to window - eglResult = eglSwapBuffers(ms_eglDisplay, m_eglSurface); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to swap EGL buffers, err=%d", eglGetError()); - } -} - -QFunctionPointer QBBGLContext::getProcAddress(const QByteArray &procName) -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - // Set current rendering API - EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to set EGL API, err=%d", eglGetError()); - } - - // Lookup EGL extension function pointer - return static_cast(eglGetProcAddress(procName.constData())); -} - -EGLint *QBBGLContext::contextAttrs() -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - // Choose EGL settings based on OpenGL version -#if defined(QT_OPENGL_ES_2) - static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - return attrs; -#else - return 0; -#endif -} - -bool QBBGLContext::isCurrent() const -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - return (eglGetCurrentContext() == m_eglContext); -} - -void QBBGLContext::createSurface(QPlatformSurface *surface) -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Get a pointer to the corresponding platform window - QBBWindow *platformWindow = dynamic_cast(surface); - if (!platformWindow) { - qFatal("QBB: unable to create EGLSurface without a QBBWindow"); - } - - // If the platform window does not yet have any buffers, we create - // a temporary set of buffers with a size of 1x1 pixels. This will - // suffice until such time as the platform window has obtained - // buffers of the proper size - if (!platformWindow->hasBuffers()) { - platformWindow->setPlatformOpenGLContext(this); - m_surfaceSize = platformWindow->geometry().size(); - platformWindow->setBufferSize(m_surfaceSize); - } - - // Obtain the native handle for our window - screen_window_t handle = platformWindow->nativeHandle(); - - const EGLint eglSurfaceAttrs[] = - { - EGL_RENDER_BUFFER, EGL_BACK_BUFFER, - EGL_NONE - }; - - // Create EGL surface - m_eglSurface = eglCreateWindowSurface(ms_eglDisplay, m_eglConfig, (EGLNativeWindowType) handle, eglSurfaceAttrs); - if (m_eglSurface == EGL_NO_SURFACE) { - checkEGLError("eglCreateWindowSurface"); - qFatal("QBB: failed to create EGL surface, err=%d", eglGetError()); - } -} - -void QBBGLContext::destroySurface() -{ -#if defined(QBBGLCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - // Destroy EGL surface if it exists - if (m_eglSurface != EGL_NO_SURFACE) { - EGLBoolean eglResult = eglDestroySurface(ms_eglDisplay, m_eglSurface); - if (eglResult != EGL_TRUE) { - qFatal("QBB: failed to destroy EGL surface, err=%d", eglGetError()); - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbglcontext.h b/src/plugins/platforms/blackberry/qbbglcontext.h deleted file mode 100644 index 8ea1df5f40..0000000000 --- a/src/plugins/platforms/blackberry/qbbglcontext.h +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBGLCONTEXT_H -#define QBBGLCONTEXT_H - -#include -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBWindow; - -class QBBGLContext : public QPlatformOpenGLContext -{ -public: - QBBGLContext(QOpenGLContext *glContext); - virtual ~QBBGLContext(); - - static void initialize(); - static void shutdown(); - - virtual bool makeCurrent(QPlatformSurface *surface); - virtual void doneCurrent(); - virtual void swapBuffers(QPlatformSurface *surface); - virtual QFunctionPointer getProcAddress(const QByteArray &procName); - - virtual QSurfaceFormat format() const { return m_windowFormat; } - - bool isCurrent() const; - - void createSurface(QPlatformSurface *surface); - void destroySurface(); - -private: - /** \todo Should this be non-static so we can use additional displays? */ - static EGLDisplay ms_eglDisplay; - - QSurfaceFormat m_windowFormat; - QOpenGLContext *m_glContext; - - EGLConfig m_eglConfig; - EGLContext m_eglContext; - EGLSurface m_eglSurface; - QSize m_surfaceSize; - - static EGLint *contextAttrs(); -}; - -QT_END_NAMESPACE - -#endif // QBBGLCONTEXT_H diff --git a/src/plugins/platforms/blackberry/qbbinputcontext_imf.cpp b/src/plugins/platforms/blackberry/qbbinputcontext_imf.cpp deleted file mode 100644 index fab3d3f151..0000000000 --- a/src/plugins/platforms/blackberry/qbbinputcontext_imf.cpp +++ /dev/null @@ -1,1696 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbinputcontext_imf.h" -#include "qbbeventthread.h" -#include "qbbvirtualkeyboard.h" - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include "imf/imf_client.h" -#include "imf/input_control.h" -#include -#include - -/** TODO: - Support inputMethodHints to restrict input (needs additional features in IMF). -*/ - -#define STRX(x) #x -#define STR(x) STRX(x) - -// Someone tell me why input_control methods are in this namespace, but the rest is not. -using namespace InputMethodSystem; - -#define qs(x) QString::fromLatin1(x) -#define iarg(name) event->mArgs[qs(#name)] = QVariant::fromValue(name) -#define parg(name) event->mArgs[qs(#name)] = QVariant::fromValue((void*)name) -namespace -{ - -spannable_string_t *toSpannableString(const QString &text); -static const input_session_t *sInputSession = 0; -bool isSessionOkay(input_session_t *ic) -{ - return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id; -} - -enum ImfEventType -{ - ImfBeginBatchEdit, - ImfClearMetaKeyStates, - ImfCommitText, - ImfDeleteSurroundingText, - ImfEndBatchEdit, - ImfFinishComposingText, - ImfGetCursorCapsMode, - ImfGetCursorPosition, - ImfGetExtractedText, - ImfGetSelectedText, - ImfGetTextAfterCursor, - ImfGetTextBeforeCursor, - ImfPerformEditorAction, - ImfReportFullscreenMode, - ImfSendEvent, - ImfSendAsyncEvent, - ImfSetComposingRegion, - ImfSetComposingText, - ImfSetSelection -}; - -// We use this class as a round about way to support a posting synchronous event into -// Qt's main thread from the IMF thread. -class ImfEventResult -{ -public: - ImfEventResult() - { - m_mutex.lock(); - } - - ~ImfEventResult() - { - m_mutex.unlock(); - } - - void wait() - { - m_wait.wait(&m_mutex); - } - - void signal() - { - m_wait.wakeAll(); - } - - void setResult(const QVariant& result) - { - m_mutex.lock(); - m_retVal = result; - signal(); - m_mutex.unlock(); - } - - QVariant result() - { - return m_retVal; - } - -private: - QVariant m_retVal; - QMutex m_mutex; - QWaitCondition m_wait; -}; - -class ImfEvent : public QEvent -{ - public: - ImfEvent(input_session_t *session, ImfEventType type, ImfEventResult *result) : - QEvent((QEvent::Type)sUserEventType), - m_session(session), - m_imfType(type), - m_result(result) - { - } - ~ImfEvent() { } - - input_session_t *m_session; - ImfEventType m_imfType; - QVariantHash m_args; - ImfEventResult *m_result; - - static int sUserEventType; -}; -int ImfEvent::sUserEventType = QEvent::registerEventType(); - -static int32_t imfBeginBatchEdit(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfBeginBatchEdit, &result); - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static int32_t imfClearMetaKeyStates(input_session_t *ic, int32_t states) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfClearMetaKeyStates, &result); - iarg(states); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static int32_t imfCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfCommitText, &result); - parg(text); - iarg(new_cursor_position); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static int32_t imfDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfDeleteSurroundingText, &result); - iarg(left_length); - iarg(right_length); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static int32_t imfEndBatchEdit(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfEndBatchEdit, &result); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static int32_t imfFinishComposingText(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfFinishComposingText, &result); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static int32_t imfGetCursorCapsMode(input_session_t *ic, int32_t req_modes) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfGetCursorCapsMode, &result); - iarg(req_modes); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - int32_t ret = result.result().value(); - return ret; -} - -static int32_t imfGetCursorPosition(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfGetCursorPosition, &result); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - - return ret; -} - -static extracted_text_t *imfGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) { - extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1); - et->text = (spannable_string_t *)calloc(sizeof(spannable_string_t),1); - return et; - } - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfGetExtractedText, &result); - parg(request); - iarg(flags); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - return result.result().value(); -} - -static spannable_string_t *imfGetSelectedText(input_session_t *ic, int32_t flags) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return toSpannableString(""); - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfGetSelectedText, &result); - iarg(flags); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - return result.result().value(); -} - -static spannable_string_t *imfGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return toSpannableString(""); - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfGetTextAfterCursor, &result); - iarg(n); - iarg(flags); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - return result.result().value(); -} - -static spannable_string_t *imfGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return toSpannableString(""); - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfGetTextBeforeCursor, &result); - iarg(n); - iarg(flags); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - return result.result().value(); -} - -static int32_t imfPerformEditorAction(input_session_t *ic, int32_t editor_action) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfPerformEditorAction, &result); - iarg(editor_action); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - return ret; -} - -static int32_t imfReportFullscreenMode(input_session_t *ic, int32_t enabled) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfReportFullscreenMode, &result); - iarg(enabled); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - return ret; -} - -static int32_t imfSendEvent(input_session_t *ic, event_t *event) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEvent *imfEvent = new ImfEvent(ic, ImfSendEvent, 0); - imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast(event)); - - QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent); - - return 0; -} - -static int32_t imfSendAsyncEvent(input_session_t *ic, event_t *event) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEvent *imfEvent = new ImfEvent(ic, ImfSendAsyncEvent, 0); - imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast(event)); - - QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent); - - return 0; -} - -static int32_t imfSetComposingRegion(input_session_t *ic, int32_t start, int32_t end) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfSetComposingRegion, &result); - iarg(start); - iarg(end); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - return ret; -} - -static int32_t imfSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfSetComposingText, &result); - parg(text); - iarg(new_cursor_position); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - return ret; -} - -static int32_t imfSetSelection(input_session_t *ic, int32_t start, int32_t end) -{ -#if defined(QBBINPUTCONTEXT_IMF_EVENT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - ImfEventResult result; - ImfEvent *event = new ImfEvent(ic, ImfSetSelection, &result); - iarg(start); - iarg(end); - - QCoreApplication::postEvent(QCoreApplication::instance(), event); - - result.wait(); - int32_t ret = result.result().value(); - return ret; -} - -static connection_interface_t ic_funcs = { - imfBeginBatchEdit, - imfClearMetaKeyStates, - imfCommitText, - imfDeleteSurroundingText, - imfEndBatchEdit, - imfFinishComposingText, - imfGetCursorCapsMode, - imfGetCursorPosition, - imfGetExtractedText, - imfGetSelectedText, - imfGetTextAfterCursor, - imfGetTextBeforeCursor, - imfPerformEditorAction, - imfReportFullscreenMode, - NULL, //ic_send_key_event - imfSendEvent, - imfSendAsyncEvent, - imfSetComposingRegion, - imfSetComposingText, - imfSetSelection, - NULL, //ic_set_candidates, -}; - -static void -initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId) -{ - static int s_transactionId; - - // Make sure structure is squeaky clean since it's not clear just what is significant. - memset(pEvent, 0, sizeof(event_t)); - pEvent->event_type = eventType; - pEvent->event_id = eventId; - pEvent->pid = getpid(); - pEvent->component_id = pSession->component_id; - pEvent->transaction_id = ++s_transactionId; -} - -spannable_string_t *toSpannableString(const QString &text) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << text; -#endif - - spannable_string_t *pString = reinterpret_cast(malloc(sizeof(spannable_string_t))); - pString->str = (wchar_t *)malloc(sizeof(wchar_t) * text.length() + 1); - pString->length = text.length(); - pString->spans = NULL; - pString->spans_count = 0; - - const QChar *pData = text.constData(); - wchar_t *pDst = pString->str; - - while (!pData->isNull()) - { - *pDst = pData->unicode(); - pDst++; - pData++; - } - *pDst = 0; - - return pString; -} - -} // namespace - -static const input_session_t *(*p_ictrl_open_session)(connection_interface_t *) = 0; -static void (*p_ictrl_close_session)(input_session_t *) = 0; -static int32_t (*p_ictrl_dispatch_event)(event_t*) = 0; -static int32_t (*p_imf_client_init)() = 0; -static void (*p_imf_client_disconnect)() = 0; -static int32_t (*p_vkb_init_selection_service)() = 0; -static int32_t (*p_ictrl_get_num_active_sessions)() = 0; -static bool s_imfInitFailed = false; - -static bool imfAvailable() -{ - static bool s_imfDisabled = getenv("DISABLE_IMF") != NULL; - static bool s_imfReady = false; - - if ( s_imfInitFailed || s_imfDisabled) { - return false; - } - else if ( s_imfReady ) { - return true; - } - - if ( p_imf_client_init == NULL ) { - void *handle = dlopen("libinput_client.so.1", 0); - if ( handle ) { - p_imf_client_init = (int32_t (*)()) dlsym(handle, "imf_client_init"); - p_imf_client_disconnect = (void (*)()) dlsym(handle, "imf_client_disconnect"); - p_ictrl_open_session = (const input_session_t *(*)(connection_interface_t *))dlsym(handle, "ictrl_open_session"); - p_ictrl_close_session = (void (*)(input_session_t *))dlsym(handle, "ictrl_close_session"); - p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle, "ictrl_dispatch_event"); - p_vkb_init_selection_service = (int32_t (*)())dlsym(handle, "vkb_init_selection_service"); - p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle, "ictrl_get_num_active_sessions"); - } - else - { - qCritical() << Q_FUNC_INFO << "libinput_client.so.1 is not present - IMF services are disabled."; - s_imfDisabled = true; - return false; - } - if ( p_imf_client_init && p_ictrl_open_session && p_ictrl_dispatch_event ) { - s_imfReady = true; - } - else { - p_ictrl_open_session = NULL; - p_ictrl_dispatch_event = NULL; - s_imfDisabled = true; - qCritical() << Q_FUNC_INFO << "libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled."; - return false; - } - } - - return s_imfReady; -} - -QBBInputContext::QBBInputContext(): - QPlatformInputContext(), - m_lastCaretPos(0), - m_isComposing(false), - m_inputPanelVisible(false), - m_inputPanelLocale(QLocale::c()) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!imfAvailable()) - return; - - if ( p_imf_client_init() != 0 ) { - s_imfInitFailed = true; - qCritical("imf_client_init failed - IMF services will be unavailable"); - } - - QCoreApplication::instance()->installEventFilter(this); - - // p_vkb_init_selection_service(); - - QBBVirtualKeyboard &keyboard = QBBVirtualKeyboard::instance(); - connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool))); - connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale))); - keyboardVisibilityChanged(keyboard.isVisible()); - keyboardLocaleChanged(keyboard.locale()); - - QInputMethod *inputMethod = qApp->inputMethod(); - connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); - -} - -QBBInputContext::~QBBInputContext() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!imfAvailable()) - return; - - QCoreApplication::instance()->removeEventFilter(this); - p_imf_client_disconnect(); -} - -#define getarg(type, name) type name = imfEvent->mArgs[qs(#name)].value() -#define getparg(type, name) type name = (type)(imfEvent->mArgs[qs(#name)].value()) - -bool QBBInputContext::isValid() const -{ - return imfAvailable(); -} - -bool QBBInputContext::eventFilter(QObject *obj, QEvent *event) -{ - if (event->type() == ImfEvent::sUserEventType) { - // Forward the event to our real handler. - ImfEvent *imfEvent = static_cast(event); - switch (imfEvent->m_imfType) { - case ImfBeginBatchEdit: { - int32_t ret = onBeginBatchEdit(imfEvent->m_session); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfClearMetaKeyStates: { - getarg(int32_t, states); - int32_t ret = onClearMetaKeyStates(imfEvent->m_session, states); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfCommitText: { - getparg(spannable_string_t*, text); - getarg(int32_t, new_cursor_position); - int32_t ret = onCommitText(imfEvent->m_session, text, new_cursor_position); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfDeleteSurroundingText: { - getarg(int32_t, left_length); - getarg(int32_t, right_length); - int32_t ret = onDeleteSurroundingText(imfEvent->m_session, left_length, right_length); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfEndBatchEdit: { - int32_t ret = onEndBatchEdit(imfEvent->m_session); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfFinishComposingText: { - int32_t ret = onFinishComposingText(imfEvent->m_session); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfGetCursorCapsMode: { - getarg(int32_t, req_modes); - int32_t ret = onGetCursorCapsMode(imfEvent->m_session, req_modes); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfGetCursorPosition: { - int32_t ret = onGetCursorPosition(imfEvent->m_session); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfGetExtractedText: { - getparg(extracted_text_request_t*, request); - getarg(int32_t, flags); - extracted_text_t *ret = onGetExtractedText(imfEvent->m_session, request, flags); - imfEvent->m_result->setResult(QVariant::fromValue(static_cast(ret))); - break; - } - - case ImfGetSelectedText: { - getarg(int32_t, flags); - spannable_string_t *ret = onGetSelectedText(imfEvent->m_session, flags); - imfEvent->m_result->setResult(QVariant::fromValue(static_cast(ret))); - break; - } - - case ImfGetTextAfterCursor: { - getarg(int32_t, n); - getarg(int32_t, flags); - spannable_string_t *ret = onGetTextAfterCursor(imfEvent->m_session, n, flags); - imfEvent->m_result->setResult(QVariant::fromValue(static_cast(ret))); - break; - } - - case ImfGetTextBeforeCursor: { - getarg(int32_t, n); - getarg(int32_t, flags); - spannable_string_t *ret = onGetTextBeforeCursor(imfEvent->m_session, n, flags); - imfEvent->m_result->setResult(QVariant::fromValue((void*)ret)); - break; - } - - case ImfPerformEditorAction: { - getarg(int32_t, editor_action); - int32_t ret = onPerformEditorAction(imfEvent->m_session, editor_action); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfReportFullscreenMode: { - getarg(int32_t, enabled); - int32_t ret = onReportFullscreenMode(imfEvent->m_session, enabled); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfSendEvent: { - getparg(event_t*, event); - onSendEvent(imfEvent->m_session, event); - break; - } - - case ImfSendAsyncEvent: { - getparg(event_t*, event); - onSendAsyncEvent(imfEvent->m_session, event); - break; - } - - case ImfSetComposingRegion: { - getarg(int32_t, start); - getarg(int32_t, end); - int32_t ret = onSetComposingRegion(imfEvent->m_session, start, end); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfSetComposingText: { - getparg(spannable_string_t*, text); - getarg(int32_t, new_cursor_position); - int32_t ret = onSetComposingText(imfEvent->m_session, text, new_cursor_position); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - - case ImfSetSelection: { - getarg(int32_t, start); - getarg(int32_t, end); - int32_t ret = onSetSelection(imfEvent->m_session, start, end); - imfEvent->m_result->setResult(QVariant::fromValue(ret)); - break; - } - }; //switch - - return true; - } else { - // standard event processing - return QObject::eventFilter(obj, event); - } -} - -bool QBBInputContext::filterEvent( const QEvent *event ) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << event; -#endif - switch (event->type()) { - case QEvent::CloseSoftwareInputPanel: { - return dispatchCloseSoftwareInputPanel(); - } - case QEvent::RequestSoftwareInputPanel: { - return dispatchRequestSoftwareInputPanel(); - } - default: - return false; - } -} - -void QBBInputContext::reset() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - endComposition(); -} - -void QBBInputContext::update(Qt::InputMethodQueries queries) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - reset(); - - QPlatformInputContext::update(queries); -} - -void QBBInputContext::closeSession() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO -#endif - if (!imfAvailable()) - return; - - if (sInputSession) { - p_ictrl_close_session((input_session_t *)sInputSession); - sInputSession = 0; - } -} - -void QBBInputContext::openSession() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO -#endif - if (!imfAvailable()) - return; - - closeSession(); - sInputSession = p_ictrl_open_session(&ic_funcs); -} - -bool QBBInputContext::hasSession() -{ - return sInputSession != 0; -} - -bool QBBInputContext::hasSelectedText() -{ - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!input) - return false; - - QInputMethodQueryEvent query(Qt::ImCurrentSelection); - QCoreApplication::sendEvent(input, &query); - - return !query.value(Qt::ImCurrentSelection).toString().isEmpty(); -} - -bool QBBInputContext::dispatchRequestSoftwareInputPanel() -{ - QBBVirtualKeyboard::instance().showKeyboard(); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << "QBB: requesting virtual keyboard"; -#endif - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return true; - - if (!hasSession()) - openSession(); - - // This also means that the caret position has moved - QInputMethodQueryEvent query(Qt::ImCursorPosition); - QCoreApplication::sendEvent(input, &query); - int caretPos = query.value(Qt::ImCursorPosition).toInt(); - caret_event_t caretEvent; - memset(&caretEvent, 0, sizeof(caret_event_t)); - initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED); - caretEvent.old_pos = m_lastCaretPos; - m_lastCaretPos = caretEvent.new_pos = caretPos; - p_ictrl_dispatch_event((event_t *)&caretEvent); - return true; -} - -bool QBBInputContext::dispatchCloseSoftwareInputPanel() -{ - QBBVirtualKeyboard::instance().hideKeyboard(); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << "QBB: hiding virtual keyboard"; -#endif - - // This also means we are stopping composition, but we should already have done that. - return true; -} - -/** - * IMF Event Dispatchers. - */ -bool QBBInputContext::dispatchFocusEvent(FocusEventId id, int hints) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!sInputSession) { - qWarning() << Q_FUNC_INFO << "Attempt to dispatch a focus event with no input session."; - return false; - } - - if (!imfAvailable()) - return false; - - // Set the last caret position to 0 since we don't really have one and we don't - // want to have the old one. - m_lastCaretPos = 0; - - focus_event_t focusEvent; - memset(&focusEvent, 0, sizeof(focusEvent)); - initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, id); - focusEvent.style = DEFAULT_STYLE; - - if (hints && Qt::ImhNoPredictiveText) - focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION; - if (hints && Qt::ImhNoAutoUppercase) - focusEvent.style |= NO_AUTO_TEXT; - - p_ictrl_dispatch_event((event_t *)&focusEvent); - - return true; -} - -bool QBBInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap) -{ - if (!imfAvailable()) - return false; - - int key = (flags & KEY_SYM_VALID) ? sym : cap; - bool navKey = false; - switch ( key ) { - case KEYCODE_RETURN: - /* In a single line edit we should end composition because enter might be used by something. - endComposition(); - return false;*/ - break; - - case KEYCODE_BACKSPACE: - case KEYCODE_DELETE: - // If there is a selection range, then we want a delete key to operate on that (by - // deleting the contents of the select range) rather than operating on the composition - // range. - if (hasSelectedText()) - return false; - break; - case KEYCODE_LEFT: - key = NAVIGATE_LEFT; - navKey = true; - break; - case KEYCODE_RIGHT: - key = NAVIGATE_RIGHT; - navKey = true; - break; - case KEYCODE_UP: - key = NAVIGATE_UP; - navKey = true; - break; - case KEYCODE_DOWN: - key = NAVIGATE_DOWN; - navKey = true; - break; - case KEYCODE_CAPS_LOCK: - case KEYCODE_LEFT_SHIFT: - case KEYCODE_RIGHT_SHIFT: - case KEYCODE_LEFT_CTRL: - case KEYCODE_RIGHT_CTRL: - case KEYCODE_LEFT_ALT: - case KEYCODE_RIGHT_ALT: - case KEYCODE_MENU: - case KEYCODE_LEFT_HYPER: - case KEYCODE_RIGHT_HYPER: - case KEYCODE_INSERT: - case KEYCODE_HOME: - case KEYCODE_PG_UP: - case KEYCODE_END: - case KEYCODE_PG_DOWN: - // Don't send these - key = 0; - break; - } - - if ( mod & KEYMOD_CTRL ) { - // If CTRL is pressed, just let AIR handle it. But terminate any composition first - //endComposition(); - return false; - } - - // Pass the keys we don't know about on through - if ( key == 0 ) - return false; - - // IMF doesn't need key releases so just swallow them. - if (!(flags & KEY_DOWN)) - return true; - - if ( navKey ) { - // Even if we're forwarding up events, we can't do this for - // navigation keys. - if ( flags & KEY_DOWN ) { - navigation_event_t navEvent; - initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key); - navEvent.magnitude = 1; -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "dispatch navigation event " << key; -#endif - p_ictrl_dispatch_event(&navEvent.event); - } - } - else { - key_event_t keyEvent; - initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP); - keyEvent.key_code = key; - keyEvent.character = 0; - keyEvent.meta_key_state = 0; - - p_ictrl_dispatch_event(&keyEvent.event); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "dispatch key event " << key; -#endif - } - - scan = 0; - return true; -} - -void QBBInputContext::endComposition() -{ - if (!m_isComposing) - return; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return; - - QList attributes; - QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(m_composingText); - m_composingText = QString(); - m_isComposing = false; - QCoreApplication::sendEvent(input, &event); - - action_event_t actionEvent; - memset(&actionEvent, 0, sizeof(actionEvent)); - initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION); - p_ictrl_dispatch_event(&actionEvent.event); -} - -void QBBInputContext::setComposingText(QString const& composingText) -{ - m_composingText = composingText; - m_isComposing = true; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return; - - QList attributes; - QTextCharFormat format; - format.setFontUnderline(true); - attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, composingText.length(), format)); - - QInputMethodEvent event(composingText, attributes); - - QCoreApplication::sendEvent(input, &event); -} - -int32_t QBBInputContext::processEvent(event_t *event) -{ - int32_t result = -1; - switch (event->event_type) { - case EVENT_SPELL_CHECK: { - #if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "EVENT_SPELL_CHECK"; - #endif - result = 0; - break; - } - - case EVENT_NAVIGATION: { - #if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "EVENT_NAVIGATION"; - #endif - - int key = event->event_id == NAVIGATE_UP ? KEYCODE_UP : - event->event_id == NAVIGATE_DOWN ? KEYCODE_DOWN : - event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT : - event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0; - - QBBEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0); - QBBEventThread::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0); - result = 0; - break; - } - - case EVENT_KEY: { - #if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "EVENT_KEY"; - #endif - key_event_t *kevent = static_cast(event); - - QBBEventThread::injectKeyboardEvent(KEY_DOWN | KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code); - QBBEventThread::injectKeyboardEvent(KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code); - - result = 0; - break; - } - - case EVENT_ACTION: - // Don't care, indicates that IMF is done. - break; - - case EVENT_CARET: - case EVENT_NOTHING: - case EVENT_FOCUS: - case EVENT_USER_ACTION: - case EVENT_STROKE: - case EVENT_INVOKE_LATER: - qCritical() << Q_FUNC_INFO << "Unsupported event type: " << event->event_type; - break; - default: - qCritical() << Q_FUNC_INFO << "Unknown event type: " << event->event_type; - } - return result; -} - -/** - * IMF Event Handlers - */ - -int32_t QBBInputContext::onBeginBatchEdit(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - // We don't care. - return 0; -} - -int32_t QBBInputContext::onClearMetaKeyStates(input_session_t *ic, int32_t states) -{ - Q_UNUSED(states); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - // Should never get called. - qCritical() << Q_FUNC_INFO << "onClearMetaKeyStates is unsupported."; - return 0; -} - -int32_t QBBInputContext::onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) -{ - Q_UNUSED(new_cursor_position); // TODO: How can we set the cursor position it's not part of the API. - if (!isSessionOkay(ic)) - return 0; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - QString commitString = QString::fromWCharArray(text->str, text->length); - -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "Committing [" << commitString << "]"; -#endif - - QList attributes; - QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(commitString, 0, 0); - - QCoreApplication::sendEvent(input, &event); - m_composingText = QString(); - - return 0; -} - -int32_t QBBInputContext::onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "L:" << left_length << " R:" << right_length; -#endif - - if (!isSessionOkay(ic)) - return 0; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - if (hasSelectedText()) { - QBBEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0); - QBBEventThread::injectKeyboardEvent(KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0); - reset(); - return 0; - } - - int replacementLength = left_length + right_length; - int replacementStart = -left_length; - - QList attributes; - QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(QLatin1String(""), replacementStart, replacementLength); - QCoreApplication::sendEvent(input, &event); - - return 0; -} - -int32_t QBBInputContext::onEndBatchEdit(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - return 0; -} - -int32_t QBBInputContext::onFinishComposingText(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - // Only update the control, no need to send a message back to imf (don't call - // end composition) - QList attributes; - QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(m_composingText); - m_composingText = QString(); - m_isComposing = false; - QCoreApplication::sendEvent(input, &event); - - return 0; -} - -int32_t QBBInputContext::onGetCursorCapsMode(input_session_t *ic, int32_t req_modes) -{ - Q_UNUSED(req_modes); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - // Should never get called. - qCritical() << Q_FUNC_INFO << "onGetCursorCapsMode is unsupported."; - - return 0; -} - -int32_t QBBInputContext::onGetCursorPosition(input_session_t *ic) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - QInputMethodQueryEvent query(Qt::ImCursorPosition); - QCoreApplication::sendEvent(input, &query); - m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); - - return m_lastCaretPos; -} - -extracted_text_t *QBBInputContext::onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags) -{ - Q_UNUSED(flags); - Q_UNUSED(request); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) { - extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1); - et->text = reinterpret_cast(calloc(sizeof(spannable_string_t),1)); - return et; - } - - // Used to update dictionaries, but not supported right now. - extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1); - et->text = reinterpret_cast(calloc(sizeof(spannable_string_t),1)); - - return et; -} - -spannable_string_t *QBBInputContext::onGetSelectedText(input_session_t *ic, int32_t flags) -{ - Q_UNUSED(flags); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return toSpannableString(""); - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - QInputMethodQueryEvent query(Qt::ImCurrentSelection); - QCoreApplication::sendEvent(input, &query); - QString text = query.value(Qt::ImCurrentSelection).toString(); - - return toSpannableString(text); -} - -spannable_string_t *QBBInputContext::onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags) -{ - Q_UNUSED(flags); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return toSpannableString(""); - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return toSpannableString(""); - - QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText); - QCoreApplication::sendEvent(input, &query); - QString text = query.value(Qt::ImSurroundingText).toString(); - m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); - - return toSpannableString(text.mid(m_lastCaretPos+1, n)); -} - -spannable_string_t *QBBInputContext::onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags) -{ - Q_UNUSED(flags); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return toSpannableString(""); - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return toSpannableString(""); - - QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText); - QCoreApplication::sendEvent(input, &query); - QString text = query.value(Qt::ImSurroundingText).toString(); - m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); - - if (n < m_lastCaretPos) { - return toSpannableString(text.mid(m_lastCaretPos - n, n)); - } else { - return toSpannableString(text.mid(0, m_lastCaretPos)); - } -} - -int32_t QBBInputContext::onPerformEditorAction(input_session_t *ic, int32_t editor_action) -{ - Q_UNUSED(editor_action); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - // Should never get called. - qCritical() << Q_FUNC_INFO << "onPerformEditorAction is unsupported."; - - return 0; -} - -int32_t QBBInputContext::onReportFullscreenMode(input_session_t *ic, int32_t enabled) -{ - Q_UNUSED(enabled); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - // Should never get called. - qCritical() << Q_FUNC_INFO << "onReportFullscreenMode is unsupported."; - - return 0; -} - -int32_t QBBInputContext::onSendEvent(input_session_t *ic, event_t *event) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - return processEvent(event); -} - -int32_t QBBInputContext::onSendAsyncEvent(input_session_t *ic, event_t *event) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - return processEvent(event); -} - -int32_t QBBInputContext::onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText); - QCoreApplication::sendEvent(input, &query); - QString text = query.value(Qt::ImSurroundingText).toString(); - m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); - - QString empty = QString::fromLatin1(""); - text = text.mid(start, end - start); - - // Delete the current text. - QList attributes; - QInputMethodEvent event(empty, attributes); - event.setCommitString(empty, start - m_lastCaretPos, end - start); - QCoreApplication::sendEvent(input, &event); - - // Move the specified text into a preedit string. - setComposingText(text); - - return 0; -} - -int32_t QBBInputContext::onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) -{ - Q_UNUSED(new_cursor_position); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - QInputPanel *panel = qApp->inputPanel(); - QObject *input = panel->inputItem(); - if (!imfAvailable() || !input) - return 0; - - m_isComposing = true; - - QString preeditString = QString::fromWCharArray(text->str, text->length); - setComposingText(preeditString); - - return 0; -} - -int32_t QBBInputContext::onSetSelection(input_session_t *ic, int32_t start, int32_t end) -{ - Q_UNUSED(start); - Q_UNUSED(end); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - - if (!isSessionOkay(ic)) - return 0; - - // Should never get called. - qCritical() << Q_FUNC_INFO << "onSetSelection is unsupported."; - - return 0; -} - -void QBBInputContext::showInputPanel() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - dispatchRequestSoftwareInputPanel(); -} - -void QBBInputContext::hideInputPanel() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - dispatchCloseSoftwareInputPanel(); -} - -bool QBBInputContext::isInputPanelVisible() const -{ - return m_inputPanelVisible; -} - -QLocale QBBInputContext::locale() const -{ - return m_inputPanelLocale; -} - -void QBBInputContext::keyboardVisibilityChanged(bool visible) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "visible=" << visible; -#endif - if (m_inputPanelVisible != visible) { - m_inputPanelVisible = visible; - emitInputPanelVisibleChanged(); - } -} - -void QBBInputContext::keyboardLocaleChanged(const QLocale &locale) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "locale=" << locale; -#endif - if (m_inputPanelLocale != locale) { - m_inputPanelLocale = locale; - emitLocaleChanged(); - } -} - -void QBBInputContext::inputItemChanged() -{ - QInputMethod *inputMethod = qApp->inputMethod(); - QObject *inputItem = inputMethod->inputItem(); - -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "input item=" << inputItem; -#endif - - if (!inputItem) { - if (m_inputPanelVisible) - hideInputPanel(); - } else { - if (qobject_cast(inputItem)) { - QBBVirtualKeyboard::instance().setKeyboardMode(QBBVirtualKeyboard::NumPunc); - } else { - QBBVirtualKeyboard::instance().setKeyboardMode(QBBVirtualKeyboard::Default); - } - if (!m_inputPanelVisible) - showInputPanel(); - } -} diff --git a/src/plugins/platforms/blackberry/qbbinputcontext_imf.h b/src/plugins/platforms/blackberry/qbbinputcontext_imf.h deleted file mode 100644 index 135ec02971..0000000000 --- a/src/plugins/platforms/blackberry/qbbinputcontext_imf.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBINPUTCONTEXT_H -#define QBBINPUTCONTEXT_H - -#include - -#include -#include -#include - -#include "imf/imf_client.h" -#include "imf/input_control.h" - -QT_BEGIN_NAMESPACE - -class QBBInputContext : public QPlatformInputContext -{ - Q_OBJECT -public: - QBBInputContext(); - ~QBBInputContext(); - - virtual bool isValid() const; - - virtual bool filterEvent(const QEvent *event); - virtual void reset(); - virtual void update(Qt::InputMethodQueries); - bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - - virtual void showInputPanel(); - virtual void hideInputPanel(); - virtual bool isInputPanelVisible() const; - - virtual QLocale locale() const; - -protected: - // Filters only for IMF events. - bool eventFilter(QObject *obj, QEvent *event); - -private Q_SLOTS: - void keyboardVisibilityChanged(bool visible); - void keyboardLocaleChanged(const QLocale &locale); - void inputItemChanged(); - -private: - // IMF Event dispatchers - bool dispatchFocusEvent(FocusEventId id, int hints = Qt::ImhNone); - bool dispatchRequestSoftwareInputPanel(); - bool dispatchCloseSoftwareInputPanel(); - int32_t processEvent(event_t *event); - - void closeSession(); - void openSession(); - bool hasSession(); - void endComposition(); - void setComposingText(QString const &composingText); - bool hasSelectedText(); - - // IMF Event handlers - these events will come in from QCoreApplication. - int32_t onBeginBatchEdit(input_session_t *ic); - int32_t onClearMetaKeyStates(input_session_t *ic, int32_t states); - int32_t onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position); - int32_t onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length); - int32_t onEndBatchEdit(input_session_t *ic); - int32_t onFinishComposingText(input_session_t *ic); - int32_t onGetCursorCapsMode(input_session_t *ic, int32_t req_modes); - int32_t onGetCursorPosition(input_session_t *ic); - extracted_text_t *onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags); - spannable_string_t *onGetSelectedText(input_session_t *ic, int32_t flags); - spannable_string_t *onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags); - spannable_string_t *onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags); - int32_t onPerformEditorAction(input_session_t *ic, int32_t editor_action); - int32_t onReportFullscreenMode(input_session_t *ic, int32_t enabled); - int32_t onSendEvent(input_session_t *ic, event_t *event); - int32_t onSendAsyncEvent(input_session_t *ic, event_t *event); - int32_t onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end); - int32_t onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position); - int32_t onSetSelection(input_session_t *ic, int32_t start, int32_t end); - int32_t onForceUpdate(); - - int m_lastCaretPos; - bool m_isComposing; - QString m_composingText; - bool m_inputPanelVisible; - QLocale m_inputPanelLocale; -}; - -Q_DECLARE_METATYPE(extracted_text_t*) - -QT_END_NAMESPACE - -#endif // QBBINPUTCONTEXT_H diff --git a/src/plugins/platforms/blackberry/qbbinputcontext_noimf.cpp b/src/plugins/platforms/blackberry/qbbinputcontext_noimf.cpp deleted file mode 100644 index abe84e2e53..0000000000 --- a/src/plugins/platforms/blackberry/qbbinputcontext_noimf.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbinputcontext_noimf.h" -#include "qbbvirtualkeyboard.h" - -#include -#include -#include - -QBBInputContext::QBBInputContext() : - QPlatformInputContext(), - m_inputPanelVisible(false), - m_inputPanelLocale(QLocale::c()) -{ - QBBVirtualKeyboard &keyboard = QBBVirtualKeyboard::instance(); - connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool))); - connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale))); - keyboardVisibilityChanged(keyboard.isVisible()); - keyboardLocaleChanged(keyboard.locale()); - - QInputMethod *inputMethod = qApp->inputMethod(); - connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); -} - -QBBInputContext::~QBBInputContext() -{ -} - -bool QBBInputContext::isValid() const -{ - return true; -} - -bool QBBInputContext::hasPhysicalKeyboard() -{ - // TODO: This should query the system to check if a USB keyboard is connected. - return false; -} - -void QBBInputContext::reset() -{ -} - -bool QBBInputContext::filterEvent( const QEvent *event ) -{ - if (hasPhysicalKeyboard()) - return false; - - if (event->type() == QEvent::CloseSoftwareInputPanel) { - QBBVirtualKeyboard::instance().hideKeyboard(); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << "QBB: hiding virtual keyboard"; -#endif - return false; - } - - if (event->type() == QEvent::RequestSoftwareInputPanel) { - QBBVirtualKeyboard::instance().showKeyboard(); -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << "QBB: requesting virtual keyboard"; -#endif - return false; - } - - return false; - -} - -bool QBBInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap) -{ - Q_UNUSED(flags); - Q_UNUSED(sym); - Q_UNUSED(mod); - Q_UNUSED(scan); - Q_UNUSED(cap); - return false; -} - -void QBBInputContext::showInputPanel() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - QBBVirtualKeyboard::instance().showKeyboard(); -} - -void QBBInputContext::hideInputPanel() -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - QBBVirtualKeyboard::instance().hideKeyboard(); -} - -bool QBBInputContext::isInputPanelVisible() const -{ - return m_inputPanelVisible; -} - -QLocale QBBInputContext::locale() const -{ - return m_inputPanelLocale; -} - -void QBBInputContext::keyboardVisibilityChanged(bool visible) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "visible=" << visible; -#endif - if (m_inputPanelVisible != visible) { - m_inputPanelVisible = visible; - emitInputPanelVisibleChanged(); - } -} - -void QBBInputContext::keyboardLocaleChanged(const QLocale &locale) -{ -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "locale=" << locale; -#endif - if (m_inputPanelLocale != locale) { - m_inputPanelLocale = locale; - emitLocaleChanged(); - } -} - -void QBBInputContext::inputItemChanged() -{ - QInputMethod *inputMethod = qApp->inputMethod(); - QObject *inputItem = inputMethod->inputItem(); - -#if defined(QBBINPUTCONTEXT_DEBUG) - qDebug() << Q_FUNC_INFO << "input item=" << inputItem; -#endif - - if (!inputItem) { - if (m_inputPanelVisible) - hideInputPanel(); - } else { - if (qobject_cast(inputItem)) { - QBBVirtualKeyboard::instance().setKeyboardMode(QBBVirtualKeyboard::NumPunc); - } else { - QBBVirtualKeyboard::instance().setKeyboardMode(QBBVirtualKeyboard::Default); - } - if (!m_inputPanelVisible) - showInputPanel(); - } -} diff --git a/src/plugins/platforms/blackberry/qbbinputcontext_noimf.h b/src/plugins/platforms/blackberry/qbbinputcontext_noimf.h deleted file mode 100644 index 3d4d6da830..0000000000 --- a/src/plugins/platforms/blackberry/qbbinputcontext_noimf.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBINPUTCONTEXT_H -#define QBBINPUTCONTEXT_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QBBInputContext : public QPlatformInputContext -{ - Q_OBJECT -public: - explicit QBBInputContext(); - ~QBBInputContext(); - - virtual bool isValid() const; - - void reset(); - virtual bool filterEvent( const QEvent *event ); - bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap); - - virtual void showInputPanel(); - virtual void hideInputPanel(); - virtual bool isInputPanelVisible() const; - - virtual QLocale locale() const; - -private Q_SLOTS: - void keyboardVisibilityChanged(bool visible); - void keyboardLocaleChanged(const QLocale &locale); - void inputItemChanged(); - -private: - bool hasPhysicalKeyboard(); - - bool m_inputPanelVisible; - QLocale m_inputPanelLocale; -}; - -QT_END_NAMESPACE - -#endif // QBBINPUTCONTEXT_H diff --git a/src/plugins/platforms/blackberry/qbbintegration.cpp b/src/plugins/platforms/blackberry/qbbintegration.cpp deleted file mode 100644 index 9f922a419e..0000000000 --- a/src/plugins/platforms/blackberry/qbbintegration.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbintegration.h" -#include "qbbeventthread.h" -#include "qbbglbackingstore.h" -#include "qbbglcontext.h" -#include "qbbnavigatorthread.h" -#include "qbbrasterbackingstore.h" -#include "qbbscreen.h" -#include "qbbwindow.h" -#include "qbbvirtualkeyboard.h" -#include "qbbclipboard.h" -#include "qbbglcontext.h" - -#if defined(QBB_IMF) -#include "qbbinputcontext_imf.h" -#else -#include "qbbinputcontext_noimf.h" -#endif - -#include "private/qgenericunixfontdatabase_p.h" -#include "private/qgenericunixeventdispatcher_p.h" - -#include -#include -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -QBBWindowMapper QBBIntegration::ms_windowMapper; -QMutex QBBIntegration::ms_windowMapperMutex; - -QBBIntegration::QBBIntegration() - : QPlatformIntegration() - , m_eventThread(0) - , m_navigatorThread(0) - , m_inputContext(0) - , m_fontDatabase(new QGenericUnixFontDatabase()) - , m_paintUsingOpenGL(false) - , m_eventDispatcher(createUnixEventDispatcher()) -#ifndef QT_NO_CLIPBOARD - , m_clipboard(0) -#endif -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Open connection to QNX composition manager - errno = 0; - int result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT); - if (result != 0) { - qFatal("QBB: failed to connect to composition manager, errno=%d", errno); - } - - // Create displays for all possible screens (which may not be attached) - QBBScreen::createDisplays(m_screenContext); - Q_FOREACH (QPlatformScreen *screen, QBBScreen::screens()) { - screenAdded(screen); - } - - // Initialize global OpenGL resources - QBBGLContext::initialize(); - - // Create/start event thread - m_eventThread = new QBBEventThread(m_screenContext, *QBBScreen::primaryDisplay()); - m_eventThread->start(); - - // Create/start navigator thread - m_navigatorThread = new QBBNavigatorThread(*QBBScreen::primaryDisplay()); - m_navigatorThread->start(); - - // Create/start the keyboard class. - QBBVirtualKeyboard::instance(); - - // Set up the input context - m_inputContext = new QBBInputContext; -} - -QBBIntegration::~QBBIntegration() -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << "QBB: platform plugin shutdown begin"; -#endif - // Destroy the keyboard class. - QBBVirtualKeyboard::destroy(); - -#ifndef QT_NO_CLIPBOARD - // Delete the clipboard - delete m_clipboard; -#endif - - // Stop/destroy event thread - delete m_eventThread; - - // Stop/destroy navigator thread - delete m_navigatorThread; - - // Destroy all displays - QBBScreen::destroyDisplays(); - - // Close connection to QNX composition manager - screen_destroy_context(m_screenContext); - - // Cleanup global OpenGL resources - QBBGLContext::shutdown(); - -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << "QBB: platform plugin shutdown end"; -#endif -} - -bool QBBIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - switch (cap) { - case ThreadedPixmaps: return true; -#if defined(QT_OPENGL_ES) - case OpenGL: - return true; -#endif - default: return QPlatformIntegration::hasCapability(cap); - } -} - -QPlatformWindow *QBBIntegration::createPlatformWindow(QWindow *window) const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // New windows are created on the primary display. - return new QBBWindow(window, m_screenContext); -} - -QPlatformBackingStore *QBBIntegration::createPlatformBackingStore(QWindow *window) const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - if (paintUsingOpenGL()) - return new QBBGLBackingStore(window); - else - return new QBBRasterBackingStore(window); -} - -QPlatformOpenGLContext *QBBIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - return new QBBGLContext(context); -} - -QPlatformInputContext *QBBIntegration::inputContext() const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - return m_inputContext; -} - -void QBBIntegration::moveToScreen(QWindow *window, int screen) -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << "QBBIntegration::moveToScreen - w=" << window << ", s=" << screen; -#endif - - // get platform window used by widget - QBBWindow *platformWindow = static_cast(window->handle()); - - // lookup platform screen by index - QBBScreen *platformScreen = static_cast(QBBScreen::screens().at(screen)); - - // move the platform window to the platform screen - platformWindow->setScreen(platformScreen); -} - -QList QBBIntegration::screens() const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - return QBBScreen::screens(); -} - -QAbstractEventDispatcher *QBBIntegration::guiThreadEventDispatcher() const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - return m_eventDispatcher; -} - -#ifndef QT_NO_CLIPBOARD -QPlatformClipboard *QBBIntegration::clipboard() const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - if (!m_clipboard) { - m_clipboard = new QBBClipboard; - } - return m_clipboard; -} -#endif - -QVariant QBBIntegration::styleHint(QPlatformIntegration::StyleHint hint) const -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - if (hint == ShowIsFullScreen) - return true; - - return QPlatformIntegration::styleHint(hint); -} - -QWindow *QBBIntegration::window(screen_window_t qnxWindow) -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - QMutexLocker locker(&ms_windowMapperMutex); - Q_UNUSED(locker); - return ms_windowMapper.value(qnxWindow, 0); -} - -void QBBIntegration::addWindow(screen_window_t qnxWindow, QWindow *window) -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - QMutexLocker locker(&ms_windowMapperMutex); - Q_UNUSED(locker); - ms_windowMapper.insert(qnxWindow, window); -} - -void QBBIntegration::removeWindow(screen_window_t qnxWindow) -{ -#if defined(QBBINTEGRATION_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - QMutexLocker locker(&ms_windowMapperMutex); - Q_UNUSED(locker); - ms_windowMapper.remove(qnxWindow); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbintegration.h b/src/plugins/platforms/blackberry/qbbintegration.h deleted file mode 100644 index 6b54329dac..0000000000 --- a/src/plugins/platforms/blackberry/qbbintegration.h +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBINTEGRATION_H -#define QBBINTEGRATION_H - -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBEventThread; -class QBBInputContext; -class QBBNavigatorThread; -class QBBWindow; - -#ifndef QT_NO_CLIPBOARD -class QBBClipboard; -#endif - -template class QHash; -typedef QHash QBBWindowMapper; - -class QBBIntegration : public QPlatformIntegration -{ -public: - QBBIntegration(); - virtual ~QBBIntegration(); - - virtual bool hasCapability(QPlatformIntegration::Capability cap) const; - - virtual QPlatformWindow *createPlatformWindow(QWindow *window) const; - virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; - - virtual QPlatformInputContext *inputContext() const; - - virtual QList screens() const; - virtual void moveToScreen(QWindow *window, int screen); - - virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const; - - virtual QPlatformFontDatabase *fontDatabase() const { return m_fontDatabase; } - -#ifndef QT_NO_CLIPBOARD - virtual QPlatformClipboard *clipboard() const; -#endif - - virtual QVariant styleHint(StyleHint hint) const; - - bool paintUsingOpenGL() const { return m_paintUsingOpenGL; } - - static QWindow *window(screen_window_t qnxWindow); - -private: - static void addWindow(screen_window_t qnxWindow, QWindow *window); - static void removeWindow(screen_window_t qnxWindow); - - screen_context_t m_screenContext; - QBBEventThread *m_eventThread; - QBBNavigatorThread *m_navigatorThread; - QBBInputContext *m_inputContext; - QPlatformFontDatabase *m_fontDatabase; - bool m_paintUsingOpenGL; - QAbstractEventDispatcher *m_eventDispatcher; -#ifndef QT_NO_CLIPBOARD - mutable QBBClipboard* m_clipboard; -#endif - - static QBBWindowMapper ms_windowMapper; - static QMutex ms_windowMapperMutex; - - friend class QBBWindow; -}; - -QT_END_NAMESPACE - -#endif // QBBINTEGRATION_H diff --git a/src/plugins/platforms/blackberry/qbbkeytranslator.h b/src/plugins/platforms/blackberry/qbbkeytranslator.h deleted file mode 100644 index fdc1220aba..0000000000 --- a/src/plugins/platforms/blackberry/qbbkeytranslator.h +++ /dev/null @@ -1,269 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBKEYTRANSLATOR_H -#define QBBKEYTRANSLATOR_H - -#include - -#if defined(QBBEVENTTHREAD_DEBUG) -#include -#endif - -QT_BEGIN_NAMESPACE - -Qt::Key keyTranslator( int key ) -{ - switch (key) { - case KEYCODE_PAUSE: - return Qt::Key_Pause; - - case KEYCODE_SCROLL_LOCK: - return Qt::Key_ScrollLock; - - case KEYCODE_PRINT: - return Qt::Key_Print; - - case KEYCODE_SYSREQ: - return Qt::Key_SysReq; - -// case KEYCODE_BREAK: - - case KEYCODE_ESCAPE: - return Qt::Key_Escape; - - case KEYCODE_BACKSPACE: - return Qt::Key_Backspace; - - case KEYCODE_TAB: - return Qt::Key_Tab; - - case KEYCODE_BACK_TAB: - return Qt::Key_Backtab; - - case KEYCODE_RETURN: - return Qt::Key_Return; - - case KEYCODE_CAPS_LOCK: - return Qt::Key_CapsLock; - - case KEYCODE_LEFT_SHIFT: - case KEYCODE_RIGHT_SHIFT: - return Qt::Key_Shift; - - case KEYCODE_LEFT_CTRL: - case KEYCODE_RIGHT_CTRL: - return Qt::Key_Control; - - case KEYCODE_LEFT_ALT: - case KEYCODE_RIGHT_ALT: - return Qt::Key_Alt; - - case KEYCODE_MENU: - return Qt::Key_Menu; - - case KEYCODE_LEFT_HYPER: - return Qt::Key_Hyper_L; - - case KEYCODE_RIGHT_HYPER: - return Qt::Key_Hyper_R; - - case KEYCODE_INSERT: - return Qt::Key_Insert; - - case KEYCODE_HOME: - return Qt::Key_Home; - - case KEYCODE_PG_UP: - return Qt::Key_PageUp; - - case KEYCODE_DELETE: - return Qt::Key_Delete; - - case KEYCODE_END: - return Qt::Key_End; - - case KEYCODE_PG_DOWN: - return Qt::Key_PageDown; - - case KEYCODE_LEFT: - return Qt::Key_Left; - - case KEYCODE_RIGHT: - return Qt::Key_Right; - - case KEYCODE_UP: - return Qt::Key_Up; - - case KEYCODE_DOWN: - return Qt::Key_Down; - - case KEYCODE_NUM_LOCK: - return Qt::Key_NumLock; - - case KEYCODE_KP_PLUS: - return Qt::Key_Plus; - - case KEYCODE_KP_MINUS: - return Qt::Key_Minus; - - case KEYCODE_KP_MULTIPLY: - return Qt::Key_Asterisk; - - case KEYCODE_KP_DIVIDE: - return Qt::Key_Slash; - - case KEYCODE_KP_ENTER: - return Qt::Key_Enter; - - case KEYCODE_KP_HOME: - return Qt::Key_Home; - - case KEYCODE_KP_UP: - return Qt::Key_Up; - - case KEYCODE_KP_PG_UP: - return Qt::Key_PageUp; - - case KEYCODE_KP_LEFT: - return Qt::Key_Left; - - // Is this right? - case KEYCODE_KP_FIVE: - return Qt::Key_5; - - case KEYCODE_KP_RIGHT: - return Qt::Key_Right; - - case KEYCODE_KP_END: - return Qt::Key_End; - - case KEYCODE_KP_DOWN: - return Qt::Key_Down; - - case KEYCODE_KP_PG_DOWN: - return Qt::Key_PageDown; - - case KEYCODE_KP_INSERT: - return Qt::Key_Insert; - - case KEYCODE_KP_DELETE: - return Qt::Key_Delete; - - case KEYCODE_F1: - return Qt::Key_F1; - - case KEYCODE_F2: - return Qt::Key_F2; - - case KEYCODE_F3: - return Qt::Key_F3; - - case KEYCODE_F4: - return Qt::Key_F4; - - case KEYCODE_F5: - return Qt::Key_F5; - - case KEYCODE_F6: - return Qt::Key_F6; - - case KEYCODE_F7: - return Qt::Key_F7; - - case KEYCODE_F8: - return Qt::Key_F8; - - case KEYCODE_F9: - return Qt::Key_F9; - - case KEYCODE_F10: - return Qt::Key_F10; - - case KEYCODE_F11: - return Qt::Key_F11; - - case KEYCODE_F12: - return Qt::Key_F12; - - // See keycodes.h for more, but these are all the basics. And printables are already included. - - default: -#if defined(QBBEVENTTHREAD_DEBUG) - qDebug() << "QBB: unknown key for translation:" << key; -#endif - break; - } - - return Qt::Key_Escape; -} - -bool isKeypadKey( int key ) -{ - switch (key) - { - case KEYCODE_KP_PLUS: - case KEYCODE_KP_MINUS: - case KEYCODE_KP_MULTIPLY: - case KEYCODE_KP_DIVIDE: - case KEYCODE_KP_ENTER: - case KEYCODE_KP_HOME: - case KEYCODE_KP_UP: - case KEYCODE_KP_PG_UP: - case KEYCODE_KP_LEFT: - case KEYCODE_KP_FIVE: - case KEYCODE_KP_RIGHT: - case KEYCODE_KP_END: - case KEYCODE_KP_DOWN: - case KEYCODE_KP_PG_DOWN: - case KEYCODE_KP_INSERT: - case KEYCODE_KP_DELETE: - return true; - default: - break; - } - - return false; -} - -QT_END_NAMESPACE - -#endif // QBBKEYTRANSLATOR_H diff --git a/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp b/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp deleted file mode 100644 index 03cf458b80..0000000000 --- a/src/plugins/platforms/blackberry/qbbnavigatorthread.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbnavigatorthread.h" -#include "qbbscreen.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static const char *navigatorControlPath = "/pps/services/navigator/control"; -static const int ppsBufferSize = 4096; - -QBBNavigatorThread::QBBNavigatorThread(QBBScreen& primaryScreen) - : m_primaryScreen(primaryScreen), - m_fd(-1), - m_readNotifier(0) -{ -} - -QBBNavigatorThread::~QBBNavigatorThread() -{ - // block until thread terminates - shutdown(); - - delete m_readNotifier; -} - -void QBBNavigatorThread::run() -{ -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "QBB: navigator thread started"; -#endif - - // open connection to navigator - errno = 0; - m_fd = open(navigatorControlPath, O_RDWR); - if (m_fd == -1) { - qWarning("QBB: failed to open navigator pps, errno=%d", errno); - return; - } - - m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read); - // using direct connection to get the slot called in this thread's context - connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readData()), Qt::DirectConnection); - - exec(); - - // close connection to navigator - close(m_fd); - -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "QBB: navigator thread stopped"; -#endif -} - -void QBBNavigatorThread::shutdown() -{ -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "QBB: navigator thread shutdown begin"; -#endif - - // signal thread to terminate - quit(); - - // block until thread terminates - wait(); - -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "QBB: navigator thread shutdown end"; -#endif -} - -void QBBNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id) -{ -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: data=" << ppsData; -#endif - - // tokenize pps data into lines - QList lines = ppsData.split('\n'); - - // validate pps object - if (lines.size() == 0 || lines.at(0) != "@control") { - qFatal("QBB: unrecognized pps object, data=%s", ppsData.constData()); - } - - // parse pps object attributes and extract values - for (int i = 1; i < lines.size(); i++) { - - // tokenize current attribute - const QByteArray &attr = lines.at(i); - -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: attr=" << attr; -#endif - - int firstColon = attr.indexOf(':'); - if (firstColon == -1) { - // abort - malformed attribute - continue; - } - - int secondColon = attr.indexOf(':', firstColon + 1); - if (secondColon == -1) { - // abort - malformed attribute - continue; - } - - QByteArray key = attr.left(firstColon); - QByteArray value = attr.mid(secondColon + 1); - -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: key=" << key; - qDebug() << "PPS: val=" << value; -#endif - - // save attribute value - if (key == "msg") { - msg = value; - } else if (key == "dat") { - dat = value; - } else if (key == "id") { - id = value; - } else { - qFatal("QBB: unrecognized pps attribute, attr=%s", key.constData()); - } - } -} - -void QBBNavigatorThread::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat) -{ - // construct pps message - QByteArray ppsData = "res::"; - ppsData += res; - ppsData += "\nid::"; - ppsData += id; - if (!dat.isEmpty()) { - ppsData += "\ndat::"; - ppsData += dat; - } - ppsData += "\n"; - -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS reply=" << ppsData; -#endif - - // send pps message to navigator - errno = 0; - int bytes = write(m_fd, ppsData.constData(), ppsData.size()); - if (bytes == -1) { - qFatal("QBB: failed to write navigator pps, errno=%d", errno); - } -} - -void QBBNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id) -{ -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: msg=" << msg << ", dat=" << dat << ", id=" << id; -#endif - - // check message type - if (msg == "orientationCheck") { - - // reply to navigator that (any) orientation is acceptable -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: orientation check, o=" << dat; -#endif - replyPPS(msg, id, "true"); - - } else if (msg == "orientation") { - - // update screen geometry and reply to navigator that we're ready -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: orientation, o=" << dat; -#endif - m_primaryScreen.setRotation( dat.toInt() ); - QWindowSystemInterface::handleScreenGeometryChange(0, m_primaryScreen.geometry()); - replyPPS(msg, id, ""); - - } else if (msg == "SWIPE_DOWN") { - - // simulate menu key press -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: menu"; -#endif - QWindow *w = QGuiApplication::focusWindow(); - QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyPress, Qt::Key_Menu, Qt::NoModifier); - QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyRelease, Qt::Key_Menu, Qt::NoModifier); - - } else if (msg == "exit") { - - // shutdown everything -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "PPS: exit"; -#endif - QCoreApplication::quit(); - } -} - -void QBBNavigatorThread::readData() -{ -#if defined(QBBNAVIGATORTHREAD_DEBUG) - qDebug() << "QBB: reading navigator data"; -#endif - // allocate buffer for pps data - char buffer[ppsBufferSize]; - - // attempt to read pps data - errno = 0; - int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1); - if (bytes == -1) { - qFatal("QBB: failed to read navigator pps, errno=%d", errno); - } - - // check if pps data was received - if (bytes > 0) { - - // ensure data is null terminated - buffer[bytes] = '\0'; - - // process received message - QByteArray ppsData(buffer); - QByteArray msg; - QByteArray dat; - QByteArray id; - parsePPS(ppsData, msg, dat, id); - handleMessage(msg, dat, id); - } -} diff --git a/src/plugins/platforms/blackberry/qbbnavigatorthread.h b/src/plugins/platforms/blackberry/qbbnavigatorthread.h deleted file mode 100644 index fda24b0c67..0000000000 --- a/src/plugins/platforms/blackberry/qbbnavigatorthread.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBNAVIGATORTHREAD_H -#define QBBNAVIGATORTHREAD_H - -#include - -QT_BEGIN_NAMESPACE - -class QBBScreen; -class QSocketNotifier; - -class QBBNavigatorThread : public QThread -{ - Q_OBJECT -public: - QBBNavigatorThread(QBBScreen &primaryScreen); - virtual ~QBBNavigatorThread(); - -protected: - virtual void run(); - -private Q_SLOTS: - void readData(); - -private: - void shutdown(); - void parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id); - void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat); - void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id); - - QBBScreen &m_primaryScreen; - int m_fd; - QSocketNotifier *m_readNotifier; -}; - -QT_END_NAMESPACE - -#endif // QBBNAVIGATORTHREAD_H diff --git a/src/plugins/platforms/blackberry/qbbrasterbackingstore.cpp b/src/plugins/platforms/blackberry/qbbrasterbackingstore.cpp deleted file mode 100644 index 405e09260f..0000000000 --- a/src/plugins/platforms/blackberry/qbbrasterbackingstore.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbrasterbackingstore.h" -#include "qbbwindow.h" - -#include - -#include - -QT_BEGIN_NAMESPACE - -QBBRasterBackingStore::QBBRasterBackingStore(QWindow *window) - : QPlatformBackingStore(window) -{ -#if defined(QBBRASTERBACKINGSTORE_DEBUG) - qDebug() << "QBBRasterBackingStore::QBBRasterBackingStore - w=" << window; -#endif - - // save platform window associated with widget - m_platformWindow = static_cast(window->handle()); -} - -QBBRasterBackingStore::~QBBRasterBackingStore() -{ -#if defined(QBBRasterBackingStore_DEBUG) - qDebug() << "QBBRasterBackingStore::~QBBRasterBackingStore - w=" << window(); -#endif -} - -QPaintDevice *QBBRasterBackingStore::paintDevice() -{ - return m_platformWindow->renderBuffer().image(); -} - -void QBBRasterBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(window); - Q_UNUSED(offset); - -#if defined(QBBRASTERBACKINGSTORE_DEBUG) - qDebug() << "QBBRasterBackingStore::flush - w=" << this->window(); -#endif - - // visit all pending scroll operations - for (int i = m_scrollOpList.size() - 1; i >= 0; i--) { - - // do the scroll operation - ScrollOp &op = m_scrollOpList[i]; - QRegion srcArea = op.totalArea.intersected( op.totalArea.translated(-op.dx, -op.dy) ); - m_platformWindow->scroll(srcArea, op.dx, op.dy); - } - - // clear all pending scroll operations - m_scrollOpList.clear(); - - // update the display with newly rendered content - m_platformWindow->post(region); -} - -void QBBRasterBackingStore::resize(const QSize &size, const QRegion &staticContents) -{ - Q_UNUSED(size); - Q_UNUSED(staticContents); -#if defined(QBBRASTERBACKINGSTORE_DEBUG) - qDebug() << "QBBRasterBackingStore::resize - w=" << window() << ", s=" << size; -#endif - - // NOTE: defer resizing window buffers until next paint as - // resize() can be called multiple times before a paint occurs -} - -bool QBBRasterBackingStore::scroll(const QRegion &area, int dx, int dy) -{ -#if defined(QBBRASTERBACKINGSTORE_DEBUG) - qDebug() << "QBBRasterBackingStore::scroll - w=" << window(); -#endif - - // calculate entire region affected by scroll operation (src + dst) - QRegion totalArea = area.translated(dx, dy); - totalArea += area; - - // visit all pending scroll operations - for (int i = m_scrollOpList.size() - 1; i >= 0; i--) { - - ScrollOp &op = m_scrollOpList[i]; - if (op.totalArea == totalArea) { - // same area is being scrolled again - update delta - op.dx += dx; - op.dy += dy; - return true; - } else if (op.totalArea.intersects(totalArea)) { - // current scroll overlaps previous scroll but is - // not equal in area - just paint everything - qWarning("QBB: pending scroll operations overlap but not equal"); - return false; - } - } - - // create new scroll operation - m_scrollOpList.append( ScrollOp(totalArea, dx, dy) ); - return true; -} - -void QBBRasterBackingStore::beginPaint(const QRegion ®ion) -{ - Q_UNUSED(region); - -#if defined(QBBRASTERBACKINGSTORE_DEBUG) - qDebug() << "QBBRasterBackingStore::beginPaint - w=" << window(); -#endif - - // resize window buffers if surface resized - QSize s = window()->size(); - if (s != m_platformWindow->bufferSize()) { - m_platformWindow->setBufferSize(s); - } -} - -void QBBRasterBackingStore::endPaint(const QRegion ®ion) -{ - Q_UNUSED(region); -#if defined(QBBRasterBackingStore_DEBUG) - qDebug() << "QBBRasterBackingStore::endPaint - w=" << window(); -#endif -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbrasterbackingstore.h b/src/plugins/platforms/blackberry/qbbrasterbackingstore.h deleted file mode 100644 index ca1e27bcc8..0000000000 --- a/src/plugins/platforms/blackberry/qbbrasterbackingstore.h +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBRASTERWINDOWSURFACE_H -#define QBBRASTERWINDOWSURFACE_H - -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBWindow; - -class QBBRasterBackingStore : public QPlatformBackingStore -{ -public: - QBBRasterBackingStore(QWindow *window); - virtual ~QBBRasterBackingStore(); - - virtual QPaintDevice *paintDevice(); - virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); - virtual void resize(const QSize &size, const QRegion &staticContents); - virtual bool scroll(const QRegion &area, int dx, int dy); - virtual void beginPaint(const QRegion ®ion); - virtual void endPaint(const QRegion ®ion); - -private: - class ScrollOp { - public: - ScrollOp(const QRegion &a, int x, int y) : totalArea(a), dx(x), dy(y) {} - QRegion totalArea; - int dx; - int dy; - }; - - QBBWindow *m_platformWindow; - QList m_scrollOpList; -}; - -QT_END_NAMESPACE - -#endif // QBBRASTERWINDOWSURFACE_H diff --git a/src/plugins/platforms/blackberry/qbbrootwindow.cpp b/src/plugins/platforms/blackberry/qbbrootwindow.cpp deleted file mode 100644 index 831b0774f9..0000000000 --- a/src/plugins/platforms/blackberry/qbbrootwindow.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbrootwindow.h" - -#include "qbbscreen.h" - -#include - -#if defined(QBBROOTWINDOW_DEBUG) -#include -#endif - -#include -#include - -static const int MAGIC_ZORDER_FOR_NO_NAV = 10; - -QBBRootWindow::QBBRootWindow(QBBScreen *screen) - : m_screen(screen), - m_window(0), - m_windowGroupName() -{ -#if defined(QBBROOTWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // 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("QBBRootWindow: 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("QBBRootWindow: 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("QBBRootWindow: 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("QBBRootWindow: 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("QBBRootWindow: 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("QBBRootWindow: failed to set window buffer size, errno=%d", errno); - } - - errno = 0; - result = screen_create_window_buffers(m_window, 1); - if (result != 0) { - qFatal("QBB: 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("QBBRootWindow: failed to set window size, errno=%d", errno); - } - - // Fill the window with solid black - errno = 0; - val[0] = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_COLOR, val); - if (result != 0) { - qFatal("QBBRootWindow: 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("QBBRootWindow: 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("QBBRootWindow: 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("QBBRootWindow: failed to set window source size, errno=%d", errno); - } - - errno = 0; - val[0] = 1; - val[1] = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_POSITION, val); - if (result != 0) { - qFatal("QBBRootWindow: failed to set window source position, errno=%d", errno); - } - - createWindowGroup(); - post(); -} - -QBBRootWindow::~QBBRootWindow() -{ - // Cleanup top-level QNX window - screen_destroy_window(m_window); -} - -void QBBRootWindow::post() const -{ -#if defined(QBBROOTWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - 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("QBBRootWindow: 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("QBB: failed to post window buffer, errno=%d", errno); - } -} - -void QBBRootWindow::flush() const -{ -#if defined(QBBROOTWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Force immediate display update - errno = 0; - int result = screen_flush_context(m_screen->nativeContext(), 0); - if (result != 0) { - qFatal("QBBRootWindow: failed to flush context, errno=%d", errno); - } -} - -void QBBRootWindow::setRotation(int rotation) -{ -#if defined(QBBROOTWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "angle =" << rotation; -#endif - errno = 0; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation); - if (result != 0) { - qFatal("QBBRootWindow: failed to set window rotation, errno=%d", errno); - } -} - -void QBBRootWindow::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("QBBRootWindow: 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("QBBRootWindow: failed to set window source size, errno=%d", errno); - } - - // NOTE: display will update when child windows relayout and repaint -} - -void QBBRootWindow::createWindowGroup() -{ - // Generate a random window group name - m_windowGroupName = QUuid::createUuid().toString().toAscii(); - - // 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("QBBRootWindow: failed to create app window group, errno=%d", errno); - } -} diff --git a/src/plugins/platforms/blackberry/qbbrootwindow.h b/src/plugins/platforms/blackberry/qbbrootwindow.h deleted file mode 100644 index 0b89f52a5e..0000000000 --- a/src/plugins/platforms/blackberry/qbbrootwindow.h +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBROOTWINDOW_H -#define QBBROOTWINDOW_H - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBScreen; - -class QBBRootWindow -{ -public: - QBBRootWindow(QBBScreen *screen); - ~QBBRootWindow(); - - screen_window_t nativeHandle() const { return m_window; } - - void post() const; - void flush() const; - - void setRotation(int rotation); - - void resize(const QSize &size); - - QByteArray groupName() const { return m_windowGroupName; } - -private: - void createWindowGroup(); - - QBBScreen *m_screen; - screen_window_t m_window; - QByteArray m_windowGroupName; -}; - -QT_END_NAMESPACE - -#endif // QBBROOTWINDOW_H diff --git a/src/plugins/platforms/blackberry/qbbscreen.cpp b/src/plugins/platforms/blackberry/qbbscreen.cpp deleted file mode 100644 index 11e40f6150..0000000000 --- a/src/plugins/platforms/blackberry/qbbscreen.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbscreen.h" -#include "qbbvirtualkeyboard.h" -#include "qbbwindow.h" - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -QList QBBScreen::ms_screens; -QList QBBScreen::ms_childWindows; - -QBBScreen::QBBScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen) - : m_screenContext(screenContext), - m_display(display), - m_rootWindow(), - m_primaryScreen(primaryScreen), - m_posted(false), - m_platformContext(0) -{ -#if defined(QBBSCREEN_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Cache initial orientation of this display - // TODO: use ORIENTATION environment variable? - errno = 0; - int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION, &m_initialRotation); - if (result != 0) { - qFatal("QBBScreen: failed to query display rotation, errno=%d", errno); - } - m_currentRotation = m_initialRotation; - - // Cache size of this display in pixels - // TODO: use WIDTH and HEIGHT environment variables? - errno = 0; - int val[2]; - result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val); - if (result != 0) { - qFatal("QBBScreen: failed to query display size, errno=%d", errno); - } - - m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]); - - // Cache size of this display in millimeters - errno = 0; - result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_PHYSICAL_SIZE, val); - if (result != 0) { - qFatal("QBBScreen: failed to query display physical size, errno=%d", errno); - } - - // Peg the DPI to 96 (for now) so fonts are a reasonable size. We'll want to match - // everything with a QStyle later, and at that point the physical size can be used - // instead. - { - static const int dpi = 96; - int width = m_currentGeometry.width() / dpi * qreal(25.4) ; - int height = m_currentGeometry.height() / dpi * qreal(25.4) ; - - m_currentPhysicalSize = m_initialPhysicalSize = QSize(width,height); - } - - // We only create the root window if we are the primary display. - if (primaryScreen) - m_rootWindow = QSharedPointer(new QBBRootWindow(this)); -} - -QBBScreen::~QBBScreen() -{ -#if defined(QBBSCREEN_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif -} - -/* static */ -void QBBScreen::createDisplays(screen_context_t context) -{ -#if defined(QBBSCREEN_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Query number of displays - errno = 0; - int displayCount; - int result = screen_get_context_property_iv(context, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount); - if (result != 0) { - qFatal("QBBScreen: failed to query display count, errno=%d", errno); - } - - // Get all displays - errno = 0; - screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount); - result = screen_get_context_property_pv(context, SCREEN_PROPERTY_DISPLAYS, (void **)displays); - if (result != 0) { - qFatal("QBBScreen: failed to query displays, errno=%d", errno); - } - - for (int i=0; iupdateZorder(topZorder); - - // After a hierarchy update, we need to force a flush on all screens. - // Right now, all screens share a context. - screen_flush_context( primaryDisplay()->m_screenContext, 0 ); -} - -void QBBScreen::onWindowPost(QBBWindow *window) -{ -#if defined(QBBSCREEN_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - 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 && m_rootWindow) { - m_rootWindow->post(); - m_posted = true; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbscreen.h b/src/plugins/platforms/blackberry/qbbscreen.h deleted file mode 100644 index 16606944d8..0000000000 --- a/src/plugins/platforms/blackberry/qbbscreen.h +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBSCREEN_H -#define QBBSCREEN_H - -#include - -#include "qbbrootwindow.h" - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QBBWindow; - -class QBBScreen : public QPlatformScreen -{ -public: - static QList screens() { return ms_screens; } - static void createDisplays(screen_context_t context); - static void destroyDisplays(); - static QBBScreen *primaryDisplay() { return static_cast(ms_screens.at(0)); } - static int defaultDepth(); - - virtual QRect geometry() const { return m_currentGeometry; } - virtual QRect availableGeometry() const; - virtual int depth() const { return defaultDepth(); } - virtual QImage::Format format() const { return (depth() == 32) ? QImage::Format_RGB32 : QImage::Format_RGB16; } - virtual QSizeF physicalSize() const { return m_currentPhysicalSize; } - - bool isPrimaryScreen() const { return m_primaryScreen; } - - int rotation() const { return m_currentRotation; } - void setRotation(int rotation); - - int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; } - screen_display_t nativeDisplay() const { return m_display; } - screen_context_t nativeContext() const { return m_screenContext; } - const char *windowGroupName() const { return m_rootWindow->groupName().constData(); } - - /* Window hierarchy management */ - static void addWindow(QBBWindow *child); - static void removeWindow(QBBWindow *child); - static void raiseWindow(QBBWindow *window); - static void lowerWindow(QBBWindow *window); - static void updateHierarchy(); - - void onWindowPost(QBBWindow *window); - - QSharedPointer rootWindow() const { return m_rootWindow; } - -private: - QBBScreen(screen_context_t context, screen_display_t display, bool primaryScreen); - virtual ~QBBScreen(); - - static bool orthogonal(int rotation1, int rotation2); - - screen_context_t m_screenContext; - screen_display_t m_display; - QSharedPointer m_rootWindow; - bool m_primaryScreen; - bool m_posted; - bool m_usingOpenGL; - - int m_initialRotation; - int m_currentRotation; - QSize m_initialPhysicalSize; - QSize m_currentPhysicalSize; - QRect m_initialGeometry; - QRect m_currentGeometry; - QPlatformOpenGLContext *m_platformContext; - - static QList ms_screens; - static QList ms_childWindows; -}; - -QT_END_NAMESPACE - -#endif // QBBSCREEN_H diff --git a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp b/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp deleted file mode 100644 index 082ef9b19d..0000000000 --- a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbvirtualkeyboard.h" -#include "qbbscreen.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *QBBVirtualKeyboard::ms_PPSPath = "/pps/services/input/control?wait"; -const size_t QBBVirtualKeyboard::ms_bufferSize = 2048; - -static QBBVirtualKeyboard *s_instance = 0; - -// Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP. -#define KEYBOARD_SHADOW_HEIGHT 8 - -QBBVirtualKeyboard::QBBVirtualKeyboard() : - m_encoder(NULL), - m_decoder(NULL), - m_buffer(NULL), - m_height(0), - m_fd(-1), - m_keyboardMode(Default), - m_visible(false), - m_locale(QLatin1String("en_US")) -{ - connect(); -} - -QBBVirtualKeyboard::~QBBVirtualKeyboard() -{ - close(); -} - -/* static */ -QBBVirtualKeyboard& QBBVirtualKeyboard::instance() -{ - if (!s_instance) { - s_instance = new QBBVirtualKeyboard(); - s_instance->start(); - } - - return *s_instance; -} - -/* static */ -void QBBVirtualKeyboard::destroy() -{ - if (s_instance) { - delete s_instance; - s_instance = 0; - } -} - -void QBBVirtualKeyboard::close() -{ - if (m_fd) { - // any reads will fail after we close the fd, which is basically what we want. - ::close(m_fd); - } - - // Wait for the thread to die (should be immediate), then continue the cleanup. - wait(); - - if (m_fd) { - m_fd = -1; - } - - - if (m_decoder) - { - pps_decoder_cleanup(m_decoder); - delete m_decoder; - m_decoder = NULL; - } - - if (m_encoder) - { - pps_encoder_cleanup(m_encoder); - delete m_encoder; - m_encoder = NULL; - } - - delete [] m_buffer; - m_buffer = NULL; -} - -bool QBBVirtualKeyboard::connect() -{ - close(); - - m_encoder = new pps_encoder_t; - m_decoder = new pps_decoder_t; - - pps_encoder_initialize(m_encoder, false); - pps_decoder_initialize(m_decoder, NULL); - - errno = 0; - m_fd = ::open(ms_PPSPath, O_RDWR); - if (m_fd == -1) - { - qCritical("QBBVirtualKeyboard: Unable to open \"%s\" for keyboard: %s (%d).", - ms_PPSPath, strerror(errno), errno); - close(); - return false; - } - - m_buffer = new char[ms_bufferSize]; - if (!m_buffer) { - qCritical("QBBVirtualKeyboard: Unable to allocate buffer of %d bytes. Size is unavailable.", ms_bufferSize); - return false; - } - - if (!queryPPSInfo()) - return false; - - start(); - - return true; -} - -bool QBBVirtualKeyboard::queryPPSInfo() -{ - // Request info, requires id to regenerate res message. - pps_encoder_add_string(m_encoder, "msg", "info"); - pps_encoder_add_string(m_encoder, "id", "libWebView"); - - if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { - close(); - return false; - } - - pps_encoder_reset(m_encoder); - - return true; -} - -void QBBVirtualKeyboard::notifyClientActiveStateChange(bool active) -{ - if (!active) - hideKeyboard(); -} - -void QBBVirtualKeyboard::run() -{ - ppsDataReady(); -} - -void QBBVirtualKeyboard::ppsDataReady() -{ - while (1) { - ssize_t nread = read(m_fd, m_buffer, ms_bufferSize - 1); - -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: keyboardMessage size: " << nread; -#endif - if (nread < 0) - break; - - // nread is the real space necessary, not the amount read. - if (static_cast(nread) > ms_bufferSize - 1) { - qCritical("QBBVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1); - break; - } - - m_buffer[nread] = 0; - pps_decoder_parse_pps_str(m_decoder, m_buffer); - pps_decoder_push(m_decoder, NULL); -#ifdef QBBVIRTUALKEYBOARD_DEBUG - pps_decoder_dump_tree(m_decoder, stderr); -#endif - - const char *value; - if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]"); - continue; - } - - if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) { - if (strcmp(value, "show") == 0) { - const bool oldVisible = m_visible; - m_visible = true; - handleKeyboardStateChangeMessage(true); - if (oldVisible != m_visible) - emit visibilityChanged(m_visible); - } else if (strcmp(value, "hide") == 0) { - const bool oldVisible = m_visible; - m_visible = false; - handleKeyboardStateChangeMessage(false); - if (oldVisible != m_visible) - emit visibilityChanged(m_visible); - } else if (strcmp(value, "info") == 0) - handleKeyboardInfoMessage(); - else if (strcmp(value, "connect") == 0) { } - else - qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]"); - } else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) { - if (strcmp(value, "info") == 0) - handleKeyboardInfoMessage(); - else - qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]"); - } else - qCritical("QBBVirtualKeyboard: Unexpected keyboard PPS message type"); - } - -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: exiting keyboard thread"; -#endif - - if (m_decoder) - pps_decoder_cleanup(m_decoder); -} - -void QBBVirtualKeyboard::handleKeyboardInfoMessage() -{ - int newHeight = 0; - const char *value; - - if (pps_decoder_push(m_decoder, "dat") != PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS dat object not found"); - return; - } - if (pps_decoder_get_int(m_decoder, "size", &newHeight) != PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS size field not found"); - return; - } - if (pps_decoder_push(m_decoder, "locale") != PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS locale object not found"); - return; - } - if (pps_decoder_get_string(m_decoder, "languageId", &value) != PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS languageId field not found"); - return; - } - const QString languageId = QString::fromLatin1(value); - if (pps_decoder_get_string(m_decoder, "countryId", &value) != PPS_DECODER_OK) { - qCritical("QBBVirtualKeyboard: Keyboard PPS size countryId not found"); - return; - } - const QString countryId = QString::fromLatin1(value); - - // HUGE hack, should be removed ASAP. - newHeight -= KEYBOARD_SHADOW_HEIGHT; // We want to ignore the 8 pixel shadow above the keyboard. (PR 88400) - - if (newHeight != m_height) { - m_height = newHeight; - updateAvailableScreenGeometry(); - } - - const QLocale locale = QLocale(languageId + QLatin1Char('_') + countryId); - if (locale != m_locale) { - m_locale = locale; - emit localeChanged(locale); - } - -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: handleKeyboardInfoMessage size=" << m_height << "locale=" << m_locale; -#endif -} - -void QBBVirtualKeyboard::handleKeyboardStateChangeMessage(bool visible) -{ - -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: handleKeyboardStateChangeMessage " << visible; -#endif - updateAvailableScreenGeometry(); - - if (visible) - showKeyboard(); - else - hideKeyboard(); -} - -void QBBVirtualKeyboard::updateAvailableScreenGeometry() -{ -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: updateAvailableScreenGeometry: keyboard visible=" << m_visible << ", keyboard height=" << m_height; -#endif - - // TODO: What screen index should be used? I assume primaryScreen here because it works, and - // we do it for handleScreenGeometryChange elsewhere but since we have support - // for more than one screen, that's not going to always work. - QBBScreen *platformScreen = QBBScreen::primaryDisplay(); - QWindowSystemInterface::handleScreenAvailableGeometryChange(platformScreen->screen(), platformScreen->availableGeometry()); -} - -bool QBBVirtualKeyboard::showKeyboard() -{ -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: showKeyboard()"; -#endif - - // Try to connect. - if (m_fd == -1 && !connect()) - return false; - - // NOTE: This must be done everytime the keyboard is shown even if there is no change because - // hiding the keyboard wipes the setting. - applyKeyboardModeOptions(); - - pps_encoder_reset(m_encoder); - - // Send the show message. - pps_encoder_add_string(m_encoder, "msg", "show"); - - if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { - close(); - return false; - } - - pps_encoder_reset(m_encoder); - - // Return true if no error occurs. Sizing response will be triggered when confirmation of - // the change arrives. - return true; -} - -bool QBBVirtualKeyboard::hideKeyboard() -{ -#ifdef QBBVIRTUALKEYBOARD_DEBUG - qDebug() << "QBB: hideKeyboard()"; -#endif - - if (m_fd == -1 && !connect()) - return false; - - pps_encoder_add_string(m_encoder, "msg", "hide"); - - if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { - close(); - - //Try again. - if (connect()) { - if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { - close(); - return false; - } - } - else - return false; - } - - pps_encoder_reset(m_encoder); - - // Return true if no error occurs. Sizing response will be triggered when confirmation of - // the change arrives. - return true; -} - -void QBBVirtualKeyboard::setKeyboardMode(KeyboardMode mode) -{ - m_keyboardMode = mode; -} - -void QBBVirtualKeyboard::applyKeyboardModeOptions() -{ - // Try to connect. - if (m_fd == -1 && !connect()) - return; - - // Send the options message. - pps_encoder_add_string(m_encoder, "msg", "options"); - - pps_encoder_start_object(m_encoder, "dat"); - switch (m_keyboardMode) { - case Url: - addUrlModeOptions(); - break; - case Email: - addEmailModeOptions(); - break; - case Web: - addWebModeOptions(); - break; - case NumPunc: - addNumPuncModeOptions(); - break; - case Symbol: - addSymbolModeOptions(); - break; - case Phone: - addPhoneModeOptions(); - break; - case Pin: - addPinModeOptions(); - break; - case Default: - default: - addDefaultModeOptions(); - break; - } - - pps_encoder_end_object(m_encoder); - - if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { - close(); - } - - pps_encoder_reset(m_encoder); -} - -void QBBVirtualKeyboard::addDefaultModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "default"); -} - -void QBBVirtualKeyboard::addUrlModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "url"); -} - -void QBBVirtualKeyboard::addEmailModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "email"); -} - -void QBBVirtualKeyboard::addWebModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "web"); -} - -void QBBVirtualKeyboard::addNumPuncModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "numPunc"); -} - -void QBBVirtualKeyboard::addPhoneModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "phone"); -} - -void QBBVirtualKeyboard::addPinModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "pin"); -} - -void QBBVirtualKeyboard::addSymbolModeOptions() -{ - pps_encoder_add_string(m_encoder, "enter", "enter.default"); - pps_encoder_add_string(m_encoder, "type", "symbol"); -} diff --git a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h b/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h deleted file mode 100644 index 14003ee897..0000000000 --- a/src/plugins/platforms/blackberry/qbbvirtualkeyboard.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VIRTUALKEYBOARD_H_ -#define VIRTUALKEYBOARD_H_ - -#include -#include -#include -#include - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/* Shamelessly copied from the browser - this should be rewritten once we have a proper PPS wrapper class */ -class QBBVirtualKeyboard : public QThread -{ - Q_OBJECT -public: - // NOTE: Not all the following keyboard modes are currently used. - // Default - Regular Keyboard - // Url/Email - Enhanced keys for each types. - // Web - Regular keyboard with two blank keys, currently unused. - // NumPunc - Numbers & Punctionation, alternate to Symbol - // Symbol - All symbols, alternate to NumPunc, currently unused. - // Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z - // Pin - Keyboard for entering Pins (Hex values) currently unused. - // - // SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional. - // - enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin }; - - static QBBVirtualKeyboard& instance(); - static void destroy(); - - bool showKeyboard(); - bool hideKeyboard(); - int height() { return m_visible ? m_height : 0; } - void setKeyboardMode(KeyboardMode); - void notifyClientActiveStateChange(bool); - bool isVisible() const { return m_visible; } - QLocale locale() const { return m_locale; } - -Q_SIGNALS: - void localeChanged(const QLocale &locale); - void visibilityChanged(bool visible); - -private: - QBBVirtualKeyboard(); - virtual ~QBBVirtualKeyboard(); - - // Will be called internally if needed. - bool connect(); - void close(); - void ppsDataReady(); - bool queryPPSInfo(); - void handleKeyboardInfoMessage(); - void handleKeyboardStateChangeMessage(bool visible); - void updateAvailableScreenGeometry(); - - void applyKeyboardModeOptions(); - void addDefaultModeOptions(); - void addUrlModeOptions(); - void addEmailModeOptions(); - void addWebModeOptions(); - void addNumPuncModeOptions(); - void addSymbolModeOptions(); - void addPhoneModeOptions(); - void addPinModeOptions(); - - // QThread overrides - virtual void run(); - - pps_encoder_t *m_encoder; - pps_decoder_t *m_decoder; - char *m_buffer; - int m_height; - int m_fd; - KeyboardMode m_keyboardMode; - bool m_visible; - QLocale m_locale; - - // Path to keyboardManager in PPS. - static const char *ms_PPSPath; - static const size_t ms_bufferSize; -}; - -#endif /* VIRTUALKEYBOARD_H_ */ diff --git a/src/plugins/platforms/blackberry/qbbwindow.cpp b/src/plugins/platforms/blackberry/qbbwindow.cpp deleted file mode 100644 index bc9f112b01..0000000000 --- a/src/plugins/platforms/blackberry/qbbwindow.cpp +++ /dev/null @@ -1,665 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbbwindow.h" -#include "qbbglcontext.h" -#include "qbbintegration.h" -#include "qbbscreen.h" - -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -QBBWindow::QBBWindow(QWindow *window, screen_context_t context) - : QPlatformWindow(window), - m_screenContext(context), - m_window(0), - m_currentBufferIndex(-1), - m_previousBufferIndex(-1), - m_platformOpenGLContext(0), - m_screen(0), - m_parentWindow(0), - m_visible(true) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size(); -#endif - int result; - - // Create child QNX window - errno = 0; - result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW); - if (result != 0) { - qFatal("QBBWindow: failed to create window, errno=%d", errno); - } - - // Set window buffer usage based on rendering API - int val; - QSurface::SurfaceType surfaceType = window->surfaceType(); - switch (surfaceType) { - case QSurface::RasterSurface: - val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE; - break; - case QSurface::OpenGLSurface: - val = SCREEN_USAGE_OPENGL_ES2; - break; - default: - qFatal("QBBWindow: unsupported window API"); - break; - } - - errno = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, &val); - if (result != 0) { - qFatal("QBBWindow: failed to set window buffer usage, errno=%d", errno); - } - - // Alpha channel is always pre-multiplied if present - errno = 0; - val = SCREEN_PRE_MULTIPLIED_ALPHA; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val); - if (result != 0) { - qFatal("QBBWindow: failed to set window alpha mode, errno=%d", errno); - } - - // Make the window opaque - errno = 0; - val = SCREEN_TRANSPARENCY_NONE; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val); - if (result != 0) { - qFatal("QBBWindow: failed to set window transparency, errno=%d", errno); - } - - // Set the window swap interval - errno = 0; - val = 1; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val); - if (result != 0) { - qFatal("QBBWindow: failed to set window swap interval, errno=%d", errno); - } - - // Assign the window to the primary display (this is the default specified by screen). - setScreen(QBBScreen::primaryDisplay()); - - // Add the window to the root of the hierarchy - QBBScreen::addWindow(this); - - // Add window to plugin's window mapper - QBBIntegration::addWindow(m_window, window); -} - -QBBWindow::~QBBWindow() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - // Remove from plugin's window mapper - QBBIntegration::removeWindow(m_window); - - // Remove from parent's Hierarchy. - removeFromParent(); - QBBScreen::updateHierarchy(); - - // We shouldn't allow this case unless QT allows it. Does it? Or should we send the - // handleCloseEvent on all children when this window is deleted? - if (m_childWindows.size() > 0) - qFatal("QBBWindow: window destroyed before children!"); - - // Cleanup QNX window and its buffers - screen_destroy_window(m_window); -} - -void QBBWindow::setGeometry(const QRect &rect) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window() << ", (" << rect.x() << "," << rect.y() << "," << rect.width() << "," << rect.height() << ")"; -#endif - - QRect oldGeometry = geometry(); - - // Call base class method - QPlatformWindow::setGeometry(rect); - - // Set window geometry equal to widget geometry - errno = 0; - int val[2]; - val[0] = rect.x(); - val[1] = rect.y(); - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val); - if (result != 0) { - qFatal("QBBWindow: failed to set window position, errno=%d", errno); - } - - errno = 0; - val[0] = rect.width(); - val[1] = rect.height(); - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val); - if (result != 0) { - qFatal("QBBWindow: failed to set window size, errno=%d", errno); - } - - // Set viewport size equal to window size - errno = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val); - if (result != 0) { - qFatal("QBBWindow: failed to set window source size, errno=%d", errno); - } - - // Now move all children. - QPoint offset; - if (!oldGeometry.isEmpty()) { - offset = rect.topLeft(); - offset -= oldGeometry.topLeft(); - - QList::iterator it; - for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { - (*it)->offset(offset); - } - } -} - -void QBBWindow::offset(const QPoint &offset) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - // Move self and then children. - QRect newGeometry = geometry(); - newGeometry.translate(offset); - - // Call the base class - QPlatformWindow::setGeometry(newGeometry); - - int val[2]; - - errno = 0; - val[0] = newGeometry.x(); - val[1] = newGeometry.y(); - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val); - if (result != 0) { - qFatal("QBBWindow: failed to set window position, errno=%d", errno); - } - - QList::iterator it; - for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { - (*it)->offset(offset); - } -} - -void QBBWindow::setVisible(bool visible) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window() << "visible =" << visible; -#endif - - m_visible = visible; - - QBBWindow *root = this; - while (root->m_parentWindow) - root = root->m_parentWindow; - - root->updateVisibility(root->m_visible); - - window()->requestActivateWindow(); -} - -void QBBWindow::updateVisibility(bool parentVisible) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window(); -#endif - // Set window visibility - errno = 0; - int val = (m_visible && parentVisible) ? 1 : 0; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val); - if (result != 0) { - qFatal("QBBWindow: failed to set window visibility, errno=%d", errno); - } - - QList::iterator it; - for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { - (*it)->updateVisibility(m_visible && parentVisible); - } -} - -void QBBWindow::setOpacity(qreal level) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level; -#endif - // Set window global alpha - errno = 0; - int val = (int)(level * 255); - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val); - if (result != 0) { - qFatal("QBBWindow: failed to set window global alpha, errno=%d", errno); - } - - // TODO: How to handle children of this window? If we change all the visibilities, then - // the transparency will look wrong... -} - -void QBBWindow::setBufferSize(const QSize &size) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size; -#endif - // Set window buffer size - errno = 0; - int val[2] = { size.width(), size.height() }; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val); - if (result != 0) { - qFatal("QBBWindow: failed to set window buffer size, errno=%d", errno); - } - - // Create window buffers if they do not exist - if (!hasBuffers()) { - // Get pixel format from EGL config if using OpenGL; - // otherwise inherit pixel format of window's screen - if (m_platformOpenGLContext != 0) { - val[0] = platformWindowFormatToNativeFormat(m_platformOpenGLContext->format()); - } else { - val[0] = m_screen->nativeFormat(); - } - - errno = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val); - if (result != 0) { - qFatal("QBBWindow: failed to set window pixel format, errno=%d", errno); - } - - errno = 0; - result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT); - if (result != 0) { - qFatal("QBBWindow: failed to create window buffers, errno=%d", errno); - } - } - - // Cache new buffer size - m_bufferSize = size; - - // Buffers were destroyed; reacquire them - m_currentBufferIndex = -1; - m_previousDirty = QRegion(); - m_scrolled = QRegion(); -} - -QBBBuffer &QBBWindow::renderBuffer() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - // Check if render buffer is invalid - if (m_currentBufferIndex == -1) { - // Get all buffers available for rendering - errno = 0; - screen_buffer_t buffers[MAX_BUFFER_COUNT]; - int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers); - if (result != 0) { - qFatal("QBBWindow: failed to query window buffers, errno=%d", errno); - } - - // Wrap each buffer - for (int i = 0; i < MAX_BUFFER_COUNT; ++i) { - m_buffers[i] = QBBBuffer(buffers[i]); - } - - // Use the first available render buffer - m_currentBufferIndex = 0; - m_previousBufferIndex = -1; - } - - return m_buffers[m_currentBufferIndex]; -} - -void QBBWindow::scroll(const QRegion ®ion, int dx, int dy, bool flush) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - copyBack(region, dx, dy, flush); - m_scrolled += region; -} - -void QBBWindow::post(const QRegion &dirty) -{ - // Check if render buffer exists and something was rendered - if (m_currentBufferIndex != -1 && !dirty.isEmpty()) { -#if defined(QBBWINDOW_DEBUG) - qDebug() << "QBBWindow::post - window =" << window(); -#endif - QBBBuffer ¤tBuffer = m_buffers[m_currentBufferIndex]; - - // Copy unmodified region from old render buffer to new render buffer; - // required to allow partial updates - QRegion preserve = m_previousDirty - dirty - m_scrolled; - copyBack(preserve, 0, 0); - - // Calculate region that changed - QRegion modified = preserve + dirty + m_scrolled; - QRect rect = modified.boundingRect(); - int dirtyRect[4] = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() }; - - // Update the display with contents of render buffer - errno = 0; - int result = screen_post_window(m_window, currentBuffer.nativeBuffer(), 1, dirtyRect, 0); - if (result != 0) { - qFatal("QBBWindow: failed to post window buffer, errno=%d", errno); - } - - // Advance to next nender buffer - m_previousBufferIndex = m_currentBufferIndex++; - if (m_currentBufferIndex >= MAX_BUFFER_COUNT) { - m_currentBufferIndex = 0; - } - - // Save modified region and clear scrolled region - m_previousDirty = dirty; - m_scrolled = QRegion(); - - // Notify screen that window posted - if (m_screen != 0) { - m_screen->onWindowPost(this); - } - } -} - -void QBBWindow::setScreen(QBBScreen *platformScreen) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window() << "platformScreen =" << platformScreen; -#endif - - if (m_screen == platformScreen) - return; - - 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("QBBWindow: failed to set window display, errno=%d", errno); - } - - // Add window to display's window group - errno = 0; - result = screen_join_window_group(m_window, platformScreen->windowGroupName()); - if (result != 0) { - qFatal("QBBWindow: failed to join window group, errno=%d", errno); - } - - QList::iterator it; - for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { - // Only subwindows and tooltips need necessarily be moved to another display with the window. - if ((window()->windowType() & Qt::WindowType_Mask) == Qt::SubWindow || - (window()->windowType() & Qt::WindowType_Mask) == Qt::ToolTip) - (*it)->setScreen(platformScreen); - } - - QBBScreen::updateHierarchy(); -} - -void QBBWindow::removeFromParent() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - // Remove from old Hierarchy position - if (m_parentWindow) { - if (m_parentWindow->m_childWindows.removeAll(this)) - m_parentWindow = 0; - else - qFatal("QBBWindow: Window Hierarchy broken; window has parent, but parent hasn't got child."); - } else { - QBBScreen::removeWindow(this); - } -} - -void QBBWindow::setParent(const QPlatformWindow *window) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << this->window() << "platformWindow =" << window; -#endif - // Cast away the const, we need to modify the hierarchy. - QBBWindow *newParent = 0; - - if (window) - newParent = static_cast((QPlatformWindow *)window); - - if (newParent == m_parentWindow) - return; - - removeFromParent(); - m_parentWindow = newParent; - - // Add to new hierarchy position. - if (m_parentWindow) { - if (m_parentWindow->m_screen != m_screen) - setScreen(m_parentWindow->m_screen); - - m_parentWindow->m_childWindows.push_back(this); - } else { - QBBScreen::addWindow(this); - } - - QBBScreen::updateHierarchy(); -} - -void QBBWindow::raise() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - - QBBWindow *oldParent = m_parentWindow; - if (oldParent) { - removeFromParent(); - oldParent->m_childWindows.push_back(this); - } else { - QBBScreen::raiseWindow(this); - } - - QBBScreen::updateHierarchy(); -} - -void QBBWindow::lower() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - - QBBWindow *oldParent = m_parentWindow; - if (oldParent) { - removeFromParent(); - oldParent->m_childWindows.push_front(this); - } else { - QBBScreen::lowerWindow(this); - } - - QBBScreen::updateHierarchy(); -} - -void QBBWindow::requestActivateWindow() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - - // TODO: Tell screen to set keyboard focus to this window. - - // Notify that we gained focus. - gainedFocus(); -} - -void QBBWindow::gainedFocus() -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - - // Got focus - QWindowSystemInterface::handleWindowActivated(window()); -} - -void QBBWindow::setPlatformOpenGLContext(QBBGLContext *platformOpenGLContext) -{ - // This function does not take ownership of the platform gl context. - // It is owned by the frontend QOpenGLContext - m_platformOpenGLContext = platformOpenGLContext; -} - -void QBBWindow::updateZorder(int &topZorder) -{ - errno = 0; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder); - topZorder++; - - if (result != 0) - qFatal("QBBWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window); - - QList::const_iterator it; - - for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) - (*it)->updateZorder(topZorder); -} - -void QBBWindow::copyBack(const QRegion ®ion, int dx, int dy, bool flush) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO << "window =" << window(); -#endif - int result; - - // Abort if previous buffer is invalid - if (m_previousBufferIndex == -1) { - return; - } - - // Abort if nothing to copy - if (region.isEmpty()) { - return; - } - - QBBBuffer ¤tBuffer = m_buffers[m_currentBufferIndex]; - QBBBuffer &previousBuffer = m_buffers[m_previousBufferIndex]; - - // Break down region into non-overlapping rectangles - QVector rects = region.rects(); - for (int i = rects.size() - 1; i >= 0; i--) { - // Clip rectangle to bounds of target - QRect rect = rects[i].intersected( currentBuffer.rect() ); - - if (rect.isEmpty()) - continue; - - // Setup blit operation - int attribs[] = { SCREEN_BLIT_SOURCE_X, rect.x(), - SCREEN_BLIT_SOURCE_Y, rect.y(), - SCREEN_BLIT_SOURCE_WIDTH, rect.width(), - SCREEN_BLIT_SOURCE_HEIGHT, rect.height(), - SCREEN_BLIT_DESTINATION_X, rect.x() + dx, - SCREEN_BLIT_DESTINATION_Y, rect.y() + dy, - SCREEN_BLIT_DESTINATION_WIDTH, rect.width(), - SCREEN_BLIT_DESTINATION_HEIGHT, rect.height(), - SCREEN_BLIT_END }; - - // Queue blit operation - errno = 0; - result = screen_blit(m_screenContext, currentBuffer.nativeBuffer(), previousBuffer.nativeBuffer(), attribs); - if (result != 0) { - qFatal("QBBWindow: failed to blit buffers, errno=%d", errno); - } - } - - // Check if flush requested - if (flush) { - // Wait for all blits to complete - errno = 0; - result = screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE); - if (result != 0) { - qFatal("QBBWindow: failed to flush blits, errno=%d", errno); - } - - // Buffer was modified outside the CPU - currentBuffer.invalidateInCache(); - } -} - -int QBBWindow::platformWindowFormatToNativeFormat(const QSurfaceFormat &format) -{ -#if defined(QBBWINDOW_DEBUG) - qDebug() << Q_FUNC_INFO; -#endif - // Extract size of colour channels from window format - int redSize = format.redBufferSize(); - if (redSize == -1) { - qFatal("QBBWindow: red size not defined"); - } - - int greenSize = format.greenBufferSize(); - if (greenSize == -1) { - qFatal("QBBWindow: green size not defined"); - } - - int blueSize = format.blueBufferSize(); - if (blueSize == -1) { - qFatal("QBBWindow: blue size not defined"); - } - - // select matching native format - if (redSize == 5 && greenSize == 6 && blueSize == 5) { - return SCREEN_FORMAT_RGB565; - } else if (redSize == 8 && greenSize == 8 && blueSize == 8) { - return SCREEN_FORMAT_RGBA8888; - } else { - qFatal("QBBWindow: unsupported pixel format"); - return 0; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/blackberry/qbbwindow.h b/src/plugins/platforms/blackberry/qbbwindow.h deleted file mode 100644 index ffdeba423a..0000000000 --- a/src/plugins/platforms/blackberry/qbbwindow.h +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBBWINDOW_H -#define QBBWINDOW_H - -#include - -#include "qbbbuffer.h" - -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -// all surfaces double buffered -#define MAX_BUFFER_COUNT 2 - -class QBBGLContext; -class QBBScreen; - -class QPlatformGLContext; -class QSurfaceFormat; - -class QBBWindow : public QPlatformWindow -{ -friend class QBBScreen; -public: - QBBWindow(QWindow *window, screen_context_t context); - virtual ~QBBWindow(); - - virtual void setGeometry(const QRect &rect); - virtual void setVisible(bool visible); - virtual void setOpacity(qreal level); - - virtual WId winId() const { return (WId)m_window; } - screen_window_t nativeHandle() const { return m_window; } - - void setBufferSize(const QSize &size); - QSize bufferSize() const { return m_bufferSize; } - bool hasBuffers() const { return !m_bufferSize.isEmpty(); } - - QBBBuffer &renderBuffer(); - void scroll(const QRegion ®ion, int dx, int dy, bool flush=false); - void post(const QRegion &dirty); - - void setScreen(QBBScreen *platformScreen); - - virtual void setParent(const QPlatformWindow *window); - virtual void raise(); - virtual void lower(); - virtual void requestActivateWindow(); - - void gainedFocus(); - - QBBScreen *screen() const { return m_screen; } - const QList& children() const { return m_childWindows; } - - void setPlatformOpenGLContext(QBBGLContext *platformOpenGLContext); - QBBGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; } - -private: - void removeFromParent(); - void offset(const QPoint &offset); - void updateVisibility(bool parentVisible); - void updateZorder(int &topZorder); - - void fetchBuffers(); - - void copyBack(const QRegion ®ion, int dx, int dy, bool flush=false); - - static int platformWindowFormatToNativeFormat(const QSurfaceFormat &format); - - screen_context_t m_screenContext; - screen_window_t m_window; - QSize m_bufferSize; - QBBBuffer m_buffers[MAX_BUFFER_COUNT]; - int m_currentBufferIndex; - int m_previousBufferIndex; - QRegion m_previousDirty; - QRegion m_scrolled; - - QBBGLContext *m_platformOpenGLContext; - QBBScreen *m_screen; - QList m_childWindows; - QBBWindow *m_parentWindow; - bool m_visible; -}; - -QT_END_NAMESPACE - -#endif // QBBWINDOW_H diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 52d3d83bbc..c97c1def0c 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -13,5 +13,5 @@ mac { win32: SUBDIRS += windows qnx-*-qcc { - SUBDIRS += blackberry + SUBDIRS += qnx } diff --git a/src/plugins/platforms/qnx/main.cpp b/src/plugins/platforms/qnx/main.cpp new file mode 100644 index 0000000000..b1e1687150 --- /dev/null +++ b/src/plugins/platforms/qnx/main.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qqnxintegration.h" + +QT_BEGIN_NAMESPACE + +class QQnxIntegrationPlugin : public QPlatformIntegrationPlugin +{ +public: + QStringList keys() const; + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QStringList QQnxIntegrationPlugin::keys() const +{ + QStringList list; + list << QLatin1String("qnx"); + return list; +} + +QPlatformIntegration *QQnxIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == QLatin1String("qnx")) + return new QQnxIntegration; + + return 0; +} + +Q_EXPORT_PLUGIN2(qnx, QQnxIntegrationPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro new file mode 100644 index 0000000000..1bd3548b7d --- /dev/null +++ b/src/plugins/platforms/qnx/qnx.pro @@ -0,0 +1,71 @@ +TARGET = qnx +include(../../qpluginbase.pri) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms +QT += opengl opengl-private platformsupport platformsupport-private widgets-private + +# Uncomment this to build with support for IMF once it becomes available in the BBNDK +#CONFIG += qqnx_imf + +# Uncomment these to enable debugging output for various aspects of the plugin +#DEFINES += QQNXBUFFER_DEBUG +#DEFINES += QQNXCLIPBOARD_DEBUG +#DEFINES += QQNXEVENTTHREAD_DEBUG +#DEFINES += QQNXGLBACKINGSTORE_DEBUG +#DEFINES += QQNXGLCONTEXT_DEBUG +#DEFINES += QQNXINPUTCONTEXT_DEBUG +#DEFINES += QQNXINPUTCONTEXT_IMF_EVENT_DEBUG +#DEFINES += QQNXINTEGRATION_DEBUG +#DEFINES += QQNXNAVIGATORTHREAD_DEBUG +#DEFINES += QQNXRASTERBACKINGSTORE_DEBUG +#DEFINES += QQNXROOTWINDOW_DEBUG +#DEFINES += QQNXSCREEN_DEBUG +#DEFINES += QQNXVIRTUALKEYBOARD_DEBUG +#DEFINES += QQNXWINDOW_DEBUG + +SOURCES = main.cpp \ + qqnxbuffer.cpp \ + qqnxeventthread.cpp \ + qqnxglcontext.cpp \ + qqnxglbackingstore.cpp \ + qqnxintegration.cpp \ + qqnxnavigatorthread.cpp \ + qqnxscreen.cpp \ + qqnxwindow.cpp \ + qqnxrasterbackingstore.cpp \ + qqnxvirtualkeyboard.cpp \ + qqnxclipboard.cpp \ + qqnxrootwindow.cpp + +HEADERS = qqnxbuffer.h \ + qqnxeventthread.h \ + qqnxkeytranslator.h \ + qqnxintegration.h \ + qqnxnavigatorthread.h \ + qqnxglcontext.h \ + qqnxglbackingstore.h \ + qqnxscreen.h \ + qqnxwindow.h \ + qqnxrasterbackingstore.h \ + qqnxvirtualkeyboard.h \ + qqnxclipboard.h \ + qqnxrootwindow.h + +CONFIG(qqnx_imf) { + DEFINES += QQNX_IMF + HEADERS += qqnxinputcontext_imf.h + SOURCES += qqnxinputcontext_imf.cpp +} else { + HEADERS += qqnxinputcontext_noimf.h + SOURCES += qqnxinputcontext_noimf.cpp +} + +QMAKE_CXXFLAGS += -I./private + +LIBS += -lpps -lscreen -lEGL -lclipboard + +include (../../../platformsupport/eglconvenience/eglconvenience.pri) +include (../../../platformsupport/fontdatabases/fontdatabases.pri) + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp new file mode 100644 index 0000000000..048aec8ff6 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp @@ -0,0 +1,165 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxbuffer.h" + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +QQnxBuffer::QQnxBuffer() + : m_buffer(0) +{ +#if defined(QQNXBUFFER_DEBUG) + qDebug() << "QQnxBuffer::QQnxBuffer - empty"; +#endif +} + +QQnxBuffer::QQnxBuffer(screen_buffer_t buffer) + : m_buffer(buffer) +{ +#if defined(QQNXBUFFER_DEBUG) + qDebug() << "QQnxBuffer::QQnxBuffer - normal"; +#endif + + // Get size of buffer + errno = 0; + int size[2]; + int result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (result != 0) { + qFatal("QQNX: failed to query buffer size, errno=%d", errno); + } + + // Get stride of buffer + errno = 0; + int stride; + result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride); + if (result != 0) { + qFatal("QQNX: failed to query buffer stride, errno=%d", errno); + } + + // Get access to buffer's data + errno = 0; + uchar *dataPtr = 0; + result = screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr); + if (result != 0) { + qFatal("QQNX: failed to query buffer pointer, errno=%d", errno); + } + if (dataPtr == NULL) { + qFatal("QQNX: buffer pointer is NULL, errno=%d", errno); + } + + // Get format of buffer + errno = 0; + int screenFormat; + result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat); + if (result != 0) { + qFatal("QQNX: failed to query buffer format, errno=%d", errno); + } + + // Convert screen format to QImage format + QImage::Format imageFormat = QImage::Format_Invalid; + switch (screenFormat) { + case SCREEN_FORMAT_RGBX4444: + imageFormat = QImage::Format_RGB444; + break; + case SCREEN_FORMAT_RGBA4444: + imageFormat = QImage::Format_ARGB4444_Premultiplied; + break; + case SCREEN_FORMAT_RGBX5551: + imageFormat = QImage::Format_RGB555; + break; + case SCREEN_FORMAT_RGB565: + imageFormat = QImage::Format_RGB16; + break; + case SCREEN_FORMAT_RGBX8888: + imageFormat = QImage::Format_RGB32; + break; + case SCREEN_FORMAT_RGBA8888: + imageFormat = QImage::Format_ARGB32_Premultiplied; + break; + default: + qFatal("QQNX: unsupported buffer format, format=%d", screenFormat); + } + + // wrap buffer in an image + m_image = QImage(dataPtr, size[0], size[1], stride, imageFormat); +} + +QQnxBuffer::QQnxBuffer(const QQnxBuffer &other) + : m_buffer(other.m_buffer), + m_image(other.m_image) +{ +#if defined(QQNXBUFFER_DEBUG) + qDebug() << "QQnxBuffer::QQnxBuffer - copy"; +#endif +} + +QQnxBuffer::~QQnxBuffer() +{ +#if defined(QQNXBUFFER_DEBUG) + qDebug() << "QQnxBuffer::~QQnxBuffer"; +#endif +} + +void QQnxBuffer::invalidateInCache() +{ +#if defined(QQNXBUFFER_DEBUG) + qDebug() << "QQnxBuffer::invalidateInCache"; +#endif + + // Verify native buffer exists + if (m_buffer == 0) { + qFatal("QQNX: can't invalidate cache for null buffer"); + } + + // Evict buffer's data from cache + errno = 0; + int result = msync(m_image.bits(), m_image.height() * m_image.bytesPerLine(), MS_INVALIDATE | MS_CACHE_ONLY); + if (result != 0) { + qFatal("QQNX: failed to invalidate cache, errno=%d", errno); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxbuffer.h b/src/plugins/platforms/qnx/qqnxbuffer.h new file mode 100644 index 0000000000..be8dfcafad --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxbuffer.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXBUFFER_H +#define QQNXBUFFER_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxBuffer +{ +public: + QQnxBuffer(); + QQnxBuffer(screen_buffer_t buffer); + QQnxBuffer(const QQnxBuffer &other); + virtual ~QQnxBuffer(); + + screen_buffer_t nativeBuffer() const { return m_buffer; } + const QImage *image() const { return (m_buffer != NULL) ? &m_image : NULL; } + QImage *image() { return (m_buffer != NULL) ? &m_image : NULL; } + + QRect rect() const { return m_image.rect(); } + + void invalidateInCache(); + +private: + screen_buffer_t m_buffer; + QImage m_image; +}; + +QT_END_NAMESPACE + +#endif // QQNXBUFFER_H diff --git a/src/plugins/platforms/qnx/qqnxclipboard.cpp b/src/plugins/platforms/qnx/qqnxclipboard.cpp new file mode 100644 index 0000000000..8931a15139 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxclipboard.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_NO_CLIPBOARD + +#include "qqnxclipboard.h" + +#include + +#include +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +// null terminated array +static const char *typeList[] = {"text/html", "text/plain", "image/png", "image/jpeg", "application/x-color", 0}; + +static QByteArray readClipboardBuff(const char *type) +{ + char *pbuffer; + if (is_clipboard_format_present(type) == 0) { + int size = get_clipboard_data(type, &pbuffer); + if (size != -1 && pbuffer) { + const QByteArray result = QByteArray(pbuffer, size); + free(pbuffer); + return result; + } + } + + return QByteArray(); +} + +class QQnxClipboard::MimeData : public QMimeData +{ + Q_OBJECT +public: + MimeData(QQnxClipboard *clipboard) + : QMimeData(), + m_clipboard(clipboard), + m_userMimeData(0) + { + Q_ASSERT(clipboard); + + for (int i = 0; typeList[i] != 0; ++i) { + m_formatsToCheck << QString::fromUtf8(typeList[i]); + } + } + + ~MimeData() + { + delete m_userMimeData; + } + + void addFormatToCheck(const QString &format) { + m_formatsToCheck << format; + +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << Q_FUNC_INFO << "formats=" << m_formatsToCheck; +#endif + } + + bool hasFormat(const QString &mimetype) const + { + const bool result = is_clipboard_format_present(mimetype.toUtf8().constData()) == 0; +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "result=" << result; +#endif + return result; + } + + QStringList formats() const + { + QStringList result; + + Q_FOREACH (const QString &format, m_formatsToCheck) { + if (is_clipboard_format_present(format.toUtf8().constData()) == 0) + result << format; + } + +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << Q_FUNC_INFO << "result=" << result; +#endif + return result; + } + + void setUserMimeData(QMimeData *userMimeData) + { + delete m_userMimeData; + m_userMimeData = userMimeData; + + // system clipboard API doesn't allow detection of changes by other applications + // simulate an owner change through delayed invocation + // basically transfer ownership of data to the system clipboard once event processing resumes + if (m_userMimeData) + QMetaObject::invokeMethod(this, "releaseOwnership", Qt::QueuedConnection); + } + + QMimeData *userMimeData() + { + return m_userMimeData; + } + +protected: + QVariant retrieveData(const QString &mimetype, QVariant::Type preferredType) const + { +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "preferredType=" << preferredType; +#endif + if (is_clipboard_format_present(mimetype.toUtf8().constData()) != 0) + return QMimeData::retrieveData(mimetype, preferredType); + + const QByteArray data = readClipboardBuff(mimetype.toUtf8().constData()); + return qVariantFromValue(data); + } + +private Q_SLOTS: + void releaseOwnership() + { + if (m_userMimeData) { +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << Q_FUNC_INFO << "user data formats=" << m_userMimeData->formats() << "system formats=" << formats(); +#endif + delete m_userMimeData; + m_userMimeData = 0; + m_clipboard->emitChanged(QClipboard::Clipboard); + } + } + +private: + QQnxClipboard * const m_clipboard; + + QSet m_formatsToCheck; + QMimeData *m_userMimeData; +}; + +QQnxClipboard::QQnxClipboard() + : m_mimeData(new MimeData(this)) +{ +} + +QQnxClipboard::~QQnxClipboard() +{ + delete m_mimeData; +} + +void QQnxClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) +{ + if (mode != QClipboard::Clipboard) + return; + + if (data == m_mimeData || data == m_mimeData->userMimeData()) + return; + + empty_clipboard(); + + m_mimeData->clear(); + m_mimeData->setUserMimeData(data); + + if (data == 0) + return; + + const QStringList formats = data->formats(); +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << Q_FUNC_INFO << "formats=" << formats; +#endif + + Q_FOREACH (const QString &format, formats) { + const QByteArray buf = data->data(format); + + if (buf.isEmpty()) + continue; + + int ret = set_clipboard_data(format.toUtf8().data(), buf.size(), buf.data()); +#if defined(QQNXCLIPBOARD_DEBUG) + qDebug() << "QQNX: set " << format << "to clipboard, size=" << buf.size() << ";ret=" << ret; +#endif + if (ret) + m_mimeData->addFormatToCheck(format); + } + + emitChanged(QClipboard::Clipboard); +} + +QMimeData *QQnxClipboard::mimeData(QClipboard::Mode mode) +{ + if (mode != QClipboard::Clipboard) + return 0; + + if (m_mimeData->userMimeData()) + return m_mimeData->userMimeData(); + + m_mimeData->clear(); + + return m_mimeData; +} + +QT_END_NAMESPACE + +#include "qqnxclipboard.moc" + +#endif //QT_NO_CLIPBOARD diff --git a/src/plugins/platforms/qnx/qqnxclipboard.h b/src/plugins/platforms/qnx/qqnxclipboard.h new file mode 100644 index 0000000000..1104885d8c --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxclipboard.h @@ -0,0 +1,66 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXCLIPBOARD_H +#define QQNXCLIPBOARD_H + +#ifndef QT_NO_CLIPBOARD +#include + +QT_BEGIN_NAMESPACE + +class QQnxClipboard : public QPlatformClipboard +{ +public: + QQnxClipboard(); + virtual ~QQnxClipboard(); + virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); + virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); + +private: + class MimeData; + MimeData *m_mimeData; +}; + +QT_END_NAMESPACE + +#endif //QT_NO_CLIPBOARD +#endif //QQNXCLIPBOARD_H diff --git a/src/plugins/platforms/qnx/qqnxeventthread.cpp b/src/plugins/platforms/qnx/qqnxeventthread.cpp new file mode 100644 index 0000000000..cd30da1971 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxeventthread.cpp @@ -0,0 +1,572 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxeventthread.h" +#include "qqnxintegration.h" +#include "qqnxkeytranslator.h" + +#if defined(QQNX_IMF) +#include "qqnxinputcontext_imf.h" +#else +#include "qqnxinputcontext_noimf.h" +#endif + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +QQnxEventThread::QQnxEventThread(screen_context_t context, QPlatformScreen& screen) + : QThread(), + m_screenContext(context), + m_platformScreen(screen), + m_quit(false), + m_lastButtonState(Qt::NoButton), + m_lastMouseWindow(0) +{ + // Create a touch device + m_touchDevice = new QTouchDevice; + m_touchDevice->setType(QTouchDevice::TouchScreen); + m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(m_touchDevice); + + // initialize array of touch points + for (int i = 0; i < MaximumTouchPoints; i++) { + + // map array index to id + m_touchPoints[i].id = i; + + // pressure is not supported - use default + m_touchPoints[i].pressure = 1.0; + + // nothing touching + m_touchPoints[i].state = Qt::TouchPointReleased; + } +} + +QQnxEventThread::~QQnxEventThread() +{ + // block until thread terminates + shutdown(); +} + +void QQnxEventThread::run() +{ + screen_event_t event; + + // create screen event + errno = 0; + int result = screen_create_event(&event); + if (result) { + qFatal("QQNX: failed to create event, errno=%d", errno); + } + +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: event loop started"; +#endif + + // loop indefinitely + while (!m_quit) { + + // block until screen event is available + errno = 0; + result = screen_get_event(m_screenContext, event, -1); + if (result) { + qFatal("QQNX: failed to get event, errno=%d", errno); + } + + // process received event + dispatchEvent(event); + } + +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: event loop stopped"; +#endif + + // cleanup + screen_destroy_event(event); +} + +void QQnxEventThread::shutdown() +{ + screen_event_t event; + + // create screen event + errno = 0; + int result = screen_create_event(&event); + if (result) { + qFatal("QQNX: failed to create event, errno=%d", errno); + } + + // set the event type as user + errno = 0; + int type = SCREEN_EVENT_USER; + result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type); + if (result) { + qFatal("QQNX: failed to set event type, errno=%d", errno); + } + + // NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events + + // post event to event loop so it will wake up and die + errno = 0; + result = screen_send_event(m_screenContext, event, getpid()); + if (result) { + qFatal("QQNX: failed to set event type, errno=%d", errno); + } + + // cleanup + screen_destroy_event(event); + +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: event loop shutdown begin"; +#endif + + // block until thread terminates + wait(); + +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: event loop shutdown end"; +#endif +} + +void QQnxEventThread::dispatchEvent(screen_event_t event) +{ + // get the event type + errno = 0; + int qnxType; + int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType); + if (result) { + qFatal("QQNX: failed to query event type, errno=%d", errno); + } + + switch (qnxType) { + case SCREEN_EVENT_MTOUCH_TOUCH: + case SCREEN_EVENT_MTOUCH_MOVE: + case SCREEN_EVENT_MTOUCH_RELEASE: + handleTouchEvent(event, qnxType); + break; + + case SCREEN_EVENT_KEYBOARD: + handleKeyboardEvent(event); + break; + + case SCREEN_EVENT_POINTER: + handlePointerEvent(event); + break; + + case SCREEN_EVENT_CLOSE: + handleCloseEvent(event); + break; + + case SCREEN_EVENT_USER: + // treat all user events as shutdown requests +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: QNX user event"; +#endif + m_quit = true; + break; + + default: + // event ignored +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: QNX unknown event"; +#endif + break; + } +} + +void QQnxEventThread::handleKeyboardEvent(screen_event_t event) +{ + // get flags of key event + errno = 0; + int flags; + int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags); + if (result) { + qFatal("QQNX: failed to query event flags, errno=%d", errno); + } + + // get key code + errno = 0; + int sym; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym); + if (result) { + qFatal("QQNX: failed to query event sym, errno=%d", errno); + } + + int modifiers; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers); + if (result) { + qFatal("QQNX: failed to query event modifiers, errno=%d", errno); + } + + int scan; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan); + if (result) { + qFatal("QQNX: failed to query event modifiers, errno=%d", errno); + } + + int cap; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap); + if (result) { + qFatal("QQNX: failed to query event cap, errno=%d", errno); + } + + injectKeyboardEvent(flags, sym, modifiers, scan, cap); +} + +void QQnxEventThread::injectKeyboardEvent(int flags, int sym, int modifiers, int scan, int cap) +{ + Q_UNUSED(scan); + + Qt::KeyboardModifiers qtMod = Qt::NoModifier; + if (modifiers & KEYMOD_SHIFT) + qtMod |= Qt::ShiftModifier; + if (modifiers & KEYMOD_CTRL) + qtMod |= Qt::ControlModifier; + if (modifiers & KEYMOD_ALT) + qtMod |= Qt::AltModifier; + + // determine event type + QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease; + + // Check if the key cap is valid + if (flags & KEY_CAP_VALID) { + Qt::Key key; + QString keyStr; + + if (cap >= 0x20 && cap <= 0x0ff) { + key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case. + + if ( qtMod & Qt::ControlModifier ) { + keyStr = QChar((int)(key & 0x3f)); + } else { + if (flags & KEY_SYM_VALID) { + keyStr = QChar(sym); + } + } + } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) { + key = (Qt::Key)cap; + keyStr = QChar(sym); + } else { + if (isKeypadKey(cap)) + qtMod |= Qt::KeypadModifier; // Is this right? + key = keyTranslator(cap); + } + + QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, keyStr); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt key t=" << type << ", k=" << key << ", s=" << keyStr; +#endif + } +} + +void QQnxEventThread::handlePointerEvent(screen_event_t event) +{ + errno = 0; + + // Query the window that was clicked + screen_window_t qnxWindow; + void *handle; + int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); + if (result) { + qFatal("QQNX: failed to query event window, errno=%d", errno); + } + qnxWindow = static_cast(handle); + + // Query the button states + int buttonState = 0; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState); + if (result) { + qFatal("QQNX: failed to query event button state, errno=%d", errno); + } + + // Query the window position + int windowPos[2]; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); + if (result) { + qFatal("QQNX: failed to query event window position, errno=%d", errno); + } + + // Query the screen position + int pos[2]; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); + if (result) { + qFatal("QQNX: failed to query event position, errno=%d", errno); + } + + // Query the wheel delta + int wheelDelta = 0; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta); + if (result) { + qFatal("QQNX: failed to query event wheel delta, errno=%d", errno); + } + + // Map window handle to top-level QWindow + QWindow *w = QQnxIntegration::window(qnxWindow); + + // Generate enter and leave events as needed. + if (qnxWindow != m_lastMouseWindow) { + QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); + + if (wOld) { + QWindowSystemInterface::handleLeaveEvent(wOld); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt leave, w=" << wOld; +#endif + } + + if (w) { + QWindowSystemInterface::handleEnterEvent(w); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt enter, w=" << w; +#endif + } + } + m_lastMouseWindow = qnxWindow; + + // Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale + // this via a system preference at some point. But for now this is a sane value and makes + // the wheel usable. + wheelDelta *= -10; + + // convert point to local coordinates + QPoint globalPoint(pos[0], pos[1]); + QPoint localPoint(windowPos[0], windowPos[1]); + + // Convert buttons. + // Some QNX header files invert 'Right Button versus "Left Button' ('Right' == 0x01). But they also offer a 'Button Swap' bit, + // so we may receive events as shown. (If this is wrong, the fix is easy.) + // QNX Button mask is 8 buttons wide, with a maximum value of x080. + Qt::MouseButtons buttons = Qt::NoButton; + if (buttonState & 0x01) + buttons |= Qt::LeftButton; + if (buttonState & 0x02) + buttons |= Qt::MidButton; + if (buttonState & 0x04) + buttons |= Qt::RightButton; + if (buttonState & 0x08) + buttons |= Qt::ExtraButton1; // AKA 'Qt::BackButton' + if (buttonState & 0x10) + buttons |= Qt::ExtraButton2; // AKA 'Qt::ForwardButton' + if (buttonState & 0x20) + buttons |= Qt::ExtraButton3; + if (buttonState & 0x40) + buttons |= Qt::ExtraButton4; + if (buttonState & 0x80) + buttons |= Qt::ExtraButton5; + + if (w) { + // Inject mouse event into Qt only if something has changed. + if (m_lastGlobalMousePoint != globalPoint || + m_lastLocalMousePoint != localPoint || + m_lastButtonState != buttons) { + QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << static_cast(buttons); +#endif + } + + if (wheelDelta) { + // Screen only supports a single wheel, so we will assume Vertical orientation for + // now since that is pretty much standard. + QWindowSystemInterface::handleWheelEvent(w, localPoint, globalPoint, wheelDelta, Qt::Vertical); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt wheel, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), d=" << static_cast(wheelDelta); +#endif + } + } + + m_lastGlobalMousePoint = globalPoint; + m_lastLocalMousePoint = localPoint; + m_lastButtonState = buttons; +} + +void QQnxEventThread::handleTouchEvent(screen_event_t event, int qnxType) +{ + // get display coordinates of touch + errno = 0; + int pos[2]; + int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos); + if (result) { + qFatal("QQNX: failed to query event position, errno=%d", errno); + } + + // get window coordinates of touch + errno = 0; + int windowPos[2]; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos); + if (result) { + qFatal("QQNX: failed to query event window position, errno=%d", errno); + } + + // determine which finger touched + errno = 0; + int touchId; + result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId); + if (result) { + qFatal("QQNX: failed to query event touch id, errno=%d", errno); + } + + // determine which window was touched + errno = 0; + void *handle; + result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); + if (result) { + qFatal("QQNX: failed to query event window, errno=%d", errno); + } + screen_window_t qnxWindow = static_cast(handle); + + // check if finger is valid + if (touchId < MaximumTouchPoints) { + + // Map window handle to top-level QWindow + QWindow *w = QQnxIntegration::window(qnxWindow); + + // Generate enter and leave events as needed. + if (qnxWindow != m_lastMouseWindow) { + QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow); + + if (wOld) { + QWindowSystemInterface::handleLeaveEvent(wOld); + #if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt leave, w=" << wOld; + #endif + } + + if (w) { + QWindowSystemInterface::handleEnterEvent(w); + #if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt enter, w=" << w; + #endif + } + } + m_lastMouseWindow = qnxWindow; + + if (w) { + // convert primary touch to mouse event + if (touchId == 0) { + + // convert point to local coordinates + QPoint globalPoint(pos[0], pos[1]); + QPoint localPoint(windowPos[0], windowPos[1]); + + // map touch state to button state + Qt::MouseButtons buttons = (qnxType == SCREEN_EVENT_MTOUCH_RELEASE) ? Qt::NoButton : Qt::LeftButton; + + // inject event into Qt + QWindowSystemInterface::handleMouseEvent(w, localPoint, globalPoint, buttons); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt mouse, w=" << w << ", (" << localPoint.x() << "," << localPoint.y() << "), b=" << buttons; +#endif + } + + // get size of screen which contains window + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w); + QSizeF screenSize = platformScreen->physicalSize(); + + // update cached position of current touch point + m_touchPoints[touchId].normalPosition = QPointF( static_cast(pos[0]) / screenSize.width(), static_cast(pos[1]) / screenSize.height() ); + m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 ); + + // determine event type and update state of current touch point + QEvent::Type type = QEvent::None; + switch (qnxType) { + case SCREEN_EVENT_MTOUCH_TOUCH: + m_touchPoints[touchId].state = Qt::TouchPointPressed; + type = QEvent::TouchBegin; + break; + case SCREEN_EVENT_MTOUCH_MOVE: + m_touchPoints[touchId].state = Qt::TouchPointMoved; + type = QEvent::TouchUpdate; + break; + case SCREEN_EVENT_MTOUCH_RELEASE: + m_touchPoints[touchId].state = Qt::TouchPointReleased; + type = QEvent::TouchEnd; + break; + } + + // build list of active touch points + QList pointList; + for (int i = 0; i < MaximumTouchPoints; i++) { + if (i == touchId) { + // current touch point is always active + pointList.append(m_touchPoints[i]); + } else if (m_touchPoints[i].state != Qt::TouchPointReleased) { + // finger is down but did not move + m_touchPoints[i].state = Qt::TouchPointStationary; + pointList.append(m_touchPoints[i]); + } + } + + // inject event into Qt + QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList); +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: Qt touch, w=" << w << ", p=(" << pos[0] << "," << pos[1] << "), t=" << type; +#endif + } + } +} + +void QQnxEventThread::handleCloseEvent(screen_event_t event) +{ + // Query the window that was closed + void *handle; + int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle); + if (result != 0) { + qFatal("QQNX: failed to query event window, errno=%d", errno); + } + screen_window_t qnxWindow = static_cast(handle); + + // Map window handle to top-level QWindow + QWindow *w = QQnxIntegration::window(qnxWindow); + if (w != 0) { + QWindowSystemInterface::handleCloseEvent(w); + } +} + diff --git a/src/plugins/platforms/qnx/qqnxeventthread.h b/src/plugins/platforms/qnx/qqnxeventthread.h new file mode 100644 index 0000000000..61831233e9 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxeventthread.h @@ -0,0 +1,90 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXEVENTTHREAD_H +#define QQNXEVENTTHREAD_H + +#include + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxEventThread : public QThread +{ +public: + QQnxEventThread(screen_context_t context, QPlatformScreen& screen); + virtual ~QQnxEventThread(); + + static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); + +protected: + virtual void run(); + +private: + enum { + MaximumTouchPoints = 10 + }; + + void shutdown(); + void dispatchEvent(screen_event_t event); + void handleKeyboardEvent(screen_event_t event); + void handlePointerEvent(screen_event_t event); + void handleTouchEvent(screen_event_t event, int type); + void handleCloseEvent(screen_event_t event); + + screen_context_t m_screenContext; + QPlatformScreen& m_platformScreen; + bool m_quit; + QPoint m_lastGlobalMousePoint; + QPoint m_lastLocalMousePoint; + Qt::MouseButtons m_lastButtonState; + screen_window_t m_lastMouseWindow; + QTouchDevice *m_touchDevice; + QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints]; +}; + +QT_END_NAMESPACE + +#endif // QQNXEVENTTHREAD_H diff --git a/src/plugins/platforms/qnx/qqnxglbackingstore.cpp b/src/plugins/platforms/qnx/qqnxglbackingstore.cpp new file mode 100644 index 0000000000..97a03e0042 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxglbackingstore.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxglbackingstore.h" +#include "qqnxglcontext.h" +#include "qqnxwindow.h" +#include "qqnxscreen.h" + +#include + +#include +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +QQnxGLPaintDevice::QQnxGLPaintDevice(QWindow *window) + : QGLPaintDevice(), + m_window(0), + m_glContext(0) +{ + m_window = static_cast(window->handle()); + + // Extract the QPlatformOpenGLContext from the window + QPlatformOpenGLContext *platformOpenGLContext = m_window->platformOpenGLContext(); + + // Convert this to a QGLContext + m_glContext = QGLContext::fromOpenGLContext(platformOpenGLContext->context()); +} + +QQnxGLPaintDevice::~QQnxGLPaintDevice() +{ + // Cleanup GL context + delete m_glContext; +} + +QPaintEngine *QQnxGLPaintDevice::paintEngine() const +{ + // Select a paint engine based on configued OpenGL version + return qt_qgl_paint_engine(); +} + +QSize QQnxGLPaintDevice::size() const +{ + // Get size of EGL surface + return m_window->geometry().size(); +} + + +QQnxGLBackingStore::QQnxGLBackingStore(QWindow *window) + : QPlatformBackingStore(window), + m_openGLContext(0), + m_paintDevice(0), + m_requestedSize(), + m_size() +{ +#if defined(QQNXGLBACKINGSTORE_DEBUG) + qDebug() << "QQnxGLBackingStore::QQnxGLBackingStore - w=" << window; +#endif + + // Create an OpenGL paint device which in turn creates a QGLContext for us + m_paintDevice = new QQnxGLPaintDevice(window); + m_openGLContext = m_paintDevice->context()->contextHandle(); +} + +QQnxGLBackingStore::~QQnxGLBackingStore() +{ +#if defined(QQNXGLBACKINGSTORE_DEBUG) + qDebug() << "QQnxGLBackingStore::~QQnxGLBackingStore - w=" << window(); +#endif + + // cleanup OpenGL paint device + delete m_paintDevice; +} + +void QQnxGLBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(region); + Q_UNUSED(offset); + +#if defined(QQNXGLBACKINGSTORE_DEBUG) + qDebug() << "QQnxGLBackingStore::flush - w=" << window; +#endif + + // update the display with newly rendered content + m_openGLContext->swapBuffers(window); +} + +void QQnxGLBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(staticContents); +#if defined(QQNXGLBACKINGSTORE_DEBUG) + qDebug() << "QQnxGLBackingStore::resize - w=" << window() << ", s=" << size; +#endif + // NOTE: defer resizing window buffers until next paint as + // resize() can be called multiple times before a paint occurs + m_requestedSize = size; +} + +void QQnxGLBackingStore::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); + +#if defined(QQNXGLBACKINGSTORE_DEBUG) + qDebug() << "QQnxGLBackingStore::beginPaint - w=" << window(); +#endif + + // resize EGL surface if window surface resized + if (m_size != m_requestedSize) { + resizeSurface(m_requestedSize); + } +} + +void QQnxGLBackingStore::endPaint(const QRegion ®ion) +{ + Q_UNUSED(region); +#if defined(QQNXGLBACKINGSTORE_DEBUG) + qDebug() << "QQnxGLBackingStore::endPaint - w=" << window(); +#endif +} + +void QQnxGLBackingStore::resizeSurface(const QSize &size) +{ + // need to destroy surface so make sure its not current + bool restoreCurrent = false; + QQnxGLContext *platformContext = static_cast(m_openGLContext->handle()); + if (platformContext->isCurrent()) { + m_openGLContext->doneCurrent(); + restoreCurrent = true; + } + + // destroy old EGL surface + platformContext->destroySurface(); + + // resize window's buffers + static_cast(window()->handle())->setBufferSize(size); + + // re-create EGL surface with new size + m_size = size; + platformContext->createSurface(window()->handle()); + + // make context current again + if (restoreCurrent) { + m_openGLContext->makeCurrent(window()); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxglbackingstore.h b/src/plugins/platforms/qnx/qqnxglbackingstore.h new file mode 100644 index 0000000000..d04fe22f5d --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxglbackingstore.h @@ -0,0 +1,95 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXGLBACKINGSTORE_H +#define QQNXGLBACKINGSTORE_H + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QGLContext; +class QQnxGLContext; +class QQnxScreen; +class QQnxWindow; + +class QQnxGLPaintDevice : public QGLPaintDevice +{ +public: + QQnxGLPaintDevice(QWindow *window); + virtual ~QQnxGLPaintDevice(); + + virtual QPaintEngine *paintEngine() const; + virtual QSize size() const; + virtual QGLContext *context() const { return m_glContext; } + +private: + QQnxWindow *m_window; + QGLContext *m_glContext; +}; + +class QQnxGLBackingStore : public QPlatformBackingStore +{ +public: + QQnxGLBackingStore(QWindow *window); + virtual ~QQnxGLBackingStore(); + + virtual QPaintDevice *paintDevice() { return m_paintDevice; } + virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + virtual void resize(const QSize &size, const QRegion &staticContents); + virtual void beginPaint(const QRegion ®ion); + virtual void endPaint(const QRegion ®ion); + + void resizeSurface(const QSize &size); + +private: + QOpenGLContext *m_openGLContext; + QQnxGLPaintDevice *m_paintDevice; + QSize m_requestedSize; + QSize m_size; +}; + +QT_END_NAMESPACE + +#endif // QQNXGLBACKINGSTORE_H diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp new file mode 100644 index 0000000000..d620feb710 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -0,0 +1,356 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxglcontext.h" +#include "qqnxrootwindow.h" +#include "qqnxscreen.h" +#include "qqnxwindow.h" + +#include "private/qeglconvenience_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY; + +static EGLenum checkEGLError(const char *msg) +{ + static const char *errmsg[] = + { + "EGL function succeeded", + "EGL is not initialized, or could not be initialized, for the specified display", + "EGL cannot access a requested resource", + "EGL failed to allocate resources for the requested operation", + "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list", + "EGLConfig argument does not name a valid EGLConfig", + "EGLContext argument does not name a valid EGLContext", + "EGL current surface of the calling thread is no longer valid", + "EGLDisplay argument does not name a valid EGLDisplay", + "EGL arguments are inconsistent", + "EGLNativePixmapType argument does not refer to a valid native pixmap", + "EGLNativeWindowType argument does not refer to a valid native window", + "EGL one or more argument values are invalid", + "EGLSurface argument does not name a valid surface configured for rendering", + "EGL power management event has occurred", + }; + EGLenum error = eglGetError(); + fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]); + return error; +} + +QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) + : QPlatformOpenGLContext(), + m_glContext(glContext), + m_eglSurface(EGL_NO_SURFACE) +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + QSurfaceFormat format = m_glContext->format(); + + // Set current rendering API + EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); + } + + // Get colour channel sizes from window format + int alphaSize = format.alphaBufferSize(); + int redSize = format.redBufferSize(); + int greenSize = format.greenBufferSize(); + int blueSize = format.blueBufferSize(); + + // Check if all channels are don't care + if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) { + // Set colour channels based on depth of window's screen + QQnxScreen *screen = static_cast(QQnxScreen::screens().first()); + int depth = screen->depth(); + if (depth == 32) { + // SCREEN_FORMAT_RGBA8888 + alphaSize = 8; + redSize = 8; + greenSize = 8; + blueSize = 8; + } else { + // SCREEN_FORMAT_RGB565 + alphaSize = 0; + redSize = 5; + greenSize = 6; + blueSize = 5; + } + } else { + // Choose best match based on supported pixel formats + if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) { + // SCREEN_FORMAT_RGB565 + alphaSize = 0; + redSize = 5; + greenSize = 6; + blueSize = 5; + } else { + // SCREEN_FORMAT_RGBA8888 + alphaSize = 8; + redSize = 8; + greenSize = 8; + blueSize = 8; + } + } + + // Update colour channel sizes in window format + format.setAlphaBufferSize(alphaSize); + format.setRedBufferSize(redSize); + format.setGreenBufferSize(greenSize); + format.setBlueBufferSize(blueSize); + format.setSamples(2); + + // Select EGL config based on requested window format + m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format); + if (m_eglConfig == 0) { + qFatal("QQNXQBBWindow: failed to find EGL config"); + } + + m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs()); + if (m_eglContext == EGL_NO_CONTEXT) { + checkEGLError("eglCreateContext"); + qFatal("QQNXQBBWindow: failed to create EGL context, err=%d", eglGetError()); + } + + // Query/cache window format of selected EGL config + m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig); +} + +QQnxGLContext::~QQnxGLContext() +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + // Cleanup EGL context if it exists + if (m_eglContext != EGL_NO_CONTEXT) { + eglDestroyContext(ms_eglDisplay, m_eglContext); + } + + // Cleanup EGL surface if it exists + destroySurface(); +} + +void QQnxGLContext::initialize() +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Initialize connection to EGL + ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (ms_eglDisplay == EGL_NO_DISPLAY) { + checkEGLError("eglGetDisplay"); + qFatal("QQNXQBBWindow: failed to obtain EGL display"); + } + + EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0); + if (eglResult != EGL_TRUE) { + checkEGLError("eglInitialize"); + qFatal("QQNXQBBWindow: failed to initialize EGL display, err=%d", eglGetError()); + } +} + +void QQnxGLContext::shutdown() +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Close connection to EGL + eglTerminate(ms_eglDisplay); +} + +bool QQnxGLContext::makeCurrent(QPlatformSurface *surface) +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Set current rendering API + EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); + if (eglResult != EGL_TRUE) { + qFatal("QQNXQBBWindow: failed to set EGL API, err=%d", eglGetError()); + } + + if (m_eglSurface == EGL_NO_SURFACE) + createSurface(surface); + + eglResult = eglMakeCurrent(ms_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); + if (eglResult != EGL_TRUE) { + checkEGLError("eglMakeCurrent"); + qFatal("QQNX: failed to set current EGL context, err=%d", eglGetError()); + } + return (eglResult == EGL_TRUE); +} + +void QQnxGLContext::doneCurrent() +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // set current rendering API + EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); + } + + // clear curent EGL context and unbind EGL surface + eglResult = eglMakeCurrent(ms_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to clear current EGL context, err=%d", eglGetError()); + } +} + +void QQnxGLContext::swapBuffers(QPlatformSurface *surface) +{ + Q_UNUSED(surface); +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + // Set current rendering API + EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); + } + + // Post EGL surface to window + eglResult = eglSwapBuffers(ms_eglDisplay, m_eglSurface); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError()); + } +} + +QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName) +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + // Set current rendering API + EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to set EGL API, err=%d", eglGetError()); + } + + // Lookup EGL extension function pointer + return static_cast(eglGetProcAddress(procName.constData())); +} + +EGLint *QQnxGLContext::contextAttrs() +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + // Choose EGL settings based on OpenGL version +#if defined(QT_OPENGL_ES_2) + static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + return attrs; +#else + return 0; +#endif +} + +bool QQnxGLContext::isCurrent() const +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + return (eglGetCurrentContext() == m_eglContext); +} + +void QQnxGLContext::createSurface(QPlatformSurface *surface) +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Get a pointer to the corresponding platform window + QQnxWindow *platformWindow = dynamic_cast(surface); + if (!platformWindow) { + qFatal("QQNX: unable to create EGLSurface without a QQnxWindow"); + } + + // If the platform window does not yet have any buffers, we create + // a temporary set of buffers with a size of 1x1 pixels. This will + // suffice until such time as the platform window has obtained + // buffers of the proper size + if (!platformWindow->hasBuffers()) { + platformWindow->setPlatformOpenGLContext(this); + m_surfaceSize = platformWindow->geometry().size(); + platformWindow->setBufferSize(m_surfaceSize); + } + + // Obtain the native handle for our window + screen_window_t handle = platformWindow->nativeHandle(); + + const EGLint eglSurfaceAttrs[] = + { + EGL_RENDER_BUFFER, EGL_BACK_BUFFER, + EGL_NONE + }; + + // Create EGL surface + m_eglSurface = eglCreateWindowSurface(ms_eglDisplay, m_eglConfig, (EGLNativeWindowType) handle, eglSurfaceAttrs); + if (m_eglSurface == EGL_NO_SURFACE) { + checkEGLError("eglCreateWindowSurface"); + qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError()); + } +} + +void QQnxGLContext::destroySurface() +{ +#if defined(QQNXGLCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + // Destroy EGL surface if it exists + if (m_eglSurface != EGL_NO_SURFACE) { + EGLBoolean eglResult = eglDestroySurface(ms_eglDisplay, m_eglSurface); + if (eglResult != EGL_TRUE) { + qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError()); + } + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h new file mode 100644 index 0000000000..36c439802a --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxglcontext.h @@ -0,0 +1,93 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXGLCONTEXT_H +#define QQNXGLCONTEXT_H + +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxWindow; + +class QQnxGLContext : public QPlatformOpenGLContext +{ +public: + QQnxGLContext(QOpenGLContext *glContext); + virtual ~QQnxGLContext(); + + static void initialize(); + static void shutdown(); + + virtual bool makeCurrent(QPlatformSurface *surface); + virtual void doneCurrent(); + virtual void swapBuffers(QPlatformSurface *surface); + virtual QFunctionPointer getProcAddress(const QByteArray &procName); + + virtual QSurfaceFormat format() const { return m_windowFormat; } + + bool isCurrent() const; + + void createSurface(QPlatformSurface *surface); + void destroySurface(); + +private: + /** \todo Should this be non-static so we can use additional displays? */ + static EGLDisplay ms_eglDisplay; + + QSurfaceFormat m_windowFormat; + QOpenGLContext *m_glContext; + + EGLConfig m_eglConfig; + EGLContext m_eglContext; + EGLSurface m_eglSurface; + QSize m_surfaceSize; + + static EGLint *contextAttrs(); +}; + +QT_END_NAMESPACE + +#endif // QQNXGLCONTEXT_H diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp new file mode 100644 index 0000000000..3f9d768ccc --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp @@ -0,0 +1,1696 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxinputcontext_imf.h" +#include "qqnxeventthread.h" +#include "qqnxvirtualkeyboard.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "imf/imf_client.h" +#include "imf/input_control.h" +#include +#include + +/** TODO: + Support inputMethodHints to restrict input (needs additional features in IMF). +*/ + +#define STRX(x) #x +#define STR(x) STRX(x) + +// Someone tell me why input_control methods are in this namespace, but the rest is not. +using namespace InputMethodSystem; + +#define qs(x) QString::fromLatin1(x) +#define iarg(name) event->mArgs[qs(#name)] = QVariant::fromValue(name) +#define parg(name) event->mArgs[qs(#name)] = QVariant::fromValue((void*)name) +namespace +{ + +spannable_string_t *toSpannableString(const QString &text); +static const input_session_t *sInputSession = 0; +bool isSessionOkay(input_session_t *ic) +{ + return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id; +} + +enum ImfEventType +{ + ImfBeginBatchEdit, + ImfClearMetaKeyStates, + ImfCommitText, + ImfDeleteSurroundingText, + ImfEndBatchEdit, + ImfFinishComposingText, + ImfGetCursorCapsMode, + ImfGetCursorPosition, + ImfGetExtractedText, + ImfGetSelectedText, + ImfGetTextAfterCursor, + ImfGetTextBeforeCursor, + ImfPerformEditorAction, + ImfReportFullscreenMode, + ImfSendEvent, + ImfSendAsyncEvent, + ImfSetComposingRegion, + ImfSetComposingText, + ImfSetSelection +}; + +// We use this class as a round about way to support a posting synchronous event into +// Qt's main thread from the IMF thread. +class ImfEventResult +{ +public: + ImfEventResult() + { + m_mutex.lock(); + } + + ~ImfEventResult() + { + m_mutex.unlock(); + } + + void wait() + { + m_wait.wait(&m_mutex); + } + + void signal() + { + m_wait.wakeAll(); + } + + void setResult(const QVariant& result) + { + m_mutex.lock(); + m_retVal = result; + signal(); + m_mutex.unlock(); + } + + QVariant result() + { + return m_retVal; + } + +private: + QVariant m_retVal; + QMutex m_mutex; + QWaitCondition m_wait; +}; + +class ImfEvent : public QEvent +{ + public: + ImfEvent(input_session_t *session, ImfEventType type, ImfEventResult *result) : + QEvent((QEvent::Type)sUserEventType), + m_session(session), + m_imfType(type), + m_result(result) + { + } + ~ImfEvent() { } + + input_session_t *m_session; + ImfEventType m_imfType; + QVariantHash m_args; + ImfEventResult *m_result; + + static int sUserEventType; +}; +int ImfEvent::sUserEventType = QEvent::registerEventType(); + +static int32_t imfBeginBatchEdit(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfBeginBatchEdit, &result); + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static int32_t imfClearMetaKeyStates(input_session_t *ic, int32_t states) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfClearMetaKeyStates, &result); + iarg(states); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static int32_t imfCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfCommitText, &result); + parg(text); + iarg(new_cursor_position); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static int32_t imfDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfDeleteSurroundingText, &result); + iarg(left_length); + iarg(right_length); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static int32_t imfEndBatchEdit(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfEndBatchEdit, &result); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static int32_t imfFinishComposingText(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfFinishComposingText, &result); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static int32_t imfGetCursorCapsMode(input_session_t *ic, int32_t req_modes) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfGetCursorCapsMode, &result); + iarg(req_modes); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + int32_t ret = result.result().value(); + return ret; +} + +static int32_t imfGetCursorPosition(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfGetCursorPosition, &result); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + + return ret; +} + +static extracted_text_t *imfGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) { + extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1); + et->text = (spannable_string_t *)calloc(sizeof(spannable_string_t),1); + return et; + } + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfGetExtractedText, &result); + parg(request); + iarg(flags); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + return result.result().value(); +} + +static spannable_string_t *imfGetSelectedText(input_session_t *ic, int32_t flags) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return toSpannableString(""); + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfGetSelectedText, &result); + iarg(flags); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + return result.result().value(); +} + +static spannable_string_t *imfGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return toSpannableString(""); + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfGetTextAfterCursor, &result); + iarg(n); + iarg(flags); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + return result.result().value(); +} + +static spannable_string_t *imfGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return toSpannableString(""); + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfGetTextBeforeCursor, &result); + iarg(n); + iarg(flags); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + return result.result().value(); +} + +static int32_t imfPerformEditorAction(input_session_t *ic, int32_t editor_action) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfPerformEditorAction, &result); + iarg(editor_action); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + return ret; +} + +static int32_t imfReportFullscreenMode(input_session_t *ic, int32_t enabled) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfReportFullscreenMode, &result); + iarg(enabled); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + return ret; +} + +static int32_t imfSendEvent(input_session_t *ic, event_t *event) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEvent *imfEvent = new ImfEvent(ic, ImfSendEvent, 0); + imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast(event)); + + QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent); + + return 0; +} + +static int32_t imfSendAsyncEvent(input_session_t *ic, event_t *event) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEvent *imfEvent = new ImfEvent(ic, ImfSendAsyncEvent, 0); + imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast(event)); + + QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent); + + return 0; +} + +static int32_t imfSetComposingRegion(input_session_t *ic, int32_t start, int32_t end) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfSetComposingRegion, &result); + iarg(start); + iarg(end); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + return ret; +} + +static int32_t imfSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfSetComposingText, &result); + parg(text); + iarg(new_cursor_position); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + return ret; +} + +static int32_t imfSetSelection(input_session_t *ic, int32_t start, int32_t end) +{ +#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + ImfEventResult result; + ImfEvent *event = new ImfEvent(ic, ImfSetSelection, &result); + iarg(start); + iarg(end); + + QCoreApplication::postEvent(QCoreApplication::instance(), event); + + result.wait(); + int32_t ret = result.result().value(); + return ret; +} + +static connection_interface_t ic_funcs = { + imfBeginBatchEdit, + imfClearMetaKeyStates, + imfCommitText, + imfDeleteSurroundingText, + imfEndBatchEdit, + imfFinishComposingText, + imfGetCursorCapsMode, + imfGetCursorPosition, + imfGetExtractedText, + imfGetSelectedText, + imfGetTextAfterCursor, + imfGetTextBeforeCursor, + imfPerformEditorAction, + imfReportFullscreenMode, + NULL, //ic_send_key_event + imfSendEvent, + imfSendAsyncEvent, + imfSetComposingRegion, + imfSetComposingText, + imfSetSelection, + NULL, //ic_set_candidates, +}; + +static void +initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId) +{ + static int s_transactionId; + + // Make sure structure is squeaky clean since it's not clear just what is significant. + memset(pEvent, 0, sizeof(event_t)); + pEvent->event_type = eventType; + pEvent->event_id = eventId; + pEvent->pid = getpid(); + pEvent->component_id = pSession->component_id; + pEvent->transaction_id = ++s_transactionId; +} + +spannable_string_t *toSpannableString(const QString &text) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << text; +#endif + + spannable_string_t *pString = reinterpret_cast(malloc(sizeof(spannable_string_t))); + pString->str = (wchar_t *)malloc(sizeof(wchar_t) * text.length() + 1); + pString->length = text.length(); + pString->spans = NULL; + pString->spans_count = 0; + + const QChar *pData = text.constData(); + wchar_t *pDst = pString->str; + + while (!pData->isNull()) + { + *pDst = pData->unicode(); + pDst++; + pData++; + } + *pDst = 0; + + return pString; +} + +} // namespace + +static const input_session_t *(*p_ictrl_open_session)(connection_interface_t *) = 0; +static void (*p_ictrl_close_session)(input_session_t *) = 0; +static int32_t (*p_ictrl_dispatch_event)(event_t*) = 0; +static int32_t (*p_imf_client_init)() = 0; +static void (*p_imf_client_disconnect)() = 0; +static int32_t (*p_vkb_init_selection_service)() = 0; +static int32_t (*p_ictrl_get_num_active_sessions)() = 0; +static bool s_imfInitFailed = false; + +static bool imfAvailable() +{ + static bool s_imfDisabled = getenv("DISABLE_IMF") != NULL; + static bool s_imfReady = false; + + if ( s_imfInitFailed || s_imfDisabled) { + return false; + } + else if ( s_imfReady ) { + return true; + } + + if ( p_imf_client_init == NULL ) { + void *handle = dlopen("libinput_client.so.1", 0); + if ( handle ) { + p_imf_client_init = (int32_t (*)()) dlsym(handle, "imf_client_init"); + p_imf_client_disconnect = (void (*)()) dlsym(handle, "imf_client_disconnect"); + p_ictrl_open_session = (const input_session_t *(*)(connection_interface_t *))dlsym(handle, "ictrl_open_session"); + p_ictrl_close_session = (void (*)(input_session_t *))dlsym(handle, "ictrl_close_session"); + p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle, "ictrl_dispatch_event"); + p_vkb_init_selection_service = (int32_t (*)())dlsym(handle, "vkb_init_selection_service"); + p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle, "ictrl_get_num_active_sessions"); + } + else + { + qCritical() << Q_FUNC_INFO << "libinput_client.so.1 is not present - IMF services are disabled."; + s_imfDisabled = true; + return false; + } + if ( p_imf_client_init && p_ictrl_open_session && p_ictrl_dispatch_event ) { + s_imfReady = true; + } + else { + p_ictrl_open_session = NULL; + p_ictrl_dispatch_event = NULL; + s_imfDisabled = true; + qCritical() << Q_FUNC_INFO << "libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled."; + return false; + } + } + + return s_imfReady; +} + +QQnxInputContext::QQnxInputContext(): + QPlatformInputContext(), + m_lastCaretPos(0), + m_isComposing(false), + m_inputPanelVisible(false), + m_inputPanelLocale(QLocale::c()) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!imfAvailable()) + return; + + if ( p_imf_client_init() != 0 ) { + s_imfInitFailed = true; + qCritical("imf_client_init failed - IMF services will be unavailable"); + } + + QCoreApplication::instance()->installEventFilter(this); + + // p_vkb_init_selection_service(); + + QQnxVirtualKeyboard &keyboard = QQnxVirtualKeyboard::instance(); + connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool))); + connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale))); + keyboardVisibilityChanged(keyboard.isVisible()); + keyboardLocaleChanged(keyboard.locale()); + + QInputMethod *inputMethod = qApp->inputMethod(); + connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); + +} + +QQnxInputContext::~QQnxInputContext() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!imfAvailable()) + return; + + QCoreApplication::instance()->removeEventFilter(this); + p_imf_client_disconnect(); +} + +#define getarg(type, name) type name = imfEvent->mArgs[qs(#name)].value() +#define getparg(type, name) type name = (type)(imfEvent->mArgs[qs(#name)].value()) + +bool QQnxInputContext::isValid() const +{ + return imfAvailable(); +} + +bool QQnxInputContext::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == ImfEvent::sUserEventType) { + // Forward the event to our real handler. + ImfEvent *imfEvent = static_cast(event); + switch (imfEvent->m_imfType) { + case ImfBeginBatchEdit: { + int32_t ret = onBeginBatchEdit(imfEvent->m_session); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfClearMetaKeyStates: { + getarg(int32_t, states); + int32_t ret = onClearMetaKeyStates(imfEvent->m_session, states); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfCommitText: { + getparg(spannable_string_t*, text); + getarg(int32_t, new_cursor_position); + int32_t ret = onCommitText(imfEvent->m_session, text, new_cursor_position); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfDeleteSurroundingText: { + getarg(int32_t, left_length); + getarg(int32_t, right_length); + int32_t ret = onDeleteSurroundingText(imfEvent->m_session, left_length, right_length); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfEndBatchEdit: { + int32_t ret = onEndBatchEdit(imfEvent->m_session); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfFinishComposingText: { + int32_t ret = onFinishComposingText(imfEvent->m_session); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfGetCursorCapsMode: { + getarg(int32_t, req_modes); + int32_t ret = onGetCursorCapsMode(imfEvent->m_session, req_modes); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfGetCursorPosition: { + int32_t ret = onGetCursorPosition(imfEvent->m_session); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfGetExtractedText: { + getparg(extracted_text_request_t*, request); + getarg(int32_t, flags); + extracted_text_t *ret = onGetExtractedText(imfEvent->m_session, request, flags); + imfEvent->m_result->setResult(QVariant::fromValue(static_cast(ret))); + break; + } + + case ImfGetSelectedText: { + getarg(int32_t, flags); + spannable_string_t *ret = onGetSelectedText(imfEvent->m_session, flags); + imfEvent->m_result->setResult(QVariant::fromValue(static_cast(ret))); + break; + } + + case ImfGetTextAfterCursor: { + getarg(int32_t, n); + getarg(int32_t, flags); + spannable_string_t *ret = onGetTextAfterCursor(imfEvent->m_session, n, flags); + imfEvent->m_result->setResult(QVariant::fromValue(static_cast(ret))); + break; + } + + case ImfGetTextBeforeCursor: { + getarg(int32_t, n); + getarg(int32_t, flags); + spannable_string_t *ret = onGetTextBeforeCursor(imfEvent->m_session, n, flags); + imfEvent->m_result->setResult(QVariant::fromValue((void*)ret)); + break; + } + + case ImfPerformEditorAction: { + getarg(int32_t, editor_action); + int32_t ret = onPerformEditorAction(imfEvent->m_session, editor_action); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfReportFullscreenMode: { + getarg(int32_t, enabled); + int32_t ret = onReportFullscreenMode(imfEvent->m_session, enabled); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfSendEvent: { + getparg(event_t*, event); + onSendEvent(imfEvent->m_session, event); + break; + } + + case ImfSendAsyncEvent: { + getparg(event_t*, event); + onSendAsyncEvent(imfEvent->m_session, event); + break; + } + + case ImfSetComposingRegion: { + getarg(int32_t, start); + getarg(int32_t, end); + int32_t ret = onSetComposingRegion(imfEvent->m_session, start, end); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfSetComposingText: { + getparg(spannable_string_t*, text); + getarg(int32_t, new_cursor_position); + int32_t ret = onSetComposingText(imfEvent->m_session, text, new_cursor_position); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + + case ImfSetSelection: { + getarg(int32_t, start); + getarg(int32_t, end); + int32_t ret = onSetSelection(imfEvent->m_session, start, end); + imfEvent->m_result->setResult(QVariant::fromValue(ret)); + break; + } + }; //switch + + return true; + } else { + // standard event processing + return QObject::eventFilter(obj, event); + } +} + +bool QQnxInputContext::filterEvent( const QEvent *event ) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << event; +#endif + switch (event->type()) { + case QEvent::CloseSoftwareInputPanel: { + return dispatchCloseSoftwareInputPanel(); + } + case QEvent::RequestSoftwareInputPanel: { + return dispatchRequestSoftwareInputPanel(); + } + default: + return false; + } +} + +void QQnxInputContext::reset() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + endComposition(); +} + +void QQnxInputContext::update(Qt::InputMethodQueries queries) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + reset(); + + QPlatformInputContext::update(queries); +} + +void QQnxInputContext::closeSession() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO +#endif + if (!imfAvailable()) + return; + + if (sInputSession) { + p_ictrl_close_session((input_session_t *)sInputSession); + sInputSession = 0; + } +} + +void QQnxInputContext::openSession() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO +#endif + if (!imfAvailable()) + return; + + closeSession(); + sInputSession = p_ictrl_open_session(&ic_funcs); +} + +bool QQnxInputContext::hasSession() +{ + return sInputSession != 0; +} + +bool QQnxInputContext::hasSelectedText() +{ + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!input) + return false; + + QInputMethodQueryEvent query(Qt::ImCurrentSelection); + QCoreApplication::sendEvent(input, &query); + + return !query.value(Qt::ImCurrentSelection).toString().isEmpty(); +} + +bool QQnxInputContext::dispatchRequestSoftwareInputPanel() +{ + QQnxVirtualKeyboard::instance().showKeyboard(); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << "QQNX: requesting virtual keyboard"; +#endif + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return true; + + if (!hasSession()) + openSession(); + + // This also means that the caret position has moved + QInputMethodQueryEvent query(Qt::ImCursorPosition); + QCoreApplication::sendEvent(input, &query); + int caretPos = query.value(Qt::ImCursorPosition).toInt(); + caret_event_t caretEvent; + memset(&caretEvent, 0, sizeof(caret_event_t)); + initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED); + caretEvent.old_pos = m_lastCaretPos; + m_lastCaretPos = caretEvent.new_pos = caretPos; + p_ictrl_dispatch_event((event_t *)&caretEvent); + return true; +} + +bool QQnxInputContext::dispatchCloseSoftwareInputPanel() +{ + QQnxVirtualKeyboard::instance().hideKeyboard(); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << "QQNX: hiding virtual keyboard"; +#endif + + // This also means we are stopping composition, but we should already have done that. + return true; +} + +/** + * IMF Event Dispatchers. + */ +bool QQnxInputContext::dispatchFocusEvent(FocusEventId id, int hints) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!sInputSession) { + qWarning() << Q_FUNC_INFO << "Attempt to dispatch a focus event with no input session."; + return false; + } + + if (!imfAvailable()) + return false; + + // Set the last caret position to 0 since we don't really have one and we don't + // want to have the old one. + m_lastCaretPos = 0; + + focus_event_t focusEvent; + memset(&focusEvent, 0, sizeof(focusEvent)); + initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, id); + focusEvent.style = DEFAULT_STYLE; + + if (hints && Qt::ImhNoPredictiveText) + focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION; + if (hints && Qt::ImhNoAutoUppercase) + focusEvent.style |= NO_AUTO_TEXT; + + p_ictrl_dispatch_event((event_t *)&focusEvent); + + return true; +} + +bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap) +{ + if (!imfAvailable()) + return false; + + int key = (flags & KEY_SYM_VALID) ? sym : cap; + bool navKey = false; + switch ( key ) { + case KEYCODE_RETURN: + /* In a single line edit we should end composition because enter might be used by something. + endComposition(); + return false;*/ + break; + + case KEYCODE_BACKSPACE: + case KEYCODE_DELETE: + // If there is a selection range, then we want a delete key to operate on that (by + // deleting the contents of the select range) rather than operating on the composition + // range. + if (hasSelectedText()) + return false; + break; + case KEYCODE_LEFT: + key = NAVIGATE_LEFT; + navKey = true; + break; + case KEYCODE_RIGHT: + key = NAVIGATE_RIGHT; + navKey = true; + break; + case KEYCODE_UP: + key = NAVIGATE_UP; + navKey = true; + break; + case KEYCODE_DOWN: + key = NAVIGATE_DOWN; + navKey = true; + break; + case KEYCODE_CAPS_LOCK: + case KEYCODE_LEFT_SHIFT: + case KEYCODE_RIGHT_SHIFT: + case KEYCODE_LEFT_CTRL: + case KEYCODE_RIGHT_CTRL: + case KEYCODE_LEFT_ALT: + case KEYCODE_RIGHT_ALT: + case KEYCODE_MENU: + case KEYCODE_LEFT_HYPER: + case KEYCODE_RIGHT_HYPER: + case KEYCODE_INSERT: + case KEYCODE_HOME: + case KEYCODE_PG_UP: + case KEYCODE_END: + case KEYCODE_PG_DOWN: + // Don't send these + key = 0; + break; + } + + if ( mod & KEYMOD_CTRL ) { + // If CTRL is pressed, just let AIR handle it. But terminate any composition first + //endComposition(); + return false; + } + + // Pass the keys we don't know about on through + if ( key == 0 ) + return false; + + // IMF doesn't need key releases so just swallow them. + if (!(flags & KEY_DOWN)) + return true; + + if ( navKey ) { + // Even if we're forwarding up events, we can't do this for + // navigation keys. + if ( flags & KEY_DOWN ) { + navigation_event_t navEvent; + initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key); + navEvent.magnitude = 1; +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "dispatch navigation event " << key; +#endif + p_ictrl_dispatch_event(&navEvent.event); + } + } + else { + key_event_t keyEvent; + initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP); + keyEvent.key_code = key; + keyEvent.character = 0; + keyEvent.meta_key_state = 0; + + p_ictrl_dispatch_event(&keyEvent.event); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "dispatch key event " << key; +#endif + } + + scan = 0; + return true; +} + +void QQnxInputContext::endComposition() +{ + if (!m_isComposing) + return; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return; + + QList attributes; + QInputMethodEvent event(QLatin1String(""), attributes); + event.setCommitString(m_composingText); + m_composingText = QString(); + m_isComposing = false; + QCoreApplication::sendEvent(input, &event); + + action_event_t actionEvent; + memset(&actionEvent, 0, sizeof(actionEvent)); + initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION); + p_ictrl_dispatch_event(&actionEvent.event); +} + +void QQnxInputContext::setComposingText(QString const& composingText) +{ + m_composingText = composingText; + m_isComposing = true; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return; + + QList attributes; + QTextCharFormat format; + format.setFontUnderline(true); + attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, composingText.length(), format)); + + QInputMethodEvent event(composingText, attributes); + + QCoreApplication::sendEvent(input, &event); +} + +int32_t QQnxInputContext::processEvent(event_t *event) +{ + int32_t result = -1; + switch (event->event_type) { + case EVENT_SPELL_CHECK: { + #if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "EVENT_SPELL_CHECK"; + #endif + result = 0; + break; + } + + case EVENT_NAVIGATION: { + #if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "EVENT_NAVIGATION"; + #endif + + int key = event->event_id == NAVIGATE_UP ? KEYCODE_UP : + event->event_id == NAVIGATE_DOWN ? KEYCODE_DOWN : + event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT : + event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0; + + QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0); + QQnxEventThread::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0); + result = 0; + break; + } + + case EVENT_KEY: { + #if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "EVENT_KEY"; + #endif + key_event_t *kevent = static_cast(event); + + QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code); + QQnxEventThread::injectKeyboardEvent(KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code); + + result = 0; + break; + } + + case EVENT_ACTION: + // Don't care, indicates that IMF is done. + break; + + case EVENT_CARET: + case EVENT_NOTHING: + case EVENT_FOCUS: + case EVENT_USER_ACTION: + case EVENT_STROKE: + case EVENT_INVOKE_LATER: + qCritical() << Q_FUNC_INFO << "Unsupported event type: " << event->event_type; + break; + default: + qCritical() << Q_FUNC_INFO << "Unknown event type: " << event->event_type; + } + return result; +} + +/** + * IMF Event Handlers + */ + +int32_t QQnxInputContext::onBeginBatchEdit(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + // We don't care. + return 0; +} + +int32_t QQnxInputContext::onClearMetaKeyStates(input_session_t *ic, int32_t states) +{ + Q_UNUSED(states); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + // Should never get called. + qCritical() << Q_FUNC_INFO << "onClearMetaKeyStates is unsupported."; + return 0; +} + +int32_t QQnxInputContext::onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) +{ + Q_UNUSED(new_cursor_position); // TODO: How can we set the cursor position it's not part of the API. + if (!isSessionOkay(ic)) + return 0; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + QString commitString = QString::fromWCharArray(text->str, text->length); + +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "Committing [" << commitString << "]"; +#endif + + QList attributes; + QInputMethodEvent event(QLatin1String(""), attributes); + event.setCommitString(commitString, 0, 0); + + QCoreApplication::sendEvent(input, &event); + m_composingText = QString(); + + return 0; +} + +int32_t QQnxInputContext::onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "L:" << left_length << " R:" << right_length; +#endif + + if (!isSessionOkay(ic)) + return 0; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + if (hasSelectedText()) { + QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0); + QQnxEventThread::injectKeyboardEvent(KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0); + reset(); + return 0; + } + + int replacementLength = left_length + right_length; + int replacementStart = -left_length; + + QList attributes; + QInputMethodEvent event(QLatin1String(""), attributes); + event.setCommitString(QLatin1String(""), replacementStart, replacementLength); + QCoreApplication::sendEvent(input, &event); + + return 0; +} + +int32_t QQnxInputContext::onEndBatchEdit(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + return 0; +} + +int32_t QQnxInputContext::onFinishComposingText(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + // Only update the control, no need to send a message back to imf (don't call + // end composition) + QList attributes; + QInputMethodEvent event(QLatin1String(""), attributes); + event.setCommitString(m_composingText); + m_composingText = QString(); + m_isComposing = false; + QCoreApplication::sendEvent(input, &event); + + return 0; +} + +int32_t QQnxInputContext::onGetCursorCapsMode(input_session_t *ic, int32_t req_modes) +{ + Q_UNUSED(req_modes); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + // Should never get called. + qCritical() << Q_FUNC_INFO << "onGetCursorCapsMode is unsupported."; + + return 0; +} + +int32_t QQnxInputContext::onGetCursorPosition(input_session_t *ic) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + QInputMethodQueryEvent query(Qt::ImCursorPosition); + QCoreApplication::sendEvent(input, &query); + m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); + + return m_lastCaretPos; +} + +extracted_text_t *QQnxInputContext::onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags) +{ + Q_UNUSED(flags); + Q_UNUSED(request); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) { + extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1); + et->text = reinterpret_cast(calloc(sizeof(spannable_string_t),1)); + return et; + } + + // Used to update dictionaries, but not supported right now. + extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1); + et->text = reinterpret_cast(calloc(sizeof(spannable_string_t),1)); + + return et; +} + +spannable_string_t *QQnxInputContext::onGetSelectedText(input_session_t *ic, int32_t flags) +{ + Q_UNUSED(flags); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return toSpannableString(""); + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + QInputMethodQueryEvent query(Qt::ImCurrentSelection); + QCoreApplication::sendEvent(input, &query); + QString text = query.value(Qt::ImCurrentSelection).toString(); + + return toSpannableString(text); +} + +spannable_string_t *QQnxInputContext::onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags) +{ + Q_UNUSED(flags); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return toSpannableString(""); + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return toSpannableString(""); + + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText); + QCoreApplication::sendEvent(input, &query); + QString text = query.value(Qt::ImSurroundingText).toString(); + m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); + + return toSpannableString(text.mid(m_lastCaretPos+1, n)); +} + +spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags) +{ + Q_UNUSED(flags); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return toSpannableString(""); + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return toSpannableString(""); + + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText); + QCoreApplication::sendEvent(input, &query); + QString text = query.value(Qt::ImSurroundingText).toString(); + m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); + + if (n < m_lastCaretPos) { + return toSpannableString(text.mid(m_lastCaretPos - n, n)); + } else { + return toSpannableString(text.mid(0, m_lastCaretPos)); + } +} + +int32_t QQnxInputContext::onPerformEditorAction(input_session_t *ic, int32_t editor_action) +{ + Q_UNUSED(editor_action); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + // Should never get called. + qCritical() << Q_FUNC_INFO << "onPerformEditorAction is unsupported."; + + return 0; +} + +int32_t QQnxInputContext::onReportFullscreenMode(input_session_t *ic, int32_t enabled) +{ + Q_UNUSED(enabled); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + // Should never get called. + qCritical() << Q_FUNC_INFO << "onReportFullscreenMode is unsupported."; + + return 0; +} + +int32_t QQnxInputContext::onSendEvent(input_session_t *ic, event_t *event) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + return processEvent(event); +} + +int32_t QQnxInputContext::onSendAsyncEvent(input_session_t *ic, event_t *event) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + return processEvent(event); +} + +int32_t QQnxInputContext::onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText); + QCoreApplication::sendEvent(input, &query); + QString text = query.value(Qt::ImSurroundingText).toString(); + m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt(); + + QString empty = QString::fromLatin1(""); + text = text.mid(start, end - start); + + // Delete the current text. + QList attributes; + QInputMethodEvent event(empty, attributes); + event.setCommitString(empty, start - m_lastCaretPos, end - start); + QCoreApplication::sendEvent(input, &event); + + // Move the specified text into a preedit string. + setComposingText(text); + + return 0; +} + +int32_t QQnxInputContext::onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position) +{ + Q_UNUSED(new_cursor_position); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + QInputPanel *panel = qApp->inputPanel(); + QObject *input = panel->inputItem(); + if (!imfAvailable() || !input) + return 0; + + m_isComposing = true; + + QString preeditString = QString::fromWCharArray(text->str, text->length); + setComposingText(preeditString); + + return 0; +} + +int32_t QQnxInputContext::onSetSelection(input_session_t *ic, int32_t start, int32_t end) +{ + Q_UNUSED(start); + Q_UNUSED(end); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + + if (!isSessionOkay(ic)) + return 0; + + // Should never get called. + qCritical() << Q_FUNC_INFO << "onSetSelection is unsupported."; + + return 0; +} + +void QQnxInputContext::showInputPanel() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + dispatchRequestSoftwareInputPanel(); +} + +void QQnxInputContext::hideInputPanel() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + dispatchCloseSoftwareInputPanel(); +} + +bool QQnxInputContext::isInputPanelVisible() const +{ + return m_inputPanelVisible; +} + +QLocale QQnxInputContext::locale() const +{ + return m_inputPanelLocale; +} + +void QQnxInputContext::keyboardVisibilityChanged(bool visible) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "visible=" << visible; +#endif + if (m_inputPanelVisible != visible) { + m_inputPanelVisible = visible; + emitInputPanelVisibleChanged(); + } +} + +void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "locale=" << locale; +#endif + if (m_inputPanelLocale != locale) { + m_inputPanelLocale = locale; + emitLocaleChanged(); + } +} + +void QQnxInputContext::inputItemChanged() +{ + QInputMethod *inputMethod = qApp->inputMethod(); + QObject *inputItem = inputMethod->inputItem(); + +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "input item=" << inputItem; +#endif + + if (!inputItem) { + if (m_inputPanelVisible) + hideInputPanel(); + } else { + if (qobject_cast(inputItem)) { + QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::NumPunc); + } else { + QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::Default); + } + if (!m_inputPanelVisible) + showInputPanel(); + } +} diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h new file mode 100644 index 0000000000..1fb55296a6 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h @@ -0,0 +1,132 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXINPUTCONTEXT_H +#define QQNXINPUTCONTEXT_H + +#include + +#include +#include +#include + +#include "imf/imf_client.h" +#include "imf/input_control.h" + +QT_BEGIN_NAMESPACE + +class QQnxInputContext : public QPlatformInputContext +{ + Q_OBJECT +public: + QQnxInputContext(); + ~QQnxInputContext(); + + virtual bool isValid() const; + + virtual bool filterEvent(const QEvent *event); + virtual void reset(); + virtual void update(Qt::InputMethodQueries); + bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap); + + virtual void showInputPanel(); + virtual void hideInputPanel(); + virtual bool isInputPanelVisible() const; + + virtual QLocale locale() const; + +protected: + // Filters only for IMF events. + bool eventFilter(QObject *obj, QEvent *event); + +private Q_SLOTS: + void keyboardVisibilityChanged(bool visible); + void keyboardLocaleChanged(const QLocale &locale); + void inputItemChanged(); + +private: + // IMF Event dispatchers + bool dispatchFocusEvent(FocusEventId id, int hints = Qt::ImhNone); + bool dispatchRequestSoftwareInputPanel(); + bool dispatchCloseSoftwareInputPanel(); + int32_t processEvent(event_t *event); + + void closeSession(); + void openSession(); + bool hasSession(); + void endComposition(); + void setComposingText(QString const &composingText); + bool hasSelectedText(); + + // IMF Event handlers - these events will come in from QCoreApplication. + int32_t onBeginBatchEdit(input_session_t *ic); + int32_t onClearMetaKeyStates(input_session_t *ic, int32_t states); + int32_t onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position); + int32_t onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length); + int32_t onEndBatchEdit(input_session_t *ic); + int32_t onFinishComposingText(input_session_t *ic); + int32_t onGetCursorCapsMode(input_session_t *ic, int32_t req_modes); + int32_t onGetCursorPosition(input_session_t *ic); + extracted_text_t *onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags); + spannable_string_t *onGetSelectedText(input_session_t *ic, int32_t flags); + spannable_string_t *onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags); + spannable_string_t *onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags); + int32_t onPerformEditorAction(input_session_t *ic, int32_t editor_action); + int32_t onReportFullscreenMode(input_session_t *ic, int32_t enabled); + int32_t onSendEvent(input_session_t *ic, event_t *event); + int32_t onSendAsyncEvent(input_session_t *ic, event_t *event); + int32_t onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end); + int32_t onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position); + int32_t onSetSelection(input_session_t *ic, int32_t start, int32_t end); + int32_t onForceUpdate(); + + int m_lastCaretPos; + bool m_isComposing; + QString m_composingText; + bool m_inputPanelVisible; + QLocale m_inputPanelLocale; +}; + +Q_DECLARE_METATYPE(extracted_text_t*) + +QT_END_NAMESPACE + +#endif // QQNXINPUTCONTEXT_H diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp new file mode 100644 index 0000000000..33b6c0e6f3 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxinputcontext_noimf.h" +#include "qqnxvirtualkeyboard.h" + +#include +#include +#include + +QQnxInputContext::QQnxInputContext() : + QPlatformInputContext(), + m_inputPanelVisible(false), + m_inputPanelLocale(QLocale::c()) +{ + QQnxVirtualKeyboard &keyboard = QQnxVirtualKeyboard::instance(); + connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool))); + connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale))); + keyboardVisibilityChanged(keyboard.isVisible()); + keyboardLocaleChanged(keyboard.locale()); + + QInputMethod *inputMethod = qApp->inputMethod(); + connect(inputMethod, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged())); +} + +QQnxInputContext::~QQnxInputContext() +{ +} + +bool QQnxInputContext::isValid() const +{ + return true; +} + +bool QQnxInputContext::hasPhysicalKeyboard() +{ + // TODO: This should query the system to check if a USB keyboard is connected. + return false; +} + +void QQnxInputContext::reset() +{ +} + +bool QQnxInputContext::filterEvent( const QEvent *event ) +{ + if (hasPhysicalKeyboard()) + return false; + + if (event->type() == QEvent::CloseSoftwareInputPanel) { + QQnxVirtualKeyboard::instance().hideKeyboard(); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << "QQNX: hiding virtual keyboard"; +#endif + return false; + } + + if (event->type() == QEvent::RequestSoftwareInputPanel) { + QQnxVirtualKeyboard::instance().showKeyboard(); +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << "QQNX: requesting virtual keyboard"; +#endif + return false; + } + + return false; + +} + +bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap) +{ + Q_UNUSED(flags); + Q_UNUSED(sym); + Q_UNUSED(mod); + Q_UNUSED(scan); + Q_UNUSED(cap); + return false; +} + +void QQnxInputContext::showInputPanel() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + QQnxVirtualKeyboard::instance().showKeyboard(); +} + +void QQnxInputContext::hideInputPanel() +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + QQnxVirtualKeyboard::instance().hideKeyboard(); +} + +bool QQnxInputContext::isInputPanelVisible() const +{ + return m_inputPanelVisible; +} + +QLocale QQnxInputContext::locale() const +{ + return m_inputPanelLocale; +} + +void QQnxInputContext::keyboardVisibilityChanged(bool visible) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "visible=" << visible; +#endif + if (m_inputPanelVisible != visible) { + m_inputPanelVisible = visible; + emitInputPanelVisibleChanged(); + } +} + +void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale) +{ +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "locale=" << locale; +#endif + if (m_inputPanelLocale != locale) { + m_inputPanelLocale = locale; + emitLocaleChanged(); + } +} + +void QQnxInputContext::inputItemChanged() +{ + QInputMethod *inputMethod = qApp->inputMethod(); + QObject *inputItem = inputMethod->inputItem(); + +#if defined(QQNXINPUTCONTEXT_DEBUG) + qDebug() << Q_FUNC_INFO << "input item=" << inputItem; +#endif + + if (!inputItem) { + if (m_inputPanelVisible) + hideInputPanel(); + } else { + if (qobject_cast(inputItem)) { + QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::NumPunc); + } else { + QQnxVirtualKeyboard::instance().setKeyboardMode(QQnxVirtualKeyboard::Default); + } + if (!m_inputPanelVisible) + showInputPanel(); + } +} diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h new file mode 100644 index 0000000000..33a4631d16 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.h @@ -0,0 +1,84 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXINPUTCONTEXT_H +#define QQNXINPUTCONTEXT_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QQnxInputContext : public QPlatformInputContext +{ + Q_OBJECT +public: + explicit QQnxInputContext(); + ~QQnxInputContext(); + + virtual bool isValid() const; + + void reset(); + virtual bool filterEvent( const QEvent *event ); + bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap); + + virtual void showInputPanel(); + virtual void hideInputPanel(); + virtual bool isInputPanelVisible() const; + + virtual QLocale locale() const; + +private Q_SLOTS: + void keyboardVisibilityChanged(bool visible); + void keyboardLocaleChanged(const QLocale &locale); + void inputItemChanged(); + +private: + bool hasPhysicalKeyboard(); + + bool m_inputPanelVisible; + QLocale m_inputPanelLocale; +}; + +QT_END_NAMESPACE + +#endif // QQNXINPUTCONTEXT_H diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp new file mode 100644 index 0000000000..2811661269 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -0,0 +1,293 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxintegration.h" +#include "qqnxeventthread.h" +#include "qqnxglbackingstore.h" +#include "qqnxglcontext.h" +#include "qqnxnavigatorthread.h" +#include "qqnxrasterbackingstore.h" +#include "qqnxscreen.h" +#include "qqnxwindow.h" +#include "qqnxvirtualkeyboard.h" +#include "qqnxclipboard.h" +#include "qqnxglcontext.h" + +#if defined(QQnx_IMF) +#include "qqnxinputcontext_imf.h" +#else +#include "qqnxinputcontext_noimf.h" +#endif + +#include "private/qgenericunixfontdatabase_p.h" +#include "private/qgenericunixeventdispatcher_p.h" + +#include +#include +#include + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +QQnxWindowMapper QQnxIntegration::ms_windowMapper; +QMutex QQnxIntegration::ms_windowMapperMutex; + +QQnxIntegration::QQnxIntegration() + : QPlatformIntegration() + , m_eventThread(0) + , m_navigatorThread(0) + , m_inputContext(0) + , m_fontDatabase(new QGenericUnixFontDatabase()) + , m_paintUsingOpenGL(false) + , m_eventDispatcher(createUnixEventDispatcher()) +#ifndef QT_NO_CLIPBOARD + , m_clipboard(0) +#endif +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Open connection to QNX composition manager + errno = 0; + int result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT); + if (result != 0) { + qFatal("QQnx: failed to connect to composition manager, errno=%d", errno); + } + + // Create displays for all possible screens (which may not be attached) + QQnxScreen::createDisplays(m_screenContext); + Q_FOREACH (QPlatformScreen *screen, QQnxScreen::screens()) { + screenAdded(screen); + } + + // Initialize global OpenGL resources + QQnxGLContext::initialize(); + + // Create/start event thread + m_eventThread = new QQnxEventThread(m_screenContext, *QQnxScreen::primaryDisplay()); + m_eventThread->start(); + + // Create/start navigator thread + m_navigatorThread = new QQnxNavigatorThread(*QQnxScreen::primaryDisplay()); + m_navigatorThread->start(); + + // Create/start the keyboard class. + QQnxVirtualKeyboard::instance(); + + // Set up the input context + m_inputContext = new QQnxInputContext; +} + +QQnxIntegration::~QQnxIntegration() +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << "QQnx: platform plugin shutdown begin"; +#endif + // Destroy the keyboard class. + QQnxVirtualKeyboard::destroy(); + +#ifndef QT_NO_CLIPBOARD + // Delete the clipboard + delete m_clipboard; +#endif + + // Stop/destroy event thread + delete m_eventThread; + + // Stop/destroy navigator thread + delete m_navigatorThread; + + // Destroy all displays + QQnxScreen::destroyDisplays(); + + // Close connection to QNX composition manager + screen_destroy_context(m_screenContext); + + // Cleanup global OpenGL resources + QQnxGLContext::shutdown(); + +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << "QQnx: platform plugin shutdown end"; +#endif +} + +bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + switch (cap) { + case ThreadedPixmaps: return true; +#if defined(QT_OPENGL_ES) + case OpenGL: + return true; +#endif + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // New windows are created on the primary display. + return new QQnxWindow(window, m_screenContext); +} + +QPlatformBackingStore *QQnxIntegration::createPlatformBackingStore(QWindow *window) const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + if (paintUsingOpenGL()) + return new QQnxGLBackingStore(window); + else + return new QQnxRasterBackingStore(window); +} + +QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + return new QQnxGLContext(context); +} + +QPlatformInputContext *QQnxIntegration::inputContext() const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + return m_inputContext; +} + +void QQnxIntegration::moveToScreen(QWindow *window, int screen) +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << "QQnxIntegration::moveToScreen - w=" << window << ", s=" << screen; +#endif + + // get platform window used by widget + QQnxWindow *platformWindow = static_cast(window->handle()); + + // lookup platform screen by index + QQnxScreen *platformScreen = static_cast(QQnxScreen::screens().at(screen)); + + // move the platform window to the platform screen + platformWindow->setScreen(platformScreen); +} + +QList QQnxIntegration::screens() const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + return QQnxScreen::screens(); +} + +QAbstractEventDispatcher *QQnxIntegration::guiThreadEventDispatcher() const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + return m_eventDispatcher; +} + +#ifndef QT_NO_CLIPBOARD +QPlatformClipboard *QQnxIntegration::clipboard() const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + if (!m_clipboard) { + m_clipboard = new QQnxClipboard; + } + return m_clipboard; +} +#endif + +QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + if (hint == ShowIsFullScreen) + return true; + + return QPlatformIntegration::styleHint(hint); +} + +QWindow *QQnxIntegration::window(screen_window_t qnxWindow) +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + QMutexLocker locker(&ms_windowMapperMutex); + Q_UNUSED(locker); + return ms_windowMapper.value(qnxWindow, 0); +} + +void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window) +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + QMutexLocker locker(&ms_windowMapperMutex); + Q_UNUSED(locker); + ms_windowMapper.insert(qnxWindow, window); +} + +void QQnxIntegration::removeWindow(screen_window_t qnxWindow) +{ +#if defined(QQNXINTEGRATION_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + QMutexLocker locker(&ms_windowMapperMutex); + Q_UNUSED(locker); + ms_windowMapper.remove(qnxWindow); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h new file mode 100644 index 0000000000..51d06bd0e6 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -0,0 +1,119 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXINTEGRATION_H +#define QQNXINTEGRATION_H + +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxEventThread; +class QQnxInputContext; +class QQnxNavigatorThread; +class QQnxWindow; + +#ifndef QT_NO_CLIPBOARD +class QQnxClipboard; +#endif + +template class QHash; +typedef QHash QQnxWindowMapper; + +class QQnxIntegration : public QPlatformIntegration +{ +public: + QQnxIntegration(); + virtual ~QQnxIntegration(); + + virtual bool hasCapability(QPlatformIntegration::Capability cap) const; + + virtual QPlatformWindow *createPlatformWindow(QWindow *window) const; + virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + + virtual QPlatformInputContext *inputContext() const; + + virtual QList screens() const; + virtual void moveToScreen(QWindow *window, int screen); + + virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const; + + virtual QPlatformFontDatabase *fontDatabase() const { return m_fontDatabase; } + +#ifndef QT_NO_CLIPBOARD + virtual QPlatformClipboard *clipboard() const; +#endif + + virtual QVariant styleHint(StyleHint hint) const; + + bool paintUsingOpenGL() const { return m_paintUsingOpenGL; } + + static QWindow *window(screen_window_t qnxWindow); + +private: + static void addWindow(screen_window_t qnxWindow, QWindow *window); + static void removeWindow(screen_window_t qnxWindow); + + screen_context_t m_screenContext; + QQnxEventThread *m_eventThread; + QQnxNavigatorThread *m_navigatorThread; + QQnxInputContext *m_inputContext; + QPlatformFontDatabase *m_fontDatabase; + bool m_paintUsingOpenGL; + QAbstractEventDispatcher *m_eventDispatcher; +#ifndef QT_NO_CLIPBOARD + mutable QQnxClipboard* m_clipboard; +#endif + + static QQnxWindowMapper ms_windowMapper; + static QMutex ms_windowMapperMutex; + + friend class QQnxWindow; +}; + +QT_END_NAMESPACE + +#endif // QQNXINTEGRATION_H diff --git a/src/plugins/platforms/qnx/qqnxkeytranslator.h b/src/plugins/platforms/qnx/qqnxkeytranslator.h new file mode 100644 index 0000000000..46bdfacd97 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxkeytranslator.h @@ -0,0 +1,269 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXKEYTRANSLATOR_H +#define QQNXKEYTRANSLATOR_H + +#include + +#if defined(QQNXEVENTTHREAD_DEBUG) +#include +#endif + +QT_BEGIN_NAMESPACE + +Qt::Key keyTranslator( int key ) +{ + switch (key) { + case KEYCODE_PAUSE: + return Qt::Key_Pause; + + case KEYCODE_SCROLL_LOCK: + return Qt::Key_ScrollLock; + + case KEYCODE_PRINT: + return Qt::Key_Print; + + case KEYCODE_SYSREQ: + return Qt::Key_SysReq; + +// case KEYCODE_BREAK: + + case KEYCODE_ESCAPE: + return Qt::Key_Escape; + + case KEYCODE_BACKSPACE: + return Qt::Key_Backspace; + + case KEYCODE_TAB: + return Qt::Key_Tab; + + case KEYCODE_BACK_TAB: + return Qt::Key_Backtab; + + case KEYCODE_RETURN: + return Qt::Key_Return; + + case KEYCODE_CAPS_LOCK: + return Qt::Key_CapsLock; + + case KEYCODE_LEFT_SHIFT: + case KEYCODE_RIGHT_SHIFT: + return Qt::Key_Shift; + + case KEYCODE_LEFT_CTRL: + case KEYCODE_RIGHT_CTRL: + return Qt::Key_Control; + + case KEYCODE_LEFT_ALT: + case KEYCODE_RIGHT_ALT: + return Qt::Key_Alt; + + case KEYCODE_MENU: + return Qt::Key_Menu; + + case KEYCODE_LEFT_HYPER: + return Qt::Key_Hyper_L; + + case KEYCODE_RIGHT_HYPER: + return Qt::Key_Hyper_R; + + case KEYCODE_INSERT: + return Qt::Key_Insert; + + case KEYCODE_HOME: + return Qt::Key_Home; + + case KEYCODE_PG_UP: + return Qt::Key_PageUp; + + case KEYCODE_DELETE: + return Qt::Key_Delete; + + case KEYCODE_END: + return Qt::Key_End; + + case KEYCODE_PG_DOWN: + return Qt::Key_PageDown; + + case KEYCODE_LEFT: + return Qt::Key_Left; + + case KEYCODE_RIGHT: + return Qt::Key_Right; + + case KEYCODE_UP: + return Qt::Key_Up; + + case KEYCODE_DOWN: + return Qt::Key_Down; + + case KEYCODE_NUM_LOCK: + return Qt::Key_NumLock; + + case KEYCODE_KP_PLUS: + return Qt::Key_Plus; + + case KEYCODE_KP_MINUS: + return Qt::Key_Minus; + + case KEYCODE_KP_MULTIPLY: + return Qt::Key_Asterisk; + + case KEYCODE_KP_DIVIDE: + return Qt::Key_Slash; + + case KEYCODE_KP_ENTER: + return Qt::Key_Enter; + + case KEYCODE_KP_HOME: + return Qt::Key_Home; + + case KEYCODE_KP_UP: + return Qt::Key_Up; + + case KEYCODE_KP_PG_UP: + return Qt::Key_PageUp; + + case KEYCODE_KP_LEFT: + return Qt::Key_Left; + + // Is this right? + case KEYCODE_KP_FIVE: + return Qt::Key_5; + + case KEYCODE_KP_RIGHT: + return Qt::Key_Right; + + case KEYCODE_KP_END: + return Qt::Key_End; + + case KEYCODE_KP_DOWN: + return Qt::Key_Down; + + case KEYCODE_KP_PG_DOWN: + return Qt::Key_PageDown; + + case KEYCODE_KP_INSERT: + return Qt::Key_Insert; + + case KEYCODE_KP_DELETE: + return Qt::Key_Delete; + + case KEYCODE_F1: + return Qt::Key_F1; + + case KEYCODE_F2: + return Qt::Key_F2; + + case KEYCODE_F3: + return Qt::Key_F3; + + case KEYCODE_F4: + return Qt::Key_F4; + + case KEYCODE_F5: + return Qt::Key_F5; + + case KEYCODE_F6: + return Qt::Key_F6; + + case KEYCODE_F7: + return Qt::Key_F7; + + case KEYCODE_F8: + return Qt::Key_F8; + + case KEYCODE_F9: + return Qt::Key_F9; + + case KEYCODE_F10: + return Qt::Key_F10; + + case KEYCODE_F11: + return Qt::Key_F11; + + case KEYCODE_F12: + return Qt::Key_F12; + + // See keycodes.h for more, but these are all the basics. And printables are already included. + + default: +#if defined(QQNXEVENTTHREAD_DEBUG) + qDebug() << "QQNX: unknown key for translation:" << key; +#endif + break; + } + + return Qt::Key_Escape; +} + +bool isKeypadKey( int key ) +{ + switch (key) + { + case KEYCODE_KP_PLUS: + case KEYCODE_KP_MINUS: + case KEYCODE_KP_MULTIPLY: + case KEYCODE_KP_DIVIDE: + case KEYCODE_KP_ENTER: + case KEYCODE_KP_HOME: + case KEYCODE_KP_UP: + case KEYCODE_KP_PG_UP: + case KEYCODE_KP_LEFT: + case KEYCODE_KP_FIVE: + case KEYCODE_KP_RIGHT: + case KEYCODE_KP_END: + case KEYCODE_KP_DOWN: + case KEYCODE_KP_PG_DOWN: + case KEYCODE_KP_INSERT: + case KEYCODE_KP_DELETE: + return true; + default: + break; + } + + return false; +} + +QT_END_NAMESPACE + +#endif // QQNXKEYTRANSLATOR_H diff --git a/src/plugins/platforms/qnx/qqnxnavigatorthread.cpp b/src/plugins/platforms/qnx/qqnxnavigatorthread.cpp new file mode 100644 index 0000000000..def4cb7eb1 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxnavigatorthread.cpp @@ -0,0 +1,280 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxnavigatorthread.h" +#include "qqnxscreen.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static const char *navigatorControlPath = "/pps/services/navigator/control"; +static const int ppsBufferSize = 4096; + +QQnxNavigatorThread::QQnxNavigatorThread(QQnxScreen& primaryScreen) + : m_primaryScreen(primaryScreen), + m_fd(-1), + m_readNotifier(0) +{ +} + +QQnxNavigatorThread::~QQnxNavigatorThread() +{ + // block until thread terminates + shutdown(); + + delete m_readNotifier; +} + +void QQnxNavigatorThread::run() +{ +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "QQNX: navigator thread started"; +#endif + + // open connection to navigator + errno = 0; + m_fd = open(navigatorControlPath, O_RDWR); + if (m_fd == -1) { + qWarning("QQNX: failed to open navigator pps, errno=%d", errno); + return; + } + + m_readNotifier = new QSocketNotifier(m_fd, QSocketNotifier::Read); + // using direct connection to get the slot called in this thread's context + connect(m_readNotifier, SIGNAL(activated(int)), this, SLOT(readData()), Qt::DirectConnection); + + exec(); + + // close connection to navigator + close(m_fd); + +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "QQNX: navigator thread stopped"; +#endif +} + +void QQnxNavigatorThread::shutdown() +{ +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "QQNX: navigator thread shutdown begin"; +#endif + + // signal thread to terminate + quit(); + + // block until thread terminates + wait(); + +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "QQNX: navigator thread shutdown end"; +#endif +} + +void QQnxNavigatorThread::parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id) +{ +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: data=" << ppsData; +#endif + + // tokenize pps data into lines + QList lines = ppsData.split('\n'); + + // validate pps object + if (lines.size() == 0 || lines.at(0) != "@control") { + qFatal("QQNX: unrecognized pps object, data=%s", ppsData.constData()); + } + + // parse pps object attributes and extract values + for (int i = 1; i < lines.size(); i++) { + + // tokenize current attribute + const QByteArray &attr = lines.at(i); + +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: attr=" << attr; +#endif + + int firstColon = attr.indexOf(':'); + if (firstColon == -1) { + // abort - malformed attribute + continue; + } + + int secondColon = attr.indexOf(':', firstColon + 1); + if (secondColon == -1) { + // abort - malformed attribute + continue; + } + + QByteArray key = attr.left(firstColon); + QByteArray value = attr.mid(secondColon + 1); + +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: key=" << key; + qDebug() << "PPS: val=" << value; +#endif + + // save attribute value + if (key == "msg") { + msg = value; + } else if (key == "dat") { + dat = value; + } else if (key == "id") { + id = value; + } else { + qFatal("QQNX: unrecognized pps attribute, attr=%s", key.constData()); + } + } +} + +void QQnxNavigatorThread::replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat) +{ + // construct pps message + QByteArray ppsData = "res::"; + ppsData += res; + ppsData += "\nid::"; + ppsData += id; + if (!dat.isEmpty()) { + ppsData += "\ndat::"; + ppsData += dat; + } + ppsData += "\n"; + +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS reply=" << ppsData; +#endif + + // send pps message to navigator + errno = 0; + int bytes = write(m_fd, ppsData.constData(), ppsData.size()); + if (bytes == -1) { + qFatal("QQNX: failed to write navigator pps, errno=%d", errno); + } +} + +void QQnxNavigatorThread::handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id) +{ +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: msg=" << msg << ", dat=" << dat << ", id=" << id; +#endif + + // check message type + if (msg == "orientationCheck") { + + // reply to navigator that (any) orientation is acceptable +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: orientation check, o=" << dat; +#endif + replyPPS(msg, id, "true"); + + } else if (msg == "orientation") { + + // update screen geometry and reply to navigator that we're ready +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: orientation, o=" << dat; +#endif + m_primaryScreen.setRotation( dat.toInt() ); + QWindowSystemInterface::handleScreenGeometryChange(0, m_primaryScreen.geometry()); + replyPPS(msg, id, ""); + + } else if (msg == "SWIPE_DOWN") { + + // simulate menu key press +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: menu"; +#endif + QWindow *w = QGuiApplication::focusWindow(); + QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyPress, Qt::Key_Menu, Qt::NoModifier); + QWindowSystemInterface::handleKeyEvent(w, QEvent::KeyRelease, Qt::Key_Menu, Qt::NoModifier); + + } else if (msg == "exit") { + + // shutdown everything +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "PPS: exit"; +#endif + QCoreApplication::quit(); + } +} + +void QQnxNavigatorThread::readData() +{ +#if defined(QQNXNAVIGATORTHREAD_DEBUG) + qDebug() << "QQNX: reading navigator data"; +#endif + // allocate buffer for pps data + char buffer[ppsBufferSize]; + + // attempt to read pps data + errno = 0; + int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1); + if (bytes == -1) { + qFatal("QQNX: failed to read navigator pps, errno=%d", errno); + } + + // check if pps data was received + if (bytes > 0) { + + // ensure data is null terminated + buffer[bytes] = '\0'; + + // process received message + QByteArray ppsData(buffer); + QByteArray msg; + QByteArray dat; + QByteArray id; + parsePPS(ppsData, msg, dat, id); + handleMessage(msg, dat, id); + } +} diff --git a/src/plugins/platforms/qnx/qqnxnavigatorthread.h b/src/plugins/platforms/qnx/qqnxnavigatorthread.h new file mode 100644 index 0000000000..40b217db73 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxnavigatorthread.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXNAVIGATORTHREAD_H +#define QQNXNAVIGATORTHREAD_H + +#include + +QT_BEGIN_NAMESPACE + +class QQnxScreen; +class QSocketNotifier; + +class QQnxNavigatorThread : public QThread +{ + Q_OBJECT +public: + QQnxNavigatorThread(QQnxScreen &primaryScreen); + virtual ~QQnxNavigatorThread(); + +protected: + virtual void run(); + +private Q_SLOTS: + void readData(); + +private: + void shutdown(); + void parsePPS(const QByteArray &ppsData, QByteArray &msg, QByteArray &dat, QByteArray &id); + void replyPPS(const QByteArray &res, const QByteArray &id, const QByteArray &dat); + void handleMessage(const QByteArray &msg, const QByteArray &dat, const QByteArray &id); + + QQnxScreen &m_primaryScreen; + int m_fd; + QSocketNotifier *m_readNotifier; +}; + +QT_END_NAMESPACE + +#endif // QQNXNAVIGATORTHREAD_H diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp new file mode 100644 index 0000000000..1d0da240b3 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp @@ -0,0 +1,166 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxrasterbackingstore.h" +#include "qqnxwindow.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +QQnxRasterBackingStore::QQnxRasterBackingStore(QWindow *window) + : QPlatformBackingStore(window) +{ +#if defined(QQNXRASTERBACKINGSTORE_DEBUG) + qDebug() << "QQnxRasterBackingStore::QQnxRasterBackingStore - w=" << window; +#endif + + // save platform window associated with widget + m_platformWindow = static_cast(window->handle()); +} + +QQnxRasterBackingStore::~QQnxRasterBackingStore() +{ +#if defined(QQnxRasterBackingStore_DEBUG) + qDebug() << "QQnxRasterBackingStore::~QQnxRasterBackingStore - w=" << window(); +#endif +} + +QPaintDevice *QQnxRasterBackingStore::paintDevice() +{ + return m_platformWindow->renderBuffer().image(); +} + +void QQnxRasterBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(window); + Q_UNUSED(offset); + +#if defined(QQNXRASTERBACKINGSTORE_DEBUG) + qDebug() << "QQnxRasterBackingStore::flush - w=" << this->window(); +#endif + + // visit all pending scroll operations + for (int i = m_scrollOpList.size() - 1; i >= 0; i--) { + + // do the scroll operation + ScrollOp &op = m_scrollOpList[i]; + QRegion srcArea = op.totalArea.intersected( op.totalArea.translated(-op.dx, -op.dy) ); + m_platformWindow->scroll(srcArea, op.dx, op.dy); + } + + // clear all pending scroll operations + m_scrollOpList.clear(); + + // update the display with newly rendered content + m_platformWindow->post(region); +} + +void QQnxRasterBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(size); + Q_UNUSED(staticContents); +#if defined(QQNXRASTERBACKINGSTORE_DEBUG) + qDebug() << "QQnxRasterBackingStore::resize - w=" << window() << ", s=" << size; +#endif + + // NOTE: defer resizing window buffers until next paint as + // resize() can be called multiple times before a paint occurs +} + +bool QQnxRasterBackingStore::scroll(const QRegion &area, int dx, int dy) +{ +#if defined(QQNXRASTERBACKINGSTORE_DEBUG) + qDebug() << "QQnxRasterBackingStore::scroll - w=" << window(); +#endif + + // calculate entire region affected by scroll operation (src + dst) + QRegion totalArea = area.translated(dx, dy); + totalArea += area; + + // visit all pending scroll operations + for (int i = m_scrollOpList.size() - 1; i >= 0; i--) { + + ScrollOp &op = m_scrollOpList[i]; + if (op.totalArea == totalArea) { + // same area is being scrolled again - update delta + op.dx += dx; + op.dy += dy; + return true; + } else if (op.totalArea.intersects(totalArea)) { + // current scroll overlaps previous scroll but is + // not equal in area - just paint everything + qWarning("QQNX: pending scroll operations overlap but not equal"); + return false; + } + } + + // create new scroll operation + m_scrollOpList.append( ScrollOp(totalArea, dx, dy) ); + return true; +} + +void QQnxRasterBackingStore::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); + +#if defined(QQNXRASTERBACKINGSTORE_DEBUG) + qDebug() << "QQnxRasterBackingStore::beginPaint - w=" << window(); +#endif + + // resize window buffers if surface resized + QSize s = window()->size(); + if (s != m_platformWindow->bufferSize()) { + m_platformWindow->setBufferSize(s); + } +} + +void QQnxRasterBackingStore::endPaint(const QRegion ®ion) +{ + Q_UNUSED(region); +#if defined(QQnxRasterBackingStore_DEBUG) + qDebug() << "QQnxRasterBackingStore::endPaint - w=" << window(); +#endif +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.h b/src/plugins/platforms/qnx/qqnxrasterbackingstore.h new file mode 100644 index 0000000000..fec51a19b9 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.h @@ -0,0 +1,81 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXRASTERWINDOWSURFACE_H +#define QQNXRASTERWINDOWSURFACE_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxWindow; + +class QQnxRasterBackingStore : public QPlatformBackingStore +{ +public: + QQnxRasterBackingStore(QWindow *window); + virtual ~QQnxRasterBackingStore(); + + virtual QPaintDevice *paintDevice(); + virtual void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + virtual void resize(const QSize &size, const QRegion &staticContents); + virtual bool scroll(const QRegion &area, int dx, int dy); + virtual void beginPaint(const QRegion ®ion); + virtual void endPaint(const QRegion ®ion); + +private: + class ScrollOp { + public: + ScrollOp(const QRegion &a, int x, int y) : totalArea(a), dx(x), dy(y) {} + QRegion totalArea; + int dx; + int dy; + }; + + QQnxWindow *m_platformWindow; + QList m_scrollOpList; +}; + +QT_END_NAMESPACE + +#endif // QQNXRASTERWINDOWSURFACE_H diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.cpp b/src/plugins/platforms/qnx/qqnxrootwindow.cpp new file mode 100644 index 0000000000..6f6b89a6d6 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxrootwindow.cpp @@ -0,0 +1,257 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxrootwindow.h" + +#include "qqnxscreen.h" + +#include + +#if defined(QQNXROOTWINDOW_DEBUG) +#include +#endif + +#include +#include + +static const int MAGIC_ZORDER_FOR_NO_NAV = 10; + +QQnxRootWindow::QQnxRootWindow(QQnxScreen *screen) + : m_screen(screen), + m_window(0), + m_windowGroupName() +{ +#if defined(QQNXROOTWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // 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 + 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] = 1; + 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); + } + + createWindowGroup(); + post(); +} + +QQnxRootWindow::~QQnxRootWindow() +{ + // Cleanup top-level QNX window + screen_destroy_window(m_window); +} + +void QQnxRootWindow::post() const +{ +#if defined(QQNXROOTWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + 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 +{ +#if defined(QQNXROOTWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // 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) +{ +#if defined(QQNXROOTWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "angle =" << rotation; +#endif + 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().toAscii(); + + // 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 new file mode 100644 index 0000000000..80b10c65f0 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxrootwindow.h @@ -0,0 +1,81 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXROOTWINDOW_H +#define QQNXROOTWINDOW_H + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxScreen; + +class QQnxRootWindow +{ +public: + QQnxRootWindow(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); + + QByteArray groupName() const { return m_windowGroupName; } + +private: + void createWindowGroup(); + + QQnxScreen *m_screen; + screen_window_t m_window; + QByteArray m_windowGroupName; +}; + +QT_END_NAMESPACE + +#endif // QQNXROOTWINDOW_H diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp new file mode 100644 index 0000000000..e0e3d6d57d --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -0,0 +1,315 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxscreen.h" +#include "qqnxvirtualkeyboard.h" +#include "qqnxwindow.h" + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +QList QQnxScreen::ms_screens; +QList QQnxScreen::ms_childWindows; + +QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen) + : m_screenContext(screenContext), + m_display(display), + m_rootWindow(), + m_primaryScreen(primaryScreen), + m_posted(false), + m_platformContext(0) +{ +#if defined(QQNXSCREEN_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Cache initial orientation of this display + // TODO: use ORIENTATION environment variable? + errno = 0; + int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION, &m_initialRotation); + if (result != 0) { + qFatal("QQnxScreen: failed to query display rotation, errno=%d", errno); + } + m_currentRotation = m_initialRotation; + + // Cache size of this display in pixels + // TODO: use WIDTH and HEIGHT environment variables? + errno = 0; + int val[2]; + result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val); + if (result != 0) { + qFatal("QQnxScreen: failed to query display size, errno=%d", errno); + } + + m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]); + + // Cache size of this display in millimeters + errno = 0; + result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_PHYSICAL_SIZE, val); + if (result != 0) { + qFatal("QQnxScreen: failed to query display physical size, errno=%d", errno); + } + + // Peg the DPI to 96 (for now) so fonts are a reasonable size. We'll want to match + // everything with a QStyle later, and at that point the physical size can be used + // instead. + { + static const int dpi = 96; + int width = m_currentGeometry.width() / dpi * qreal(25.4) ; + int height = m_currentGeometry.height() / dpi * qreal(25.4) ; + + m_currentPhysicalSize = m_initialPhysicalSize = QSize(width,height); + } + + // We only create the root window if we are the primary display. + if (primaryScreen) + m_rootWindow = QSharedPointer(new QQnxRootWindow(this)); +} + +QQnxScreen::~QQnxScreen() +{ +#if defined(QQNXSCREEN_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif +} + +/* static */ +void QQnxScreen::createDisplays(screen_context_t context) +{ +#if defined(QQNXSCREEN_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Query number of displays + errno = 0; + int displayCount; + int result = screen_get_context_property_iv(context, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount); + if (result != 0) { + qFatal("QQnxScreen: failed to query display count, errno=%d", errno); + } + + // Get all displays + errno = 0; + screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount); + result = screen_get_context_property_pv(context, SCREEN_PROPERTY_DISPLAYS, (void **)displays); + if (result != 0) { + qFatal("QQnxScreen: failed to query displays, errno=%d", errno); + } + + for (int i=0; iupdateZorder(topZorder); + + // After a hierarchy update, we need to force a flush on all screens. + // Right now, all screens share a context. + screen_flush_context( primaryDisplay()->m_screenContext, 0 ); +} + +void QQnxScreen::onWindowPost(QQnxWindow *window) +{ +#if defined(QQNXSCREEN_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + 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 && m_rootWindow) { + m_rootWindow->post(); + m_posted = true; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h new file mode 100644 index 0000000000..5749a66f5d --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -0,0 +1,121 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBBSCREEN_H +#define QBBSCREEN_H + +#include + +#include "qqnxrootwindow.h" + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QQnxWindow; + +class QQnxScreen : public QPlatformScreen +{ +public: + static QList screens() { return ms_screens; } + static void createDisplays(screen_context_t context); + static void destroyDisplays(); + static QQnxScreen *primaryDisplay() { return static_cast(ms_screens.at(0)); } + static int defaultDepth(); + + virtual QRect geometry() const { return m_currentGeometry; } + virtual QRect availableGeometry() const; + virtual int depth() const { return defaultDepth(); } + virtual QImage::Format format() const { return (depth() == 32) ? QImage::Format_RGB32 : QImage::Format_RGB16; } + virtual QSizeF physicalSize() const { return m_currentPhysicalSize; } + + bool isPrimaryScreen() const { return m_primaryScreen; } + + int rotation() const { return m_currentRotation; } + void setRotation(int rotation); + + int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; } + screen_display_t nativeDisplay() const { return m_display; } + screen_context_t nativeContext() const { return m_screenContext; } + const char *windowGroupName() const { return m_rootWindow->groupName().constData(); } + + /* Window hierarchy management */ + static void addWindow(QQnxWindow *child); + static void removeWindow(QQnxWindow *child); + static void raiseWindow(QQnxWindow *window); + static void lowerWindow(QQnxWindow *window); + static void updateHierarchy(); + + void onWindowPost(QQnxWindow *window); + + QSharedPointer rootWindow() const { return m_rootWindow; } + +private: + QQnxScreen(screen_context_t context, screen_display_t display, bool primaryScreen); + virtual ~QQnxScreen(); + + static bool orthogonal(int rotation1, int rotation2); + + screen_context_t m_screenContext; + screen_display_t m_display; + QSharedPointer m_rootWindow; + bool m_primaryScreen; + bool m_posted; + bool m_usingOpenGL; + + int m_initialRotation; + int m_currentRotation; + QSize m_initialPhysicalSize; + QSize m_currentPhysicalSize; + QRect m_initialGeometry; + QRect m_currentGeometry; + QPlatformOpenGLContext *m_platformContext; + + static QList ms_screens; + static QList ms_childWindows; +}; + +QT_END_NAMESPACE + +#endif // QBBSCREEN_H diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp new file mode 100644 index 0000000000..9d7fe92660 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.cpp @@ -0,0 +1,500 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxvirtualkeyboard.h" +#include "qqnxscreen.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *QQnxVirtualKeyboard::ms_PPSPath = "/pps/services/input/control?wait"; +const size_t QQnxVirtualKeyboard::ms_bufferSize = 2048; + +static QQnxVirtualKeyboard *s_instance = 0; + +// Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP. +#define KEYBOARD_SHADOW_HEIGHT 8 + +QQnxVirtualKeyboard::QQnxVirtualKeyboard() : + m_encoder(NULL), + m_decoder(NULL), + m_buffer(NULL), + m_height(0), + m_fd(-1), + m_keyboardMode(Default), + m_visible(false), + m_locale(QLatin1String("en_US")) +{ + connect(); +} + +QQnxVirtualKeyboard::~QQnxVirtualKeyboard() +{ + close(); +} + +/* static */ +QQnxVirtualKeyboard& QQnxVirtualKeyboard::instance() +{ + if (!s_instance) { + s_instance = new QQnxVirtualKeyboard(); + s_instance->start(); + } + + return *s_instance; +} + +/* static */ +void QQnxVirtualKeyboard::destroy() +{ + if (s_instance) { + delete s_instance; + s_instance = 0; + } +} + +void QQnxVirtualKeyboard::close() +{ + if (m_fd) { + // any reads will fail after we close the fd, which is basically what we want. + ::close(m_fd); + } + + // Wait for the thread to die (should be immediate), then continue the cleanup. + wait(); + + if (m_fd) { + m_fd = -1; + } + + + if (m_decoder) + { + pps_decoder_cleanup(m_decoder); + delete m_decoder; + m_decoder = NULL; + } + + if (m_encoder) + { + pps_encoder_cleanup(m_encoder); + delete m_encoder; + m_encoder = NULL; + } + + delete [] m_buffer; + m_buffer = NULL; +} + +bool QQnxVirtualKeyboard::connect() +{ + close(); + + m_encoder = new pps_encoder_t; + m_decoder = new pps_decoder_t; + + pps_encoder_initialize(m_encoder, false); + pps_decoder_initialize(m_decoder, NULL); + + errno = 0; + m_fd = ::open(ms_PPSPath, O_RDWR); + if (m_fd == -1) + { + qCritical("QQnxVirtualKeyboard: Unable to open \"%s\" for keyboard: %s (%d).", + ms_PPSPath, strerror(errno), errno); + close(); + return false; + } + + m_buffer = new char[ms_bufferSize]; + if (!m_buffer) { + qCritical("QQnxVirtualKeyboard: Unable to allocate buffer of %d bytes. Size is unavailable.", ms_bufferSize); + return false; + } + + if (!queryPPSInfo()) + return false; + + start(); + + return true; +} + +bool QQnxVirtualKeyboard::queryPPSInfo() +{ + // Request info, requires id to regenerate res message. + pps_encoder_add_string(m_encoder, "msg", "info"); + pps_encoder_add_string(m_encoder, "id", "libWebView"); + + if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { + close(); + return false; + } + + pps_encoder_reset(m_encoder); + + return true; +} + +void QQnxVirtualKeyboard::notifyClientActiveStateChange(bool active) +{ + if (!active) + hideKeyboard(); +} + +void QQnxVirtualKeyboard::run() +{ + ppsDataReady(); +} + +void QQnxVirtualKeyboard::ppsDataReady() +{ + while (1) { + ssize_t nread = read(m_fd, m_buffer, ms_bufferSize - 1); + +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: keyboardMessage size: " << nread; +#endif + if (nread < 0) + break; + + // nread is the real space necessary, not the amount read. + if (static_cast(nread) > ms_bufferSize - 1) { + qCritical("QQnxVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1); + break; + } + + m_buffer[nread] = 0; + pps_decoder_parse_pps_str(m_decoder, m_buffer); + pps_decoder_push(m_decoder, NULL); +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + pps_decoder_dump_tree(m_decoder, stderr); +#endif + + const char *value; + if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]"); + continue; + } + + if (pps_decoder_get_string(m_decoder, "msg", &value) == PPS_DECODER_OK) { + if (strcmp(value, "show") == 0) { + const bool oldVisible = m_visible; + m_visible = true; + handleKeyboardStateChangeMessage(true); + if (oldVisible != m_visible) + emit visibilityChanged(m_visible); + } else if (strcmp(value, "hide") == 0) { + const bool oldVisible = m_visible; + m_visible = false; + handleKeyboardStateChangeMessage(false); + if (oldVisible != m_visible) + emit visibilityChanged(m_visible); + } else if (strcmp(value, "info") == 0) + handleKeyboardInfoMessage(); + else if (strcmp(value, "connect") == 0) { } + else + qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS msg value: %s", value ? value : "[null]"); + } else if (pps_decoder_get_string(m_decoder, "res", &value) == PPS_DECODER_OK) { + if (strcmp(value, "info") == 0) + handleKeyboardInfoMessage(); + else + qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS res value: %s", value ? value : "[null]"); + } else + qCritical("QQnxVirtualKeyboard: Unexpected keyboard PPS message type"); + } + +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: exiting keyboard thread"; +#endif + + if (m_decoder) + pps_decoder_cleanup(m_decoder); +} + +void QQnxVirtualKeyboard::handleKeyboardInfoMessage() +{ + int newHeight = 0; + const char *value; + + if (pps_decoder_push(m_decoder, "dat") != PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS dat object not found"); + return; + } + if (pps_decoder_get_int(m_decoder, "size", &newHeight) != PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS size field not found"); + return; + } + if (pps_decoder_push(m_decoder, "locale") != PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS locale object not found"); + return; + } + if (pps_decoder_get_string(m_decoder, "languageId", &value) != PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS languageId field not found"); + return; + } + const QString languageId = QString::fromLatin1(value); + if (pps_decoder_get_string(m_decoder, "countryId", &value) != PPS_DECODER_OK) { + qCritical("QQnxVirtualKeyboard: Keyboard PPS size countryId not found"); + return; + } + const QString countryId = QString::fromLatin1(value); + + // HUGE hack, should be removed ASAP. + newHeight -= KEYBOARD_SHADOW_HEIGHT; // We want to ignore the 8 pixel shadow above the keyboard. (PR 88400) + + if (newHeight != m_height) { + m_height = newHeight; + updateAvailableScreenGeometry(); + } + + const QLocale locale = QLocale(languageId + QLatin1Char('_') + countryId); + if (locale != m_locale) { + m_locale = locale; + emit localeChanged(locale); + } + +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: handleKeyboardInfoMessage size=" << m_height << "locale=" << m_locale; +#endif +} + +void QQnxVirtualKeyboard::handleKeyboardStateChangeMessage(bool visible) +{ + +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: handleKeyboardStateChangeMessage " << visible; +#endif + updateAvailableScreenGeometry(); + + if (visible) + showKeyboard(); + else + hideKeyboard(); +} + +void QQnxVirtualKeyboard::updateAvailableScreenGeometry() +{ +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: updateAvailableScreenGeometry: keyboard visible=" << m_visible << ", keyboard height=" << m_height; +#endif + + // TODO: What screen index should be used? I assume primaryScreen here because it works, and + // we do it for handleScreenGeometryChange elsewhere but since we have support + // for more than one screen, that's not going to always work. + QQnxScreen *platformScreen = QQnxScreen::primaryDisplay(); + QWindowSystemInterface::handleScreenAvailableGeometryChange(platformScreen->screen(), platformScreen->availableGeometry()); +} + +bool QQnxVirtualKeyboard::showKeyboard() +{ +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: showKeyboard()"; +#endif + + // Try to connect. + if (m_fd == -1 && !connect()) + return false; + + // NOTE: This must be done everytime the keyboard is shown even if there is no change because + // hiding the keyboard wipes the setting. + applyKeyboardModeOptions(); + + pps_encoder_reset(m_encoder); + + // Send the show message. + pps_encoder_add_string(m_encoder, "msg", "show"); + + if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { + close(); + return false; + } + + pps_encoder_reset(m_encoder); + + // Return true if no error occurs. Sizing response will be triggered when confirmation of + // the change arrives. + return true; +} + +bool QQnxVirtualKeyboard::hideKeyboard() +{ +#ifdef QQNXVIRTUALKEYBOARD_DEBUG + qDebug() << "QQNX: hideKeyboard()"; +#endif + + if (m_fd == -1 && !connect()) + return false; + + pps_encoder_add_string(m_encoder, "msg", "hide"); + + if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { + close(); + + //Try again. + if (connect()) { + if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { + close(); + return false; + } + } + else + return false; + } + + pps_encoder_reset(m_encoder); + + // Return true if no error occurs. Sizing response will be triggered when confirmation of + // the change arrives. + return true; +} + +void QQnxVirtualKeyboard::setKeyboardMode(KeyboardMode mode) +{ + m_keyboardMode = mode; +} + +void QQnxVirtualKeyboard::applyKeyboardModeOptions() +{ + // Try to connect. + if (m_fd == -1 && !connect()) + return; + + // Send the options message. + pps_encoder_add_string(m_encoder, "msg", "options"); + + pps_encoder_start_object(m_encoder, "dat"); + switch (m_keyboardMode) { + case Url: + addUrlModeOptions(); + break; + case Email: + addEmailModeOptions(); + break; + case Web: + addWebModeOptions(); + break; + case NumPunc: + addNumPuncModeOptions(); + break; + case Symbol: + addSymbolModeOptions(); + break; + case Phone: + addPhoneModeOptions(); + break; + case Pin: + addPinModeOptions(); + break; + case Default: + default: + addDefaultModeOptions(); + break; + } + + pps_encoder_end_object(m_encoder); + + if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) { + close(); + } + + pps_encoder_reset(m_encoder); +} + +void QQnxVirtualKeyboard::addDefaultModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "default"); +} + +void QQnxVirtualKeyboard::addUrlModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "url"); +} + +void QQnxVirtualKeyboard::addEmailModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "email"); +} + +void QQnxVirtualKeyboard::addWebModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "web"); +} + +void QQnxVirtualKeyboard::addNumPuncModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "numPunc"); +} + +void QQnxVirtualKeyboard::addPhoneModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "phone"); +} + +void QQnxVirtualKeyboard::addPinModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "pin"); +} + +void QQnxVirtualKeyboard::addSymbolModeOptions() +{ + pps_encoder_add_string(m_encoder, "enter", "enter.default"); + pps_encoder_add_string(m_encoder, "type", "symbol"); +} diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h new file mode 100644 index 0000000000..21b2e8736c --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboard.h @@ -0,0 +1,130 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIRTUALKEYBOARD_H_ +#define VIRTUALKEYBOARD_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/* Shamelessly copied from the browser - this should be rewritten once we have a proper PPS wrapper class */ +class QQnxVirtualKeyboard : public QThread +{ + Q_OBJECT +public: + // NOTE: Not all the following keyboard modes are currently used. + // Default - Regular Keyboard + // Url/Email - Enhanced keys for each types. + // Web - Regular keyboard with two blank keys, currently unused. + // NumPunc - Numbers & Punctionation, alternate to Symbol + // Symbol - All symbols, alternate to NumPunc, currently unused. + // Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z + // Pin - Keyboard for entering Pins (Hex values) currently unused. + // + // SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional. + // + enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin }; + + static QQnxVirtualKeyboard& instance(); + static void destroy(); + + bool showKeyboard(); + bool hideKeyboard(); + int height() { return m_visible ? m_height : 0; } + void setKeyboardMode(KeyboardMode); + void notifyClientActiveStateChange(bool); + bool isVisible() const { return m_visible; } + QLocale locale() const { return m_locale; } + +Q_SIGNALS: + void localeChanged(const QLocale &locale); + void visibilityChanged(bool visible); + +private: + QQnxVirtualKeyboard(); + virtual ~QQnxVirtualKeyboard(); + + // Will be called internally if needed. + bool connect(); + void close(); + void ppsDataReady(); + bool queryPPSInfo(); + void handleKeyboardInfoMessage(); + void handleKeyboardStateChangeMessage(bool visible); + void updateAvailableScreenGeometry(); + + void applyKeyboardModeOptions(); + void addDefaultModeOptions(); + void addUrlModeOptions(); + void addEmailModeOptions(); + void addWebModeOptions(); + void addNumPuncModeOptions(); + void addSymbolModeOptions(); + void addPhoneModeOptions(); + void addPinModeOptions(); + + // QThread overrides + virtual void run(); + + pps_encoder_t *m_encoder; + pps_decoder_t *m_decoder; + char *m_buffer; + int m_height; + int m_fd; + KeyboardMode m_keyboardMode; + bool m_visible; + QLocale m_locale; + + // Path to keyboardManager in PPS. + static const char *ms_PPSPath; + static const size_t ms_bufferSize; +}; + +#endif /* VIRTUALKEYBOARD_H_ */ diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp new file mode 100644 index 0000000000..cf45d062bd --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -0,0 +1,665 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxwindow.h" +#include "qqnxglcontext.h" +#include "qqnxintegration.h" +#include "qqnxscreen.h" + +#include +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) + : QPlatformWindow(window), + m_screenContext(context), + m_window(0), + m_currentBufferIndex(-1), + m_previousBufferIndex(-1), + m_platformOpenGLContext(0), + m_screen(0), + m_parentWindow(0), + m_visible(true) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size(); +#endif + int result; + + // Create child QNX window + errno = 0; + result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW); + if (result != 0) { + qFatal("QQnxWindow: failed to create window, errno=%d", errno); + } + + // Set window buffer usage based on rendering API + int val; + QSurface::SurfaceType surfaceType = window->surfaceType(); + switch (surfaceType) { + case QSurface::RasterSurface: + val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE; + break; + case QSurface::OpenGLSurface: + val = SCREEN_USAGE_OPENGL_ES2; + break; + default: + qFatal("QQnxWindow: unsupported window API"); + break; + } + + errno = 0; + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, &val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window buffer usage, errno=%d", errno); + } + + // Alpha channel is always pre-multiplied if present + errno = 0; + val = SCREEN_PRE_MULTIPLIED_ALPHA; + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window alpha mode, errno=%d", errno); + } + + // Make the window opaque + errno = 0; + val = SCREEN_TRANSPARENCY_NONE; + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno); + } + + // Set the window swap interval + errno = 0; + val = 1; + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window swap interval, errno=%d", errno); + } + + // Assign the window to the primary display (this is the default specified by screen). + setScreen(QQnxScreen::primaryDisplay()); + + // Add the window to the root of the hierarchy + QQnxScreen::addWindow(this); + + // Add window to plugin's window mapper + QQnxIntegration::addWindow(m_window, window); +} + +QQnxWindow::~QQnxWindow() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + // Remove from plugin's window mapper + QQnxIntegration::removeWindow(m_window); + + // Remove from parent's Hierarchy. + removeFromParent(); + QQnxScreen::updateHierarchy(); + + // We shouldn't allow this case unless QT allows it. Does it? Or should we send the + // handleCloseEvent on all children when this window is deleted? + if (m_childWindows.size() > 0) + qFatal("QQnxWindow: window destroyed before children!"); + + // Cleanup QNX window and its buffers + screen_destroy_window(m_window); +} + +void QQnxWindow::setGeometry(const QRect &rect) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window() << ", (" << rect.x() << "," << rect.y() << "," << rect.width() << "," << rect.height() << ")"; +#endif + + QRect oldGeometry = geometry(); + + // Call base class method + QPlatformWindow::setGeometry(rect); + + // Set window geometry equal to widget geometry + errno = 0; + int val[2]; + val[0] = rect.x(); + val[1] = rect.y(); + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window position, errno=%d", errno); + } + + errno = 0; + val[0] = rect.width(); + val[1] = rect.height(); + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window size, errno=%d", errno); + } + + // Set viewport size equal to window size + errno = 0; + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window source size, errno=%d", errno); + } + + // Now move all children. + QPoint offset; + if (!oldGeometry.isEmpty()) { + offset = rect.topLeft(); + offset -= oldGeometry.topLeft(); + + QList::iterator it; + for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { + (*it)->offset(offset); + } + } +} + +void QQnxWindow::offset(const QPoint &offset) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + // Move self and then children. + QRect newGeometry = geometry(); + newGeometry.translate(offset); + + // Call the base class + QPlatformWindow::setGeometry(newGeometry); + + int val[2]; + + errno = 0; + val[0] = newGeometry.x(); + val[1] = newGeometry.y(); + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window position, errno=%d", errno); + } + + QList::iterator it; + for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { + (*it)->offset(offset); + } +} + +void QQnxWindow::setVisible(bool visible) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window() << "visible =" << visible; +#endif + + m_visible = visible; + + QQnxWindow *root = this; + while (root->m_parentWindow) + root = root->m_parentWindow; + + root->updateVisibility(root->m_visible); + + window()->requestActivateWindow(); +} + +void QQnxWindow::updateVisibility(bool parentVisible) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window(); +#endif + // Set window visibility + errno = 0; + int val = (m_visible && parentVisible) ? 1 : 0; + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window visibility, errno=%d", errno); + } + + QList::iterator it; + for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { + (*it)->updateVisibility(m_visible && parentVisible); + } +} + +void QQnxWindow::setOpacity(qreal level) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level; +#endif + // Set window global alpha + errno = 0; + int val = (int)(level * 255); + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window global alpha, errno=%d", errno); + } + + // TODO: How to handle children of this window? If we change all the visibilities, then + // the transparency will look wrong... +} + +void QQnxWindow::setBufferSize(const QSize &size) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size; +#endif + // Set window buffer size + errno = 0; + int val[2] = { size.width(), size.height() }; + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window buffer size, errno=%d", errno); + } + + // Create window buffers if they do not exist + if (!hasBuffers()) { + // Get pixel format from EGL config if using OpenGL; + // otherwise inherit pixel format of window's screen + if (m_platformOpenGLContext != 0) { + val[0] = platformWindowFormatToNativeFormat(m_platformOpenGLContext->format()); + } else { + val[0] = m_screen->nativeFormat(); + } + + errno = 0; + result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val); + if (result != 0) { + qFatal("QQnxWindow: failed to set window pixel format, errno=%d", errno); + } + + errno = 0; + result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT); + if (result != 0) { + qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno); + } + } + + // Cache new buffer size + m_bufferSize = size; + + // Buffers were destroyed; reacquire them + m_currentBufferIndex = -1; + m_previousDirty = QRegion(); + m_scrolled = QRegion(); +} + +QQnxBuffer &QQnxWindow::renderBuffer() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + // Check if render buffer is invalid + if (m_currentBufferIndex == -1) { + // Get all buffers available for rendering + errno = 0; + screen_buffer_t buffers[MAX_BUFFER_COUNT]; + int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers); + if (result != 0) { + qFatal("QQnxWindow: failed to query window buffers, errno=%d", errno); + } + + // Wrap each buffer + for (int i = 0; i < MAX_BUFFER_COUNT; ++i) { + m_buffers[i] = QQnxBuffer(buffers[i]); + } + + // Use the first available render buffer + m_currentBufferIndex = 0; + m_previousBufferIndex = -1; + } + + return m_buffers[m_currentBufferIndex]; +} + +void QQnxWindow::scroll(const QRegion ®ion, int dx, int dy, bool flush) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + copyBack(region, dx, dy, flush); + m_scrolled += region; +} + +void QQnxWindow::post(const QRegion &dirty) +{ + // Check if render buffer exists and something was rendered + if (m_currentBufferIndex != -1 && !dirty.isEmpty()) { +#if defined(QQNXWINDOW_DEBUG) + qDebug() << "QQnxWindow::post - window =" << window(); +#endif + QQnxBuffer ¤tBuffer = m_buffers[m_currentBufferIndex]; + + // Copy unmodified region from old render buffer to new render buffer; + // required to allow partial updates + QRegion preserve = m_previousDirty - dirty - m_scrolled; + copyBack(preserve, 0, 0); + + // Calculate region that changed + QRegion modified = preserve + dirty + m_scrolled; + QRect rect = modified.boundingRect(); + int dirtyRect[4] = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() }; + + // Update the display with contents of render buffer + errno = 0; + int result = screen_post_window(m_window, currentBuffer.nativeBuffer(), 1, dirtyRect, 0); + if (result != 0) { + qFatal("QQnxWindow: failed to post window buffer, errno=%d", errno); + } + + // Advance to next nender buffer + m_previousBufferIndex = m_currentBufferIndex++; + if (m_currentBufferIndex >= MAX_BUFFER_COUNT) { + m_currentBufferIndex = 0; + } + + // Save modified region and clear scrolled region + m_previousDirty = dirty; + m_scrolled = QRegion(); + + // Notify screen that window posted + if (m_screen != 0) { + m_screen->onWindowPost(this); + } + } +} + +void QQnxWindow::setScreen(QQnxScreen *platformScreen) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window() << "platformScreen =" << platformScreen; +#endif + + if (m_screen == platformScreen) + return; + + 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); + } + + // Add window to display's window group + errno = 0; + result = screen_join_window_group(m_window, platformScreen->windowGroupName()); + if (result != 0) { + qFatal("QQnxWindow: failed to join window group, errno=%d", errno); + } + + QList::iterator it; + for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) { + // Only subwindows and tooltips need necessarily be moved to another display with the window. + if ((window()->windowType() & Qt::WindowType_Mask) == Qt::SubWindow || + (window()->windowType() & Qt::WindowType_Mask) == Qt::ToolTip) + (*it)->setScreen(platformScreen); + } + + QQnxScreen::updateHierarchy(); +} + +void QQnxWindow::removeFromParent() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + // Remove from old Hierarchy position + if (m_parentWindow) { + if (m_parentWindow->m_childWindows.removeAll(this)) + m_parentWindow = 0; + else + qFatal("QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child."); + } else { + QQnxScreen::removeWindow(this); + } +} + +void QQnxWindow::setParent(const QPlatformWindow *window) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << this->window() << "platformWindow =" << window; +#endif + // Cast away the const, we need to modify the hierarchy. + QQnxWindow *newParent = 0; + + if (window) + newParent = static_cast((QPlatformWindow *)window); + + if (newParent == m_parentWindow) + return; + + removeFromParent(); + m_parentWindow = newParent; + + // Add to new hierarchy position. + if (m_parentWindow) { + if (m_parentWindow->m_screen != m_screen) + setScreen(m_parentWindow->m_screen); + + m_parentWindow->m_childWindows.push_back(this); + } else { + QQnxScreen::addWindow(this); + } + + QQnxScreen::updateHierarchy(); +} + +void QQnxWindow::raise() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + + QQnxWindow *oldParent = m_parentWindow; + if (oldParent) { + removeFromParent(); + oldParent->m_childWindows.push_back(this); + } else { + QQnxScreen::raiseWindow(this); + } + + QQnxScreen::updateHierarchy(); +} + +void QQnxWindow::lower() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + + QQnxWindow *oldParent = m_parentWindow; + if (oldParent) { + removeFromParent(); + oldParent->m_childWindows.push_front(this); + } else { + QQnxScreen::lowerWindow(this); + } + + QQnxScreen::updateHierarchy(); +} + +void QQnxWindow::requestActivateWindow() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + + // TODO: Tell screen to set keyboard focus to this window. + + // Notify that we gained focus. + gainedFocus(); +} + +void QQnxWindow::gainedFocus() +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + + // Got focus + QWindowSystemInterface::handleWindowActivated(window()); +} + +void QQnxWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext) +{ + // This function does not take ownership of the platform gl context. + // It is owned by the frontend QOpenGLContext + m_platformOpenGLContext = platformOpenGLContext; +} + +void QQnxWindow::updateZorder(int &topZorder) +{ + errno = 0; + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder); + topZorder++; + + if (result != 0) + qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window); + + QList::const_iterator it; + + for (it = m_childWindows.begin(); it != m_childWindows.end(); it++) + (*it)->updateZorder(topZorder); +} + +void QQnxWindow::copyBack(const QRegion ®ion, int dx, int dy, bool flush) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO << "window =" << window(); +#endif + int result; + + // Abort if previous buffer is invalid + if (m_previousBufferIndex == -1) { + return; + } + + // Abort if nothing to copy + if (region.isEmpty()) { + return; + } + + QQnxBuffer ¤tBuffer = m_buffers[m_currentBufferIndex]; + QQnxBuffer &previousBuffer = m_buffers[m_previousBufferIndex]; + + // Break down region into non-overlapping rectangles + QVector rects = region.rects(); + for (int i = rects.size() - 1; i >= 0; i--) { + // Clip rectangle to bounds of target + QRect rect = rects[i].intersected( currentBuffer.rect() ); + + if (rect.isEmpty()) + continue; + + // Setup blit operation + int attribs[] = { SCREEN_BLIT_SOURCE_X, rect.x(), + SCREEN_BLIT_SOURCE_Y, rect.y(), + SCREEN_BLIT_SOURCE_WIDTH, rect.width(), + SCREEN_BLIT_SOURCE_HEIGHT, rect.height(), + SCREEN_BLIT_DESTINATION_X, rect.x() + dx, + SCREEN_BLIT_DESTINATION_Y, rect.y() + dy, + SCREEN_BLIT_DESTINATION_WIDTH, rect.width(), + SCREEN_BLIT_DESTINATION_HEIGHT, rect.height(), + SCREEN_BLIT_END }; + + // Queue blit operation + errno = 0; + result = screen_blit(m_screenContext, currentBuffer.nativeBuffer(), previousBuffer.nativeBuffer(), attribs); + if (result != 0) { + qFatal("QQnxWindow: failed to blit buffers, errno=%d", errno); + } + } + + // Check if flush requested + if (flush) { + // Wait for all blits to complete + errno = 0; + result = screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE); + if (result != 0) { + qFatal("QQnxWindow: failed to flush blits, errno=%d", errno); + } + + // Buffer was modified outside the CPU + currentBuffer.invalidateInCache(); + } +} + +int QQnxWindow::platformWindowFormatToNativeFormat(const QSurfaceFormat &format) +{ +#if defined(QQNXWINDOW_DEBUG) + qDebug() << Q_FUNC_INFO; +#endif + // Extract size of colour channels from window format + int redSize = format.redBufferSize(); + if (redSize == -1) { + qFatal("QQnxWindow: red size not defined"); + } + + int greenSize = format.greenBufferSize(); + if (greenSize == -1) { + qFatal("QQnxWindow: green size not defined"); + } + + int blueSize = format.blueBufferSize(); + if (blueSize == -1) { + qFatal("QQnxWindow: blue size not defined"); + } + + // select matching native format + if (redSize == 5 && greenSize == 6 && blueSize == 5) { + return SCREEN_FORMAT_RGB565; + } else if (redSize == 8 && greenSize == 8 && blueSize == 8) { + return SCREEN_FORMAT_RGBA8888; + } else { + qFatal("QQnxWindow: unsupported pixel format"); + return 0; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h new file mode 100644 index 0000000000..9507b08ade --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -0,0 +1,133 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXWINDOW_H +#define QQNXWINDOW_H + +#include + +#include "qqnxbuffer.h" + +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +// all surfaces double buffered +#define MAX_BUFFER_COUNT 2 + +class QQnxGLContext; +class QQnxScreen; + +class QPlatformGLContext; +class QSurfaceFormat; + +class QQnxWindow : public QPlatformWindow +{ +friend class QQnxScreen; +public: + QQnxWindow(QWindow *window, screen_context_t context); + virtual ~QQnxWindow(); + + virtual void setGeometry(const QRect &rect); + virtual void setVisible(bool visible); + virtual void setOpacity(qreal level); + + virtual WId winId() const { return (WId)m_window; } + screen_window_t nativeHandle() const { return m_window; } + + void setBufferSize(const QSize &size); + QSize bufferSize() const { return m_bufferSize; } + bool hasBuffers() const { return !m_bufferSize.isEmpty(); } + + QQnxBuffer &renderBuffer(); + void scroll(const QRegion ®ion, int dx, int dy, bool flush=false); + void post(const QRegion &dirty); + + void setScreen(QQnxScreen *platformScreen); + + virtual void setParent(const QPlatformWindow *window); + virtual void raise(); + virtual void lower(); + virtual void requestActivateWindow(); + + void gainedFocus(); + + QQnxScreen *screen() const { return m_screen; } + const QList& children() const { return m_childWindows; } + + void setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext); + QQnxGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; } + +private: + void removeFromParent(); + void offset(const QPoint &offset); + void updateVisibility(bool parentVisible); + void updateZorder(int &topZorder); + + void fetchBuffers(); + + void copyBack(const QRegion ®ion, int dx, int dy, bool flush=false); + + static int platformWindowFormatToNativeFormat(const QSurfaceFormat &format); + + screen_context_t m_screenContext; + screen_window_t m_window; + QSize m_bufferSize; + QQnxBuffer m_buffers[MAX_BUFFER_COUNT]; + int m_currentBufferIndex; + int m_previousBufferIndex; + QRegion m_previousDirty; + QRegion m_scrolled; + + QQnxGLContext *m_platformOpenGLContext; + QQnxScreen *m_screen; + QList m_childWindows; + QQnxWindow *m_parentWindow; + bool m_visible; +}; + +QT_END_NAMESPACE + +#endif // QQNXWINDOW_H -- cgit v1.2.3 From 31043e6b8d7581bfb34174387633da188dcbe538 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Mon, 23 Jan 2012 14:55:48 +0100 Subject: Cocoa: Fix accessiiblityPerformAction Remove hardcoded pressAction(); Change-Id: Ie02e3f2f88a2cd311aec1b39daa160efb3b2b617 Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 06d75036bf..58284bcddb 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -204,8 +204,7 @@ static QAccessibleInterface *acast(void *ptr) - (void)accessibilityPerformAction:(NSString *)action { QAccessibleActionInterface *actionInterface = acast(accessibleInterface)->actionInterface(); if (actionInterface) { - QString qtAction = QCocoaAccessible::translateAction(action); - actionInterface->doAction(QAccessibleActionInterface::pressAction()); + actionInterface->doAction(QCocoaAccessible::translateAction(action)); } } -- cgit v1.2.3 From a5c1ffedb8aceaa69bb27f999cf3ead205a86a54 Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Sat, 10 Mar 2012 16:17:27 -0800 Subject: Convert xlib plugin to new format Change-Id: I00418a1eb7bf944ec360dbbb1f61f7703f3ecd37 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/xlib/main.cpp | 6 ++++-- src/plugins/platforms/xlib/xlib.json | 3 +++ src/plugins/platforms/xlib/xlib.pro | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/xlib/xlib.json (limited to 'src/plugins') diff --git a/src/plugins/platforms/xlib/main.cpp b/src/plugins/platforms/xlib/main.cpp index 6030a72236..95c4d9e4d8 100644 --- a/src/plugins/platforms/xlib/main.cpp +++ b/src/plugins/platforms/xlib/main.cpp @@ -46,6 +46,8 @@ QT_BEGIN_NAMESPACE class QXlibIntegrationPlugin : public QPlatformIntegrationPlugin { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "xlib.json") public: QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&); @@ -67,6 +69,6 @@ QPlatformIntegration* QXlibIntegrationPlugin::create(const QString& system, cons return 0; } -Q_EXPORT_PLUGIN2(xlib, QXlibIntegrationPlugin) - QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platforms/xlib/xlib.json b/src/plugins/platforms/xlib/xlib.json new file mode 100644 index 0000000000..524be2fc6d --- /dev/null +++ b/src/plugins/platforms/xlib/xlib.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "xlib" ] +} diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro index ea95ae83a1..463130a64b 100644 --- a/src/plugins/platforms/xlib/xlib.pro +++ b/src/plugins/platforms/xlib/xlib.pro @@ -32,6 +32,8 @@ HEADERS = \ qxlibdisplay.h \ qxlibnativeinterface.h +OTHER_FILES += xlib.json + LIBS += -lX11 -lXext mac { -- cgit v1.2.3 From 431eb30e9ec21c15d26d6f1b03d3bbd4cd36c30c Mon Sep 17 00:00:00 2001 From: Donald Carr Date: Fri, 9 Mar 2012 00:59:37 +0000 Subject: Remove stale references to Qtopia MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Idd9b5fae8f6a0273636a878325e82e5664a40d43 Reviewed-by: Donald Carr Reviewed-by: Samuel Rødal Reviewed-by: Oswald Buddenhagen Reviewed-by: Girish Ramakrishnan Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 36 ---------------------------- src/plugins/platforms/xlib/qxlibkeyboard.cpp | 36 ---------------------------- 2 files changed, 72 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 03156dc544..c5e124ab45 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -247,24 +247,6 @@ // end of XF86keysyms.h -// Special keys used by Qtopia, mapped into the X11 private keypad range. -#define QTOPIAXK_Select 0x11000601 -#define QTOPIAXK_Yes 0x11000602 -#define QTOPIAXK_No 0x11000603 -#define QTOPIAXK_Cancel 0x11000604 -#define QTOPIAXK_Printer 0x11000605 -#define QTOPIAXK_Execute 0x11000606 -#define QTOPIAXK_Sleep 0x11000607 -#define QTOPIAXK_Play 0x11000608 -#define QTOPIAXK_Zoom 0x11000609 -#define QTOPIAXK_Context1 0x1100060A -#define QTOPIAXK_Context2 0x1100060B -#define QTOPIAXK_Context3 0x1100060C -#define QTOPIAXK_Context4 0x1100060D -#define QTOPIAXK_Call 0x1100060E -#define QTOPIAXK_Hangup 0x1100060F -#define QTOPIAXK_Flip 0x11000610 - QT_BEGIN_NAMESPACE // keyboard mapping table @@ -573,24 +555,6 @@ static const unsigned int KeyTbl[] = { XF86XK_LaunchE, Qt::Key_LaunchG, XF86XK_LaunchF, Qt::Key_LaunchH, - // Qtopia keys - QTOPIAXK_Select, Qt::Key_Select, - QTOPIAXK_Yes, Qt::Key_Yes, - QTOPIAXK_No, Qt::Key_No, - QTOPIAXK_Cancel, Qt::Key_Cancel, - QTOPIAXK_Printer, Qt::Key_Printer, - QTOPIAXK_Execute, Qt::Key_Execute, - QTOPIAXK_Sleep, Qt::Key_Sleep, - QTOPIAXK_Play, Qt::Key_Play, - QTOPIAXK_Zoom, Qt::Key_Zoom, - QTOPIAXK_Context1, Qt::Key_Context1, - QTOPIAXK_Context2, Qt::Key_Context2, - QTOPIAXK_Context3, Qt::Key_Context3, - QTOPIAXK_Context4, Qt::Key_Context4, - QTOPIAXK_Call, Qt::Key_Call, - QTOPIAXK_Hangup, Qt::Key_Hangup, - QTOPIAXK_Flip, Qt::Key_Flip, - 0, 0 }; diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp index e2742c4c8d..590d582661 100644 --- a/src/plugins/platforms/xlib/qxlibkeyboard.cpp +++ b/src/plugins/platforms/xlib/qxlibkeyboard.cpp @@ -243,24 +243,6 @@ // end of XF86keysyms.h -// Special keys used by Qtopia, mapped into the X11 private keypad range. -#define QTOPIAXK_Select 0x11000601 -#define QTOPIAXK_Yes 0x11000602 -#define QTOPIAXK_No 0x11000603 -#define QTOPIAXK_Cancel 0x11000604 -#define QTOPIAXK_Printer 0x11000605 -#define QTOPIAXK_Execute 0x11000606 -#define QTOPIAXK_Sleep 0x11000607 -#define QTOPIAXK_Play 0x11000608 -#define QTOPIAXK_Zoom 0x11000609 -#define QTOPIAXK_Context1 0x1100060A -#define QTOPIAXK_Context2 0x1100060B -#define QTOPIAXK_Context3 0x1100060C -#define QTOPIAXK_Context4 0x1100060D -#define QTOPIAXK_Call 0x1100060E -#define QTOPIAXK_Hangup 0x1100060F -#define QTOPIAXK_Flip 0x11000610 - // keyboard mapping table static const unsigned int KeyTbl[] = { @@ -567,24 +549,6 @@ static const unsigned int KeyTbl[] = { XF86XK_LaunchE, Qt::Key_LaunchG, XF86XK_LaunchF, Qt::Key_LaunchH, - // Qtopia keys - QTOPIAXK_Select, Qt::Key_Select, - QTOPIAXK_Yes, Qt::Key_Yes, - QTOPIAXK_No, Qt::Key_No, - QTOPIAXK_Cancel, Qt::Key_Cancel, - QTOPIAXK_Printer, Qt::Key_Printer, - QTOPIAXK_Execute, Qt::Key_Execute, - QTOPIAXK_Sleep, Qt::Key_Sleep, - QTOPIAXK_Play, Qt::Key_Play, - QTOPIAXK_Zoom, Qt::Key_Zoom, - QTOPIAXK_Context1, Qt::Key_Context1, - QTOPIAXK_Context2, Qt::Key_Context2, - QTOPIAXK_Context3, Qt::Key_Context3, - QTOPIAXK_Context4, Qt::Key_Context4, - QTOPIAXK_Call, Qt::Key_Call, - QTOPIAXK_Hangup, Qt::Key_Hangup, - QTOPIAXK_Flip, Qt::Key_Flip, - 0, 0 }; -- cgit v1.2.3 From 6e278b868824db8e24b68d48fa0f6e154de1b2f6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Mar 2012 09:53:10 +0100 Subject: Implement QSystemTrayIcon for Windows. No longer base the implementation on a QWidget which is not necessary when all that is required is a message window listening to task-tray messages. Export a service function creating a message window from the Windows native interface and use that. Task-number: QTBUG-20978 Change-Id: I01d0faeac777df4eee802c51d2bc722fce814080 Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsintegration.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index b43362c045..d03abe1d93 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -84,12 +84,17 @@ QT_BEGIN_NAMESPACE class QWindowsNativeInterface : public QPlatformNativeInterface { + Q_OBJECT public: virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs); virtual EventFilter setEventFilter(const QByteArray &eventType, EventFilter filter) { return QWindowsContext::instance()->setEventFilter(eventType, filter); } + + Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate, + const QString &windowName, + void *eventProc) const; }; void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window) @@ -140,6 +145,21 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour return 0; } +/*! + \brief Creates a non-visible window handle for filtering messages. +*/ + +void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate, + const QString &windowName, + void *eventProc) const +{ + QWindowsContext *ctx = QWindowsContext::instance(); + const HWND hwnd = ctx->createDummyWindow(classNameTemplate, + (wchar_t*)windowName.utf16(), + (WNDPROC)eventProc); + return hwnd; +} + /*! \class QWindowsIntegration \brief QPlatformIntegration implementation for Windows. @@ -347,3 +367,5 @@ QPlatformServices *QWindowsIntegration::services() const } QT_END_NAMESPACE + +#include "qwindowsintegration.moc" -- cgit v1.2.3 From cf36e571eea0c1befda2abfe2a177ee9f7fc2912 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 12 Mar 2012 17:16:35 +0100 Subject: Windows: Implement QWindowsIntegration::queryKeyboardModifiers() Use code from Qt 4.8. Change-Id: I32d220e04d13ee1e692c0c58268b827bcf519dc7 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsintegration.cpp | 6 ++++++ src/plugins/platforms/windows/qwindowsintegration.h | 2 ++ src/plugins/platforms/windows/qwindowskeymapper.cpp | 12 ++++++++++++ src/plugins/platforms/windows/qwindowskeymapper.h | 2 ++ 4 files changed, 22 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index d03abe1d93..3c2ece58d0 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -56,6 +56,7 @@ #include "qwindowsdrag.h" #include "qwindowsinputcontext.h" #include "qwindowsaccessibility.h" +#include "qwindowskeymapper.h" #include #include @@ -321,6 +322,11 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co return QPlatformIntegration::styleHint(hint); } +Qt::KeyboardModifiers QWindowsIntegration::queryKeyboardModifiers() const +{ + return QWindowsKeyMapper::queryKeyboardModifiers(); +} + QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const { return &d->m_nativeInterface; diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index ba5fafbbb5..6dd65a02e4 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -73,6 +73,8 @@ public: QPlatformServices *services() const; virtual QVariant styleHint(StyleHint hint) const; + virtual Qt::KeyboardModifiers queryKeyboardModifiers() const; + static QWindowsIntegration *instance(); inline void emitScreenAdded(QPlatformScreen *s) { screenAdded(s); } diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 7b96603c44..4b5e95824a 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -1072,4 +1072,16 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms return result; } +Qt::KeyboardModifiers QWindowsKeyMapper::queryKeyboardModifiers() +{ + Qt::KeyboardModifiers modifiers = Qt::NoModifier; + if (GetKeyState(VK_SHIFT) < 0) + modifiers |= Qt::ShiftModifier; + if (GetKeyState(VK_CONTROL) < 0) + modifiers |= Qt::ControlModifier; + if (GetKeyState(VK_MENU) < 0) + modifiers |= Qt::AltModifier; + return modifiers; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h index 483ff57942..b549422966 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.h +++ b/src/plugins/platforms/windows/qwindowskeymapper.h @@ -69,6 +69,8 @@ public: QWindow *keyGrabber() const { return m_keyGrabber; } void setKeyGrabber(QWindow *w) { m_keyGrabber = w; } + static Qt::KeyboardModifiers queryKeyboardModifiers(); + private: bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab); void updateKeyMap(const MSG &msg); -- cgit v1.2.3