From 290ed7f8fafd67197f773454223410bbe57fc4d3 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Tue, 11 Dec 2012 16:10:01 -0200 Subject: QNX: QQnxCursor implementation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation of QQnxCursor, a QPlatformCursor subclass. Due to the lack of a proper cursor API from the underlying OS, this class only caches the current cursor position to make sure that the QCursor class works properly. Change-Id: I55031184a009f3b26ad4af36b1975204e8fa80dc Reviewed-by: Sérgio Martins Reviewed-by: Friedemann Kleint Reviewed-by: Nicolas Arnaud-Cormos --- src/plugins/platforms/qnx/qnx.pro | 7 +- src/plugins/platforms/qnx/qqnxcursor.cpp | 78 ++++++++++++++++++++++ src/plugins/platforms/qnx/qqnxcursor.h | 67 +++++++++++++++++++ src/plugins/platforms/qnx/qqnxscreen.cpp | 11 ++- src/plugins/platforms/qnx/qqnxscreen.h | 4 ++ .../platforms/qnx/qqnxscreeneventhandler.cpp | 2 + 6 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 src/plugins/platforms/qnx/qqnxcursor.cpp create mode 100644 src/plugins/platforms/qnx/qqnxcursor.h (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 30c95b1620..fa5f69769c 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -39,6 +39,7 @@ CONFIG(blackberry) { #DEFINES += QQNXSCREEN_DEBUG #DEFINES += QQNXVIRTUALKEYBOARD_DEBUG #DEFINES += QQNXWINDOW_DEBUG +#DEFINES += QQNXCURSOR_DEBUG SOURCES = main.cpp \ @@ -54,7 +55,8 @@ SOURCES = main.cpp \ qqnxnavigatoreventhandler.cpp \ qqnxabstractnavigator.cpp \ qqnxabstractvirtualkeyboard.cpp \ - qqnxservices.cpp + qqnxservices.cpp \ + qqnxcursor.cpp HEADERS = main.h \ qqnxbuffer.h \ @@ -70,7 +72,8 @@ HEADERS = main.h \ qqnxnavigatoreventhandler.h \ qqnxabstractnavigator.h \ qqnxabstractvirtualkeyboard.h \ - qqnxservices.h + qqnxservices.h \ + qqnxcursor.h LIBS += -lscreen diff --git a/src/plugins/platforms/qnx/qqnxcursor.cpp b/src/plugins/platforms/qnx/qqnxcursor.cpp new file mode 100644 index 0000000000..4fdff666d7 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxcursor.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxcursor.h" + +#include + +#ifdef QQNXCURSOR_DEBUG +#define qCursorDebug qDebug +#else +#define qCursorDebug QT_NO_QDEBUG_MACRO +#endif + +QT_BEGIN_NAMESPACE + +QQnxCursor::QQnxCursor() +{ +} + +#ifndef QT_NO_CURSOR +void QQnxCursor::changeCursor(QCursor *windowCursor, QWindow *window) +{ + Q_UNUSED(windowCursor); + Q_UNUSED(window); +} +#endif + +void QQnxCursor::setPos(const QPoint &pos) +{ + qCursorDebug() << "QQnxCursor::setPos -" << pos; + m_pos = pos; +} + +QPoint QQnxCursor::pos() const +{ + qCursorDebug() << "QQnxCursor::pos -" << m_pos; + return m_pos; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxcursor.h b/src/plugins/platforms/qnx/qqnxcursor.h new file mode 100644 index 0000000000..5d6a8b2c30 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxcursor.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2011 - 2012 Research In Motion +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXCURSOR_H +#define QQNXCURSOR_H + +#include + +QT_BEGIN_NAMESPACE + +class QQnxCursor : public QPlatformCursor +{ +public: + QQnxCursor(); + +#ifndef QT_NO_CURSOR + void changeCursor(QCursor *windowCursor, QWindow *window); +#endif + void setPos(const QPoint &pos); + + QPoint pos() const; + +private: + QPoint m_pos; +}; + +QT_END_NAMESPACE + +#endif // QQNXCURSOR_H diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 593bec8458..3b57f5d4e5 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -41,6 +41,7 @@ #include "qqnxscreen.h" #include "qqnxwindow.h" +#include "qqnxcursor.h" #include #include @@ -111,7 +112,8 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, m_posted(false), m_keyboardHeight(0), m_nativeOrientation(Qt::PrimaryOrientation), - m_platformContext(0) + m_platformContext(0), + m_cursor(new QQnxCursor()) { qScreenDebug() << Q_FUNC_INFO; // Cache initial orientation of this display @@ -154,6 +156,8 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, QQnxScreen::~QQnxScreen() { qScreenDebug() << Q_FUNC_INFO; + + delete m_cursor; } static int defaultDepth() @@ -497,6 +501,11 @@ void QQnxScreen::onWindowPost(QQnxWindow *window) } } +QPlatformCursor * QQnxScreen::cursor() const +{ + return m_cursor; +} + void QQnxScreen::keyboardHeightChanged(int height) { if (height == m_keyboardHeight) diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index be09eca1f8..682f681cd3 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -95,6 +95,8 @@ public: QSharedPointer rootWindow() const { return m_rootWindow; } + QPlatformCursor *cursor() const; + public Q_SLOTS: void setRotation(int rotation); void newWindowCreated(void *window); @@ -130,6 +132,8 @@ private: QList m_childWindows; QList m_overlays; + + QPlatformCursor *m_cursor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index 8b41465add..4b1cc4fdac 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -346,6 +346,8 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) qFatal("QQNX: failed to query event position, errno=%d", errno); } + QCursor::setPos(pos[0], pos[1]); + // get window coordinates of touch errno = 0; int windowPos[2]; -- cgit v1.2.3 From 51ae17d33d6cef2900f5d4edb46b22569a8ff6ad Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Wed, 12 Dec 2012 14:29:28 +0100 Subject: No reason to dynamically resolve NotifyWinEvent anymore It has been available in user32.dll since Windows2000/Windows Server 2003 Change-Id: Icbfc63e944bc9e8098e3b01fd57dc7aa45bcd345 Reviewed-by: Frederik Gladhorn --- .../platforms/windows/accessible/qwindowsaccessibility.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index db2d5f949f..94a5dd6a68 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -162,21 +162,10 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) } } - typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG); - #if defined(Q_OS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0 // There is no user32.lib nor NotifyWinEvent for CE return; #else - static PtrNotifyWinEvent ptrNotifyWinEvent = 0; - static bool resolvedNWE = false; - if (!resolvedNWE) { - resolvedNWE = true; - ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent"); - } - if (!ptrNotifyWinEvent) - return; - // An event has to be associated with a window, // so find the first parent that is a widget and that has a WId QAccessibleInterface *iface = event->accessibleInterface(); @@ -199,7 +188,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) int eventId = - (eventNum - 1); qAccessibleRecentSentEvents()->insert(eventId, qMakePair(event->object(), event->child())); - ptrNotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId ); + ::NotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId ); ++eventNum; } -- cgit v1.2.3 From 4b7be050581bfef8a064ba867489b7dd7ee7ae47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Mill=C3=A1n=20Soto?= Date: Mon, 24 Sep 2012 14:16:16 +0200 Subject: Change behaviour of selectRow, selectColumn, unselectRow, unselectColumn According to the comments of selectRow and selectColumn, the expected behaviour of this method was to select a row or a column and unselect any cell that were previously selected. However the actual behavior was to select only one cell and not deselect any cell. Moreover, according to the specification there's no simple way of selecting multiple rows or columns as when one of the methods is called for selecting one row or column the others should be unselected. The specification was changed not to require the rest of the cells to be deselected, although they might be deselected if the selectionMode requires that in order for the new row/column to be selected. The implementation of these methods was changed in QAccessibleTable and QAccessibleTree to select the whole row/column and take into acount selectionMode and selectionBehavior. tst_qaccessibility.cpp was modified to test the new behaviour of the methods. Change-Id: I29635d014792169302435e81704e02c16f951238 Reviewed-by: Frederik Gladhorn --- src/plugins/accessible/widgets/itemviews.cpp | 125 ++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 301838997f..7130979935 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -299,9 +299,28 @@ bool QAccessibleTable::selectRow(int row) if (!view()->model() || !view()->selectionModel()) return false; QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); - if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + + if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) + return false; + + switch (view()->selectionMode()) { + case QAbstractItemView::NoSelection: return false; - view()->selectionModel()->select(index, QItemSelectionModel::Select); + case QAbstractItemView::SingleSelection: + if (view()->selectionBehavior() != QAbstractItemView::SelectRows && columnCount() > 1 ) + return false; + view()->clearSelection(); + break; + case QAbstractItemView::ContiguousSelection: + if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) + && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) + view()->clearSelection(); + break; + default: + break; + } + + view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); return true; } @@ -310,9 +329,26 @@ bool QAccessibleTable::selectColumn(int column) if (!view()->model() || !view()->selectionModel()) return false; QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); - if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + + if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectRows) + return false; + + switch (view()->selectionMode()) { + case QAbstractItemView::NoSelection: return false; - view()->selectionModel()->select(index, QItemSelectionModel::Select); + case QAbstractItemView::SingleSelection: + if (view()->selectionBehavior() != QAbstractItemView::SelectColumns && rowCount() > 1) + return false; + case QAbstractItemView::ContiguousSelection: + if ((!column || !view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) + && !view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) + view()->clearSelection(); + break; + default: + break; + } + + view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Columns); return true; } @@ -320,10 +356,35 @@ bool QAccessibleTable::unselectRow(int row) { if (!view()->model() || !view()->selectionModel()) return false; + QModelIndex index = view()->model()->index(row, 0, view()->rootIndex()); - if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + if (!index.isValid()) return false; - view()->selectionModel()->select(index, QItemSelectionModel::Deselect); + + QItemSelection selection(index, index); + + switch (view()->selectionMode()) { + case QAbstractItemView::SingleSelection: + //In SingleSelection and ContiguousSelection once an item + //is selected, there's no way for the user to unselect all items + if (selectedRowCount() == 1) + return false; + break; + case QAbstractItemView::ContiguousSelection: + if (selectedRowCount() == 1) + return false; + + if ((!row || view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) + && view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) { + //If there are rows selected both up the current row and down the current rown, + //the ones which are down the current row will be deselected + selection = QItemSelection(index, view()->model()->index(rowCount() - 1, 0, view()->rootIndex())); + } + default: + break; + } + + view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Rows); return true; } @@ -331,10 +392,35 @@ bool QAccessibleTable::unselectColumn(int column) { if (!view()->model() || !view()->selectionModel()) return false; + QModelIndex index = view()->model()->index(0, column, view()->rootIndex()); - if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + if (!index.isValid()) return false; - view()->selectionModel()->select(index, QItemSelectionModel::Columns & QItemSelectionModel::Deselect); + + QItemSelection selection(index, index); + + switch (view()->selectionMode()) { + case QAbstractItemView::SingleSelection: + //In SingleSelection and ContiguousSelection once an item + //is selected, there's no way for the user to unselect all items + if (selectedColumnCount() == 1) + return false; + break; + case QAbstractItemView::ContiguousSelection: + if (selectedColumnCount() == 1) + return false; + + if ((!column || view()->selectionModel()->isColumnSelected(column - 1, view()->rootIndex())) + && view()->selectionModel()->isColumnSelected(column + 1, view()->rootIndex())) { + //If there are columns selected both at the left of the current row and at the right + //of the current rown, the ones which are at the right will be deselected + selection = QItemSelection(index, view()->model()->index(0, columnCount() - 1, view()->rootIndex())); + } + default: + break; + } + + view()->selectionModel()->select(selection, QItemSelectionModel::Deselect | QItemSelectionModel::Columns); return true; } @@ -576,9 +662,28 @@ bool QAccessibleTree::selectRow(int row) if (!view()->selectionModel()) return false; QModelIndex index = indexFromLogical(row); - if (!index.isValid() || view()->selectionMode() & QAbstractItemView::NoSelection) + + if (!index.isValid() || view()->selectionBehavior() == QAbstractItemView::SelectColumns) return false; - view()->selectionModel()->select(index, QItemSelectionModel::Select); + + switch (view()->selectionMode()) { + case QAbstractItemView::NoSelection: + return false; + case QAbstractItemView::SingleSelection: + if ((view()->selectionBehavior() != QAbstractItemView::SelectRows) && (columnCount() > 1)) + return false; + view()->clearSelection(); + break; + case QAbstractItemView::ContiguousSelection: + if ((!row || !view()->selectionModel()->isRowSelected(row - 1, view()->rootIndex())) + && !view()->selectionModel()->isRowSelected(row + 1, view()->rootIndex())) + view()->clearSelection(); + break; + default: + break; + } + + view()->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); return true; } -- cgit v1.2.3 From e307d6074942eba356ecd4dceabf1def9a92719e Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sun, 16 Dec 2012 22:40:41 +0100 Subject: Remove usage of qt_mac_get_scaleFactor() as it is no longer needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qt_mac_get_scaleFactor() uses a deprecated function, but as this function is no longer needed internally anyway, just remove it. Task-number: QTBUG-28574 Change-Id: I4e3cd2383ecc56aa6f9e3931a1806c62b1cedeb5 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoahelpers.h | 2 -- src/plugins/platforms/cocoa/qcocoahelpers.mm | 5 ----- src/plugins/platforms/cocoa/qpaintengine_mac.mm | 9 ++------- 3 files changed, 2 insertions(+), 14 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index b0222738e1..45bfd34e03 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -84,8 +84,6 @@ HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); -CGFloat qt_mac_get_scalefactor(); - QChar qt_mac_qtKey2CocoaKey(Qt::Key key); Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 008d9da2cf..9783899742 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -614,11 +614,6 @@ InvalidContext: return err; } -CGFloat qt_mac_get_scalefactor() -{ - return [[NSScreen mainScreen] userSpaceScaleFactor]; -} - Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) { switch (buttonNum) { diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 5b83477881..4ae4fac6c2 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -1376,13 +1376,8 @@ QCoreGraphicsPaintEngine::updateRenderHints(QPainter::RenderHints hints) { Q_D(QCoreGraphicsPaintEngine); CGContextSetShouldAntialias(d->hd, hints & QPainter::Antialiasing); - static const CGFloat ScaleFactor = qt_mac_get_scalefactor(); - if (ScaleFactor > 1.) { - CGContextSetInterpolationQuality(d->hd, kCGInterpolationHigh); - } else { - CGContextSetInterpolationQuality(d->hd, (hints & QPainter::SmoothPixmapTransform) ? - kCGInterpolationHigh : kCGInterpolationNone); - } + CGContextSetInterpolationQuality(d->hd, (hints & QPainter::SmoothPixmapTransform) ? + kCGInterpolationHigh : kCGInterpolationNone); bool textAntialiasing = (hints & QPainter::TextAntialiasing) == QPainter::TextAntialiasing; if (!textAntialiasing || d->disabledSmoothFonts) { d->disabledSmoothFonts = !textAntialiasing; -- cgit v1.2.3 From dde09c429ae8b7ad0df4e4b36b8459d2b85a1219 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 21 Dec 2012 15:23:28 +0100 Subject: Make distance fields rendering work with Opentype CFF fonts If the font has a CFF table, GDI will not label it as TMPF_TRUETYPE, however, we can still use GetFontData to get the SFNT tables. This is required to get the maxp table which contains the glyph count, which is required to use the font with the distance-field renderer. Task-number: QTBUG-28746 Change-Id: I3ca1e3d96ea53c453e6fa422b33d1f1f5050a82c Reviewed-by: Konstantin Ritt --- src/plugins/platforms/windows/qwindowsfontengine.cpp | 13 ++++++++++++- src/plugins/platforms/windows/qwindowsfontengine.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 578a0cd20b..e51d6d4e7e 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -155,9 +155,20 @@ static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc) return otm; } +bool QWindowsFontEngine::hasCFFTable() const +{ + HDC hdc = m_fontEngineData->hdc; + SelectObject(hdc, hfont); + return GetFontData(hdc, MAKE_TAG('C', 'F', 'F', ' '), 0, 0, 0) != GDI_ERROR; +} + void QWindowsFontEngine::getCMap() { ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); + + // TMPF_TRUETYPE is not set for fonts with CFF tables + cffTable = !ttf && hasCFFTable(); + HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); bool symb = false; @@ -1041,7 +1052,7 @@ void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gly bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const { - if (!ttf) + if (!ttf && !cffTable) return false; HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index b1aeb94b18..b1e41e89d1 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -145,6 +145,7 @@ public: private: QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform, QImage::Format mask_format); + bool hasCFFTable() const; const QSharedPointer m_fontEngineData; @@ -155,6 +156,7 @@ private: uint stockFont : 1; uint ttf : 1; uint hasOutline : 1; + uint cffTable : 1; TEXTMETRIC tm; int lw; const unsigned char *cmap; -- cgit v1.2.3 From 9b0fab6b62df98519ebfab117f14b9d3465d8c68 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 21 Dec 2012 18:35:58 +0200 Subject: Update Qt internals to use QChar::Script ...and remove the outdated QUnicodeTables::Script enum. QFontEngineData now has one extra slot that never used (engines[QChar::Script_Inherited]). engines[QChar::Script_Unknown], if accessed, would be set with a Box engine instance, and could be used as a minor optimization some time later. In order to preserve the existing behavior, we map all scripts up to Latin to Common. Change-Id: Ide4182a0f8447b4bf25713ecc3fe8097b8fed040 Reviewed-by: Pierre Rossi Reviewed-by: Konstantin Ritt --- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 14 ++++++-------- src/plugins/platforms/windows/qwindowsfontdatabase.h | 4 ++-- src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp | 10 +++++----- src/plugins/platforms/windows/qwindowsfontdatabase_ft.h | 4 ++-- src/plugins/platforms/windows/qwindowsfontengine.cpp | 3 +-- 5 files changed, 16 insertions(+), 19 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 76fe5f1a43..5a1b4f1522 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1132,9 +1132,7 @@ QWindowsFontDatabase::~QWindowsFontDatabase() removeApplicationFonts(); } -QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, - QUnicodeTables::Script script, - void *handle) +QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle) { QFontEngine *fe = QWindowsFontDatabase::createEngine(script, fontDef, 0, QWindowsContext::instance()->defaultDPI(), false, @@ -1187,7 +1185,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; request.hintingPreference = hintingPreference; - fontEngine = QWindowsFontDatabase::createEngine(QUnicodeTables::Common, request, 0, + fontEngine = QWindowsFontDatabase::createEngine(QChar::Script_Common, request, 0, QWindowsContext::instance()->defaultDPI(), false, QStringList(), m_fontEngineData); @@ -1300,7 +1298,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal return fontEngine; } -QStringList QWindowsFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const +QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const { QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script); if (!result.isEmpty()) @@ -1538,8 +1536,8 @@ HFONT QWindowsFontDatabase::systemFont() static inline bool scriptRequiresOpenType(int script) { - return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala) - || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko); + return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala) + || script == QChar::Script_Khmer || script == QChar::Script_Nko); } static const char *other_tryFonts[] = { @@ -1850,7 +1848,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ directWriteFont->Release(); #endif - if(script == QUnicodeTables::Common + if (script == QChar::Script_Common && !(request.styleStrategy & QFont::NoFontMerging)) { QFontDatabase db; if (!db.writingSystems(request.family).contains(QFontDatabase::Symbol)) { diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h index 94327f723d..3325daf4cf 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h @@ -78,9 +78,9 @@ public: ~QWindowsFontDatabase(); virtual void populateFontDatabase(); - virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); + virtual QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle); virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); - virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; + virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); virtual void releaseHandle(void *handle); virtual QString fontDir() const; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 4c3d412b8e..d30c1f984d 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -362,7 +362,7 @@ void QWindowsFontDatabaseFT::populate(const QString &family) ReleaseDC(0, dummy); } -QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle) +QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle) { QFontEngine *fe = QBasicFontDatabase::fontEngine(fontDef, script, handle); if (QWindowsContext::verboseFonts) @@ -430,9 +430,9 @@ static const char *kr_tryFonts[] = { static const char **tryFonts = 0; -QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const +QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const { - if(script == QUnicodeTables::Common) { + if (script == QChar::Script_Common) { // && !(request.styleStrategy & QFont::NoFontMerging)) { QFontDatabase db; if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) { @@ -518,8 +518,8 @@ HFONT QWindowsFontDatabaseFT::systemFont() static inline bool scriptRequiresOpenType(int script) { - return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala) - || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko); + return ((script >= QChar::Script_Syriac && script <= QChar::Script_Sinhala) + || script == QChar::Script_Khmer || script == QChar::Script_Nko); } static inline int verticalDPI() diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h index f48b87a251..17820335ec 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h @@ -52,10 +52,10 @@ class QWindowsFontDatabaseFT : public QBasicFontDatabase { public: void populateFontDatabase(); - QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); + QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle); QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); - QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; + QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; virtual QString fontDir() const; virtual QFont defaultFont() const; diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index e51d6d4e7e..6937e6bce3 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -66,7 +66,6 @@ #include #include -#include #include #include @@ -1269,7 +1268,7 @@ QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const request.styleStrategy |= QFont::NoFontMerging; QFontEngine *fontEngine = - QWindowsFontDatabase::createEngine(QUnicodeTables::Common, request, 0, + QWindowsFontDatabase::createEngine(QChar::Script_Common, request, 0, QWindowsContext::instance()->defaultDPI(), false, QStringList(), m_fontEngineData); -- cgit v1.2.3 From cc378774b86d732a1758260eca690637e99c1ac2 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 16 Nov 2012 11:39:26 +0200 Subject: Move ForceIntegerMetrics testing out of the loop Change-Id: I5732999dee63568eb83e5186cf5bf8c63709724e Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index add36c78cf..f7ba0d237d 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -371,10 +371,12 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn if (SUCCEEDED(hr)) { for (int i=0; inumGlyphs; ++i) { glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth); - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - glyphs->advances_x[i] = glyphs->advances_x[i].round(); glyphs->advances_y[i] = 0; } + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + for (int i = 0; i < glyphs->numGlyphs; ++i) + glyphs->advances_x[i] = glyphs->advances_x[i].round(); + } } else { qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__); } -- cgit v1.2.3 From 6ecc3e76e822b1545bcbfa78f5caf94156a026d2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 10 Dec 2012 12:00:53 +0100 Subject: Add API dealing with QMargins to QRect. - Addition of a QMargin to a QRect. - Removal of a QMargin from a QRect. - Remove implementation from Windows platform plugin. Change-Id: Iae54bc13e94a7ece48853b1d3f3de2bfc154d2dd Reviewed-by: Oliver Wolff Reviewed-by: Mitch Curtis --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 +- src/plugins/platforms/windows/qwindowswindow.h | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 3831c6b10e..97aeadacd3 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1118,7 +1118,7 @@ QRect QWindowsWindow::frameGeometry_sys() const QRect QWindowsWindow::geometry_sys() const { - return frameGeometry_sys() - frameMargins(); + return frameGeometry_sys().marginsRemoved(frameMargins()); } /*! diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 978d1d5a53..7af1e2f718 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -283,17 +283,6 @@ private: HICON m_iconBig; }; -// Conveniences for window frames. -inline QRect operator+(const QRect &r, const QMargins &m) -{ - return r.adjusted(-m.left(), -m.top(), m.right(), m.bottom()); -} - -inline QRect operator-(const QRect &r, const QMargins &m) -{ - return r.adjusted(m.left(), m.top(), -m.right(), -m.bottom()); -} - // Debug QDebug operator<<(QDebug d, const RECT &r); #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO/WM_NCCALCSIZE -- cgit v1.2.3 From f5fd53460387411a3ed192595562fc2cfd92a2b6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 17 Dec 2012 09:41:36 +0100 Subject: Fix frame of Aero-Style wizards. Add custom frames which are added to the system frame to the platform plugin. Make them settable when creating a platform window using dynamic properties and per window properties of the platform native interface. Use this in favor of the native event handling changing the frame in wizard_win.cpp since that caused the frame/backing store sizes of the QWindow to be wrong. Task-number: QTBUG-28099 Change-Id: Idd6416cf1b0eb629f56663088b0ce17162e1739d Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowscontext.cpp | 9 +- .../platforms/windows/qwindowsintegration.cpp | 42 ++++++++++ src/plugins/platforms/windows/qwindowswindow.cpp | 98 ++++++++++++++++++---- src/plugins/platforms/windows/qwindowswindow.h | 9 ++ 4 files changed, 135 insertions(+), 23 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 28269e8653..40aa446a66 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -783,7 +783,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return true; case QtWindows::CalculateSize: - return false; + return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->customMargins, msg, result); default: break; } @@ -818,12 +818,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, platformWindow->getSizeHints(reinterpret_cast(lParam)); return true;// maybe available on some SDKs revisit WM_NCCALCSIZE case QtWindows::CalculateSize: - // NCCALCSIZE_PARAMS structure if wParam==TRUE - if (wParam && QWindowsContext::verboseWindows) { - const NCCALCSIZE_PARAMS *ncp = reinterpret_cast(lParam); - qDebug() << platformWindow->window() << *ncp; - } - break; + return QWindowsGeometryHint::handleCalculateSize(platformWindow->customMargins(), msg, result); #endif case QtWindows::ExposeEvent: return platformWindow->handleWmPaint(hwnd, message, wParam, lParam); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index f5ad442e68..30d399f556 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -75,6 +75,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -109,6 +110,11 @@ public: void *eventProc) const; bool asyncExpose() const; void setAsyncExpose(bool value); + + QVariantMap windowProperties(QPlatformWindow *window) const; + QVariant windowProperty(QPlatformWindow *window, const QString &name) const; + QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const; + void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); }; void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window) @@ -145,6 +151,37 @@ void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &r return 0; } +static const char customMarginPropertyC[] = "WindowsCustomMargins"; + +QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const +{ + QWindowsWindow *platformWindow = static_cast(window); + if (name == QLatin1String(customMarginPropertyC)) + return qVariantFromValue(platformWindow->customMargins()); + return QVariant(); +} + +QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const +{ + const QVariant result = windowProperty(window, name); + return result.isValid() ? result : defaultValue; +} + +void QWindowsNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) +{ + QWindowsWindow *platformWindow = static_cast(window); + if (name == QLatin1String(customMarginPropertyC)) + platformWindow->setCustomMargins(qvariant_cast(value)); +} + +QVariantMap QWindowsNativeInterface::windowProperties(QPlatformWindow *window) const +{ + QVariantMap result; + const QString customMarginProperty = QLatin1String(customMarginPropertyC); + result.insert(customMarginProperty, windowProperty(window, customMarginProperty)); + return result; +} + #ifndef QT_NO_OPENGL void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { @@ -356,6 +393,11 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons QWindowsWindow::WindowData requested; requested.flags = window->flags(); requested.geometry = window->geometry(); + // Apply custom margins (see QWindowsWindow::setCustomMargins())). + const QVariant customMarginsV = window->property("_q_windowsCustomMargins"); + if (customMarginsV.isValid()) + requested.customMargins = qvariant_cast(customMarginsV); + const QWindowsWindow::WindowData obtained = QWindowsWindow::WindowData::create(window, requested, window->title()); if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 97aeadacd3..50fd7a0792 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -274,7 +274,7 @@ struct WindowCreationData tool(false), embedded(false) {} void fromWindow(const QWindow *w, const Qt::WindowFlags flags, unsigned creationFlags = 0); - inline WindowData create(const QWindow *w, const QRect &geometry, QString title) const; + inline WindowData create(const QWindow *w, const WindowData &data, QString title) const; inline void applyWindowFlags(HWND hwnd) const; void initialize(HWND h, bool frameChange, qreal opacityLevel) const; @@ -416,7 +416,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag } QWindowsWindow::WindowData - WindowCreationData::create(const QWindow *w, const QRect &geometry, QString title) const + WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const { typedef QSharedPointer QWindowCreationContextPtr; @@ -442,24 +442,25 @@ QWindowsWindow::WindowData const wchar_t *titleUtf16 = reinterpret_cast(title.utf16()); const wchar_t *classNameUtf16 = reinterpret_cast(windowClassName.utf16()); - // Capture events before CreateWindowEx() returns. - const QWindowCreationContextPtr context(new QWindowCreationContext(w, geometry, style, exStyle)); + // Capture events before CreateWindowEx() returns. The context is cleared in + // the QWindowsWindow constructor. + const QWindowCreationContextPtr context(new QWindowCreationContext(w, data.geometry, data.customMargins, style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); if (QWindowsContext::verboseWindows) qDebug().nospace() << "CreateWindowEx: " << w << *this << " class=" <frameWidth << 'x' << context->frameHeight - << '+' << context->frameX << '+' << context->frameY; + << '+' << context->frameX << '+' << context->frameY + << " custom margins: " << context->customMargins; result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16, style, context->frameX, context->frameY, context->frameWidth, context->frameHeight, parentHandle, NULL, appinst, NULL); - QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr()); if (QWindowsContext::verboseWindows) qDebug().nospace() << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: " @@ -473,6 +474,7 @@ QWindowsWindow::WindowData result.geometry = context->obtainedGeometry; result.frame = context->margins; result.embedded = embedded; + result.customMargins = context->customMargins; return result; } @@ -511,6 +513,8 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe 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, swpFlags); + } else if (frameChange) { // Force WM_NCCALCSIZE with wParam=1 in case of custom margins. + SetWindowPos(hwnd, 0, 0, 0, 0, 0, swpFlags); } if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) { HMENU systemMenu = GetSystemMenu(hwnd, FALSE); @@ -571,6 +575,33 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle) return result; } +bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result) +{ +#ifndef Q_OS_WINCE + // NCCALCSIZE_PARAMS structure if wParam==TRUE + if (!msg.wParam || customMargins.isNull()) + return false; + *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); + NCCALCSIZE_PARAMS *ncp = reinterpret_cast(msg.lParam); + const RECT oldClientArea = ncp->rgrc[0]; + ncp->rgrc[0].left += customMargins.left(); + ncp->rgrc[0].top += customMargins.top(); + ncp->rgrc[0].right -= customMargins.right(); + ncp->rgrc[0].bottom -= customMargins.bottom(); + result = 0; + if (QWindowsContext::verboseWindows) + qDebug() << __FUNCTION__ << oldClientArea << '+' << customMargins << "-->" + << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2] + << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy; + return true; +#else + Q_UNUSED(customMargins) + Q_UNUSED(msg) + Q_UNUSED(result) + return false; +#endif +} + #ifndef Q_OS_WINCE void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const { @@ -637,10 +668,11 @@ bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w) QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QRect &geometry, + const QMargins &cm, DWORD style_, DWORD exStyle_) : geometryHint(w), style(style_), exStyle(exStyle_), requestedGeometry(geometry), obtainedGeometry(geometry), - margins(QWindowsGeometryHint::frame(style, exStyle)), + margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm), frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT), frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT) { @@ -651,14 +683,16 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, if (geometry.isValid()) { frameX = geometry.x(); frameY = geometry.y(); - frameWidth = margins.left() + geometry.width() + margins.right(); - frameHeight = margins.top() + geometry.height() + margins.bottom(); + const QMargins effectiveMargins = margins + customMargins; + frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right(); + frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom(); const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel(); if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) { - frameX -= margins.left(); - frameY -= margins.top(); + frameX -= effectiveMargins.left(); + frameY -= effectiveMargins.top(); } } + if (QWindowsContext::verboseWindows) qDebug().nospace() << __FUNCTION__ << ' ' << w << geometry @@ -666,7 +700,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, << " frame: " << frameWidth << 'x' << frameHeight << '+' << frameX << '+' << frameY << " min" << geometryHint.minimumSize - << " max" << geometryHint.maximumSize; + << " max" << geometryHint.maximumSize + << " custom margins " << customMargins; } /*! @@ -713,6 +748,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : { if (aWindow->surfaceType() == QWindow::OpenGLSurface) setFlag(OpenGLSurface); + // Clear the creation context as the window can be found in QWindowsContext's map. + QWindowsContext::instance()->setWindowCreationContext(QSharedPointer()); QWindowsContext::instance()->addWindow(m_data.hwnd, this); if (aWindow->isTopLevel()) { switch (aWindow->type()) { @@ -826,8 +863,9 @@ QWindowsWindow::WindowData { WindowCreationData creationData; creationData.fromWindow(w, parameters.flags); - WindowData result = creationData.create(w, parameters.geometry, title); - creationData.initialize(result.hwnd, false, 1); + WindowData result = creationData.create(w, parameters, title); + // Force WM_NCCALCSIZE (with wParam=1) via SWP_FRAMECHANGED for custom margin. + creationData.initialize(result.hwnd, !parameters.customMargins.isNull(), 1); return result; } @@ -1452,7 +1490,7 @@ QMargins QWindowsWindow::frameMargins() const m_data.frame = QWindowsGeometryHint::frame(style(), exStyle()); clearFlag(FrameDirty); } - return m_data.frame; + return m_data.frame + m_data.customMargins; } void QWindowsWindow::setOpacity(qreal level) @@ -1808,4 +1846,32 @@ void QWindowsWindow::setWindowIcon(const QIcon &icon) } } +/*! + \brief Sets custom margins to be added to the default margins determined by + the windows style in the handling of the WM_NCCALCSIZE message. + + This is currently used to give the Aero-style QWizard a smaller top margin. + The property can be set using QPlatformNativeInterface::setWindowProperty() or, + before platform window creation, by setting a dynamic property + on the QWindow (see QWindowsIntegration::createPlatformWindow()). +*/ + +void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) +{ + if (newCustomMargins != m_data.customMargins) { + const QMargins oldCustomMargins = m_data.customMargins; + m_data.customMargins = newCustomMargins; + // Re-trigger WM_NCALCSIZE with wParam=1 by passing SWP_FRAMECHANGED + const QRect currentFrameGeometry = frameGeometry_sys(); + const QPoint topLeft = currentFrameGeometry.topLeft(); + QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins; + newFrame.moveTo(topLeft); + setFlag(FrameDirty); + if (QWindowsContext::verboseWindows) + qDebug() << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins + << currentFrameGeometry << "->" << newFrame; + SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 7af1e2f718..4e82938cf4 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -69,6 +69,7 @@ struct QWindowsGeometryHint QWindowsGeometryHint() {} explicit QWindowsGeometryHint(const QWindow *w); static QMargins frame(DWORD style, DWORD exStyle); + static bool handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result); #ifndef Q_OS_WINCE //MinMax maybe define struct if not available void applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const; void applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const; @@ -89,6 +90,7 @@ struct QWindowsGeometryHint struct QWindowCreationContext { QWindowCreationContext(const QWindow *w, const QRect &r, + const QMargins &customMargins, DWORD style, DWORD exStyle); #ifndef Q_OS_WINCE //MinMax maybe define struct if not available void applyToMinMaxInfo(MINMAXINFO *mmi) const @@ -101,6 +103,7 @@ struct QWindowCreationContext QRect requestedGeometry; QRect obtainedGeometry; QMargins margins; + QMargins customMargins; // User-defined, additional frame for WM_NCCALCSIZE int frameX; // Passed on to CreateWindowEx(), including frame. int frameY; int frameWidth; @@ -137,6 +140,7 @@ public: Qt::WindowFlags flags; QRect geometry; QMargins frame; // Do not use directly for windows, see FrameDirty. + QMargins customMargins; // User-defined, additional frame for NCCALCSIZE HWND hwnd; bool embedded; @@ -190,6 +194,9 @@ public: void setFrameStrutEventsEnabled(bool enabled); bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); } + QMargins customMargins() const { return m_data.customMargins; } + void setCustomMargins(const QMargins &m); + #ifdef QT_OPENGL_ES_2 EGLSurface eglSurfaceHandle() const { return m_eglSurface;} EGLSurface ensureEglSurfaceHandle(const QWindowsEGLStaticContextPtr &staticContext, EGLConfig config); @@ -353,4 +360,6 @@ inline void QWindowsWindow::destroyIcon() QT_END_NAMESPACE +Q_DECLARE_METATYPE(QMargins) + #endif // QWINDOWSWINDOW_H -- cgit v1.2.3 From 8927084d0acfea2bb3fc8a932069c1d5ceb001d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 10 Jan 2013 15:09:32 +0100 Subject: Refactor paint/font-engine shouldDrawCachedGlyphs and supportsTransformations Some cruft had built up over time, and this is an attempt at cleaning up the naming and use of these functions, and should not have any behavioral effects. The function supportsTransformations() has been renamed in QPaintEngineEx to reflect its use, which is to decide if QPainter needs to pre-transform the coordinates of the static text before asking the paint-engine to draw it. The new name is requiresPretransformedGlyphPositions(). The OpenGL and CoreGraphics (Mac) paint engines keep their behavior of not needing pre-transformed text, while the raster engine needs this when using cached glyphs. The base-class implementation assumes that all transforms that include a projection will need pre-transform, which is also the case for the raster engine. All decisions in the paint engines about whether or not to use the glyph cache when drawing text are now deferred to the function shouldDrawCachedGlyphs(), which has been refactored for the GL paint engine(s) to share more logic. All implementations call the base class implementation, which ensures that large font sizes will not be cached. The raster engine will in addition ask the font engine whether or not it can produce glyphs for the glyph-cache with the given transform. This is the only remaining instance of the supportsTransformations() function, and will for all font engines except the CoreText engine support affine transformations. The CoreText engine on the other hand only supports translations (for now). Change-Id: I8fb5e43e3de3ef62a526a79a6dfeda7f9546771d Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/cocoa/qpaintengine_mac_p.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac_p.h b/src/plugins/platforms/cocoa/qpaintengine_mac_p.h index 120ceae5c6..ef9878a98a 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qpaintengine_mac_p.h @@ -122,8 +122,6 @@ public: void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { QPaintEngine::drawPolygon(points, pointCount, mode); } - bool supportsTransformations(qreal, const QTransform &) const { return true; }; - protected: friend class QMacPrintEngine; friend class QMacPrintEnginePrivate; -- cgit v1.2.3 From 9fa5191b6eca7fc96b4720d9b892b0e2a8ff1469 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 4 Jan 2013 14:55:36 +0100 Subject: QPA, Cocoa: Add platform popup menus Also, allow to set menu-wide font (instead of per menu item), and minimum width. Change-Id: I5f83f260602f55b9409ad69abf670afb59b2d33a Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/cocoa/qcocoamenu.h | 6 ++++- src/plugins/platforms/cocoa/qcocoamenu.mm | 37 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 3afe089225..7407916cfc 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -71,11 +71,15 @@ public: void syncMenuItem(QPlatformMenuItem *menuItem); void setEnabled(bool enabled); void setVisible(bool visible); + void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item); + void syncSeparatorsCollapsible(bool enable); void syncModalState(bool modal); - virtual void setText(const QString &text); + void setText(const QString &text); + void setMinimumWidth(int width); + void setFont(const QFont &font); void setParentItem(QCocoaMenuItem* item); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 676f0683fa..afd007b36a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -47,6 +47,7 @@ #include #include "qcocoaapplication.h" #include "qcocoamenuloader.h" +#include "qcocoawindow.h" static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader() { @@ -133,6 +134,20 @@ void QCocoaMenu::setText(const QString &text) [m_nativeItem setTitle:QCFString::toNSString(stripped)]; } +void QCocoaMenu::setMinimumWidth(int width) +{ + m_nativeMenu.minimumWidth = width; +} + +void QCocoaMenu::setFont(const QFont &font) +{ + if (font.resolve()) { + NSFont *customMenuFont = [NSFont fontWithName:QCFString::toNSString(font.family()) + size:font.pointSize()]; + m_nativeMenu.font = customMenuFont; + } +} + void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) { QCocoaAutoReleasePool pool; @@ -290,6 +305,28 @@ void QCocoaMenu::setVisible(bool visible) [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)]; } +void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) +{ + QCocoaWindow *cocoaWindow = static_cast(parentWindow->handle()); + NSView *view = cocoaWindow->contentView(); + NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil; + NSPoint nsPos = NSMakePoint(pos.x(), pos.y()); + [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:view]; + + // The call above blocks and swallows the mouse release event, so we send a + // synthetic one to bring back any QQuickMouseArea back to a more normal state. + NSEvent *releaseEvent = [NSEvent mouseEventWithType:NSLeftMouseUp + location:nsPos + modifierFlags:0 + timestamp:0 + windowNumber:view.window.windowNumber + context:[NSGraphicsContext currentContext] + eventNumber:0 + clickCount:0 + pressure:1.0]; + [view.window sendEvent:releaseEvent]; +} + QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const { return m_menuItems.at(position); -- cgit v1.2.3 From 08bc730b4199bad839543fe17a5464cf8d547ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Mill=C3=A1n=20Soto?= Date: Mon, 24 Sep 2012 11:42:33 +0200 Subject: Implement QAccessibleActionInterface in QAccessibleTableCell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented QAccessibleActionInterface in QAccessibleTableCell to allow selecting and unselecting table cells, as there was no way of selecting or deselecting a simple cell using accessible tools. tst_qaccessibility.cpp was modified to test the new methods. Change-Id: I7bdfe0b363a9813d4a7c62e96b6c924b163f2121 Reviewed-by: Jan Arve Sæther Reviewed-by: Frederik Gladhorn --- src/plugins/accessible/widgets/itemviews.cpp | 85 ++++++++++++++++++++++++++++ src/plugins/accessible/widgets/itemviews.h | 10 +++- 2 files changed, 94 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 7130979935..92ba03753a 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -700,6 +700,8 @@ void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::TableCellInterface) return static_cast(this); + if (t == QAccessible::ActionInterface) + return static_cast(this); return 0; } @@ -773,6 +775,89 @@ bool QAccessibleTableCell::isSelected() const return view->selectionModel()->isSelected(m_index); } +QStringList QAccessibleTableCell::actionNames() const +{ + QStringList names; + names << toggleAction(); + return names; +} + +void QAccessibleTableCell::doAction(const QString& actionName) +{ + if (actionName == toggleAction()) { + if (isSelected()) + unselectCell(); + else + selectCell(); + } +} + +QStringList QAccessibleTableCell::keyBindingsForAction(const QString& actionName) const +{ + return QStringList(); +} + + +void QAccessibleTableCell::selectCell() +{ + QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); + if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection)) + return; + + QSharedPointer cellTable(table()->tableInterface()); + + switch (view->selectionBehavior()) { + case QAbstractItemView::SelectItems: + break; + case QAbstractItemView::SelectColumns: + if (cellTable.data()) + cellTable->selectColumn(m_index.column()); + return; + case QAbstractItemView::SelectRows: + if (cellTable.data()) + cellTable->selectRow(m_index.row()); + return; + } + + if (selectionMode == QAbstractItemView::SingleSelection) { + view->clearSelection(); + } + + view->selectionModel()->select(m_index, QItemSelectionModel::Select); +} + +void QAccessibleTableCell::unselectCell() +{ + + QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); + if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection)) + return; + + QSharedPointer cellTable(table()->tableInterface()); + + switch (view->selectionBehavior()) { + case QAbstractItemView::SelectItems: + break; + case QAbstractItemView::SelectColumns: + if (cellTable.data()) + cellTable->unselectColumn(m_index.column()); + return; + case QAbstractItemView::SelectRows: + if (cellTable.data()) + cellTable->unselectRow(m_index.row()); + return; + } + + //If the mode is not MultiSelection or ExtendedSelection and only + //one cell is selected it cannot be unselected by the user + if ((selectionMode != QAbstractItemView::MultiSelection) + && (selectionMode != QAbstractItemView::ExtendedSelection) + && (view->selectionModel()->selectedIndexes().count() <= 1)) + return; + + view->selectionModel()->select(m_index, QItemSelectionModel::Deselect); +} + void QAccessibleTableCell::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const { *row = m_index.row(); diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index 5ae13a8035..99c995dba8 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -159,7 +159,7 @@ private: QModelIndex indexFromLogical(int row, int column = 0) const; }; -class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface +class QAccessibleTableCell: public QAccessibleInterface, public QAccessibleTableCellInterface, public QAccessibleActionInterface { public: QAccessibleTableCell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); @@ -192,6 +192,11 @@ public: virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const; virtual QAccessibleInterface* table() const; + //action interface + virtual QStringList actionNames() const; + virtual void doAction(const QString &actionName); + virtual QStringList keyBindingsForAction(const QString &actionName) const; + private: QHeaderView *verticalHeader() const; QHeaderView *horizontalHeader() const; @@ -199,6 +204,9 @@ private: QModelIndex m_index; QAccessible::Role m_role; + void selectCell(); + void unselectCell(); + friend class QAccessibleTable; friend class QAccessibleTree; }; -- cgit v1.2.3 From 18c916517f3004d34482c20ed66bf09ec274d385 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 2 Jan 2013 16:50:06 +0100 Subject: Use backslashes for UNC paths. ShellExecute fails to open a share folder due to using '/' instead of '\'. Windows API doesn't support forward slashes for extended-length path. Extended-length path are path that start with a "\\?\" prefix. For example, "\\?\c:\very_long_path\foo\bar.txt", or in the case of a UNC path that would be "\\?\very_long_path\foo\bar.txt". [1] [1] http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maxpath Task-number: QTBUG-13359 Change-Id: Ibb113abeebd56f106f76520bc23dba797de548fa Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsservices.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index 3121d5c869..cd446efc62 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #ifndef Q_OS_WINCE @@ -57,7 +58,8 @@ enum { debug = 0 }; static inline bool shellExecute(const QString &file) { #ifndef Q_OS_WINCE - const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)file.utf16(), 0, 0, SW_SHOWNORMAL); + const QString nativeFilePath = QDir::toNativeSeparators(file); + const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)nativeFilePath.utf16(), 0, 0, SW_SHOWNORMAL); // ShellExecute returns a value greater than 32 if successful if (result <= 32) { qWarning("ShellExecute '%s' failed (error %s).", qPrintable(file), qPrintable(QString::number(result))); -- cgit v1.2.3 From 5d2bb24cc90194a3458f8741e30ae7afe0b45f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Boya=20Garc=C3=ADa?= Date: Tue, 15 Jan 2013 05:58:49 +0100 Subject: Fixed dead keys on MS Windows Since Qt4, there is a bug which causes Qt to drop dead key modifiers (like graves and acutes) if the user types enough fast on MS Windows. This happens because of an extrange behavior of Windows, which drops dead keys on ToUnicode() calls. This patch tries to workaround that. Task-number: QTBUG-8764 Task-number: QTBUG-10032 Change-Id: Ifdde25817743194fd5c0b7533c27f46a7a108ca4 Reviewed-by: Friedemann.Kleint@digia.com Reviewed-by: oliver.wolff@digia.com Reviewed-by: marc.mutz@kdab.com Reviewed-by: bjoern.breitmeyer@kdab.com Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowskeymapper.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 5a11aee802..f64593badc 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -856,9 +856,15 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms if (isNumpad && (nModifiers & AltAny)) { code = winceKeyBend(msg.wParam); } else if (!isDeadKey) { - unsigned char kbdBuffer[256]; // Will hold the complete keyboard state - GetKeyboardState(kbdBuffer); - code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer); + // QTBUG-8764, QTBUG-10032 + // Can't call toKeyOrUnicode because that would call ToUnicode, and, if a dead key + // is pressed at the moment, Windows would NOT use it to compose a character for the next + // WM_CHAR event. + + // Instead, use MapVirtualKey, which will provide adequate values. + code = MapVirtualKey(msg.wParam, MAPVK_VK_TO_CHAR); + if (code < 0x20 || code == 0x7f) // The same logic as in toKeyOrUnicode() + code = winceKeyBend(msg.wParam); } // Invert state logic: -- cgit v1.2.3 From d29aabbca9c98eb66d9cde6058ad96929c816c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 25 Oct 2012 16:53:18 +0200 Subject: eglfs: Introduce way of filtering out unwanted EGL configs. Some times a platform might want to exclude certain configs, for example based on EGL_NATIVE_VISUAL_ID. This patch introduces a new QEglConfigChooser class which has a virtual filterConfig() function which can be re-implemented in a sub-class to give finer control of how configs are chosen. Change-Id: I8b684f01be95a47307b1e429857f01337a9a38d8 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Gunnar Sletta --- src/plugins/platforms/eglfs/qeglfscontext.cpp | 3 ++- src/plugins/platforms/eglfs/qeglfshooks.h | 1 + src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 5 ++++ src/plugins/platforms/eglfs/qeglfsintegration.cpp | 28 ++++++++++++++++++++++- src/plugins/platforms/eglfs/qeglfsintegration.h | 2 ++ src/plugins/platforms/eglfs/qeglfswindow.cpp | 3 ++- 6 files changed, 39 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 3646494bf3..32158c9e5f 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -43,6 +43,7 @@ #include "qeglfswindow.h" #include "qeglfscursor.h" #include "qeglfshooks.h" +#include "qeglfsintegration.h" #include @@ -50,7 +51,7 @@ QT_BEGIN_NAMESPACE QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLenum eglApi) - : QEGLPlatformContext(hooks->surfaceFormatFor(format), share, display, eglApi) + : QEGLPlatformContext(format, share, display, QEglFSIntegration::chooseConfig(display, format), eglApi) { } diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index 317b92e67f..2339611c96 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -67,6 +67,7 @@ public: virtual void destroyNativeWindow(EGLNativeWindowType window); virtual bool hasCapability(QPlatformIntegration::Capability cap) const; virtual QEglFSCursor *createCursor(QEglFSScreen *screen) const; + virtual bool filterConfig(EGLDisplay display, EGLConfig config) const; }; #ifdef EGLFS_PLATFORM_HOOKS diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index 7106b99490..f0219e40b2 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -134,6 +134,11 @@ QSurfaceFormat QEglFSHooks::surfaceFormatFor(const QSurfaceFormat &inputFormat) return inputFormat; } +bool QEglFSHooks::filterConfig(EGLDisplay, EGLConfig) const +{ + return true; +} + EGLNativeWindowType QEglFSHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format) { Q_UNUSED(size); diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index cf45818ed4..b0c55b51c1 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #if !defined(QT_NO_EVDEV) @@ -150,7 +151,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - return new QEglFSContext(context->format(), 0 /*share*/, mDisplay); + return new QEglFSContext(hooks->surfaceFormatFor(context->format()), 0 /*share*/, mDisplay); } QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const @@ -201,4 +202,29 @@ void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QO return 0; } +EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) +{ + class Chooser : public QEglConfigChooser { + public: + Chooser(EGLDisplay display, QEglFSHooks *hooks) + : QEglConfigChooser(display) + , m_hooks(hooks) + { + } + + protected: + bool filterConfig(EGLConfig config) const + { + return m_hooks->filterConfig(display(), config) && QEglConfigChooser::filterConfig(config); + } + + private: + QEglFSHooks *m_hooks; + }; + + Chooser chooser(display, hooks); + chooser.setSurfaceFormat(format); + return chooser.chooseConfig(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 63f37d9a8d..1dd41b33f5 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -75,6 +75,8 @@ public: void *nativeResourceForIntegration(const QByteArray &resource); void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); + static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); + private: EGLDisplay mDisplay; QAbstractEventDispatcher *mEventDispatcher; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index df665cea84..9fad0af623 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -84,7 +84,8 @@ void QEglFSWindow::create() EGLDisplay display = (static_cast(window()->screen()->handle()))->display(); QSurfaceFormat platformFormat = hooks->surfaceFormatFor(window()->requestedFormat()); - EGLConfig config = q_configFromGLFormat(display, platformFormat); + EGLConfig config = QEglFSIntegration::chooseConfig(display, platformFormat); + m_format = q_glFormatFromConfig(display, config); m_window = hooks->createNativeWindow(hooks->screenSize(), m_format); m_surface = eglCreateWindowSurface(display, config, m_window, NULL); -- cgit v1.2.3 From 6f225b0b5d774828df310948435f1cc3a4720104 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Jan 2013 12:15:00 +0100 Subject: Fix MinGW-warnings about comparing signed/unsigned. Change-Id: I970264e5b096a3d6384b59d0ae0876bb80fd0009 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp | 2 +- src/plugins/platforms/windows/qwindowsdrag.cpp | 6 +++--- src/plugins/platforms/windows/qwindowskeymapper.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 44a79d86ee..e4ad962fd1 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -270,7 +270,7 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W { if (static_cast(lParam) == static_cast(UiaRootObjectId)) { /* For UI Automation */ - } else if ((DWORD)lParam == OBJID_CLIENT) { + } else if ((DWORD)lParam == DWORD(OBJID_CLIENT)) { #if 1 // Ignoring all requests while starting up // ### Maybe QPA takes care of this??? diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 805046c715..2da3c9cb18 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -304,10 +304,10 @@ private: class DragCursorHandle { Q_DISABLE_COPY(DragCursorHandle) public: - DragCursorHandle(HCURSOR c, quint64 k) : cursor(c), cacheKey(k) {} + DragCursorHandle(HCURSOR c, qint64 k) : cursor(c), cacheKey(k) {} ~DragCursorHandle() { DestroyCursor(cursor); } HCURSOR cursor; - quint64 cacheKey; + qint64 cacheKey; }; typedef QMap > ActionCursorMap; @@ -490,7 +490,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action); QSharedPointer cursorHandler = m_cursors.value(action); - quint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey(); + qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey(); if (cursorHandler.isNull() || currentCacheKey != cursorHandler->cacheKey) createCursors(); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index f64593badc..737d83a637 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -1126,7 +1126,7 @@ QList QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const } result << int(baseKey + keyMods); // The base key is _always_ valid, of course - for (int i = 1; i < NumMods; ++i) { + for (size_t i = 1; i < NumMods; ++i) { Qt::KeyboardModifiers neededMods = ModsTbl[i]; quint32 key = kbItem.qtKey[i]; if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) -- cgit v1.2.3 From 92237b22ea80b043bfd441ecad89cd504965b50f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 11 Jan 2013 17:34:49 +0100 Subject: Cocoa: Make QCocoaMenu::showPopup() more robust Change-Id: Ie4ae5806ea2f23f16597578796be36f2123c05fa Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qcocoamenu.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index afd007b36a..ff3aeaeb11 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -307,8 +307,8 @@ void QCocoaMenu::setVisible(bool visible) void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) { - QCocoaWindow *cocoaWindow = static_cast(parentWindow->handle()); - NSView *view = cocoaWindow->contentView(); + QCocoaWindow *cocoaWindow = parentWindow ? static_cast(parentWindow->handle()) : 0; + NSView *view = cocoaWindow ? cocoaWindow->contentView() : nil; NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil; NSPoint nsPos = NSMakePoint(pos.x(), pos.y()); [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:view]; -- cgit v1.2.3 From 661c3701f4731283a3f1062e4a8c8c02fb01e3c6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 16 Jan 2013 16:44:25 +0100 Subject: Fix Windows native file dialogs for use with QtQuick. - Correct modality check. - Allow for properties to be set if there is no native dialog. - Make dialog thread for non-modal call back into dialog helper for exec(). - Introduce QWindowsFileDialogSharedData to contain data to be cached while no native dialog exists and to be updated by the change notifications of the IFileDialogEvent interface to avoid querying the dialog results after the dialog has closed. Reduce virtual methods of QWindowsNativeFileDialogBase accordingly. This also fixes a bug in the previous implementation causing the directory not to reported back since the native API would not return the directory after closing the dialog. - Support nonmodal native dialogs when constructed on a QQuickWindow. - Delete native dialogs after exec as QtQuick keeps the dialog instances around. Change-Id: Id1169d6657d9476afe12fb9909c36cbd03aa2a40 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann Reviewed-by: Shawn Rutledge --- .../platforms/windows/qwindowsdialoghelpers.cpp | 415 +++++++++++++-------- .../platforms/windows/qwindowsdialoghelpers.h | 6 +- 2 files changed, 254 insertions(+), 167 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 9e5578d35d..16acf439a0 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -58,6 +58,10 @@ #include #include #include +#include +#include +#include +#include #include #include "qtwindows_additional.h" @@ -387,6 +391,9 @@ void eatMouseMove() Vista on) that mimick the behaviour of their QDialog counterparts as close as possible. + Instances of derived classes are controlled by + QWindowsDialogHelperBase-derived classes. + A major difference is that there is only an exec(), which is a modal, blocking call; there is no non-blocking show(). There 2 types of native dialogs: @@ -401,6 +408,7 @@ void eatMouseMove() like close() can be called on them from event handlers. \endlist + \sa QWindowsDialogHelperBase \internal \ingroup qt-lighthouse-win */ @@ -411,7 +419,6 @@ class QWindowsNativeDialogBase : public QObject public: virtual void setWindowTitle(const QString &title) = 0; virtual void exec(HWND owner = 0) = 0; - virtual QPlatformDialogHelper::DialogCode result() const = 0; signals: void accepted(); @@ -432,12 +439,10 @@ protected: The native dialog is created in setVisible_sys() since then modality and the state of DontUseNativeDialog is known. - Modal dialogs are then started via the platformNativeDialogModalHelp(), - platformNativeDialogModalHelp() slots. - Non-modal dialogs are shown using a separate thread should - they support it. + Modal dialogs are then run by exec(). Non-modal dialogs are shown using a + separate thread started in show() should they support it. - \sa QWindowsDialogThread + \sa QWindowsDialogThread, QWindowsNativeDialogBase \internal \ingroup qt-lighthouse-win */ @@ -449,12 +454,6 @@ QWindowsDialogHelperBase::QWindowsDialogHelperBase() : { } -template -QWindowsDialogHelperBase::~QWindowsDialogHelperBase() -{ - delete m_nativeDialog; -} - template QWindowsNativeDialogBase *QWindowsDialogHelperBase::nativeDialog() const { @@ -465,6 +464,13 @@ QWindowsNativeDialogBase *QWindowsDialogHelperBase::nativeDialog() co return m_nativeDialog; } +template +void QWindowsDialogHelperBase::deleteNativeDialog() +{ + delete m_nativeDialog; + m_nativeDialog = 0; +} + template QWindowsNativeDialogBase *QWindowsDialogHelperBase::ensureNativeDialog() { @@ -486,22 +492,18 @@ QWindowsNativeDialogBase *QWindowsDialogHelperBase::ensureNativeDialo class QWindowsDialogThread : public QThread { public: - QWindowsDialogThread(QWindowsNativeDialogBase *dialog, - HWND owner = 0) : - m_dialog(dialog), m_owner(owner) {} - + QWindowsDialogThread(QPlatformDialogHelper *h) : m_helper(h) {} void run(); private: - QWindowsNativeDialogBase *m_dialog; - const HWND m_owner; + QPlatformDialogHelper *m_helper; }; void QWindowsDialogThread::run() { if (QWindowsContext::verboseDialogs) qDebug(">%s" , __FUNCTION__); - m_dialog->exec(m_owner); + m_helper->exec(); deleteLater(); if (QWindowsContext::verboseDialogs) qDebug("<%s" , __FUNCTION__); @@ -512,7 +514,7 @@ bool QWindowsDialogHelperBase::show(Qt::WindowFlags, Qt::WindowModality windowModality, QWindow *parent) { - const bool modal = (windowModality == Qt::ApplicationModal); + const bool modal = (windowModality != Qt::NonModal); if (parent) { m_ownerWindow = QWindowsWindow::handleOf(parent); } else { @@ -521,12 +523,12 @@ bool QWindowsDialogHelperBase::show(Qt::WindowFlags, if (QWindowsContext::verboseDialogs) qDebug("%s modal=%d native=%p parent=%p" , __FUNCTION__, modal, m_nativeDialog, m_ownerWindow); - if (!modal && !supportsNonModalDialog()) + if (!modal && !supportsNonModalDialog(parent)) return false; // Was it changed in-between? if (!ensureNativeDialog()) return false; if (!modal) { // Modal dialogs are shown in separate slot. - QWindowsDialogThread *thread = new QWindowsDialogThread(m_nativeDialog, m_ownerWindow); + QWindowsDialogThread *thread = new QWindowsDialogThread(this); thread->start(); } return true; @@ -545,8 +547,10 @@ void QWindowsDialogHelperBase::exec() { if (QWindowsContext::verboseDialogs) qDebug("%s" , __FUNCTION__); - if (QWindowsNativeDialogBase *nd = nativeDialog()) + if (QWindowsNativeDialogBase *nd = nativeDialog()) { nd->exec(m_ownerWindow); + deleteNativeDialog(); + } } static inline bool snapToDefaultButtonHint() @@ -567,6 +571,101 @@ QVariant QWindowsDialogHelperBase::styleHint(QPlatformDialogHelper::S return BaseClass::styleHint(hint); } +/*! + \class QWindowsFileDialogSharedData + \brief Explicitly shared file dialog parameters that are not in QFileDialogOptions. + + Contain Parameters that need to be cached while the native dialog does not + exist yet. In addition, the data are updated by the change notifications of the + IFileDialogEvent, as querying them after the dialog has closed + does not reliably work. Provides thread-safe setters (for the non-modal case). + + \internal + \ingroup qt-lighthouse-win + \sa QFileDialogOptions +*/ + +class QWindowsFileDialogSharedData +{ +public: + QWindowsFileDialogSharedData() : m_data(new Data) {} + void fromOptions(const QSharedPointer &o); + + QString directory() const; + void setDirectory(const QString &); + QString selectedNameFilter() const; + void setSelectedNameFilter(const QString &); + QStringList selectedFiles() const; + void setSelectedFiles(const QStringList &); + QString selectedFile() const; + +private: + class Data : public QSharedData { + public: + QString directory; + QString selectedNameFilter; + QStringList selectedFiles; + QMutex mutex; + }; + QExplicitlySharedDataPointer m_data; +}; + +inline QString QWindowsFileDialogSharedData::directory() const +{ + m_data->mutex.lock(); + const QString result = m_data->directory; + m_data->mutex.unlock(); + return result; +} + +inline void QWindowsFileDialogSharedData::setDirectory(const QString &d) +{ + QMutexLocker (&m_data->mutex); + m_data->directory = d; +} + +inline QString QWindowsFileDialogSharedData::selectedNameFilter() const +{ + m_data->mutex.lock(); + const QString result = m_data->selectedNameFilter; + m_data->mutex.unlock(); + return result; +} + +inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f) +{ + QMutexLocker (&m_data->mutex); + m_data->selectedNameFilter = f; +} + +inline QStringList QWindowsFileDialogSharedData::selectedFiles() const +{ + m_data->mutex.lock(); + const QStringList result = m_data->selectedFiles; + m_data->mutex.unlock(); + return result; +} + +inline QString QWindowsFileDialogSharedData::selectedFile() const +{ + const QStringList files = selectedFiles(); + return files.isEmpty() ? QString() : files.front(); +} + +inline void QWindowsFileDialogSharedData::setSelectedFiles(const QStringList &f) +{ + QMutexLocker (&m_data->mutex); + m_data->selectedFiles = f; +} + +inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer &o) +{ + QMutexLocker (&m_data->mutex); + m_data->directory = o->initialDirectory(); + m_data->selectedFiles = o->initiallySelectedFiles(); + m_data->selectedNameFilter = o->initiallySelectedNameFilter(); +} + /*! \class QWindowsNativeFileDialogEventHandler \brief Listens to IFileDialog events and forwards them to QWindowsNativeFileDialogBase @@ -609,7 +708,7 @@ public: } // IFileDialogEvents methods - IFACEMETHODIMP OnFileOk(IFileDialog *) { return S_OK; } + IFACEMETHODIMP OnFileOk(IFileDialog *); IFACEMETHODIMP OnFolderChange(IFileDialog *) { return S_OK; } IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *); IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; } @@ -658,29 +757,33 @@ class QWindowsNativeFileDialogBase : public QWindowsNativeDialogBase public: ~QWindowsNativeFileDialogBase(); - inline static QWindowsNativeFileDialogBase *create(QFileDialogOptions::AcceptMode am); + inline static QWindowsNativeFileDialogBase *create(QFileDialogOptions::AcceptMode am, const QWindowsFileDialogSharedData &data); virtual void setWindowTitle(const QString &title); inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::FileDialogOptions options); inline void setDirectory(const QString &directory); + inline void updateDirectory() { setDirectory(m_data.directory()); } inline QString directory() const; virtual void exec(HWND owner = 0); inline void setNameFilters(const QStringList &f); inline void selectNameFilter(const QString &filter); + inline void updateSelectedNameFilter() { selectNameFilter(m_data.selectedNameFilter()); } inline QString selectedNameFilter() const; bool hideFiltersDetails() const { return m_hideFiltersDetails; } void setHideFiltersDetails(bool h) { m_hideFiltersDetails = h; } void setDefaultSuffix(const QString &s); inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text); - virtual QPlatformDialogHelper::DialogCode result() const - { return fileResult(); } - virtual QPlatformDialogHelper::DialogCode fileResult(QStringList *fileResult = 0) const = 0; + // Return the selected files for tracking in OnSelectionChanged(). virtual QStringList selectedFiles() const = 0; + // Return the result for tracking in OnFileOk(). Differs from selection for + // example by appended default suffixes, etc. + virtual QStringList dialogResult() const = 0; inline void onFolderChange(IShellItem *); inline void onSelectionChange(); inline void onTypeChange(); + inline bool onFileOk(); signals: void directoryEntered(const QString& directory); @@ -691,23 +794,28 @@ public slots: virtual void close() { m_fileDialog->Close(S_OK); } protected: - QWindowsNativeFileDialogBase(); + explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data); bool init(const CLSID &clsId, const IID &iid); inline IFileDialog * fileDialog() const { return m_fileDialog; } static QString itemPath(IShellItem *item); static int itemPaths(IShellItemArray *items, QStringList *fileResult = 0); static IShellItem *shellItem(const QString &path); + const QWindowsFileDialogSharedData &data() const { return m_data; } + QWindowsFileDialogSharedData &data() { return m_data; } + private: IFileDialog *m_fileDialog; IFileDialogEvents *m_dialogEvents; DWORD m_cookie; QStringList m_nameFilters; bool m_hideFiltersDetails; + QWindowsFileDialogSharedData m_data; }; -QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase() : - m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false) +QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) : + m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false), + m_data(data) { } @@ -763,15 +871,17 @@ IShellItem *QWindowsNativeFileDialogBase::shellItem(const QString &path) return result; } #endif - qErrnoWarning("%s: SHCreateItemFromParsingName()) failed", __FUNCTION__); + qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(path)); return 0; } void QWindowsNativeFileDialogBase::setDirectory(const QString &directory) { - if (IShellItem *psi = QWindowsNativeFileDialogBase::shellItem(directory)) { - m_fileDialog->SetFolder(psi); - psi->Release(); + if (!directory.isEmpty()) { + if (IShellItem *psi = QWindowsNativeFileDialogBase::shellItem(directory)) { + m_fileDialog->SetFolder(psi); + psi->Release(); + } } } @@ -977,14 +1087,16 @@ static int indexOfNameFilter(const QStringList &filters, const QString &needle) void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter) { + if (filter.isEmpty()) + return; const int index = indexOfNameFilter(m_nameFilters, filter); - if (index >= 0) { - m_fileDialog->SetFileTypeIndex(index + 1); // one-based. - } else { + if (index < 0) { qWarning("%s: Invalid parameter '%s' not found in '%s'.", __FUNCTION__, qPrintable(filter), qPrintable(m_nameFilters.join(QStringLiteral(", ")))); + return; } + m_fileDialog->SetFileTypeIndex(index + 1); // one-based. } QString QWindowsNativeFileDialogBase::selectedNameFilter() const @@ -1002,6 +1114,7 @@ void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item) { if (item) { const QString directory = QWindowsNativeFileDialogBase::itemPath(item); + m_data.setDirectory(directory); emit directoryEntered(directory); } } @@ -1009,13 +1122,23 @@ void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item) void QWindowsNativeFileDialogBase::onSelectionChange() { const QStringList current = selectedFiles(); + m_data.setSelectedFiles(current); if (current.size() == 1) emit currentChanged(current.front()); } void QWindowsNativeFileDialogBase::onTypeChange() { - emit filterSelected(selectedNameFilter()); + const QString filter = selectedNameFilter(); + m_data.setSelectedNameFilter(filter); + emit filterSelected(filter); +} + +bool QWindowsNativeFileDialogBase::onFileOk() +{ + // Store selected files as GetResults() returns invalid data after the dialog closes. + m_data.setSelectedFiles(dialogResult()); + return true; } HRESULT QWindowsNativeFileDialogEventHandler::OnFolderChanging(IFileDialog *, IShellItem *item) @@ -1036,6 +1159,11 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnTypeChange(IFileDialog *) return S_OK; } +HRESULT QWindowsNativeFileDialogEventHandler::OnFileOk(IFileDialog *) +{ + return m_nativeFileDialog->onFileOk() ? S_OK : S_FALSE; +} + /*! \class QWindowsNativeSaveFileDialog \brief Windows native file save dialog wrapper around IFileSaveDialog. @@ -1049,8 +1177,10 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnTypeChange(IFileDialog *) class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase { public: - virtual QPlatformDialogHelper::DialogCode fileResult(QStringList *fileResult = 0) const; + explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data) : + QWindowsNativeFileDialogBase(data) {} virtual QStringList selectedFiles() const; + virtual QStringList dialogResult() const; }; // Append a suffix from the name filter "Foo files (*.foo;*.bar)" @@ -1073,17 +1203,13 @@ static inline QString appendSuffix(const QString &fileName, const QString &filte return fileName + QLatin1Char('.') + filter.mid(suffixPos, endPos - suffixPos); } -QPlatformDialogHelper::DialogCode QWindowsNativeSaveFileDialog::fileResult(QStringList *result /* = 0 */) const +QStringList QWindowsNativeSaveFileDialog::dialogResult() const { - if (result) - result->clear(); + QStringList result; IShellItem *item = 0; - const HRESULT hr = fileDialog()->GetResult(&item); - if (FAILED(hr) || !item) - return QPlatformDialogHelper::Rejected; - if (result) - result->push_back(appendSuffix(QWindowsNativeFileDialogBase::itemPath(item), selectedNameFilter())); - return QPlatformDialogHelper::Accepted; + if (SUCCEEDED(fileDialog()->GetResult(&item)) && item) + result.push_back(appendSuffix(QWindowsNativeFileDialogBase::itemPath(item), selectedNameFilter())); + return result; } QStringList QWindowsNativeSaveFileDialog::selectedFiles() const @@ -1109,23 +1235,23 @@ QStringList QWindowsNativeSaveFileDialog::selectedFiles() const class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase { public: - virtual QPlatformDialogHelper::DialogCode fileResult(QStringList *fileResult = 0) const; + explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) : + QWindowsNativeFileDialogBase(data) {} virtual QStringList selectedFiles() const; + virtual QStringList dialogResult() const; private: inline IFileOpenDialog *openFileDialog() const { return static_cast(fileDialog()); } }; -QPlatformDialogHelper::DialogCode QWindowsNativeOpenFileDialog::fileResult(QStringList *result /* = 0 */) const +QStringList QWindowsNativeOpenFileDialog::dialogResult() const { - if (result) - result->clear(); + QStringList result; IShellItemArray *items = 0; - const HRESULT hr = openFileDialog()->GetResults(&items); - if (SUCCEEDED(hr) && items && QWindowsNativeFileDialogBase::itemPaths(items, result) > 0) - return QPlatformDialogHelper::Accepted; - return QPlatformDialogHelper::Rejected; + if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items) + QWindowsNativeFileDialogBase::itemPaths(items, &result); + return result; } QStringList QWindowsNativeOpenFileDialog::selectedFiles() const @@ -1144,17 +1270,18 @@ QStringList QWindowsNativeOpenFileDialog::selectedFiles() const QFileDialog::AcceptMode. */ -QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialogOptions::AcceptMode am) +QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialogOptions::AcceptMode am, + const QWindowsFileDialogSharedData &data) { QWindowsNativeFileDialogBase *result = 0; if (am == QFileDialogOptions::AcceptOpen) { - result = new QWindowsNativeOpenFileDialog; + result = new QWindowsNativeOpenFileDialog(data); if (!result->init(CLSID_FileOpenDialog, IID_IFileOpenDialog)) { delete result; return 0; } } else { - result = new QWindowsNativeSaveFileDialog; + result = new QWindowsNativeSaveFileDialog(data); if (!result->init(CLSID_FileSaveDialog, IID_IFileSaveDialog)) { delete result; return 0; @@ -1163,16 +1290,17 @@ QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialogOp return result; } +static inline bool isQQuickWindow(const QWindow *w = 0) +{ + return w && w->inherits("QQuickWindow"); +} + /*! \class QWindowsFileDialogHelper \brief Helper for native Windows file dialogs - Non-modal dialogs are disabled for now. The functionality is - implemented in principle, however there are failures - when querying the results from a dialog run in another thread. - This could probably be fixed be calling CoInitializeEx() with - the right parameters from each thread. The problem is though - that calls to CoInitialize() occur in several places in Qt. + For Qt 4 compatibility, do not create native non-modal dialogs on widgets, + but only on QQuickWindows, which do not have a fallback. \internal \ingroup qt-lighthouse-win @@ -1182,8 +1310,9 @@ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase(nativeDialog()); } + + // Cache for the case no native dialog is created. + QWindowsFileDialogSharedData m_data; }; QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog() { - QWindowsNativeFileDialogBase *result = QWindowsNativeFileDialogBase::create(options()->acceptMode()); + QWindowsNativeFileDialogBase *result = QWindowsNativeFileDialogBase::create(options()->acceptMode(), m_data); if (!result) return 0; QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept())); @@ -1217,6 +1349,7 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog() // Apply settings. const QSharedPointer &opts = options(); + m_data.fromOptions(opts); result->setWindowTitle(opts->windowTitle()); result->setMode(opts->fileMode(), opts->options()); result->setHideFiltersDetails(opts->testOption(QFileDialogOptions::HideNameFilterDetails)); @@ -1227,12 +1360,8 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog() result->setLabelText(QFileDialogOptions::FileName, opts->labelText(QFileDialogOptions::FileName)); if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) result->setLabelText(QFileDialogOptions::Accept, opts->labelText(QFileDialogOptions::Accept)); - const QString initialDirectory = opts->initialDirectory(); - if (!initialDirectory.isEmpty()) - result->setDirectory(initialDirectory); - const QString initialNameFilter = opts->initiallySelectedNameFilter(); - if (!initialNameFilter.isEmpty()) - result->selectNameFilter(initialNameFilter); + result->updateDirectory(); + result->updateSelectedNameFilter(); const QString defaultSuffix = opts->defaultSuffix(); if (!defaultSuffix.isEmpty()) result->setDefaultSuffix(defaultSuffix); @@ -1244,15 +1373,14 @@ void QWindowsFileDialogHelper::setDirectory(const QString &directory) if (QWindowsContext::verboseDialogs) qDebug("%s %s" , __FUNCTION__, qPrintable(directory)); - if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog()) - nfd->setDirectory(directory); + m_data.setDirectory(directory); + if (hasNativeDialog()) + nativeFileDialog()->updateDirectory(); } QString QWindowsFileDialogHelper::directory() const { - if (const QWindowsNativeFileDialogBase *nfd = nativeFileDialog()) - return nfd->directory(); - return QString(); + return m_data.directory(); } void QWindowsFileDialogHelper::selectFile(const QString & /* filename */) @@ -1262,13 +1390,7 @@ void QWindowsFileDialogHelper::selectFile(const QString & /* filename */) QStringList QWindowsFileDialogHelper::selectedFiles() const { - QStringList files; - if (const QWindowsNativeFileDialogBase *nfd = nativeFileDialog()) - nfd->fileResult(&files); - if (QWindowsContext::verboseDialogs) - qDebug("%s files='%s'" , __FUNCTION__, - qPrintable(files.join(QStringLiteral(", ")))); - return files; + return m_data.selectedFiles(); } void QWindowsFileDialogHelper::setFilter() @@ -1287,15 +1409,14 @@ void QWindowsFileDialogHelper::setNameFilters(const QStringList &filters) void QWindowsFileDialogHelper::selectNameFilter(const QString &filter) { - if (QWindowsNativeFileDialogBase *nfd = nativeFileDialog()) - nfd->selectNameFilter(filter); + m_data.setSelectedNameFilter(filter); + if (hasNativeDialog()) + nativeFileDialog()->updateSelectedNameFilter(); } QString QWindowsFileDialogHelper::selectedNameFilter() const { - if (const QWindowsNativeFileDialogBase *nfd = nativeFileDialog()) - return nfd->selectedNameFilter(); - return QString(); + return m_data.selectedNameFilter(); } #ifndef Q_OS_WINCE @@ -1319,20 +1440,12 @@ class QWindowsXpNativeFileDialog : public QWindowsNativeDialogBase public: typedef QSharedPointer OptionsPtr; - static QWindowsXpNativeFileDialog *create(const OptionsPtr &options); + static QWindowsXpNativeFileDialog *create(const OptionsPtr &options, const QWindowsFileDialogSharedData &data); virtual void setWindowTitle(const QString &t) { m_title = t; } virtual void exec(HWND owner = 0); virtual QPlatformDialogHelper::DialogCode result() const { return m_result; } - void setDirectory(const QString &d) { m_directory = d; } - QString directory() const { return m_directory; } - void selectFile(const QString &f) { m_initialFile = f; } - QStringList selectedFiles() const { return m_selectedFiles; } - void setNameFilters(const QStringList &n) { m_nameFilters = n; } - void selectNameFilter(const QString &f); - QString selectedNameFilter() const { return m_selectedNameFilter; } - int existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam); public slots: @@ -1342,19 +1455,15 @@ private: typedef BOOL (APIENTRY *PtrGetOpenFileNameW)(LPOPENFILENAMEW); typedef BOOL (APIENTRY *PtrGetSaveFileNameW)(LPOPENFILENAMEW); - explicit QWindowsXpNativeFileDialog(const OptionsPtr &options); + explicit QWindowsXpNativeFileDialog(const OptionsPtr &options, const QWindowsFileDialogSharedData &data); void populateOpenFileName(OPENFILENAME *ofn, HWND owner) const; QStringList execExistingDir(HWND owner); QStringList execFileNames(HWND owner, int *selectedFilterIndex) const; const OptionsPtr m_options; QString m_title; - QString m_directory; - QString m_initialFile; - QStringList m_selectedFiles; - QString m_selectedNameFilter; - QStringList m_nameFilters; QPlatformDialogHelper::DialogCode m_result; + QWindowsFileDialogSharedData m_data; static PtrGetOpenFileNameW m_getOpenFileNameW; static PtrGetSaveFileNameW m_getSaveFileNameW; @@ -1363,7 +1472,7 @@ private: QWindowsXpNativeFileDialog::PtrGetOpenFileNameW QWindowsXpNativeFileDialog::m_getOpenFileNameW = 0; QWindowsXpNativeFileDialog::PtrGetSaveFileNameW QWindowsXpNativeFileDialog::m_getSaveFileNameW = 0; -QWindowsXpNativeFileDialog *QWindowsXpNativeFileDialog::create(const OptionsPtr &options) +QWindowsXpNativeFileDialog *QWindowsXpNativeFileDialog::create(const OptionsPtr &options, const QWindowsFileDialogSharedData &data) { // GetOpenFileNameW() GetSaveFileName() are resolved // dynamically as not to create a dependency on Comdlg32, which @@ -1374,51 +1483,33 @@ QWindowsXpNativeFileDialog *QWindowsXpNativeFileDialog::create(const OptionsPtr m_getSaveFileNameW = (PtrGetSaveFileNameW)(library.resolve("GetSaveFileNameW")); } if (m_getOpenFileNameW && m_getSaveFileNameW) - return new QWindowsXpNativeFileDialog(options); + return new QWindowsXpNativeFileDialog(options, data); return 0; } -QWindowsXpNativeFileDialog::QWindowsXpNativeFileDialog(const OptionsPtr &options) : - m_options(options), m_result(QPlatformDialogHelper::Rejected) +QWindowsXpNativeFileDialog::QWindowsXpNativeFileDialog(const OptionsPtr &options, + const QWindowsFileDialogSharedData &data) : + m_options(options), m_result(QPlatformDialogHelper::Rejected), m_data(data) { - const QStringList nameFilters = m_options->nameFilters(); - if (!nameFilters.isEmpty()) - setNameFilters(nameFilters); - const QString initialDirectory = m_options->initialDirectory(); - if (!initialDirectory.isEmpty()) - setDirectory(initialDirectory); - const QString initialNameFilter = m_options->initiallySelectedNameFilter(); - if (!initialNameFilter.isEmpty()) - selectNameFilter(initialNameFilter); - const QStringList selectedFiles = m_options->initiallySelectedFiles(); - if (!selectedFiles.isEmpty()) - selectFile(selectedFiles.front()); setWindowTitle(m_options->windowTitle()); } -void QWindowsXpNativeFileDialog::selectNameFilter(const QString &f) -{ - const int index = indexOfNameFilter(m_nameFilters, f); - if (index >= 0) - m_selectedNameFilter = m_nameFilters.at(index); -} - void QWindowsXpNativeFileDialog::exec(HWND owner) { int selectedFilterIndex = -1; - m_selectedFiles = m_options->fileMode() == QFileDialogOptions::DirectoryOnly ? + const QStringList selectedFiles = + m_options->fileMode() == QFileDialogOptions::DirectoryOnly ? execExistingDir(owner) : execFileNames(owner, &selectedFilterIndex); + m_data.setSelectedFiles(selectedFiles); QWindowsDialogs::eatMouseMove(); - if (m_selectedFiles.isEmpty()) { + if (selectedFiles.isEmpty()) { m_result = QPlatformDialogHelper::Rejected; emit rejected(); } else { - if (selectedFilterIndex >= 0 && selectedFilterIndex < m_nameFilters.size()) { - m_selectedNameFilter = m_nameFilters.at(selectedFilterIndex); - } else { - m_selectedNameFilter.clear(); - } - m_directory = QFileInfo(m_selectedFiles.front()).absolutePath(); + const QStringList nameFilters = m_options->nameFilters(); + if (selectedFilterIndex >= 0 && selectedFilterIndex < nameFilters.size()) + m_data.setSelectedNameFilter(nameFilters.at(selectedFilterIndex)); + m_data.setDirectory(QFileInfo(selectedFiles.front()).absolutePath()); m_result = QPlatformDialogHelper::Accepted; emit accepted(); } @@ -1442,9 +1533,11 @@ typedef PIDLIST_ABSOLUTE qt_LpItemIdList; int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam) { switch (uMsg) { - case BFFM_INITIALIZED: - if (!m_initialFile.isEmpty()) - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(m_initialFile.utf16())); + case BFFM_INITIALIZED: { + const QString initialFile = m_data.selectedFile(); + if (!initialFile.isEmpty()) + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initialFile.utf16())); + } break; case BFFM_SELCHANGED: { wchar_t path[MAX_PATH]; @@ -1516,7 +1609,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow *ptr++ = 0; } *ptr = 0; - const int nameFilterIndex = indexOfNameFilter(m_nameFilters, m_selectedNameFilter); + const int nameFilterIndex = indexOfNameFilter(m_options->nameFilters(), m_data.selectedNameFilter()); if (nameFilterIndex >= 0) ofn->nFilterIndex = nameFilterIndex + 1; // 1..n based. // lpstrFile receives the initial selection and is the buffer @@ -1524,10 +1617,10 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow // will not show. ofn->nMaxFile = 65535; const QString initiallySelectedFile = - QDir::toNativeSeparators(m_initialFile).remove(QLatin1Char('<')). + QDir::toNativeSeparators(m_data.selectedFile()).remove(QLatin1Char('<')). remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|')); ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile); - ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_directory)); + ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_data.directory())); ofn->lpstrTitle = (wchar_t*)m_title.utf16(); // Determine lpstrDefExt. Note that the current MSDN docs document this // member wrong. It should rather be documented as "the default extension @@ -1596,8 +1689,7 @@ class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase(nativeDialog()); } + + QWindowsFileDialogSharedData m_data; }; QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog() { - if (QWindowsNativeDialogBase *result = QWindowsXpNativeFileDialog::create(options())) { + m_data.fromOptions(options()); + if (QWindowsXpNativeFileDialog *result = QWindowsXpNativeFileDialog::create(options(), m_data)) { QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept())); QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject())); return result; @@ -1627,47 +1722,37 @@ QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog() void QWindowsXpFileDialogHelper::setDirectory(const QString &directory) { - if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - nfd->setDirectory(directory); + m_data.setDirectory(directory); // Dialog cannot be updated at run-time. } QString QWindowsXpFileDialogHelper::directory() const { - if (const QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - return nfd->directory(); - return QString(); + return m_data.directory(); } void QWindowsXpFileDialogHelper::selectFile(const QString &filename) { - if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - nfd->selectFile(filename); + m_data.setSelectedFiles(QStringList(filename)); // Dialog cannot be updated at run-time. } QStringList QWindowsXpFileDialogHelper::selectedFiles() const { - if (const QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - return nfd->selectedFiles(); - return QStringList(); + return m_data.selectedFiles(); } -void QWindowsXpFileDialogHelper::setNameFilters(const QStringList &n) +void QWindowsXpFileDialogHelper::setNameFilters(const QStringList &) { - if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - nfd->setNameFilters(n); + // Dialog cannot be updated at run-time. } void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f) { - if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - nfd->selectNameFilter(f); + m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time. } QString QWindowsXpFileDialogHelper::selectedNameFilter() const { - if (const QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) - return nfd->selectedNameFilter(); - return QString(); + return m_data.selectedNameFilter(); } #endif // Q_OS_WINCE diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index c656f72d6e..9ec93f1b4c 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -65,6 +65,7 @@ template class QWindowsDialogHelperBase : public BaseClass { public: + ~QWindowsDialogHelperBase() { deleteNativeDialog(); } virtual void exec(); virtual bool show(Qt::WindowFlags windowFlags, @@ -73,12 +74,13 @@ public: virtual void hide(); virtual QVariant styleHint(QPlatformDialogHelper::StyleHint) const; - virtual bool supportsNonModalDialog() const { return true; } + virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; } protected: QWindowsDialogHelperBase(); - ~QWindowsDialogHelperBase(); QWindowsNativeDialogBase *nativeDialog() const; + inline bool hasNativeDialog() const { return m_nativeDialog; } + void deleteNativeDialog(); private: virtual QWindowsNativeDialogBase *createNativeDialog() = 0; -- cgit v1.2.3 From 1029049e1d8aa84f19fe344e605849c36522a97f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Jan 2013 12:16:39 +0100 Subject: Fix MinGW-warning about pointer/integer of different sizes (64bit). Change-Id: I26945bbcd0994e478332ea1250ad7d0bbaa8420f Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowsfontengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 6937e6bce3..b0d68eb2af 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -1226,13 +1226,13 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra { HFONT font = hfont; - int contrast; + UINT contrast; SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0); SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0); int margin = glyphMargin(QFontEngineGlyphCache::Raster_RGBMask); QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32); - SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0); + SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) quintptr(contrast), 0); if (mask == 0) return QImage(); -- cgit v1.2.3 From c24a7377dd9cfb503b43ef3f5a2d5cac9a4e1b8c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 14 Jan 2013 10:00:12 +0100 Subject: Regression: Fix setting of custom cursors for native widgets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, there is no concept of not having a cursor set on a Window. Qt::ArrowCursor is always set instead. This causes bugs when native child widgets are involved, for example setting a cursor on the native widget's parent no longer works since the child's Qt::ArrowCursor applies. Introduce QWindowPrivate::hasCursor tracking whether a cursor has been explicitly set and clear in QWindow::unsetCursor(). Handle 0 in QPlatformCursor::changeCursor() to mean "unsetCursor()": - Windows: Introduce default constructor for QWindowsWindowCursor meaning "0". Search for applicable parent cursor in applyCursor. - XCB: No big changes required, set XCB_CURSOR_NONE for no cursor. - Other platforms: Assume Qt::ArrowCursor when cursor = 0 is passed for now. Task-number: QTBUG-28879 Change-Id: Id82722592f3cd5fe577a5b64dcc600c85cfea484 Reviewed-by: Jonathan Liu Reviewed-by: Morten Johan Sørvig Reviewed-by: Samuel Rødal --- src/plugins/platforms/cocoa/qcocoacursor.mm | 7 ++--- src/plugins/platforms/directfb/qdirectfbcursor.cpp | 5 ++-- src/plugins/platforms/eglfs/qeglfscursor.cpp | 7 ++--- src/plugins/platforms/kms/qkmscursor.cpp | 5 ++-- src/plugins/platforms/windows/qwindowscursor.cpp | 20 ++++++++++++-- src/plugins/platforms/windows/qwindowscursor.h | 2 ++ src/plugins/platforms/windows/qwindowswindow.cpp | 31 ++++++++++++++++++---- src/plugins/platforms/xcb/qxcbcursor.cpp | 24 +++++++++-------- 8 files changed, 73 insertions(+), 28 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index a584e22e59..238a900c08 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -61,8 +61,9 @@ void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) { Q_UNUSED(window); + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; // Check for a suitable built-in NSCursor first: - switch (cursor->shape()) { + switch (newShape) { case Qt::ArrowCursor: [[NSCursor arrowCursor] set]; break; @@ -99,14 +100,14 @@ void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) default : { // No suitable OS cursor exist, use cursors provided // by Qt for the rest. Check for a cached cursor: - NSCursor *cocoaCursor = m_cursors.value(cursor->shape()); + NSCursor *cocoaCursor = m_cursors.value(newShape); if (cocoaCursor == 0) { cocoaCursor = createCursorData(cursor); if (cocoaCursor == 0) { [[NSCursor arrowCursor] set]; return; } - m_cursors.insert(cursor->shape(), cocoaCursor); + m_cursors.insert(newShape, cocoaCursor); } [cocoaCursor set]; diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp index b04848ec40..23f115e313 100644 --- a/src/plugins/platforms/directfb/qdirectfbcursor.cpp +++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp @@ -59,8 +59,9 @@ void QDirectFBCursor::changeCursor(QCursor *cursor, QWindow *) int ySpot; QPixmap map; - if (cursor->shape() != Qt::BitmapCursor) { - m_image->set(cursor->shape()); + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + if (newShape != Qt::BitmapCursor) { + m_image->set(newShape); xSpot = m_image->hotspot().x(); ySpot = m_image->hotspot().y(); QImage *i = m_image->image(); diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp index b29849226f..88da8d7f42 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp @@ -196,15 +196,16 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) bool QEglFSCursor::setCurrentCursor(QCursor *cursor) { - if (m_cursor.shape == cursor->shape() && cursor->shape() != Qt::BitmapCursor) + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor) return false; if (m_cursor.shape == Qt::BitmapCursor) { m_cursor.customCursorImage = QImage(); // in case render() never uploaded it } - m_cursor.shape = cursor->shape(); - if (cursor->shape() != Qt::BitmapCursor) { // standard cursor + m_cursor.shape = newShape; + if (newShape != Qt::BitmapCursor) { // standard cursor const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width, hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height; m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow), diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp index 9a86d6c7cb..5101b4c7e2 100644 --- a/src/plugins/platforms/kms/qkmscursor.cpp +++ b/src/plugins/platforms/kms/qkmscursor.cpp @@ -85,8 +85,9 @@ void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window) if (!m_moved) drmModeMoveCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0); - if (widgetCursor->shape() != Qt::BitmapCursor) { - m_cursorImage->set(widgetCursor->shape()); + const Qt::CursorShape newShape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor; + if (newShape != Qt::BitmapCursor) { + m_cursorImage->set(newShape); } else { m_cursorImage->set(widgetCursor->pixmap().toImage(), widgetCursor->hotSpot().x(), diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index ac4070a93b..84c82dca45 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -405,8 +405,12 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) if (QWindowsContext::verboseWindows > 1) qDebug() << __FUNCTION__ << cursorIn << window; - if (!cursorIn || !window) + if (!window) return; + if (!cursorIn) { + QWindowsWindow::baseWindowOf(window)->setCursor(QWindowsWindowCursor()); + return; + } const QWindowsWindowCursor wcursor = cursorIn->shape() == Qt::BitmapCursor ? QWindowsWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape()); @@ -448,6 +452,7 @@ void QWindowsCursor::setPos(const QPoint &pos) class QWindowsWindowCursorData : public QSharedData { public: + QWindowsWindowCursorData() : m_cursor(Qt::ArrowCursor), m_handle(0) {} explicit QWindowsWindowCursorData(const QCursor &c); ~QWindowsWindowCursorData(); @@ -463,7 +468,13 @@ QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) : QWindowsWindowCursorData::~QWindowsWindowCursorData() { - DestroyCursor(m_handle); + if (m_handle) + DestroyCursor(m_handle); +} + +QWindowsWindowCursor::QWindowsWindowCursor() : + m_data(new QWindowsWindowCursorData) +{ } QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) : @@ -487,6 +498,11 @@ QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCurs return *this; } +bool QWindowsWindowCursor::isNull() const +{ + return m_data->m_handle == 0; +} + QCursor QWindowsWindowCursor::cursor() const { return m_data->m_cursor; diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 2d415c04ce..b4026f00bc 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -55,11 +55,13 @@ class QWindowsWindowCursorData; class QWindowsWindowCursor { public: + QWindowsWindowCursor(); explicit QWindowsWindowCursor(const QCursor &c); ~QWindowsWindowCursor(); QWindowsWindowCursor(const QWindowsWindowCursor &c); QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c); + bool isNull() const; QCursor cursor() const; HCURSOR handle() const; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 23ebd6bd9e..21cd3f7d17 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -739,7 +739,6 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : m_hdc(0), m_windowState(Qt::WindowNoState), m_opacity(1.0), - m_cursor(QWindowsScreen::screenOf(aWindow)->windowsCursor()->standardWindowCursor()), m_dropTarget(0), m_savedStyle(0), m_format(aWindow->format()), @@ -1668,18 +1667,40 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const void QWindowsWindow::applyCursor() { - SetCursor(m_cursor.handle()); + if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor. + if (const QWindow *p = window()->parent()) + QWindowsWindow::baseWindowOf(p)->applyCursor(); + } else { + SetCursor(m_cursor.handle()); + } +} + +// Check whether to apply a new cursor. Either the window in question is +// currently under mouse, or it is the parent of the window under mouse and +// there is no other window with an explicitly set cursor in-between. +static inline bool applyNewCursor(const QWindow *w) +{ + const QWindow *underMouse = QWindowsContext::instance()->windowUnderMouse(); + if (underMouse == w) + return true; + for (const QWindow *p = underMouse; p ; p = p->parent()) { + if (p == w) + return true; + if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull()) + return false; + } + return false; } void QWindowsWindow::setCursor(const QWindowsWindowCursor &c) { if (c.handle() != m_cursor.handle()) { - const bool underMouse = QWindowsContext::instance()->windowUnderMouse() == window(); + const bool apply = applyNewCursor(window()); if (QWindowsContext::verboseWindows) qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape() - << " isWUM=" << underMouse; + << " doApply=" << apply; m_cursor = c; - if (underMouse) + if (apply) applyCursor(); } } diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index e2843d04dc..0704ab6205 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -301,17 +301,19 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) // No X11 cursor control when there is no widget under the cursor return; - xcb_cursor_t c; - if (cursor->shape() == Qt::BitmapCursor) { - qint64 id = cursor->pixmap().cacheKey(); - if (!m_bitmapCursorMap.contains(id)) - m_bitmapCursorMap.insert(id, createBitmapCursor(cursor)); - c = m_bitmapCursorMap.value(id); - } else { - int id = cursor->shape(); - if (!m_shapeCursorMap.contains(id)) - m_shapeCursorMap.insert(id, createFontCursor(cursor->shape())); - c = m_shapeCursorMap.value(id); + xcb_cursor_t c = XCB_CURSOR_NONE; + if (cursor) { + if (cursor->shape() == Qt::BitmapCursor) { + qint64 id = cursor->pixmap().cacheKey(); + if (!m_bitmapCursorMap.contains(id)) + m_bitmapCursorMap.insert(id, createBitmapCursor(cursor)); + c = m_bitmapCursorMap.value(id); + } else { + int id = cursor->shape(); + if (!m_shapeCursorMap.contains(id)) + m_shapeCursorMap.insert(id, createFontCursor(cursor->shape())); + c = m_shapeCursorMap.value(id); + } } w->setCursor(c); -- cgit v1.2.3 From 63faa00066dfdbcca4f7875d18038c3161c542e2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 21 Jan 2013 11:55:11 +0100 Subject: Windows: Introduce pixmap cursor cache. Cache custom cursors. Task-number: QTBUG-28879 Change-Id: I8f2b5b9149966399a6173dbd19f6a8e85898924b Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowscursor.cpp | 15 ++++++++++++++- src/plugins/platforms/windows/qwindowscursor.h | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 84c82dca45..31b49a516f 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -393,6 +393,19 @@ QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) return it.value(); } +/*! + \brief Return cached pixmap cursor or create new one. +*/ + +QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c) +{ + const qint64 cacheKey = c.pixmap().cacheKey(); + PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey); + if (it == m_pixmapCursorCache.end()) + it = m_pixmapCursorCache.insert(cacheKey, QWindowsWindowCursor(c)); + return it.value(); +} + /*! \brief Set a cursor on a window. @@ -413,7 +426,7 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) } const QWindowsWindowCursor wcursor = cursorIn->shape() == Qt::BitmapCursor ? - QWindowsWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape()); + pixmapWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape()); if (wcursor.handle()) { QWindowsWindow::baseWindowOf(window)->setCursor(wcursor); } else { diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index b4026f00bc..4ee6695188 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -83,11 +83,14 @@ public: static QPoint mousePosition(); QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor); + QWindowsWindowCursor pixmapWindowCursor(const QCursor &c); private: typedef QHash StandardCursorCache; + typedef QHash PixmapCursorCache; StandardCursorCache m_standardCursorCache; + PixmapCursorCache m_pixmapCursorCache; }; QT_END_NAMESPACE -- cgit v1.2.3 From 2692db542e5f567ddea078c167fb0baf878883ae Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 17 Jan 2013 18:59:53 +0100 Subject: Implement focus handling of child windows for cocoa. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1e05ef39aa67f8febdd27215d8ad05d26ece7caa Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.h | 2 ++ src/plugins/platforms/cocoa/qcocoawindow.mm | 7 +++++++ src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 17 +++++++++++++++++ 4 files changed, 27 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 228644c351..169de81129 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -114,6 +114,8 @@ public: bool setMouseGrabEnabled(bool grab); QMargins frameMargins() const; + void requestActivateWindow(); + WId winId() const; void setParent(const QPlatformWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b545844a24..3c7d6d6584 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -656,6 +656,13 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) setOpacity(opacity); } +void QCocoaWindow::requestActivateWindow() +{ + NSWindow *window = [m_contentView window]; + [ window makeFirstResponder : m_contentView ]; + [ window makeKeyWindow ]; +} + NSWindow * QCocoaWindow::createNSWindow() { QCocoaAutoReleasePool pool; diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 9cdfe6f5bb..c4ff79429f 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -82,6 +82,7 @@ QT_END_NAMESPACE - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; +- (BOOL)becomeFirstResponder; - (void)handleMouseEvent:(NSEvent *)theEvent; - (void)mouseDown:(NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 678f88baa0..d653bd9cee 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -330,8 +330,25 @@ static QTouchDevice *touchDevice = 0; return YES; } +- (BOOL)becomeFirstResponder +{ + QWindow *focusWindow = m_window; + + // For widgets we need to do a bit of trickery as the window + // to activate is the window of the top-level widget. + if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) { + while (focusWindow->parent()) { + focusWindow = focusWindow->parent(); + } + } + QWindowSystemInterface::handleWindowActivated(focusWindow); + return YES; +} + - (BOOL)acceptsFirstResponder { + if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip) + return NO; return YES; } -- cgit v1.2.3 From 14675681b5e88b178adbdef775ac6a4b1e573458 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 22 Jan 2013 14:59:29 +0100 Subject: Implement click-to-focus for native child windows. Change-Id: If7633781a7167de2161cd74c62cfc883eb4d1b0e Reviewed-by: Gunnar Sletta --- src/plugins/platforms/windows/qwindowsmousehandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 357def57c8..410ac7ca41 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -236,6 +237,9 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, platformWindow->setFlag(QWindowsWindow::AutoMouseCapture); if (QWindowsContext::verboseEvents) qDebug() << "Automatic mouse capture " << window; + // Implement "Click to focus" for native child windows. + if (!window->isTopLevel() && QGuiApplication::focusWindow() != window) + window->requestActivate(); } else if (platformWindow->hasMouseCapture() && platformWindow->testFlag(QWindowsWindow::AutoMouseCapture) && (msg.message == WM_LBUTTONUP || msg.message == WM_MBUTTONUP -- cgit v1.2.3 From 3c9cc32086bfaf9947324f8792ce40a6fc23ef00 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 22 Jan 2013 14:08:13 -0600 Subject: Support shared GL contexts in eglfs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows shared texture uploads in a background thread. Change-Id: Ib390243bc9dfabd6c579dff9b74e7f44211739d3 Reviewed-by: Samuel Rødal --- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index b0c55b51c1..7608012eb5 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -151,7 +151,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - return new QEglFSContext(hooks->surfaceFormatFor(context->format()), 0 /*share*/, mDisplay); + return new QEglFSContext(hooks->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay); } QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const -- cgit v1.2.3 From 896bf9ff5c142dd218ccca4f102ab5d267be7557 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 14 Jan 2013 17:25:10 +0100 Subject: Several bug fixes in QCocoaFileDialogHelper to support declarative MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Required to prevent crashes and incorrect behavior in https://codereview.qt-project.org/#change,44201 Change-Id: If6025429caabafd150cdd44fec152ff584232220 Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoafiledialoghelper.mm | 30 +++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 5747cc01e9..a159682ddb 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -216,7 +216,7 @@ static QString strippedText(QString s) - (void)closePanel { *mCurrentSelection = QT_PREPEND_NAMESPACE(QCFString::toQString)([[mSavePanel URL] path]); - if ([mSavePanel respondsToSelector:@selector(closePanel:)]) + if ([mSavePanel respondsToSelector:@selector(close)]) [mSavePanel close]; } @@ -228,6 +228,7 @@ static QString strippedText(QString s) bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; + [self updateProperties]; [mOpenPanel setAllowedFileTypes:nil]; [mOpenPanel setDirectoryURL:selectable ? [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath())] : [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.path())]]; @@ -271,6 +272,7 @@ static QString strippedText(QString s) bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; + [self updateProperties]; [mSavePanel setDirectoryURL:selectable ? [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath())] : [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.path())]]; NSWindow *nsparent = static_cast(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent)); @@ -401,6 +403,9 @@ static QString strippedText(QString s) [mSavePanel setCanCreateDirectories:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::ReadOnly)))]; [mOpenPanel setAllowsMultipleSelection:(fileMode == QT_PREPEND_NAMESPACE(QFileDialogOptions::ExistingFiles))]; [mOpenPanel setResolvesAliases:!(mOptions->testOption(QT_PREPEND_NAMESPACE(QFileDialogOptions::DontResolveSymlinks)))]; + [mOpenPanel setTitle:QCFString::toNSString(mOptions->windowTitle())]; + [mSavePanel setTitle:QCFString::toNSString(mOptions->windowTitle())]; + [mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead? QStringList ext = [self acceptableExtensionsForSave]; const QString defaultSuffix = mOptions->defaultSuffix(); @@ -569,13 +574,16 @@ extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding void QCocoaFileDialogHelper::setDirectory(const QString &directory) { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); - [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory)]]; + if (delegate) + [delegate->mSavePanel setDirectoryURL:[NSURL fileURLWithPath:QCFString::toNSString(directory)]]; } QString QCocoaFileDialogHelper::directory() const { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); - return QCFString::toQString([delegate->mSavePanel directory]); + if (delegate) + return QCFString::toQString([delegate->mSavePanel directory]); + return QString(); } void QCocoaFileDialogHelper::selectFile(const QString &filename) @@ -592,12 +600,16 @@ void QCocoaFileDialogHelper::selectFile(const QString &filename) QStringList QCocoaFileDialogHelper::selectedFiles() const { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); - return [delegate selectedFiles]; + if (delegate) + return [delegate selectedFiles]; + return QStringList(); } void QCocoaFileDialogHelper::setFilter() { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); + if (!delegate) + return; const SharedPointerFileDialogOptions &opts = options(); [delegate->mSavePanel setTitle:QCFString::toNSString(opts->windowTitle())]; if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) @@ -610,9 +622,13 @@ void QCocoaFileDialogHelper::setFilter() void QCocoaFileDialogHelper::selectNameFilter(const QString &filter) { + if (!options()) + return; const int index = options()->nameFilters().indexOf(filter); if (index != -1) { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); + if (!delegate) + return; [delegate->mPopUpButton selectItemAtIndex:index]; [delegate filterChanged:nil]; } @@ -621,7 +637,11 @@ void QCocoaFileDialogHelper::selectNameFilter(const QString &filter) QString QCocoaFileDialogHelper::selectedNameFilter() const { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); + if (!delegate) + return QString(); int index = [delegate->mPopUpButton indexOfSelectedItem]; + if (index >= options()->nameFilters().count()) + return QString(); return index != -1 ? options()->nameFilters().at(index) : QString(); } @@ -667,6 +687,8 @@ bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModalit { createNSOpenSavePanelDelegate(); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); + if (!delegate) + return false; if (windowModality == Qt::NonModal) [delegate showModelessPanel]; else if (windowModality == Qt::WindowModal && parent) -- cgit v1.2.3 From 06e4b1cff4c469d2fc3afbfe7a6b1954fedc90ff Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 26 Nov 2012 11:57:47 +0100 Subject: QImage plugins should report supported mime types Introduces the methods QImageReader::supportedMimeTypes and QImageWriter::supportedMimeTypes which corresponds to the similar supportedImageFormats methods, except they return lists of MIME types. Task-number: QTBUG-28177 Change-Id: Ibb0e264a12eaf972a8bfd6bd891dcd9f89efd085 Reviewed-by: Lars Knoll --- src/plugins/imageformats/gif/gif.json | 3 ++- src/plugins/imageformats/ico/ico.json | 3 ++- src/plugins/imageformats/jpeg/jpeg.json | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/imageformats/gif/gif.json b/src/plugins/imageformats/gif/gif.json index b599b40ffe..1d6cb126c4 100644 --- a/src/plugins/imageformats/gif/gif.json +++ b/src/plugins/imageformats/gif/gif.json @@ -1,3 +1,4 @@ { - "Keys": [ "gif" ] + "Keys": [ "gif" ], + "MimeTypes": [ "image/gif" ] } diff --git a/src/plugins/imageformats/ico/ico.json b/src/plugins/imageformats/ico/ico.json index d22cb739a1..bd46e07e54 100644 --- a/src/plugins/imageformats/ico/ico.json +++ b/src/plugins/imageformats/ico/ico.json @@ -1,3 +1,4 @@ { - "Keys": [ "ico" ] + "Keys": [ "ico" ], + "MimeTypes": [ "image/vnd.microsoft.icon" ] } diff --git a/src/plugins/imageformats/jpeg/jpeg.json b/src/plugins/imageformats/jpeg/jpeg.json index 132c642c05..5e26a97206 100644 --- a/src/plugins/imageformats/jpeg/jpeg.json +++ b/src/plugins/imageformats/jpeg/jpeg.json @@ -1,3 +1,4 @@ { - "Keys": [ "jpg", "jpeg" ] + "Keys": [ "jpg", "jpeg" ], + "MimeTypes": [ "image/jpeg", "image/jpeg" ] } -- cgit v1.2.3 From fc663b5f9aae16fe6a03160e3eb148a5f742ac58 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 22 Jan 2013 10:19:49 +0100 Subject: Fix focus handling of native child widgets in xcb. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If4d596195624011142bff6853849a23064e478df Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbconnection.cpp | 8 +++++++- src/plugins/platforms/xcb/qxcbconnection.h | 5 +++++ src/plugins/platforms/xcb/qxcbwindow.cpp | 14 +++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index c477c3a1a5..44c730d375 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -258,6 +258,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char , has_randr_extension(false) , has_input_shape(false) , m_buttons(0) + , m_focusWindow(0) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -418,7 +419,7 @@ break; if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \ handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ if (!handled) \ - m_keyboard->handler(platformWindow, e); \ + m_keyboard->handler(m_focusWindow, e); \ } \ } \ break; @@ -942,6 +943,11 @@ void QXcbEventReader::unlock() m_mutex.unlock(); } +void QXcbConnection::setFocusWindow(QXcbWindow *w) +{ + m_focusWindow = w; +} + void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) { xcb_client_message_event_t event; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 68d2b85f78..b499f75b78 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -385,6 +385,9 @@ public: Qt::MouseButtons buttons() const { return m_buttons; } + QXcbWindow *focusWindow() const { return m_focusWindow; } + void setFocusWindow(QXcbWindow *); + private slots: void processXcbEvents(); @@ -511,6 +514,8 @@ private: bool has_input_shape; Qt::MouseButtons m_buttons; + + QXcbWindow *m_focusWindow; }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 60cc547979..a8957d5810 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -403,6 +403,9 @@ QXcbWindow::~QXcbWindow() void QXcbWindow::destroy() { + if (connection()->focusWindow() == this) + connection()->setFocusWindow(0); + if (m_syncCounter && m_screen->syncRequestSupported()) Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter)); if (m_window) { @@ -1483,6 +1486,11 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) { + if (window() != QGuiApplication::focusWindow()) { + QWindow *w = static_cast(QObjectPrivate::get(window()))->eventReceiver(); + w->requestActivate(); + } + updateNetWmUserTime(event->time); QPoint local(event->event_x, event->event_y); @@ -1645,7 +1653,10 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) { - QWindowSystemInterface::handleWindowActivated(window()); + QWindow *w = window(); + w = static_cast(QObjectPrivate::get(w))->eventReceiver(); + connection()->setFocusWindow(static_cast(w->handle())); + QWindowSystemInterface::handleWindowActivated(w); } static bool focusInPeeker(xcb_generic_event_t *event) @@ -1661,6 +1672,7 @@ static bool focusInPeeker(xcb_generic_event_t *event) void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) { + connection()->setFocusWindow(0); // Do not set the active window to 0 if there is a FocusIn coming. // There is however no equivalent for XPutBackEvent so register a // callback for QXcbConnection instead. -- cgit v1.2.3 From 4807f70f89f9480052920b01ccefee97862be2e4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Jan 2013 11:57:50 +0100 Subject: Dnd: Do not always Retrieve URLS in canConvertFromMime(). Task-number: QTBUG-28186 Change-Id: I71d1a241d69f5fd80f6c047b9350cbd01bd48854 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowsmime.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 7fb32d3513..a8bacd631d 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -703,14 +703,14 @@ QWindowsMimeURI::QWindowsMimeURI() bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const { - if (getCf(formatetc) == CF_HDROP) { + if (mimeData->hasUrls() && getCf(formatetc) == CF_HDROP) { QList urls = mimeData->urls(); for (int i=0; ihasFormat(QStringLiteral("text/uri-list")); + return (getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL) && mimeData->hasUrls(); } bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const -- cgit v1.2.3 From 9a5ab30d52257f88931d6d09a376b4d75da69c5a Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 18 Jan 2013 17:59:52 +0100 Subject: Improve QAccessibleApplication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add more testing. This uncovers that currently the QDesktopScreenWidget shows up as child of the app. Fixed by not creating QAccessibleInterfaces for QDesktopScreenWidget. Also don't crash in indexOfChild when called with 0. Change-Id: I9fb1e47e8f1f33189e6125f56f274a7b94ecd0dd Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/main.cpp | 3 +++ src/plugins/accessible/widgets/widgets.json | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp index 9a42474910..92cda9f3ca 100644 --- a/src/plugins/accessible/widgets/main.cpp +++ b/src/plugins/accessible/widgets/main.cpp @@ -251,6 +251,9 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec } else if (classname == QLatin1String("QDockWidget")) { iface = new QAccessibleDockWidget(widget); #endif + + } else if (classname == QLatin1String("QDesktopScreenWidget")) { + iface = 0; } else { iface = new QAccessibleWidget(widget); } diff --git a/src/plugins/accessible/widgets/widgets.json b/src/plugins/accessible/widgets/widgets.json index 69584b9bc8..094987daf5 100644 --- a/src/plugins/accessible/widgets/widgets.json +++ b/src/plugins/accessible/widgets/widgets.json @@ -47,5 +47,7 @@ "QScrollArea", "QCalendarWidget", "QDockWidget", - "QAccessibleWidget" ] + "QAccessibleWidget", + "QDesktopScreenWidget" + ] } -- cgit v1.2.3 From bf5f2a9e3e3bf70c373b65bf95a332f4e1c514f9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Aug 2012 16:14:48 +0200 Subject: Switch to struct timespec everywhere instead of timeval This avoids an extra division by 1000 when getting the current time. This can't overflow, under normal circumstances, even on 32-bit: when adding two values less than 1 billion, the result is less than 2 billion, which is less than 2^31. Change-Id: I6f8e1aadfe2fcf6ac8da584eab4c1e61aee51cbb Reviewed-by: David Faure (KDE) Reviewed-by: Thiago Macieira --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 305e7ff985..b99b7e07bb 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -149,10 +149,10 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.); // Q: when should the CFRunLoopTimer fire for the first time? - struct timeval tv; + struct timespec tv; if (timerInfoList.timerWait(tv)) { // A: when we have timers to fire, of course - interval = qMax(tv.tv_sec + tv.tv_usec / 1000000., 0.0000001); + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); } else { // this shouldn't really happen, but in case it does, set the timer to fire a some point in the distant future interval = oneyear; @@ -172,10 +172,10 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() CFTimeInterval interval; // Q: when should the timer first next? - struct timeval tv; + struct timespec tv; if (timerInfoList.timerWait(tv)) { // A: when we have timers to fire, of course - interval = qMax(tv.tv_sec + tv.tv_usec / 1000000., 0.0000001); + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); } else { // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some // point in the distant future (the timer interval is one year) -- cgit v1.2.3 From 779195343f14fcbc6c12bee0948f6a20ecfec852 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 22 Jan 2013 10:58:25 +0100 Subject: Windows: Fix modal dialogs for declarative. Make it possible to show a modal dialog by just calling show(). Start an idle timer, which will start the dialog thread. This timer is stopped in exec(). Change-Id: I8f7352bf577b09a19be7df4484e0077bb1aa46ab Reviewed-by: Joerg Bornemann --- .../platforms/windows/qwindowsdialoghelpers.cpp | 38 +++++++++++++++++++--- .../platforms/windows/qwindowsdialoghelpers.h | 4 +++ 2 files changed, 38 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index b4699b6306..e9c0cccc14 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -450,7 +450,8 @@ protected: template QWindowsDialogHelperBase::QWindowsDialogHelperBase() : m_nativeDialog(0), - m_ownerWindow(0) + m_ownerWindow(0), + m_timerId(0) { } @@ -471,6 +472,12 @@ void QWindowsDialogHelperBase::deleteNativeDialog() m_nativeDialog = 0; } +template +void QWindowsDialogHelperBase::timerEvent(QTimerEvent *) +{ + startDialogThread(); +} + template QWindowsNativeDialogBase *QWindowsDialogHelperBase::ensureNativeDialog() { @@ -527,13 +534,35 @@ bool QWindowsDialogHelperBase::show(Qt::WindowFlags, return false; // Was it changed in-between? if (!ensureNativeDialog()) return false; - if (!modal) { // Modal dialogs are shown in separate slot. - QWindowsDialogThread *thread = new QWindowsDialogThread(this); - thread->start(); + // Start a background thread to show the dialog. For modal dialogs, + // a subsequent call to exec() may follow. So, start an idle timer + // which will start the dialog thread. If exec() is then called, the + // timer is stopped and dialog->exec() is called directly. + if (modal) { + m_timerId = this->startTimer(0); + } else { + startDialogThread(); } return true; } +template +void QWindowsDialogHelperBase::startDialogThread() +{ + QWindowsDialogThread *thread = new QWindowsDialogThread(this); + thread->start(); + stopTimer(); +} + +template +void QWindowsDialogHelperBase::stopTimer() +{ + if (m_timerId) { + this->killTimer(m_timerId); + m_timerId = 0; + } +} + template void QWindowsDialogHelperBase::hide() { @@ -547,6 +576,7 @@ void QWindowsDialogHelperBase::exec() { if (QWindowsContext::verboseDialogs) qDebug("%s" , __FUNCTION__); + stopTimer(); if (QWindowsNativeDialogBase *nd = nativeDialog()) { nd->exec(m_ownerWindow); deleteNativeDialog(); diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index a46caf0e1e..7884f398f3 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -81,13 +81,17 @@ protected: QWindowsNativeDialogBase *nativeDialog() const; inline bool hasNativeDialog() const { return m_nativeDialog; } void deleteNativeDialog(); + void timerEvent(QTimerEvent *); private: virtual QWindowsNativeDialogBase *createNativeDialog() = 0; inline QWindowsNativeDialogBase *ensureNativeDialog(); + inline void startDialogThread(); + inline void stopTimer(); QWindowsNativeDialogBase *m_nativeDialog; HWND m_ownerWindow; + int m_timerId; }; QT_END_NAMESPACE -- cgit v1.2.3 From 07e3bcdc106ac42703ae0fb88b6cac2d2bfdd072 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Sat, 26 Jan 2013 21:42:12 +0100 Subject: Remove QT_{BEGIN,END}_HEADER macro usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The macro was made empty in ba3dc5f3b56d1fab6fe37fe7ae08096d7dc68bcb and is no longer necessary or used. Discussed-on: http://lists.qt-project.org/pipermail/development/2013-January/009284.html Change-Id: Id2bb2e2cabde059305d4af5f12593344ba30f001 Reviewed-by: Laszlo Papp Reviewed-by: Jędrzej Nowacki Reviewed-by: hjk --- src/plugins/generic/meego/qmeegointegration.h | 4 ---- src/plugins/generic/tslib/qtslib.h | 4 ---- src/plugins/platforms/cocoa/qcocoamenu.h | 4 ---- src/plugins/platforms/cocoa/qcocoamenuitem.h | 4 ---- src/plugins/platforms/cocoa/qmacdefines_mac.h | 4 ---- src/plugins/platforms/eglfs/qeglfsintegration.h | 3 --- src/plugins/platforms/minimalegl/qminimaleglintegration.h | 3 --- src/plugins/platforms/windows/accessible/qwindowsaccessibility.h | 2 -- src/plugins/printsupport/cups/qcupsprintersupport_p.h | 2 -- src/plugins/printsupport/windows/qwindowsprintersupport.h | 2 -- 10 files changed, 32 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/generic/meego/qmeegointegration.h b/src/plugins/generic/meego/qmeegointegration.h index 88e2aae721..998bbbf8d3 100644 --- a/src/plugins/generic/meego/qmeegointegration.h +++ b/src/plugins/generic/meego/qmeegointegration.h @@ -47,8 +47,6 @@ #include "contextkitproperty.h" -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QMeeGoIntegration : public QObject @@ -67,6 +65,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QMEEGOINTEGRATION_H diff --git a/src/plugins/generic/tslib/qtslib.h b/src/plugins/generic/tslib/qtslib.h index 0c5c74f672..9342fdfea5 100644 --- a/src/plugins/generic/tslib/qtslib.h +++ b/src/plugins/generic/tslib/qtslib.h @@ -45,8 +45,6 @@ #include //#include -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QSocketNotifier; @@ -72,6 +70,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QTSLIB_H diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index fc014c26eb..9433e9f9c0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -51,8 +51,6 @@ @class NSMenu; @class NSObject; -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QCocoaMenu : public QPlatformMenu @@ -106,6 +104,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index fe5193a50c..b28274bc05 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -51,8 +51,6 @@ @class NSMenuItem; @class NSMenu; -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QCocoaMenu; @@ -110,8 +108,6 @@ private: quintptr m_tag; }; -QT_END_HEADER - QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/cocoa/qmacdefines_mac.h b/src/plugins/platforms/cocoa/qmacdefines_mac.h index 18c1ac84de..c03b398836 100644 --- a/src/plugins/platforms/cocoa/qmacdefines_mac.h +++ b/src/plugins/platforms/cocoa/qmacdefines_mac.h @@ -79,15 +79,11 @@ */ /* This is just many defines. Therefore it doesn't need things like: -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE QT_END_NAMESPACE -QT_END_HEADER - Yes, it is an informative comment ;-) */ diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 2cf0dfc71c..9eae8d2703 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -48,8 +48,6 @@ #include #include -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface @@ -85,6 +83,5 @@ private: }; QT_END_NAMESPACE -QT_END_HEADER #endif // QEGLFSINTEGRATION_H diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.h b/src/plugins/platforms/minimalegl/qminimaleglintegration.h index fb86c967e1..dba7504033 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.h +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.h @@ -47,8 +47,6 @@ #include #include -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QMinimalEglIntegration : public QPlatformIntegration @@ -75,6 +73,5 @@ private: }; QT_END_NAMESPACE -QT_END_HEADER #endif // QMINIMALEGLINTEGRATION_H diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h index af0bd65c80..5a6dc0c2e5 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h @@ -48,7 +48,6 @@ #include -QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QWindowsAccessibility : public QPlatformAccessibility @@ -69,6 +68,5 @@ public: }; QT_END_NAMESPACE -QT_END_HEADER #endif // QWINDOWSACCESSIBILITY_H diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index 43fe871021..d3f0ff5d90 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -52,7 +52,6 @@ #include -QT_BEGIN_HEADER QT_BEGIN_NAMESPACE typedef int (*CupsGetDests)(cups_dest_t **dests); @@ -86,7 +85,6 @@ private: }; QT_END_NAMESPACE -QT_END_HEADER #endif // QT_NO_PRINTER #endif // QCUPSPRINTERSUPPORT_H diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h index afa341a82f..3550c3f50c 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.h +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h @@ -44,7 +44,6 @@ #include -QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QWin32PrintEngine; @@ -61,6 +60,5 @@ public: }; QT_END_NAMESPACE -QT_END_HEADER #endif // WINDOWSPRINTERSUPPORT_H -- cgit v1.2.3 From d78bd439dcb290e4318734693d418937b0bf8129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 5 Dec 2012 14:27:41 +0100 Subject: Offscreen testing platform plugin Useful for running auto-tests without popping up a bunch of windows in the windowing system. Thus they can be run in the background and even in parallel without focus issues. Change-Id: I8b14c6de258b41225480a0af5a2a9553663bc2b7 Reviewed-by: Jason McDonald --- src/plugins/platforms/offscreen/main.cpp | 67 ++++++ src/plugins/platforms/offscreen/offscreen.json | 3 + src/plugins/platforms/offscreen/offscreen.pro | 25 ++ .../platforms/offscreen/qoffscreencommon.cpp | 229 +++++++++++++++++++ src/plugins/platforms/offscreen/qoffscreencommon.h | 109 +++++++++ .../platforms/offscreen/qoffscreenintegration.cpp | 162 +++++++++++++ .../platforms/offscreen/qoffscreenintegration.h | 80 +++++++ .../offscreen/qoffscreenintegration_dummy.cpp | 47 ++++ .../offscreen/qoffscreenintegration_x11.cpp | 252 +++++++++++++++++++++ .../offscreen/qoffscreenintegration_x11.h | 108 +++++++++ .../platforms/offscreen/qoffscreenwindow.cpp | 199 ++++++++++++++++ src/plugins/platforms/offscreen/qoffscreenwindow.h | 86 +++++++ src/plugins/platforms/platforms.pro | 2 +- 13 files changed, 1368 insertions(+), 1 deletion(-) create mode 100644 src/plugins/platforms/offscreen/main.cpp create mode 100644 src/plugins/platforms/offscreen/offscreen.json create mode 100644 src/plugins/platforms/offscreen/offscreen.pro create mode 100644 src/plugins/platforms/offscreen/qoffscreencommon.cpp create mode 100644 src/plugins/platforms/offscreen/qoffscreencommon.h create mode 100644 src/plugins/platforms/offscreen/qoffscreenintegration.cpp create mode 100644 src/plugins/platforms/offscreen/qoffscreenintegration.h create mode 100644 src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp create mode 100644 src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp create mode 100644 src/plugins/platforms/offscreen/qoffscreenintegration_x11.h create mode 100644 src/plugins/platforms/offscreen/qoffscreenwindow.cpp create mode 100644 src/plugins/platforms/offscreen/qoffscreenwindow.h (limited to 'src/plugins') diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp new file mode 100644 index 0000000000..ca7dc1d18b --- /dev/null +++ b/src/plugins/platforms/offscreen/main.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include "qoffscreenintegration.h" + +QT_BEGIN_NAMESPACE + +class QOffscreenIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "offscreen.json") +public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration *QOffscreenIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "offscreen") + return QOffscreenIntegration::createOffscreenIntegration(); + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platforms/offscreen/offscreen.json b/src/plugins/platforms/offscreen/offscreen.json new file mode 100644 index 0000000000..6e87744de0 --- /dev/null +++ b/src/plugins/platforms/offscreen/offscreen.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "offscreen" ] +} diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro new file mode 100644 index 0000000000..270e3ce228 --- /dev/null +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -0,0 +1,25 @@ +TARGET = qoffscreen + +PLUGIN_TYPE = platforms +load(qt_plugin) + +QT += core-private gui-private platformsupport-private + +SOURCES = main.cpp \ + qoffscreenintegration.cpp \ + qoffscreenwindow.cpp \ + qoffscreencommon.cpp + +HEADERS = qoffscreenintegration.h \ + qoffscreenwindow.h \ + qoffscreencommon.h + +OTHER_FILES += offscreen.json + +contains(QT_CONFIG, xcb):contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2) { + SOURCES += qoffscreenintegration_x11.cpp + HEADERS += qoffscreenintegration_x11.h + system(echo "Using X11 offscreen integration with GLX") +} else { + SOURCES += qoffscreenintegration_dummy.cpp +} diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp new file mode 100644 index 0000000000..069b20693d --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoffscreencommon.h" +#include "qoffscreenwindow.h" + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +QPlatformWindow *QOffscreenScreen::windowContainingCursor = 0; + +class QOffscreenCursor : public QPlatformCursor +{ +public: + QOffscreenCursor() : m_pos(10, 10) {} + + QPoint pos() const { return m_pos; } + void setPos(const QPoint &pos) + { + m_pos = pos; + QWindowList wl = QGuiApplication::topLevelWindows(); + QWindow *containing = 0; + foreach (QWindow *w, wl) { + if (w->type() != Qt::Desktop && w->isExposed() && w->geometry().contains(pos)) { + containing = w; + break; + } + } + + QPoint local = pos; + if (containing) + local -= containing->position(); + + QWindow *previous = QOffscreenScreen::windowContainingCursor ? QOffscreenScreen::windowContainingCursor->window() : 0; + + if (containing != previous) + QWindowSystemInterface::handleEnterLeaveEvent(containing, previous, local, pos); + + QWindowSystemInterface::handleMouseEvent(containing, local, pos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); + + QOffscreenScreen::windowContainingCursor = containing ? containing->handle() : 0; + } + + void changeCursor(QCursor *windowCursor, QWindow *window) + { + Q_UNUSED(windowCursor); + Q_UNUSED(window); + } + +private: + QPoint m_pos; +}; + +QOffscreenScreen::QOffscreenScreen() + : m_geometry(0, 0, 800, 600) + , m_cursor(new QOffscreenCursor) +{ +} + +QPixmap QOffscreenScreen::grabWindow(WId id, int x, int y, int width, int height) const +{ + QRect rect(x, y, width, height); + + QOffscreenWindow *window = QOffscreenWindow::windowForWinId(id); + if (!window || window->window()->type() == Qt::Desktop) { + QWindowList wl = QGuiApplication::topLevelWindows(); + QWindow *containing = 0; + foreach (QWindow *w, wl) { + if (w->type() != Qt::Desktop && w->isExposed() && w->geometry().contains(rect)) { + containing = w; + break; + } + } + + if (!containing) + return QPixmap(); + + id = containing->winId(); + rect = rect.translated(-containing->geometry().topLeft()); + } + + QOffscreenBackingStore *store = QOffscreenBackingStore::backingStoreForWinId(id); + if (store) + return store->grabWindow(id, rect); + return QPixmap(); +} + +QOffscreenBackingStore::QOffscreenBackingStore(QWindow *window) + : QPlatformBackingStore(window) +{ +} + +QOffscreenBackingStore::~QOffscreenBackingStore() +{ + clearHash(); +} + +QPaintDevice *QOffscreenBackingStore::paintDevice() +{ + return &m_image; +} + +void QOffscreenBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(region); + + if (m_image.size().isEmpty()) + return; + + QSize imageSize = m_image.size(); + + QRegion clipped = QRect(0, 0, window->width(), window->height()); + clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset); + + QRect bounds = clipped.boundingRect().translated(offset); + + if (bounds.isNull()) + return; + + WId id = window->winId(); + + m_windowAreaHash[id] = bounds; + m_backingStoreForWinIdHash[id] = this; +} + +void QOffscreenBackingStore::resize(const QSize &size, const QRegion &) +{ + QImage::Format format = QGuiApplication::primaryScreen()->handle()->format(); + if (m_image.size() != size) + m_image = QImage(size, format); + clearHash(); +} + +extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); + +bool QOffscreenBackingStore::scroll(const QRegion &area, int dx, int dy) +{ + if (m_image.isNull()) + return false; + + const QVector rects = area.rects(); + for (int i = 0; i < rects.size(); ++i) + qt_scrollRectInImage(m_image, rects.at(i), QPoint(dx, dy)); + + return true; +} + +QPixmap QOffscreenBackingStore::grabWindow(WId window, const QRect &rect) const +{ + QRect area = m_windowAreaHash.value(window, QRect()); + if (area.isNull()) + return QPixmap(); + + QRect adjusted = rect; + if (adjusted.width() <= 0) + adjusted.setWidth(area.width()); + if (adjusted.height() <= 0) + adjusted.setHeight(area.height()); + + adjusted = adjusted.translated(area.topLeft()) & area; + + if (adjusted.isEmpty()) + return QPixmap(); + + return QPixmap::fromImage(m_image.copy(adjusted)); +} + +QOffscreenBackingStore *QOffscreenBackingStore::backingStoreForWinId(WId id) +{ + return m_backingStoreForWinIdHash.value(id, 0); +} + +void QOffscreenBackingStore::clearHash() +{ + QList ids = m_windowAreaHash.keys(); + foreach (WId id, ids) { + QHash::iterator it = m_backingStoreForWinIdHash.find(id); + if (it.value() == this) + m_backingStoreForWinIdHash.remove(id); + } + m_windowAreaHash.clear(); +} + +QHash QOffscreenBackingStore::m_backingStoreForWinIdHash; + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.h b/src/plugins/platforms/offscreen/qoffscreencommon.h new file mode 100644 index 0000000000..a5df7d05d3 --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreencommon.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOFFSCREENCOMMON_H +#define QOFFSCREENCOMMON_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QOffscreenScreen : public QPlatformScreen +{ +public: + QOffscreenScreen(); + + QRect geometry() const { return m_geometry; } + int depth() const { return 32; } + QImage::Format format() const { return QImage::Format_RGB32; } + QPlatformCursor *cursor() const { return m_cursor.data(); } + + QPixmap grabWindow(WId window, int x, int y, int width, int height) const; + + static QPlatformWindow *windowContainingCursor; + +public: + QRect m_geometry; + QScopedPointer m_cursor; +}; + +class QOffscreenDrag : public QPlatformDrag +{ +public: + QMimeData *platformDropData() { return 0; } + Qt::DropAction drag(QDrag *) { return Qt::IgnoreAction; } +}; + +class QOffscreenBackingStore : public QPlatformBackingStore +{ +public: + QOffscreenBackingStore(QWindow *window); + ~QOffscreenBackingStore(); + + QPaintDevice *paintDevice(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + bool scroll(const QRegion &area, int dx, int dy); + + QPixmap grabWindow(WId window, const QRect &rect) const; + + static QOffscreenBackingStore *backingStoreForWinId(WId id); + +private: + void clearHash(); + + QImage m_image; + QHash m_windowAreaHash; + + static QHash m_backingStoreForWinIdHash; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp new file mode 100644 index 0000000000..e3fcc7ebb0 --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoffscreenintegration.h" +#include "qoffscreenwindow.h" +#include "qoffscreencommon.h" + +#if defined(Q_OS_UNIX) +#include +#if defined(Q_OS_MAC) +#include +#else +#include +#endif +#elif defined(Q_OS_WIN) +#include +#include +#endif + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +template +class QOffscreenEventDispatcher : public BaseEventDispatcher +{ +public: + explicit QOffscreenEventDispatcher(QObject *parent = 0) + : BaseEventDispatcher(parent) + { + } + + bool processEvents(QEventLoop::ProcessEventsFlags flags) + { + bool didSendEvents = QWindowSystemInterface::sendWindowSystemEvents(flags); + + return BaseEventDispatcher::processEvents(flags) || didSendEvents; + } + + bool hasPendingEvents() + { + return BaseEventDispatcher::hasPendingEvents() + || QWindowSystemInterface::windowSystemEventsQueued(); + } + + void flush() + { + if (qApp) + qApp->sendPostedEvents(); + BaseEventDispatcher::flush(); + } +}; + +QOffscreenIntegration::QOffscreenIntegration() +{ +#if defined(Q_OS_UNIX) + m_eventDispatcher = createUnixEventDispatcher(); +#if defined(Q_OS_MAC) + m_fontDatabase.reset(new QPlatformFontDatabase()); +#else + m_fontDatabase.reset(new QGenericUnixFontDatabase()); +#endif +#elif defined(Q_OS_WIN) + m_eventDispatcher = new QOffscreenEventDispatcher(); + m_fontDatabase.reset(new QBasicFontDatabase()); +#endif + + m_drag.reset(new QOffscreenDrag); + m_services.reset(new QPlatformServices); + + QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); + screenAdded(new QOffscreenScreen); +} + +QOffscreenIntegration::~QOffscreenIntegration() +{ +} + +bool QOffscreenIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case ThreadedPixmaps: return true; + case MultipleWindows: return true; + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformWindow *QOffscreenIntegration::createPlatformWindow(QWindow *window) const +{ + Q_UNUSED(window); + QPlatformWindow *w = new QOffscreenWindow(window); + w->requestActivateWindow(); + return w; +} + +QPlatformBackingStore *QOffscreenIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QOffscreenBackingStore(window); +} + +QAbstractEventDispatcher *QOffscreenIntegration::guiThreadEventDispatcher() const +{ + return m_eventDispatcher; +} + +QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const +{ + return m_fontDatabase.data(); +} + +QPlatformDrag *QOffscreenIntegration::drag() const +{ + return m_drag.data(); +} + +QPlatformServices *QOffscreenIntegration::services() const +{ + return m_services.data(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h new file mode 100644 index 0000000000..eb03100ec9 --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOFFSCREENINTEGRATION_H +#define QOFFSCREENINTEGRATION_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QOffscreenBackendData; + +class QOffscreenIntegration : public QPlatformIntegration +{ +public: + QOffscreenIntegration(); + ~QOffscreenIntegration(); + + bool hasCapability(QPlatformIntegration::Capability cap) const; + + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + QPlatformDrag *drag() const; + QPlatformServices *services() const; + + QPlatformFontDatabase *fontDatabase() const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; + + static QOffscreenIntegration *createOffscreenIntegration(); + +private: + QAbstractEventDispatcher *m_eventDispatcher; + QScopedPointer m_fontDatabase; + QScopedPointer m_drag; + QScopedPointer m_services; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp new file mode 100644 index 0000000000..8bc1b17a56 --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoffscreenintegration.h" + +QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() +{ + return new QOffscreenIntegration; +} diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp new file mode 100644 index 0000000000..4b27afd80f --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoffscreenintegration_x11.h" + +#include +#include + +#include +#include + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() +{ + return new QOffscreenX11Integration; +} + +bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case OpenGL: return true; + case ThreadedOpenGL: return true; + default: return QOffscreenIntegration::hasCapability(cap); + } +} + +QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + if (!m_connection) + m_connection.reset(new QOffscreenX11Connection); + + return new QOffscreenX11GLXContext(m_connection->x11Info(), context); +} + +QOffscreenX11Connection::QOffscreenX11Connection() +{ + XInitThreads(); + + QByteArray displayName = qgetenv("DISPLAY"); + Display *display = XOpenDisplay(displayName.constData()); + m_display = display; + m_screenNumber = DefaultScreen(display); +} + +QOffscreenX11Connection::~QOffscreenX11Connection() +{ + XCloseDisplay((Display *)m_display); +} + +class QOffscreenX11Info +{ +public: + QOffscreenX11Info(QOffscreenX11Connection *connection) + : m_connection(connection) + { + } + + Display *display() const { + return (Display *)m_connection->display(); + } + + Window root() const { + return DefaultRootWindow(display()); + } + + int screenNumber() const { + return m_connection->screenNumber(); + } + +private: + QOffscreenX11Connection *m_connection; +}; + +QOffscreenX11Info *QOffscreenX11Connection::x11Info() +{ + if (!m_x11Info) + m_x11Info.reset(new QOffscreenX11Info(this)); + return m_x11Info.data(); +} + +class QOffscreenX11GLXContextData +{ +public: + QOffscreenX11Info *x11; + QSurfaceFormat format; + GLXContext context; + GLXContext shareContext; + Window window; +}; + +static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo) +{ + Colormap cmap = XCreateColormap(x11->display(), x11->root(), visualInfo->visual, AllocNone); + XSetWindowAttributes a; + a.background_pixel = WhitePixel(x11->display(), x11->screenNumber()); + a.border_pixel = BlackPixel(x11->display(), x11->screenNumber()); + a.colormap = cmap; + + Window window = XCreateWindow(x11->display(), x11->root(), + 0, 0, 100, 100, + 0, visualInfo->depth, InputOutput, visualInfo->visual, + CWBackPixel|CWBorderPixel|CWColormap, &a); + XFreeColormap(x11->display(), cmap); + return window; +} + +static Window createDummyWindow(QOffscreenX11Info *x11, GLXFBConfig config) +{ + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(x11->display(), config); + if (!visualInfo) + qFatal("Could not initialize GLX"); + Window window = createDummyWindow(x11, visualInfo); + XFree(visualInfo); + return window; +} + +QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context) + : d(new QOffscreenX11GLXContextData) +{ + d->x11 = x11; + d->format = context->format(); + + d->shareContext = 0; + if (context->shareHandle()) + d->shareContext = static_cast(context->shareHandle())->d->context; + + GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), d->format); + if (config) { + d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, d->shareContext, true); + if (!d->context && d->shareContext) { + d->shareContext = 0; + // re-try without a shared glx context + d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, 0, true); + } + + // Get the basic surface format details + if (d->context) + d->format = qglx_surfaceFormatFromGLXFBConfig(x11->display(), config, d->context); + + // Create a temporary window so that we can make the new context current + d->window = createDummyWindow(x11, config); + } else { + XVisualInfo *visualInfo = qglx_findVisualInfo(x11->display(), 0, &d->format); + if (!visualInfo) + qFatal("Could not initialize GLX"); + d->context = glXCreateContext(x11->display(), visualInfo, d->shareContext, true); + if (!d->context && d->shareContext) { + // re-try without a shared glx context + d->shareContext = 0; + d->context = glXCreateContext(x11->display(), visualInfo, 0, true); + } + + d->window = createDummyWindow(x11, visualInfo); + XFree(visualInfo); + } +} + +QOffscreenX11GLXContext::~QOffscreenX11GLXContext() +{ + glXDestroyContext(d->x11->display(), d->context); + XDestroyWindow(d->x11->display(), d->window); +} + +bool QOffscreenX11GLXContext::makeCurrent(QPlatformSurface *surface) +{ + QSize size = surface->surface()->size(); + + XResizeWindow(d->x11->display(), d->window, size.width(), size.height()); + XSync(d->x11->display(), true); + + if (glXMakeCurrent(d->x11->display(), d->window, d->context)) { + glViewport(0, 0, size.width(), size.height()); + return true; + } + + return false; +} + +void QOffscreenX11GLXContext::doneCurrent() +{ + glXMakeCurrent(d->x11->display(), 0, 0); +} + +void QOffscreenX11GLXContext::swapBuffers(QPlatformSurface *) +{ +} + +void (*QOffscreenX11GLXContext::getProcAddress(const QByteArray &procName)) () +{ + return (void (*)())glXGetProcAddressARB(reinterpret_cast(procName.constData())); +} + +QSurfaceFormat QOffscreenX11GLXContext::format() const +{ + return d->format; +} + +bool QOffscreenX11GLXContext::isSharing() const +{ + return d->shareContext; +} + +bool QOffscreenX11GLXContext::isValid() const +{ + return d->context && d->window; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h new file mode 100644 index 0000000000..9afa302b04 --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOFFSCREENINTEGRATION_X11_H +#define QOFFSCREENINTEGRATION_X11_H + +#include "qoffscreenintegration.h" + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QOffscreenX11Connection; +class QOffscreenX11Info; + +class QOffscreenX11Integration : public QOffscreenIntegration +{ +public: + bool hasCapability(QPlatformIntegration::Capability cap) const; + + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + +private: + mutable QScopedPointer m_connection; +}; + +class QOffscreenX11Connection { +public: + QOffscreenX11Connection(); + ~QOffscreenX11Connection(); + + QOffscreenX11Info *x11Info(); + + void *display() const { return m_display; } + int screenNumber() const { return m_screenNumber; } + +private: + void *m_display; + int m_screenNumber; + + QScopedPointer m_x11Info; +}; + +class QOffscreenX11GLXContextData; + +class QOffscreenX11GLXContext : public QPlatformOpenGLContext +{ +public: + QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context); + ~QOffscreenX11GLXContext(); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + void swapBuffers(QPlatformSurface *surface); + void (*getProcAddress(const QByteArray &procName)) (); + + QSurfaceFormat format() const; + bool isSharing() const; + bool isValid() const; + +private: + QScopedPointer d; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/offscreen/qoffscreenwindow.cpp b/src/plugins/platforms/offscreen/qoffscreenwindow.cpp new file mode 100644 index 0000000000..702ef2300c --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenwindow.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoffscreenwindow.h" +#include "qoffscreencommon.h" + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +QOffscreenWindow::QOffscreenWindow(QWindow *window) + : QPlatformWindow(window) + , m_positionIncludesFrame(false) + , m_visible(false) + , m_pendingGeometryChangeOnShow(true) +{ + if (window->windowState() == Qt::WindowNoState) + setGeometry(window->geometry()); + else + setWindowState(window->windowState()); + + QWindowSystemInterface::flushWindowSystemEvents(); + + static WId counter = 0; + m_winId = ++counter; + + m_windowForWinIdHash[m_winId] = this; +} + +QOffscreenWindow::~QOffscreenWindow() +{ + if (QOffscreenScreen::windowContainingCursor == this) + QOffscreenScreen::windowContainingCursor = 0; + m_windowForWinIdHash.remove(m_winId); +} + +void QOffscreenWindow::setGeometry(const QRect &rect) +{ + if (window()->windowState() != Qt::WindowNoState) + return; + + m_positionIncludesFrame = qt_window_private(window())->positionPolicy == QWindowPrivate::WindowFrameInclusive; + + setFrameMarginsEnabled(true); + setGeometryImpl(rect); + + m_normalGeometry = geometry(); +} + +void QOffscreenWindow::setGeometryImpl(const QRect &rect) +{ + QRect adjusted = rect; + if (adjusted.width() <= 0) + adjusted.setWidth(1); + if (adjusted.height() <= 0) + adjusted.setHeight(1); + + if (m_positionIncludesFrame) { + adjusted.translate(m_margins.left(), m_margins.top()); + } else { + // make sure we're not placed off-screen + if (adjusted.left() < m_margins.left()) + adjusted.translate(m_margins.left(), 0); + if (adjusted.top() < m_margins.top()) + adjusted.translate(0, m_margins.top()); + } + + QPlatformWindow::setGeometry(adjusted); + + if (m_visible) { + QWindowSystemInterface::handleGeometryChange(window(), adjusted); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), adjusted.size())); + } else { + m_pendingGeometryChangeOnShow = true; + } +} + +void QOffscreenWindow::setVisible(bool visible) +{ + if (visible == m_visible) + return; + + if (visible) { + if (window()->type() != Qt::ToolTip) + QWindowSystemInterface::handleWindowActivated(window()); + + if (m_pendingGeometryChangeOnShow) { + m_pendingGeometryChangeOnShow = false; + QWindowSystemInterface::handleGeometryChange(window(), geometry()); + } + } + + if (visible) { + QRect rect(QPoint(), geometry().size()); + QWindowSystemInterface::handleExposeEvent(window(), rect); + } else { + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); + } + + m_visible = visible; +} + +void QOffscreenWindow::requestActivateWindow() +{ + if (m_visible) + QWindowSystemInterface::handleWindowActivated(window()); +} + +WId QOffscreenWindow::winId() const +{ + return m_winId; +} + +QMargins QOffscreenWindow::frameMargins() const +{ + return m_margins; +} + +void QOffscreenWindow::setFrameMarginsEnabled(bool enabled) +{ + if (enabled && !(window()->flags() & Qt::FramelessWindowHint)) + m_margins = QMargins(2, 2, 2, 2); + else + m_margins = QMargins(0, 0, 0, 0); +} + +void QOffscreenWindow::setWindowState(Qt::WindowState state) +{ + setFrameMarginsEnabled(state != Qt::WindowFullScreen); + m_positionIncludesFrame = false; + + switch (state) { + case Qt::WindowFullScreen: + setGeometryImpl(screen()->geometry()); + break; + case Qt::WindowMaximized: + setGeometryImpl(screen()->availableGeometry().adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom())); + break; + case Qt::WindowMinimized: + break; + case Qt::WindowNoState: + setGeometryImpl(m_normalGeometry); + break; + default: + break; + } + + QWindowSystemInterface::handleWindowStateChanged(window(), state); +} + +QOffscreenWindow *QOffscreenWindow::windowForWinId(WId id) +{ + return m_windowForWinIdHash.value(id, 0); +} + +QHash QOffscreenWindow::m_windowForWinIdHash; + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenwindow.h b/src/plugins/platforms/offscreen/qoffscreenwindow.h new file mode 100644 index 0000000000..cd1cf8e0aa --- /dev/null +++ b/src/plugins/platforms/offscreen/qoffscreenwindow.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOFFSCREENWINDOW_H +#define QOFFSCREENWINDOW_H + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QOffscreenWindow : public QPlatformWindow +{ +public: + QOffscreenWindow(QWindow *window); + ~QOffscreenWindow(); + + void setGeometry(const QRect &rect); + void setWindowState(Qt::WindowState state); + + QMargins frameMargins() const; + + void setVisible(bool visible); + void requestActivateWindow(); + + WId winId() const; + + static QOffscreenWindow *windowForWinId(WId id); + +private: + void setFrameMarginsEnabled(bool enabled); + void setGeometryImpl(const QRect &rect); + + QRect m_normalGeometry; + QMargins m_margins; + bool m_positionIncludesFrame; + bool m_visible; + bool m_pendingGeometryChangeOnShow; + WId m_winId; + + static QHash m_windowForWinIdHash; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 828867c3a7..173757568f 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -SUBDIRS += minimal +SUBDIRS += minimal offscreen contains(QT_CONFIG, xcb) { SUBDIRS += xcb -- cgit v1.2.3 From 7b8ab4204417844e72bb66696227a422f4ef3e2d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 17 Jan 2013 12:38:09 +0100 Subject: Reduce invocations QString::left() in XCB key event processing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6d422af4d7186356c196d6362a850f7e7b997bb4 Reviewed-by: Gatis Paeglis Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index bda54b4682..4ac60f6077 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1081,6 +1081,7 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod int qtcode = 0; int count = chars.count(); QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count); + string.truncate(count); bool isAutoRepeat = false; @@ -1102,7 +1103,7 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod bool filtered = false; if (inputContext) { - QKeyEvent event(type, qtcode, modifiers, code, sym, state, string.left(count), isAutoRepeat, count); + QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, count); event.setTimestamp(time); filtered = inputContext->filterEvent(&event); } @@ -1114,7 +1115,7 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers); } QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers, - code, sym, state, string.left(count), isAutoRepeat); + code, sym, state, string, isAutoRepeat); } if (isAutoRepeat && type == QEvent::KeyRelease) { @@ -1130,13 +1131,13 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } if (!filtered && inputContext) { - QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string.left(count), isAutoRepeat, count); + QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, count); event.setTimestamp(time); filtered = inputContext->filterEvent(&event); } if (!filtered) QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, - code, sym, state, string.left(count), isAutoRepeat); + code, sym, state, string, isAutoRepeat); } } -- cgit v1.2.3 From 6bd03762d457ed7bea3cd4e856f629430c475553 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 30 Jan 2013 09:01:05 +0100 Subject: Refactor QEglFSPandaHooks and add physicalScreenSize() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5a198af5347cc1fdce97031e0a1be99b2120c3ac Reviewed-by: Samuel Rødal --- src/plugins/platforms/eglfs/qeglfshooks.h | 5 ++- src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 46 +++++++++++++++++++++--- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 5 +++ src/plugins/platforms/eglfs/qeglfsscreen.h | 2 ++ 4 files changed, 53 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index b8b699fea1..f3b6a28e70 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -55,10 +55,11 @@ class QEglFSScreen; class QEglFSHooks { public: - virtual ~QEglFSHooks() {}; + virtual ~QEglFSHooks() {} virtual void platformInit(); virtual void platformDestroy(); virtual EGLNativeDisplayType platformDisplay() const; + virtual QSizeF physicalScreenSize() const; virtual QSize screenSize() const; virtual int screenDepth() const; virtual QImage::Format screenFormat() const; @@ -68,6 +69,8 @@ public: virtual bool hasCapability(QPlatformIntegration::Capability cap) const; virtual QEglFSCursor *createCursor(QEglFSScreen *screen) const; virtual bool filterConfig(EGLDisplay display, EGLConfig config) const; + + virtual const char *fbDeviceName() const; }; #ifdef EGLFS_PLATFORM_HOOKS diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index 0fd22e1757..d09423ec72 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -48,6 +48,11 @@ QT_BEGIN_NAMESPACE +const char *QEglFSHooks::fbDeviceName() const +{ + return "/dev/fb0"; +} + void QEglFSHooks::platformInit() { Q_UNUSED(hooks); @@ -62,6 +67,39 @@ EGLNativeDisplayType QEglFSHooks::platformDisplay() const return EGL_DEFAULT_DISPLAY; } +QSizeF QEglFSHooks::physicalScreenSize() const +{ + static QSizeF size; + if (size.isEmpty()) { + + // Note: in millimeters + int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt(); + int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt(); + + if (width && height) { + // no need to read fb0 + size.setWidth(width); + size.setHeight(height); + return size; + } + + struct fb_var_screeninfo vinfo; + int fd = open(fbDeviceName(), O_RDONLY); + + if (fd != -1) { + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) + qWarning("Could not query variable screen info."); + else + size = QSizeF(vinfo.width, vinfo.height); + + close(fd); + } else { + qWarning("Failed to open %s to detect screen size.", fbDeviceName()); + } + } + return size; +} + QSize QEglFSHooks::screenSize() const { static QSize size; @@ -78,7 +116,7 @@ QSize QEglFSHooks::screenSize() const } struct fb_var_screeninfo vinfo; - int fd = open("/dev/fb0", O_RDONLY); + int fd = open(fbDeviceName(), O_RDONLY); if (fd != -1) { if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) @@ -88,7 +126,7 @@ QSize QEglFSHooks::screenSize() const close(fd); } else { - qWarning("Failed to open /dev/fb0 to detect screen resolution."); + qWarning("Failed to open %s to detect screen depth.", fbDeviceName()); } // override fb0 from environment var setting @@ -107,7 +145,7 @@ int QEglFSHooks::screenDepth() const if (depth == 0) { struct fb_var_screeninfo vinfo; - int fd = open("/dev/fb0", O_RDONLY); + int fd = open(fbDeviceName(), O_RDONLY); if (fd != -1) { if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) @@ -117,7 +155,7 @@ int QEglFSHooks::screenDepth() const close(fd); } else { - qWarning("Failed to open /dev/fb0 to detect screen depth."); + qWarning("Failed to open %s to detect screen depth.", fbDeviceName()); } } diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 1bc1e944de..43d7cb3b1f 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -83,6 +83,11 @@ QImage::Format QEglFSScreen::format() const return hooks->screenFormat(); } +QSizeF QEglFSScreen::physicalSize() const +{ + return hooks->physicalScreenSize(); +} + QPlatformCursor *QEglFSScreen::cursor() const { return m_cursor; diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 309791d6c2..8d3c5dbaec 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -63,6 +63,8 @@ public: int depth() const; QImage::Format format() const; + QSizeF physicalSize() const; + QPlatformCursor *cursor() const; EGLDisplay display() const { return m_dpy; } -- cgit v1.2.3 From 508bbe9507a21bdb1ef1216b75e9e75fceb3b179 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 30 Jan 2013 14:41:31 +0100 Subject: XCB: Free cursors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id09046a3264724025e8a383cf40a959dafb9e0db Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbcursor.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 929a6129b4..1b11ef7f95 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -287,8 +287,14 @@ QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen) QXcbCursor::~QXcbCursor() { + xcb_connection_t *conn = xcb_connection(); if (!--cursorCount) - xcb_close_font(xcb_connection(), cursorFont); + xcb_close_font(conn, cursorFont); + + foreach (xcb_cursor_t cursor, m_bitmapCursorMap) + xcb_free_cursor(conn, cursor); + foreach (xcb_cursor_t cursor, m_shapeCursorMap) + xcb_free_cursor(conn, cursor); } #ifndef QT_NO_CURSOR -- cgit v1.2.3 From ebca7d2ea71440b0a5e465774e3abd98ff6298a8 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 29 Jan 2013 17:02:54 +0100 Subject: Introduce a native color dialog for GTK+ 2.x Change-Id: I389e6995b09df85cd6c464779e8d894b7cd33205 Reviewed-by: Friedemann Kleint Reviewed-by: Jens Bache-Wiig --- src/plugins/platformthemes/gtk2/gtk2.json | 3 + src/plugins/platformthemes/gtk2/gtk2.pro | 19 ++ src/plugins/platformthemes/gtk2/main.cpp | 67 ++++++ .../platformthemes/gtk2/qgtk2dialoghelpers.cpp | 238 +++++++++++++++++++++ .../platformthemes/gtk2/qgtk2dialoghelpers.h | 79 +++++++ src/plugins/platformthemes/gtk2/qgtk2theme.cpp | 72 +++++++ src/plugins/platformthemes/gtk2/qgtk2theme.h | 62 ++++++ src/plugins/platformthemes/platformthemes.pro | 3 + src/plugins/plugins.pro | 2 +- 9 files changed, 544 insertions(+), 1 deletion(-) create mode 100644 src/plugins/platformthemes/gtk2/gtk2.json create mode 100644 src/plugins/platformthemes/gtk2/gtk2.pro create mode 100644 src/plugins/platformthemes/gtk2/main.cpp create mode 100644 src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp create mode 100644 src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h create mode 100644 src/plugins/platformthemes/gtk2/qgtk2theme.cpp create mode 100644 src/plugins/platformthemes/gtk2/qgtk2theme.h create mode 100644 src/plugins/platformthemes/platformthemes.pro (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/gtk2.json b/src/plugins/platformthemes/gtk2/gtk2.json new file mode 100644 index 0000000000..86dd8e58fa --- /dev/null +++ b/src/plugins/platformthemes/gtk2/gtk2.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "gtk2" ] +} diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro new file mode 100644 index 0000000000..f22753e96f --- /dev/null +++ b/src/plugins/platformthemes/gtk2/gtk2.pro @@ -0,0 +1,19 @@ +TARGET = qgtk2 + +PLUGIN_TYPE = platformthemes +PLUGIN_CLASS_NAME = QGtk2ThemePlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private + +QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTK2 +LIBS += $$QT_LIBS_QGTK2 + +HEADERS += \ + qgtk2dialoghelpers.h \ + qgtk2theme.h + +SOURCES += \ + main.cpp \ + qgtk2dialoghelpers.cpp \ + qgtk2theme.cpp \ diff --git a/src/plugins/platformthemes/gtk2/main.cpp b/src/plugins/platformthemes/gtk2/main.cpp new file mode 100644 index 0000000000..0c3fe46e29 --- /dev/null +++ b/src/plugins/platformthemes/gtk2/main.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qgtk2theme.h" + +QT_BEGIN_NAMESPACE + +class QGtk2ThemePlugin : public QPlatformThemePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformThemeFactoryInterface.5.1" FILE "gtk2.json") + +public: + QPlatformTheme *create(const QString &key, const QStringList ¶ms); +}; + +QPlatformTheme *QGtk2ThemePlugin::create(const QString &key, const QStringList ¶ms) +{ + Q_UNUSED(params); + if (!key.compare(QStringLiteral("gtk2"), Qt::CaseInsensitive)) + return new QGtk2Theme; + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp new file mode 100644 index 0000000000..19d4e9e469 --- /dev/null +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgtk2dialoghelpers.h" + +#include +#include +#include +#include + +#include + +#undef signals +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QGtk2Dialog : public QWindow +{ + Q_OBJECT + +public: + QGtk2Dialog(GtkWidget *gtkWidget); + ~QGtk2Dialog(); + + GtkDialog* gtkDialog() const; + + void exec(); + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + void hide(); + +Q_SIGNALS: + void accept(); + void reject(); + +protected: + static void onResponse(QGtk2Dialog *dialog, int response); + +private: + GtkWidget *gtkWidget; +}; + +QGtk2Dialog::QGtk2Dialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget) +{ + g_signal_connect_swapped(G_OBJECT(gtkWidget), "response", G_CALLBACK(onResponse), this); + g_signal_connect(G_OBJECT(gtkWidget), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); +} + +QGtk2Dialog::~QGtk2Dialog() +{ + gtk_widget_destroy(gtkWidget); +} + +GtkDialog* QGtk2Dialog::gtkDialog() const +{ + return GTK_DIALOG(gtkWidget); +} + +void QGtk2Dialog::exec() +{ + if (modality() == Qt::ApplicationModal) { + // block input to the whole app, including other GTK dialogs + gtk_dialog_run(gtkDialog()); + } else { + // block input to the window, allow input to other GTK dialogs + QEventLoop loop; + connect(this, SIGNAL(accept()), &loop, SLOT(quit())); + connect(this, SIGNAL(reject()), &loop, SLOT(quit())); + loop.exec(); + } +} + +bool QGtk2Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + setParent(parent); + setFlags(flags); + setModality(modality); + + gtk_widget_realize(gtkWidget); // creates X window + + if (parent) { + XSetTransientForHint(gdk_x11_drawable_get_xdisplay(gtkWidget->window), + gdk_x11_drawable_get_xid(gtkWidget->window), + parent->winId()); + } + + if (modality != Qt::NonModal) { + gdk_window_set_modal_hint(gtkWidget->window, true); + QGuiApplicationPrivate::showModalWindow(this); + } + + gtk_widget_show(gtkWidget); + return true; +} + +void QGtk2Dialog::hide() +{ + QGuiApplicationPrivate::hideModalWindow(this); + gtk_widget_hide(gtkWidget); +} + +void QGtk2Dialog::onResponse(QGtk2Dialog *dialog, int response) +{ + if (response == GTK_RESPONSE_OK) + emit dialog->accept(); + else + emit dialog->reject(); +} + +QGtk2ColorDialogHelper::QGtk2ColorDialogHelper() +{ + d.reset(new QGtk2Dialog(gtk_color_selection_dialog_new(""))); + connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted())); + connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject())); + + GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(d->gtkDialog())); + g_signal_connect_swapped(gtkColorSelection, "color-changed", G_CALLBACK(onColorChanged), this); +} + +QGtk2ColorDialogHelper::~QGtk2ColorDialogHelper() +{ +} + +bool QGtk2ColorDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + applyOptions(); + return d->show(flags, modality, parent); +} + +void QGtk2ColorDialogHelper::exec() +{ + d->exec(); +} + +void QGtk2ColorDialogHelper::hide() +{ + d->hide(); +} + +void QGtk2ColorDialogHelper::setCurrentColor(const QColor &color) +{ + GtkDialog *gtkDialog = d->gtkDialog(); + GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog)); + GdkColor gdkColor; + gdkColor.red = color.red() << 8; + gdkColor.green = color.green() << 8; + gdkColor.blue = color.blue() << 8; + gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(gtkColorSelection), &gdkColor); + if (color.alpha() < 255) { + gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(gtkColorSelection), true); + gtk_color_selection_set_current_alpha(GTK_COLOR_SELECTION(gtkColorSelection), color.alpha() << 8); + } +} + +QColor QGtk2ColorDialogHelper::currentColor() const +{ + GtkDialog *gtkDialog = d->gtkDialog(); + GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog)); + GdkColor gdkColor; + gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(gtkColorSelection), &gdkColor); + guint16 alpha = gtk_color_selection_get_current_alpha(GTK_COLOR_SELECTION(gtkColorSelection)); + return QColor(gdkColor.red >> 8, gdkColor.green >> 8, gdkColor.blue >> 8, alpha >> 8); +} + +void QGtk2ColorDialogHelper::onAccepted() +{ + emit accept(); + emit colorSelected(currentColor()); +} + +void QGtk2ColorDialogHelper::onColorChanged(QGtk2ColorDialogHelper *dialog) +{ + emit dialog->currentColorChanged(dialog->currentColor()); +} + +void QGtk2ColorDialogHelper::applyOptions() +{ + GtkDialog* gtkDialog = d->gtkDialog(); + gtk_window_set_title(GTK_WINDOW(gtkDialog), options()->windowTitle().toUtf8()); + + GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog)); + gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(gtkColorSelection), options()->testOption(QColorDialogOptions::ShowAlphaChannel)); + + GtkWidget *okButton = 0; + GtkWidget *cancelButton = 0; + GtkWidget *helpButton = 0; + g_object_get(G_OBJECT(gtkDialog), "ok-button", &okButton, "cancel-button", &cancelButton, "help-button", &helpButton, NULL); + if (okButton) + g_object_set(G_OBJECT(okButton), "visible", !options()->testOption(QColorDialogOptions::NoButtons), NULL); + if (cancelButton) + g_object_set(G_OBJECT(cancelButton), "visible", !options()->testOption(QColorDialogOptions::NoButtons), NULL); + if (helpButton) + gtk_widget_hide(helpButton); +} + +QT_END_NAMESPACE + +#include "qgtk2dialoghelpers.moc" diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h new file mode 100644 index 0000000000..9dc6991601 --- /dev/null +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGTK2DIALOGHELPERS_P_H +#define QGTK2DIALOGHELPERS_P_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QGtk2Dialog; + +class QGtk2ColorDialogHelper : public QPlatformColorDialogHelper +{ + Q_OBJECT + +public: + QGtk2ColorDialogHelper(); + ~QGtk2ColorDialogHelper(); + + virtual bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + virtual void exec(); + virtual void hide(); + + virtual void setCurrentColor(const QColor &color); + virtual QColor currentColor() const; + +private Q_SLOTS: + void onAccepted(); + +private: + static void onColorChanged(QGtk2ColorDialogHelper *helper); + void applyOptions(); + + mutable QScopedPointer d; +}; + +QT_END_NAMESPACE + +#endif // QGTK2DIALOGHELPERS_P_H diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp new file mode 100644 index 0000000000..c7e612d1d6 --- /dev/null +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgtk2theme.h" +#include "qgtk2dialoghelpers.h" + +#undef signals +#include + +QT_BEGIN_NAMESPACE + +const char *QGtk2Theme::name = "gtk2"; + +QGtk2Theme::QGtk2Theme() +{ + gtk_init(0, 0); +} + +bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const +{ + return type == ColorDialog; +} + +QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) const +{ + switch (type) { + case ColorDialog: + return new QGtk2ColorDialogHelper; + default: + return 0; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.h b/src/plugins/platformthemes/gtk2/qgtk2theme.h new file mode 100644 index 0000000000..6d8768dd8e --- /dev/null +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGTK2THEME_H +#define QGTK2THEME_H + +#include + +QT_BEGIN_NAMESPACE + +class QGtk2Theme : public QGnomeTheme +{ +public: + QGtk2Theme(); + + virtual bool usePlatformNativeDialog(DialogType type) const; + virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + + static const char *name; +}; + +QT_END_NAMESPACE + +#endif // QGTK2THEME_H diff --git a/src/plugins/platformthemes/platformthemes.pro b/src/plugins/platformthemes/platformthemes.pro new file mode 100644 index 0000000000..23dcda2c82 --- /dev/null +++ b/src/plugins/platformthemes/platformthemes.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +contains(QT_CONFIG, gtk2): SUBDIRS += gtk2 diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 3b0ff3f6c8..0dba5d14d0 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs SUBDIRS *= sqldrivers bearer -qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts generic +qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic qtHaveModule(widgets): SUBDIRS += accessible !wince*:qtHaveModule(widgets): SUBDIRS += printsupport -- cgit v1.2.3 From 4c5b503f335706916a88b44e86c40de34006d887 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Jan 2013 20:15:00 -0800 Subject: Remove unused variables and functions from the source code Change-Id: I5f37414ee4846b4fe774361f49367bc0d5874039 Reviewed-by: Frederik Gladhorn Reviewed-by: Olivier Goffart --- .../ibus/qibusplatforminputcontext.cpp | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index f4e7666a85..53e9b171d5 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -226,26 +226,6 @@ void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint } -/* Kernel keycode -> X keycode table */ -static const unsigned int keycode_table[256] = { - 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 76, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 111, 221, 94, 95, 96, 211, 128, 127, 129, 208, 131, 126, - 108, 109, 112, 111, 113, 181, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, - 239, 160, 174, 176, 222, 157, 123, 110, 139, 134, 209, 210, 133, 115, 116, 117, - 232, 133, 134, 135, 140, 248, 191, 192, 122, 188, 245, 158, 161, 193, 223, 227, - 198, 199, 200, 147, 159, 151, 178, 201, 146, 203, 166, 236, 230, 235, 234, 233, - 163, 204, 253, 153, 162, 144, 164, 177, 152, 190, 208, 129, 130, 231, 209, 210, - 136, 220, 143, 246, 251, 137, 138, 182, 183, 184, 93, 184, 247, 132, 170, 219, - 249, 205, 207, 149, 150, 154, 155, 167, 168, 169, 171, 172, 173, 165, 175, 179, - 180, 0, 185, 186, 187, 118, 119, 120, 121, 229, 194, 195, 196, 197, 148, 202, - 101, 212, 237, 214, 215, 216, 217, 218, 228, 142, 213, 240, 241, 242, 243, 244, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - bool QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press) { -- cgit v1.2.3 From 2f2107c1ba8134026e4aa98d5c7c072c9ce81c19 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 4 Feb 2013 16:51:29 +0100 Subject: Add enablers for Android port in QPlatformMenu We need a couple of functions here for the Android support. Change-Id: I50e27277d7e838e277d616dbd3af9be817fb7197 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenu.h | 2 ++ src/plugins/platforms/cocoa/qcocoamenuitem.h | 1 + 2 files changed, 3 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 9433e9f9c0..439b7f1a75 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -75,6 +75,8 @@ public: void syncModalState(bool modal); + virtual void setIcon(const QIcon &icon) { Q_UNUSED(icon) } + void setText(const QString &text); void setMinimumWidth(int width); void setFont(const QFont &font); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index b28274bc05..0e6d17343d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -74,6 +74,7 @@ public: void setFont(const QFont &font); void setRole(MenuRole role); void setShortcut(const QKeySequence& shortcut); + void setCheckable(bool checkable) { Q_UNUSED(checkable) } void setChecked(bool isChecked); void setEnabled(bool isEnabled); -- cgit v1.2.3 From 83e6d1fe6006ad8e3cf37d5ca412aedae5aab9a4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 1 Jan 2013 01:33:42 +0100 Subject: Add support for getting the paper names available for the printer Task-number: QTBUG-27714 Change-Id: I9bc6f1188f262e43f581add058d7895e1b5bd9e3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/cocoa/qcocoaprintersupport.h | 1 + .../platforms/cocoa/qcocoaprintersupport.mm | 31 ++++++++++++++++++++++ .../printsupport/cups/qcupsprintersupport.cpp | 5 ++++ .../printsupport/cups/qcupsprintersupport_p.h | 1 + .../windows/qwindowsprintersupport.cpp | 5 ++++ .../printsupport/windows/qwindowsprintersupport.h | 1 + 6 files changed, 44 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.h b/src/plugins/platforms/cocoa/qcocoaprintersupport.h index 040b687c4e..83cf1ffada 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintersupport.h +++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.h @@ -55,6 +55,7 @@ public: QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE; QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE; QList supportedPaperSizes(const QPrinterInfo &) const Q_DECL_OVERRIDE; + QList > supportedSizesWithNames(const QPrinterInfo &) const Q_DECL_OVERRIDE; QList availablePrinters() Q_DECL_OVERRIDE; QPrinterInfo printerInfo(const QString &printerName) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.mm b/src/plugins/platforms/cocoa/qcocoaprintersupport.mm index a48db02949..cfa23b7a30 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintersupport.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.mm @@ -138,3 +138,34 @@ QPrinterInfo QCocoaPrinterSupport::printerInfoFromPMPrinter(const PMPrinter &pri return createPrinterInfo(name, description, location, makeAndModel, isDefault, 0); } + +QList > QCocoaPrinterSupport::supportedSizesWithNames(const QPrinterInfo &printerInfo) const +{ + QList > returnValue; + if (printerInfo.isNull()) + return returnValue; + + PMPrinter printer = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(printerInfo.printerName())); + if (!printer) + return returnValue; + + CFArrayRef array; + if (PMPrinterGetPaperList(printer, &array) != noErr) { + PMRelease(printer); + return returnValue; + } + + int count = CFArrayGetCount(array); + for (int i = 0; i < count; ++i) { + PMPaper paper = static_cast(const_cast(CFArrayGetValueAtIndex(array, i))); + double width, height; + if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) { + static const double OnePointInMillimeters = 1.0 / 72.0 * 25.4; + QCFString paperName; + if (PMPaperCreateLocalizedName(paper, printer, &paperName) == noErr) + returnValue.append(qMakePair(QString(paperName), QSizeF(width * OnePointInMillimeters, height * OnePointInMillimeters))); + } + } + PMRelease(printer); + return returnValue; +} diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp index c2e9bd445f..f41d4f5047 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -86,6 +86,11 @@ QList QCupsPrinterSupport::supportedPaperSizes(const QPrint return QCUPSSupport::getCupsPrinterPaperSizes(printerIndex(printerInfo)); } +QList > QCupsPrinterSupport::supportedSizesWithNames(const QPrinterInfo &printerInfo) const +{ + return QCUPSSupport::getCupsPrinterPaperSizesWithNames(printerIndex(printerInfo)); +} + void QCupsPrinterSupport::loadCups() { cupsGetDests = (CupsGetDests) m_cups.resolve("cupsGetDests"); diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index d3f0ff5d90..e9fe24203e 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -67,6 +67,7 @@ public: virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode); virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); virtual QList supportedPaperSizes(const QPrinterInfo &) const; + virtual QList > supportedSizesWithNames(const QPrinterInfo &) const; virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const; virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const; diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp index 469dbdb34e..36e7a3fb8e 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp @@ -93,4 +93,9 @@ QList QWindowsPrinterSupport::supportedPaperSizes(const QPr return QWin32PrintEngine::supportedPaperSizes(printerInfo); } +QList >QWindowsPrinterSupport::supportedSizesWithNames(const QPrinterInfo &printerInfo) const +{ + return QWin32PrintEngine::supportedSizesWithNames(printerInfo); +} + QT_END_NAMESPACE diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h index 3550c3f50c..1d5a4f3da4 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.h +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h @@ -57,6 +57,7 @@ public: virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode); virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); virtual QList supportedPaperSizes(const QPrinterInfo &) const; + virtual QList >supportedSizesWithNames(const QPrinterInfo &printerInfo) const; }; QT_END_NAMESPACE -- cgit v1.2.3 From d57e9b35c94ae6075db0688b954624cb6f32ec51 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 8 Feb 2013 17:12:02 +0100 Subject: QPA Cocoa Menu: Make sure mouse button state is clean after popup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling popUpMenuPositioningItem:atLocation:inView: will swallow any mouse up/released event, if we popup on mouse down/pressed. Since we cache the button state in QNSView, the safest way seems to be to clear this button state. Another option would be to send Cocoa mouse up events for each mouse button, but we prefer to keep things simple. Change-Id: I7f3f369c45e9f5ed9d2ab693bffd8be4a4596ae6 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.mm | 17 +++++------------ src/plugins/platforms/cocoa/qnsview.h | 2 ++ src/plugins/platforms/cocoa/qnsview.mm | 5 +++++ 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index ff3aeaeb11..a92f4e875c 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -48,6 +48,7 @@ #include "qcocoaapplication.h" #include "qcocoamenuloader.h" #include "qcocoawindow.h" +#import "qnsview.h" static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader() { @@ -313,18 +314,10 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatf NSPoint nsPos = NSMakePoint(pos.x(), pos.y()); [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:view]; - // The call above blocks and swallows the mouse release event, so we send a - // synthetic one to bring back any QQuickMouseArea back to a more normal state. - NSEvent *releaseEvent = [NSEvent mouseEventWithType:NSLeftMouseUp - location:nsPos - modifierFlags:0 - timestamp:0 - windowNumber:view.window.windowNumber - context:[NSGraphicsContext currentContext] - eventNumber:0 - clickCount:0 - pressure:1.0]; - [view.window sendEvent:releaseEvent]; + // The call above blocks, and also swallows any mouse release event, + // so we need to clear any mouse button that triggered the menu popup. + if ([view isKindOfClass:[QNSView class]]) + [(QNSView *)view resetMouseButtons]; } QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 8bccc2cf33..eec0cfe5f6 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -84,6 +84,8 @@ QT_END_NAMESPACE - (BOOL)acceptsFirstResponder; - (BOOL)becomeFirstResponder; +- (void)resetMouseButtons; + - (void)handleMouseEvent:(NSEvent *)theEvent; - (void)mouseDown:(NSEvent *)theEvent; - (void)mouseDragged:(NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 5d39dd2d9c..82fde6221d 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -398,6 +398,11 @@ static QTouchDevice *touchDevice = 0; } } +- (void)resetMouseButtons +{ + m_buttons = Qt::NoButton; +} + - (void)handleMouseEvent:(NSEvent *)theEvent { QPoint qtWindowPoint, qtScreenPoint; -- cgit v1.2.3 From 7abc1a6a828eb36d26901d4ea5ecf8b4514f3cd7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Jan 2013 21:28:22 -0800 Subject: Simplify a function to fix a warning reported by ICC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ICC thinks that the return statement is missing: src/plugins/accessible/widgets/itemviews.cpp(867): error #1011: missing return statement at end of non-void function "QAccessibleTableHeaderCell::parent" Clearly it's wrong, but the function is overly complex for no good reason. So just simplify it instead. Change-Id: Ic63029df18b4712d9864a4dc66b6751b2d4574b7 Reviewed-by: Jan Arve Sæther Reviewed-by: Frederik Gladhorn --- src/plugins/accessible/widgets/itemviews.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 71f47a7b56..17764a3c2e 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -1046,14 +1046,11 @@ bool QAccessibleTableHeaderCell::isValid() const QAccessibleInterface *QAccessibleTableHeaderCell::parent() const { - if (false) { #ifndef QT_NO_TREEVIEW - } else if (qobject_cast(view)) { + if (qobject_cast(view)) return new QAccessibleTree(view); #endif - } else { - return new QAccessibleTable(view); - } + return new QAccessibleTable(view); } QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const -- cgit v1.2.3 From 310235593f5ddf6cb0003edcb7ceaa59f3797788 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 13 Feb 2013 11:42:10 +0100 Subject: Fix build with old MinGW Change-Id: I9d7c40c146bb3d14cd1dccab10a70b28722c7c27 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qtwindows_additional.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index 8d59fbd7c6..3b2e9787a2 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -126,6 +126,10 @@ typedef struct tagUPDATELAYEREDWINDOWINFO { // IME. #define IMR_CONFIRMRECONVERTSTRING 0x0005 +#ifndef MAPVK_VK_TO_CHAR +# define MAPVK_VK_TO_CHAR 2 +#endif + #endif // if defined(Q_CC_MINGW) /* Touch is supported from Windows 7 onwards and data structures -- cgit v1.2.3 From 60cde0bd1496c528153d21769dfbcb2b0a9ffc91 Mon Sep 17 00:00:00 2001 From: Jonas Gastal Date: Sat, 9 Feb 2013 22:52:08 -0200 Subject: Fix undefined reference to XSetTransientForHint. Change-Id: If137fbfd566fdd2950f012013031d74e84b16d00 Reviewed-by: J-P Nurmi --- src/plugins/platformthemes/gtk2/gtk2.pro | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro index f22753e96f..bb02192f91 100644 --- a/src/plugins/platformthemes/gtk2/gtk2.pro +++ b/src/plugins/platformthemes/gtk2/gtk2.pro @@ -6,6 +6,7 @@ load(qt_plugin) QT += core-private gui-private platformsupport-private +CONFIG += X11 QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTK2 LIBS += $$QT_LIBS_QGTK2 -- cgit v1.2.3 From 8b06b4136fdf3b20c96389434b737eec00f174ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 3 Nov 2012 16:14:40 +0100 Subject: Zero-initialize paint-device in minimal EGL platform plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic6b39825cf349f8ad8a56b1fb5dd3855f8675519 Reviewed-by: Morten Johan Sørvig Reviewed-by: Samuel Rødal Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp b/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp index da89100359..cb245f2e5c 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglbackingstore.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE QMinimalEglBackingStore::QMinimalEglBackingStore(QWindow *window) : QPlatformBackingStore(window) , m_context(new QOpenGLContext) + , m_device(0) { m_context->setFormat(window->requestedFormat()); m_context->setScreen(window->screen()); -- cgit v1.2.3 From 8de8800de1523d8ed170076fc1cab15f44ec1806 Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Wed, 13 Feb 2013 17:21:48 +0100 Subject: Cocoa: QSystemTrayIcon showing native messages on Mountain Lion. This patch enables usage of the new NSUserNotificationCenter as part of Mountain Lion. On earlier versions, or if compiled on earlier versions, Growl will be used, if installed. Change-Id: I676f9c63aa3c1ada19d36b6310ae90915be63011 Reviewed-by: Jake Petroules Reviewed-by: Richard J. Moore --- .../platforms/cocoa/qcocoasystemtrayicon.mm | 47 +++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index e092db8172..99f533b33a 100755 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -93,7 +93,11 @@ QT_USE_NAMESPACE @class QT_MANGLE_NAMESPACE(QNSMenu); @class QT_MANGLE_NAMESPACE(QNSImageView); -@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject { +@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 + +#endif + { @public QCocoaSystemTrayIcon *systray; NSStatusItem *item; @@ -108,6 +112,11 @@ QT_USE_NAMESPACE -(QRectF)geometry; - (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton; - (void)doubleClickSelector:(id)sender; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; +- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification; +#endif @end @interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView { @@ -132,9 +141,19 @@ class QSystemTrayIconSys public: QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) { item = [[QT_MANGLE_NAMESPACE(QNSStatusItem) alloc] initWithSysTray:sys]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item]; + } +#endif } ~QSystemTrayIconSys() { [[[item item] view] setHidden: YES]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil]; + } +#endif [item release]; } QT_MANGLE_NAMESPACE(QNSStatusItem) *item; @@ -223,6 +242,18 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess if (!m_sys) return; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { + NSUserNotification *notification = [[NSUserNotification alloc] init]; + notification.title = [NSString stringWithUTF8String:title.toUtf8().data()]; + notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()]; + + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + + return; + } +#endif + #ifdef QT_MAC_SYSTEMTRAY_USE_GROWL // Make sure that we have Growl installed on the machine we are running on. QCFType cfurl; @@ -439,6 +470,20 @@ QT_END_NAMESPACE emit systray->activated(QPlatformSystemTrayIcon::DoubleClick); } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { + Q_UNUSED(center); + Q_UNUSED(notification); + return YES; +} + +- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { + Q_UNUSED(center); + Q_UNUSED(notification); + emit systray->messageClicked(); +} +#endif + @end class QSystemTrayIconQMenu : public QPlatformMenu -- cgit v1.2.3 From 468d010fdf851804d8f02dd93c382b512ce5c67e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 1 Feb 2013 10:36:42 +0100 Subject: Introduce a native file dialog for GTK+ 2.x Change-Id: I3cb29218a54b9120c2ab6e2e32b810a111a7bf3d Reviewed-by: Friedemann Kleint Reviewed-by: Jens Bache-Wiig Reviewed-by: Shawn Rutledge --- .../platformthemes/gtk2/qgtk2dialoghelpers.cpp | 239 +++++++++++++++++++++ .../platformthemes/gtk2/qgtk2dialoghelpers.h | 40 ++++ src/plugins/platformthemes/gtk2/qgtk2theme.cpp | 4 +- 3 files changed, 282 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp index 19d4e9e469..4f9210a3af 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp @@ -233,6 +233,245 @@ void QGtk2ColorDialogHelper::applyOptions() gtk_widget_hide(helpButton); } +QGtk2FileDialogHelper::QGtk2FileDialogHelper() +{ + d.reset(new QGtk2Dialog(gtk_file_chooser_dialog_new("", 0, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, NULL))); + connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted())); + connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject())); + + g_signal_connect(GTK_FILE_CHOOSER(d->gtkDialog()), "selection-changed", G_CALLBACK(onSelectionChanged), this); + g_signal_connect_swapped(GTK_FILE_CHOOSER(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this); +} + +QGtk2FileDialogHelper::~QGtk2FileDialogHelper() +{ +} + +bool QGtk2FileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + _dir.clear(); + _selection.clear(); + + applyOptions(); + return d->show(flags, modality, parent); +} + +void QGtk2FileDialogHelper::exec() +{ + d->exec(); +} + +void QGtk2FileDialogHelper::hide() +{ + // After GtkFileChooserDialog has been hidden, gtk_file_chooser_get_current_folder() + // & gtk_file_chooser_get_filenames() will return bogus values -> cache the actual + // values before hiding the dialog + _dir = directory(); + _selection = selectedFiles(); + + d->hide(); +} + +bool QGtk2FileDialogHelper::defaultNameFilterDisables() const +{ + return false; +} + +void QGtk2FileDialogHelper::setDirectory(const QString &directory) +{ + GtkDialog *gtkDialog = d->gtkDialog(); + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toUtf8()); +} + +QString QGtk2FileDialogHelper::directory() const +{ + // While GtkFileChooserDialog is hidden, gtk_file_chooser_get_current_folder() + // returns a bogus value -> return the cached value before hiding + if (!_dir.isEmpty()) + return _dir; + + QString ret; + GtkDialog *gtkDialog = d->gtkDialog(); + gchar *folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(gtkDialog)); + if (folder) { + ret = QString::fromUtf8(folder); + g_free(folder); + } + return ret; +} + +void QGtk2FileDialogHelper::selectFile(const QString &filename) +{ + GtkDialog *gtkDialog = d->gtkDialog(); + gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toUtf8()); +} + +QStringList QGtk2FileDialogHelper::selectedFiles() const +{ + // While GtkFileChooserDialog is hidden, gtk_file_chooser_get_filenames() + // returns a bogus value -> return the cached value before hiding + if (!_selection.isEmpty()) + return _selection; + + QStringList selection; + GtkDialog *gtkDialog = d->gtkDialog(); + GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(gtkDialog)); + for (GSList *it = filenames; it; it = it->next) + selection += QString::fromUtf8((const char*)it->data); + g_slist_free(filenames); + return selection; +} + +void QGtk2FileDialogHelper::setFilter() +{ + applyOptions(); +} + +void QGtk2FileDialogHelper::selectNameFilter(const QString &filter) +{ + GtkFileFilter *gtkFilter = _filters.value(filter); + if (gtkFilter) { + GtkDialog *gtkDialog = d->gtkDialog(); + gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(gtkDialog), gtkFilter); + } +} + +QString QGtk2FileDialogHelper::selectedNameFilter() const +{ + GtkDialog *gtkDialog = d->gtkDialog(); + GtkFileFilter *gtkFilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(gtkDialog)); + return _filterNames.value(gtkFilter); +} + +void QGtk2FileDialogHelper::onAccepted() +{ + emit accept(); + + QString filter = selectedNameFilter(); + if (filter.isEmpty()) + emit filterSelected(filter); + + QStringList files = selectedFiles(); + emit filesSelected(files); + if (files.count() == 1) + emit fileSelected(files.first()); +} + +void QGtk2FileDialogHelper::onSelectionChanged(GtkDialog *gtkDialog, QGtk2FileDialogHelper *helper) +{ + QString selection; + gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(gtkDialog)); + if (filename) { + selection = QString::fromUtf8(filename); + g_free(filename); + } + emit helper->currentChanged(selection); +} + +void QGtk2FileDialogHelper::onCurrentFolderChanged(QGtk2FileDialogHelper *dialog) +{ + emit dialog->directoryEntered(dialog->directory()); +} + +static GtkFileChooserAction gtkFileChooserAction(const QSharedPointer &options) +{ + switch (options->fileMode()) { + case QFileDialogOptions::AnyFile: + case QFileDialogOptions::ExistingFile: + case QFileDialogOptions::ExistingFiles: + if (options->acceptMode() == QFileDialogOptions::AcceptOpen) + return GTK_FILE_CHOOSER_ACTION_OPEN; + else + return GTK_FILE_CHOOSER_ACTION_SAVE; + case QFileDialogOptions::Directory: + case QFileDialogOptions::DirectoryOnly: + default: + if (options->acceptMode() == QFileDialogOptions::AcceptOpen) + return GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; + else + return GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER; + } +} + +void QGtk2FileDialogHelper::applyOptions() +{ + GtkDialog *gtkDialog = d->gtkDialog(); + const QSharedPointer &opts = options(); + + gtk_window_set_title(GTK_WINDOW(gtkDialog), opts->windowTitle().toUtf8()); + gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(gtkDialog), true); + + const GtkFileChooserAction action = gtkFileChooserAction(opts); + gtk_file_chooser_set_action(GTK_FILE_CHOOSER(gtkDialog), action); + + const bool selectMultiple = opts->fileMode() == QFileDialogOptions::ExistingFiles; + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(gtkDialog), selectMultiple); + + const bool confirmOverwrite = !opts->testOption(QFileDialogOptions::DontConfirmOverwrite); + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(gtkDialog), confirmOverwrite); + + const QStringList nameFilters = opts->nameFilters(); + if (!nameFilters.isEmpty()) + setNameFilters(nameFilters); + + const QString initialDirectory = opts->initialDirectory(); + if (!initialDirectory.isEmpty()) + setDirectory(initialDirectory); + + foreach (const QString &filename, opts->initiallySelectedFiles()) + selectFile(filename); + + const QString initialNameFilter = opts->initiallySelectedNameFilter(); + if (!initialNameFilter.isEmpty()) + selectNameFilter(initialNameFilter); + + GtkWidget *acceptButton = gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_OK); + if (acceptButton) { + if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) + gtk_button_set_label(GTK_BUTTON(acceptButton), opts->labelText(QFileDialogOptions::Accept).toUtf8()); + else if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) + gtk_button_set_label(GTK_BUTTON(acceptButton), GTK_STOCK_OPEN); + else + gtk_button_set_label(GTK_BUTTON(acceptButton), GTK_STOCK_SAVE); + } + + GtkWidget *rejectButton = gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_CANCEL); + if (rejectButton) { + if (opts->isLabelExplicitlySet(QFileDialogOptions::Reject)) + gtk_button_set_label(GTK_BUTTON(rejectButton), opts->labelText(QFileDialogOptions::Reject).toUtf8()); + else + gtk_button_set_label(GTK_BUTTON(rejectButton), GTK_STOCK_CANCEL); + } +} + +void QGtk2FileDialogHelper::setNameFilters(const QStringList& filters) +{ + GtkDialog *gtkDialog = d->gtkDialog(); + foreach (GtkFileFilter *filter, _filters) + gtk_file_chooser_remove_filter(GTK_FILE_CHOOSER(gtkDialog), filter); + + _filters.clear(); + _filterNames.clear(); + + foreach (const QString &filter, filters) { + GtkFileFilter *gtkFilter = gtk_file_filter_new(); + const QString name = filter.left(filter.indexOf(QLatin1Char('('))); + const QStringList extensions = cleanFilterList(filter); + + gtk_file_filter_set_name(gtkFilter, name.isEmpty() ? extensions.join(QStringLiteral(", ")).toUtf8() : name.toUtf8()); + foreach (const QString &ext, extensions) + gtk_file_filter_add_pattern(gtkFilter, ext.toUtf8()); + + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(gtkDialog), gtkFilter); + + _filters.insert(filter, gtkFilter); + _filterNames.insert(gtkFilter, filter); + } +} + QT_END_NAMESPACE #include "qgtk2dialoghelpers.moc" diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h index 9dc6991601..301a2aa6ae 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h @@ -45,6 +45,9 @@ #include #include +typedef struct _GtkDialog GtkDialog; +typedef struct _GtkFileFilter GtkFileFilter; + QT_BEGIN_NAMESPACE class QGtk2Dialog; @@ -74,6 +77,43 @@ private: mutable QScopedPointer d; }; +class QGtk2FileDialogHelper : public QPlatformFileDialogHelper +{ + Q_OBJECT + +public: + QGtk2FileDialogHelper(); + ~QGtk2FileDialogHelper(); + + virtual bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + virtual void exec(); + virtual void hide(); + + virtual bool defaultNameFilterDisables() const; + virtual void setDirectory(const QString &directory); + virtual QString directory() const; + virtual void selectFile(const QString &filename); + virtual QStringList selectedFiles() const; + virtual void setFilter(); + virtual void selectNameFilter(const QString &filter); + virtual QString selectedNameFilter() const; + +private Q_SLOTS: + void onAccepted(); + +private: + static void onSelectionChanged(GtkDialog *dialog, QGtk2FileDialogHelper *helper); + static void onCurrentFolderChanged(QGtk2FileDialogHelper *helper); + void applyOptions(); + void setNameFilters(const QStringList &filters); + + QString _dir; + QStringList _selection; + QHash _filters; + QHash _filterNames; + mutable QScopedPointer d; +}; + QT_END_NAMESPACE #endif // QGTK2DIALOGHELPERS_P_H diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp index c7e612d1d6..c685d7b13c 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp @@ -56,7 +56,7 @@ QGtk2Theme::QGtk2Theme() bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const { - return type == ColorDialog; + return type == ColorDialog || type == FileDialog; } QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) const @@ -64,6 +64,8 @@ QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) c switch (type) { case ColorDialog: return new QGtk2ColorDialogHelper; + case FileDialog: + return new QGtk2FileDialogHelper; default: return 0; } -- cgit v1.2.3 From 0768920dbdabef25eb7d41e8dbba891704b24f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 16 Feb 2013 14:56:50 +0100 Subject: Remove ifdefs for supporting Mac OS <= 10.5 Qt5 requires Mac OS 10.6, so we can remove checks such as if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 Change-Id: Iea21727a277291148704ecf9677ed0b68c24920f Reviewed-by: Thiago Macieira --- .../platforms/cocoa/qcocoaapplicationdelegate.h | 13 ------------- src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 2 -- .../platforms/cocoa/qcocoafiledialoghelper.mm | 4 ---- src/plugins/platforms/cocoa/qcocoahelpers.mm | 2 -- src/plugins/platforms/cocoa/qcocoaintrospection.mm | 4 ---- src/plugins/platforms/cocoa/qmultitouch_mac.mm | 5 ----- src/plugins/platforms/cocoa/qmultitouch_mac_p.h | 4 ---- src/plugins/platforms/cocoa/qnswindowdelegate.h | 20 -------------------- src/plugins/platforms/cocoa/qpaintengine_mac.mm | 16 +++------------- src/plugins/platforms/cocoa/qprintengine_mac.mm | 18 +----------------- 10 files changed, 4 insertions(+), 84 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h index 6dd7ea2fb3..e44b2d1b6d 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h @@ -93,19 +93,6 @@ @class QT_MANGLE_NAMESPACE(QCocoaMenuLoader); -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 - -@protocol NSApplicationDelegate -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification; -- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames; -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender; -- (void)applicationDidBecomeActive:(NSNotification *)notification; -- (void)applicationDidResignActive:(NSNotification *)notification; -@end - -#endif - @interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject { bool startedQuit; NSMenu *dockMenu; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index bb907674dc..987600c6b4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -490,14 +490,12 @@ static bool IsMouseOrKeyEvent( NSEvent* event ) case NSOtherMouseUp: case NSOtherMouseDragged: #ifndef QT_NO_GESTURES -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 case NSEventTypeGesture: // touch events case NSEventTypeMagnify: case NSEventTypeSwipe: case NSEventTypeRotate: case NSEventTypeBeginGesture: case NSEventTypeEndGesture: -#endif #endif // QT_NO_GESTURES result = true; break; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index faea417f0f..9cc0353dc6 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -77,11 +77,7 @@ typedef QSharedPointer SharedPointerFileDialogOptions; @class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate); @interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 : NSObject -#else - : NSObject -#endif { @public NSOpenPanel *mOpenPanel; diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index dc43666bb6..29a8c49511 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -475,11 +475,9 @@ CGColorSpaceRef qt_mac_genericColorSpace() { #if 0 if (!m_genericColorSpace) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); } else -#endif { m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); } diff --git a/src/plugins/platforms/cocoa/qcocoaintrospection.mm b/src/plugins/platforms/cocoa/qcocoaintrospection.mm index ffb6ae4294..806effc929 100644 --- a/src/plugins/platforms/cocoa/qcocoaintrospection.mm +++ b/src/plugins/platforms/cocoa/qcocoaintrospection.mm @@ -83,7 +83,6 @@ void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class prox if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) #endif { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 // The following code replaces the _implementation_ for the selector we want to hack // (originalSel) with the implementation found in proxyClass. Then it creates // a new 'backup' method inside baseClass containing the old, original, @@ -104,7 +103,6 @@ void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class prox Method backupMethod = class_getInstanceMethod(proxyClass, backupSel); class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod)); } -#endif } } @@ -114,11 +112,9 @@ void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL b if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) #endif { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 Method originalMethod = class_getInstanceMethod(baseClass, originalSel); Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel); method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass)); -#endif } } diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm index 337d962c7f..fc0048f998 100644 --- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm +++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm @@ -42,8 +42,6 @@ #include "qmultitouch_mac_p.h" #include "qcocoahelpers.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - QT_BEGIN_NAMESPACE QHash QCocoaTouch::_currentTouches; @@ -214,6 +212,3 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch) } QT_END_NAMESPACE - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac_p.h b/src/plugins/platforms/cocoa/qmultitouch_mac_p.h index 1244b8223f..736eb3f878 100644 --- a/src/plugins/platforms/cocoa/qmultitouch_mac_p.h +++ b/src/plugins/platforms/cocoa/qmultitouch_mac_p.h @@ -61,8 +61,6 @@ #include #include -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - QT_BEGIN_NAMESPACE class QCocoaTouch @@ -92,7 +90,5 @@ class QCocoaTouch QT_END_NAMESPACE -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - #endif // QMULTITOUCH_MAC_P_H diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index 53bbeb1318..98ad7b8c9d 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -46,26 +46,6 @@ #include "qcocoawindow.h" -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 -@protocol NSWindowDelegate -//- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize; -//- (void)windowDidMiniaturize:(NSNotification*)notification; -- (void)windowDidResize:(NSNotification *)notification; -- (void)windowWillClose:(NSNotification *)notification; -//- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame; -- (void)windowDidMove:(NSNotification *)notification; -//- (BOOL)windowShouldClose:(id)window; -//- (void)windowDidDeminiaturize:(NSNotification *)notification; -//- (void)windowDidBecomeMain:(NSNotification*)notification; -//- (void)windowDidResignMain:(NSNotification*)notification; -//- (void)windowDidBecomeKey:(NSNotification*)notification; -//- (void)windowDidResignKey:(NSNotification*)notification; -//- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu; -//- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard; -//- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame; -@end -#endif - @interface QNSWindowDelegate : NSObject { QCocoaWindow *m_cocoaWindow; diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 3163ae947b..56ab732a32 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -90,14 +90,11 @@ void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig if (rgn.isEmpty()) { CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); } else { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { QCFType shape = qt_mac_QRegionToHIMutableShape(rgn); Q_ASSERT(!HIShapeIsEmpty(shape)); HIShapeReplacePathInCGContext(shape, hd); - } else -#endif - { + } else { QVector rects = rgn.rects(); const int count = rects.size(); for (int i = 0; i < count; i++) { @@ -338,11 +335,9 @@ CGColorSpaceRef QCoreGraphicsPaintEngine::macGenericColorSpace() { #if 0 if (!m_genericColorSpace) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); } else -#endif { m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); } @@ -1185,7 +1180,6 @@ extern "C" { void QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode) { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { int cg_mode = kCGBlendModeNormal; switch (mode) { @@ -1267,11 +1261,9 @@ QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode) if (cg_mode > -1) { CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode)); } - } else -#endif - // The standard porter duff ops. - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3 + } else if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3 && mode <= QPainter::CompositionMode_Xor) { + // The standard porter duff ops. int cg_mode = kCGCompositeModeCopy; switch (mode) { case QPainter::CompositionMode_SourceOver: @@ -1317,7 +1309,6 @@ QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode) if (cg_mode > -1) CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode)); } else { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) bool needPrivateAPI = false; if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { int cg_mode = kCGBlendModeNormal; @@ -1367,7 +1358,6 @@ QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode) else CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode)); } -#endif } } diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 54019372bc..4570a663f6 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -190,23 +190,7 @@ QList QMacPrintEnginePrivate::supportedResolutions() const if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) { PMResolution res; OSStatus status = PMPrinterGetPrinterResolutionCount(printer, &resCount); - if (status == kPMNotImplemented) { -#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5) - // *Sigh* we have to use the non-indexed version. - if (PMPrinterGetPrinterResolution(printer, kPMMinSquareResolution, &res) == noErr) - resolutions.append(int(res.hRes)); - if (PMPrinterGetPrinterResolution(printer, kPMMaxSquareResolution, &res) == noErr) { - QVariant var(int(res.hRes)); - if (!resolutions.contains(var)) - resolutions.append(var); - } - if (PMPrinterGetPrinterResolution(printer, kPMDefaultResolution, &res) == noErr) { - QVariant var(int(res.hRes)); - if (!resolutions.contains(var)) - resolutions.append(var); - } -#endif - } else if (status == noErr) { + if (status == noErr) { // According to the docs, index start at 1. for (UInt32 i = 1; i <= resCount; ++i) { if (PMPrinterGetIndexedPrinterResolution(printer, i, &res) == noErr) -- cgit v1.2.3 From 4d14d14021ee67b30e691dc96267ffb0312e3f26 Mon Sep 17 00:00:00 2001 From: anknight Date: Thu, 14 Feb 2013 15:26:32 +0200 Subject: KMS QPA Plugin: .pro file improvements - Use qtHaveModule to check for OpenGL - Add __GBM__ to pick up the correct native types in the Mesa EGL headers Change-Id: Idfc0e81e95672b08ba8f259b9d7edf2b25fd1bad Reviewed-by: Andy Nichols --- src/plugins/platforms/kms/kms.pro | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro index c0300e0960..711cf9e5c7 100644 --- a/src/plugins/platforms/kms/kms.pro +++ b/src/plugins/platforms/kms/kms.pro @@ -4,9 +4,10 @@ PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QKmsIntegrationPlugin load(qt_plugin) -QT += core-private gui-private platformsupport-private opengl-private +QT += core-private gui-private platformsupport-private +qtHaveModule(opengl):QT += opengl-private -DEFINES += MESA_EGL_NO_X11_HEADERS +DEFINES += MESA_EGL_NO_X11_HEADERS __GBM__ CONFIG += link_pkgconfig egl qpa/genericunixfontdatabase -- cgit v1.2.3 From 936aceb5f204e6f51b69de5555d7d8337677c9c3 Mon Sep 17 00:00:00 2001 From: anknight Date: Thu, 14 Feb 2013 15:29:10 +0200 Subject: KMS QPA Plugin: use GBM cursor writer GBM provides a way to write directly to a buffer object that gets set as the drmMode cursor. This eliminates the need to create a GL texture and opens this class up to platforms that support GBM but not OpenGL. Change-Id: I7297827387ef9a717a5287b5484f14c9987b4158 Reviewed-by: Andy Nichols --- src/plugins/platforms/kms/qkmscursor.cpp | 65 ++++++++------------------------ src/plugins/platforms/kms/qkmscursor.h | 10 ++--- 2 files changed, 19 insertions(+), 56 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp index d5a28dbc9a..da5dc9bb06 100644 --- a/src/plugins/platforms/kms/qkmscursor.cpp +++ b/src/plugins/platforms/kms/qkmscursor.cpp @@ -48,22 +48,17 @@ QT_BEGIN_NAMESPACE QKmsCursor::QKmsCursor(QKmsScreen *screen) : m_screen(screen), m_graphicsBufferManager(screen->device()->gbmDevice()), + m_cursorBufferObject(gbm_bo_create(m_graphicsBufferManager, 64, 64, GBM_FORMAT_ARGB8888, + GBM_BO_USE_CURSOR_64X64|GBM_BO_USE_WRITE)), + m_cursorImage(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)), m_moved(false) { - gbm_bo *bo = gbm_bo_create(m_graphicsBufferManager, 64, 64, - GBM_BO_FORMAT_ARGB8888, - GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_RENDERING); - - m_eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR, - bo, 0); - gbm_bo_destroy(bo); - m_cursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); } QKmsCursor::~QKmsCursor() { - drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), - 0, 0, 0); + drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0, 0); + gbm_bo_destroy(m_cursorBufferObject); } void QKmsCursor::pointerEvent(const QMouseEvent &event) @@ -78,58 +73,30 @@ void QKmsCursor::pointerEvent(const QMouseEvent &event) } } -void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window) +void QKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) { Q_UNUSED(window) if (!m_moved) drmModeMoveCursor(m_screen->device()->fd(), m_screen->crtcId(), 0, 0); - const Qt::CursorShape newShape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor; + const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor; if (newShape != Qt::BitmapCursor) { m_cursorImage->set(newShape); } else { - m_cursorImage->set(widgetCursor->pixmap().toImage(), - widgetCursor->hotSpot().x(), - widgetCursor->hotSpot().y()); - } - - if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) { - qWarning("failed to set hardware cursor: larger than 64x64."); - return; - } - - QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_RGB32); - - //Load cursor image into EGLImage - GLuint cursorTexture; - glGenTextures(1, &cursorTexture); - glBindTexture(GL_TEXTURE_2D, cursorTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - //TODO: Format may be wrong here, need a color icon to test. - if (m_eglImage != EGL_NO_IMAGE_KHR) { - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cursorImage.width(), - cursorImage.height(), GL_RGBA, - GL_UNSIGNED_BYTE, cursorImage.constBits()); - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cursorImage.width(), - cursorImage.height(), 0, GL_RGBA, - GL_UNSIGNED_BYTE, cursorImage.constBits()); + m_cursorImage->set(windowCursor->pixmap().toImage(), + windowCursor->hotSpot().x(), + windowCursor->hotSpot().y()); } - //EGLImage needs to contain sprite before calling this: - gbm_bo *bufferObject = gbm_bo_import(m_graphicsBufferManager, GBM_BO_IMPORT_EGL_IMAGE, - m_eglImage, GBM_BO_USE_CURSOR_64X64); - quint32 handle = gbm_bo_get_handle(bufferObject).u32; + if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) + qWarning("Warning: cursor larger than 64x64; only 64x64 pixels will be shown."); - gbm_bo_destroy(bufferObject); + QImage cursorImage = m_cursorImage->image()-> + convertToFormat(QImage::Format_ARGB32).copy(0, 0, 64, 64); + gbm_bo_write(m_cursorBufferObject, cursorImage.constBits(), cursorImage.byteCount()); + quint32 handle = gbm_bo_get_handle(m_cursorBufferObject).u32; int status = drmModeSetCursor(m_screen->device()->fd(), m_screen->crtcId(), handle, 64, 64); diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h index fda47ebedc..ee65b01e36 100644 --- a/src/plugins/platforms/kms/qkmscursor.h +++ b/src/plugins/platforms/kms/qkmscursor.h @@ -44,15 +44,11 @@ #include -#define EGL_EGLEXT_PROTOTYPES 1 - -#include -#include - QT_BEGIN_NAMESPACE class QKmsScreen; class gbm_device; +class gbm_bo; class QKmsCursor : public QPlatformCursor { @@ -61,12 +57,12 @@ public: ~QKmsCursor(); void pointerEvent(const QMouseEvent &event); - void changeCursor(QCursor *widgetCursor, QWindow *window); + void changeCursor(QCursor *windowCursor, QWindow *window); private: QKmsScreen *m_screen; gbm_device *m_graphicsBufferManager; - EGLImageKHR m_eglImage; + gbm_bo *m_cursorBufferObject; QPlatformCursorImage *m_cursorImage; bool m_moved; }; -- cgit v1.2.3 From f8fdeb68b6e1a710438fc9084a2a3b1b9b6744fa Mon Sep 17 00:00:00 2001 From: anknight Date: Thu, 14 Feb 2013 14:52:58 +0200 Subject: KMS QPA Plugin: use preferred mode when selecting mode This should select the best mode (likely the currently running mode) for the display instead of the first one found. The built-in mode was left as a fallback. Change-Id: I4e1bc798df6f310b001566ab76cb9def3224a7ed Reviewed-by: Andy Nichols --- src/plugins/platforms/kms/qkmsscreen.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp index 123dcc283f..892f7bb01f 100644 --- a/src/plugins/platforms/kms/qkmsscreen.cpp +++ b/src/plugins/platforms/kms/qkmsscreen.cpp @@ -124,10 +124,14 @@ void QKmsScreen::initializeScreenMode() drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId); drmModeModeInfo *mode = 0; - if (connector->count_modes > 0) - mode = &connector->modes[0]; - else - mode = &builtin_1024x768; + for (int i = 0; i < connector->count_modes; ++i) { + if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) { + mode = &connector->modes[i]; + break; + } + } + if (!mode) + mode = mode = &builtin_1024x768; drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]); if (encoder == 0) -- cgit v1.2.3 From c7a51f1858a8cac5cdc458b575df1f0e064e3853 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 8 Feb 2013 20:05:34 +0100 Subject: Added QOffscreenSurface class. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inherits QSurface and allows to use OpenGL from an arbitrary thread. Platform plugins can implement QPlatformOffscreenSurface, otherwise an invisible QWindow is used by QOffscreenSurface. This patch includes an implementation of QOffscreenSurface for XCB and EglFS platform plugins using pbuffers. Change-Id: I57b4fc1db417331f34826dcfa754b7698782fde4 Reviewed-by: Lars Knoll Reviewed-by: Samuel Rødal --- src/plugins/platforms/eglfs/qeglfscontext.cpp | 18 ++++--- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 8 +++ src/plugins/platforms/eglfs/qeglfsintegration.h | 1 + src/plugins/platforms/xcb/qglxintegration.cpp | 60 +++++++++++++++++++++-- src/plugins/platforms/xcb/qglxintegration.h | 20 ++++++++ src/plugins/platforms/xcb/qxcbintegration.cpp | 21 +++++++- src/plugins/platforms/xcb/qxcbintegration.h | 2 + 7 files changed, 118 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 1f0c373818..06db4e02db 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -45,6 +45,8 @@ #include "qeglfshooks.h" #include "qeglfsintegration.h" +#include +#include #include QT_BEGIN_NAMESPACE @@ -62,16 +64,20 @@ bool QEglFSContext::makeCurrent(QPlatformSurface *surface) EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - QEglFSWindow *window = static_cast(surface); - return window->surface(); + if (surface->surface()->surfaceClass() == QSurface::Window) + return static_cast(surface)->surface(); + else + return static_cast(surface)->pbuffer(); } void QEglFSContext::swapBuffers(QPlatformSurface *surface) { - QEglFSWindow *window = static_cast(surface); - // draw the cursor - if (QEglFSCursor *cursor = static_cast(window->screen()->cursor())) - cursor->paintOnScreen(); + if (surface->surface()->surfaceClass() == QSurface::Window) { + QEglFSWindow *window = static_cast(surface); + // draw the cursor + if (QEglFSCursor *cursor = static_cast(window->screen()->cursor())) + cursor->paintOnScreen(); + } QEGLPlatformContext::swapBuffers(surface); } diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 9c48ba1575..dd212c80a0 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #if !defined(QT_NO_EVDEV) #include @@ -62,6 +63,7 @@ #include #include #include +#include #include #include "qeglfscontext.h" @@ -154,6 +156,12 @@ QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLCo return new QEglFSContext(hooks->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay); } +QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const +{ + QEglFSScreen *screen = static_cast(surface->screen()->handle()); + return new QEGLPbuffer(screen->display(), hooks->surfaceFormatFor(surface->requestedFormat()), surface); +} + QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const { return mFontDb; diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 9eae8d2703..e048c5d310 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -61,6 +61,7 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const; QPlatformNativeInterface *nativeInterface() const; QPlatformFontDatabase *fontDatabase() const; diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 23bec15b48..5e2731430d 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -50,6 +50,7 @@ #include #include +#include #include "qglxintegration.h" #include @@ -270,6 +271,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat , m_screen(screen) , m_context(0) , m_format(format) + , m_isPBufferCurrent(false) { m_shareContext = 0; if (share) @@ -390,19 +392,35 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface) { Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface); - GLXDrawable glxDrawable = static_cast(surface)->xcb_window(); - - return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxDrawable, m_context); + QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass(); + if (surfaceClass == QSurface::Window) { + m_isPBufferCurrent = false; + QXcbWindow *window = static_cast(surface); + return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), window->xcb_window(), m_context); + } else if (surfaceClass == QSurface::Offscreen) { + m_isPBufferCurrent = true; + QGLXPbuffer *pbuffer = static_cast(surface); + return glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), pbuffer->pbuffer(), pbuffer->pbuffer(), m_context); + } + return false; } void QGLXContext::doneCurrent() { - glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0); + if (m_isPBufferCurrent) + glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0, 0); + else + glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0); + m_isPBufferCurrent = false; } void QGLXContext::swapBuffers(QPlatformSurface *surface) { - GLXDrawable glxDrawable = static_cast(surface)->xcb_window(); + GLXDrawable glxDrawable = 0; + if (surface->surface()->surfaceClass() == QSurface::Offscreen) + glxDrawable = static_cast(surface)->pbuffer(); + else + glxDrawable = static_cast(surface)->xcb_window(); glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable); } @@ -454,4 +472,36 @@ bool QGLXContext::isValid() const return m_context != 0; } + +QGLXPbuffer::QGLXPbuffer(QOffscreenSurface *offscreenSurface) + : QPlatformOffscreenSurface(offscreenSurface) + , m_format(offscreenSurface->requestedFormat()) + , m_screen(static_cast(offscreenSurface->screen()->handle())) + , m_pbuffer(0) +{ + GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), m_format); + + if (config) { + const int attributes[] = { + GLX_PBUFFER_WIDTH, offscreenSurface->size().width(), + GLX_PBUFFER_HEIGHT, offscreenSurface->size().height(), + GLX_LARGEST_PBUFFER, False, + GLX_PRESERVED_CONTENTS, False, + GLX_NONE + }; + + m_pbuffer = glXCreatePbuffer(DISPLAY_FROM_XCB(m_screen), config, attributes); + + if (m_pbuffer) + m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(m_screen), config); + } +} + +QGLXPbuffer::~QGLXPbuffer() +{ + if (m_pbuffer) + glXDestroyPbuffer(DISPLAY_FROM_XCB(m_screen), m_pbuffer); +} + + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 78e9985334..d10b1d441b 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -46,6 +46,7 @@ #include "qxcbscreen.h" #include +#include #include #include @@ -89,6 +90,25 @@ private: GLXContext m_context; GLXContext m_shareContext; QSurfaceFormat m_format; + bool m_isPBufferCurrent; +}; + + +class QGLXPbuffer : public QPlatformOffscreenSurface +{ +public: + explicit QGLXPbuffer(QOffscreenSurface *offscreenSurface); + ~QGLXPbuffer(); + + QSurfaceFormat format() const { return m_format; } + bool isValid() const { return m_pbuffer != 0; } + + GLXPbuffer pbuffer() const { return m_pbuffer; } + +private: + QSurfaceFormat m_format; + QXcbScreen *m_screen; + GLXPbuffer m_pbuffer; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 1840dd1ce5..d0b0ab8d02 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -78,10 +78,12 @@ #elif defined(XCB_USE_EGL) #include "qxcbeglsurface.h" #include +#include #endif #include #include +#include #ifndef QT_NO_ACCESSIBILITY #include #ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE @@ -168,7 +170,10 @@ public: EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - return static_cast(surface)->eglSurface()->surface(); + if (surface->surface()->surfaceClass() == QSurface::Window) + return static_cast(surface)->eglSurface()->surface(); + else + return static_cast(surface)->pbuffer(); } private: @@ -205,6 +210,20 @@ QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *wind return new QXcbBackingStore(window); } +QPlatformOffscreenSurface *QXcbIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const +{ +#if defined(XCB_USE_GLX) + return new QGLXPbuffer(surface); +#elif defined(XCB_USE_EGL) + QXcbScreen *screen = static_cast(surface->screen()->handle()); + return new QEGLPbuffer(screen->connection()->egl_display(), surface->requestedFormat(), surface); +#else + Q_UNUSED(surface); + qWarning("QXcbIntegration: Cannot create platform offscreen surface, neither GLX nor EGL are enabled"); + return 0; +#endif +} + bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index cd6c2fd73c..13b3b115ca 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -68,6 +68,8 @@ public: #endif QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const; + bool hasCapability(Capability cap) const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; -- cgit v1.2.3 From 7c33ae6a7bbbd42ce70acf77aa55c1bc2a23c8ec Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 14 Feb 2013 19:50:35 +0100 Subject: Cocoa QPA: Make QCocoaMenu::menuItemAt() more robust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2c68f87eb1a4926ca5bd0bfcc842ab9c56c99cd7 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index a92f4e875c..0fe4c48510 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -322,7 +322,10 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatf QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const { - return m_menuItems.at(position); + if (0 <= position && position < m_menuItems.count()) + return m_menuItems.at(position); + + return 0; } QPlatformMenuItem *QCocoaMenu::menuItemForTag(quintptr tag) const -- cgit v1.2.3 From ffecaf85e8cd8adb5a18e4ce50b2a8f5f2b0e4b0 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 14 Feb 2013 11:33:47 +0100 Subject: QScreen::refreshRate would return 0 on Mac OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function we use to get the actual vsync on cocoa is documented to return 0 if the monitor is not a CRT monitor. A refreshrate of 0 means we have vsync deltas of 1000/0 which cause problems elsewhere. It is better to use the "default" value in this case as it will be closer to correct than 0. Change-Id: Id08007e40a9af5e42f13a07628fcad5fd3a7d0dc Reviewed-by: Morten Johan Sørvig Reviewed-by: Samuel Rødal --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 7fcdab4d97..f33d4cb68b 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -105,7 +105,9 @@ void QCocoaScreen::updateGeometry() m_physicalSize = QSizeF(size.width, size.height); m_logicalDpi.first = 72; m_logicalDpi.second = 72; - m_refreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(dpy)); + float refresh = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(dpy)); + if (refresh > 0) + m_refreshRate = refresh; // Get m_name (brand/model of the monitor) NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(dpy), kIODisplayOnlyPreferredName); -- cgit v1.2.3 From c04f3584abd621f09e8f2c81b9c6c87212a993a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Feb 2013 16:07:00 +0100 Subject: Remove deprecated use of QMAKE_MAC_SDK in corewlan.pro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We no longer support OS X < 10.6, so there's no need to check for it. Change-Id: I2628984846de0c0c19ea86b3ba6d00fc370ddae7 Reviewed-by: Tor Arne Vestbø --- src/plugins/bearer/corewlan/corewlan.pro | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro index db8651de6e..674af0cbbe 100644 --- a/src/plugins/bearer/corewlan/corewlan.pro +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -8,9 +8,7 @@ QT = core-private network-private LIBS += -framework Foundation -framework SystemConfiguration contains(QT_CONFIG, corewlan) { - !contains(QMAKE_MAC_SDK, ".*MacOSX10\\.[345]\\.sdk") { - LIBS += -framework CoreWLAN -framework Security - } + LIBS += -framework CoreWLAN -framework Security } HEADERS += qcorewlanengine.h \ -- cgit v1.2.3 From 46cc594c6753ef774fa3016c3039ebb07281a151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 15 Feb 2013 09:23:30 +0100 Subject: Fixed EGLFS reporting impossibly high physical dimensions. If FBIOGET_VSCREENINFO doesn't give us sensible values we need to default to something instead. Refactor the code that queries the resolution and depth to behave the same way. Change-Id: Id2b3fc41349a74610856273b10281f744612890b Reviewed-by: Gunnar Sletta --- src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 75 ++++++++++++++++++++---- 1 file changed, 62 insertions(+), 13 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index d09423ec72..a8fa81a6ec 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -46,6 +46,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE const char *QEglFSHooks::fbDeviceName() const @@ -86,16 +88,38 @@ QSizeF QEglFSHooks::physicalScreenSize() const struct fb_var_screeninfo vinfo; int fd = open(fbDeviceName(), O_RDONLY); + int w = -1; + int h = -1; + if (fd != -1) { - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) - qWarning("Could not query variable screen info."); - else - size = QSizeF(vinfo.width, vinfo.height); + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + qWarning("EGLFS: Could not query variable screen info."); + } else { + w = vinfo.width; + h = vinfo.height; + } close(fd); } else { - qWarning("Failed to open %s to detect screen size.", fbDeviceName()); + qWarning("EGLFS: Failed to open %s to detect physical screen size.", fbDeviceName()); } + + const int defaultPhysicalDpi = 100; + size.setWidth(w <= 0 ? vinfo.xres * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w)); + size.setHeight(h <= 0 ? vinfo.yres * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h)); + + if (w <= 0 || h <= 0) { + qWarning("EGLFS: Unable to query physical screen size, defaulting to %d dpi.\n" + "EGLFS: To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH " + "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).", + defaultPhysicalDpi); + } + + // override fb0 from environment var setting + if (width) + size.setWidth(width); + if (height) + size.setWidth(height); } return size; } @@ -118,15 +142,31 @@ QSize QEglFSHooks::screenSize() const struct fb_var_screeninfo vinfo; int fd = open(fbDeviceName(), O_RDONLY); + int xres = -1; + int yres = -1; + if (fd != -1) { - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) - qWarning("Could not query variable screen info."); - else - size = QSize(vinfo.xres, vinfo.yres); + if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + qWarning("EGLFS: Could not query variable screen info."); + } else { + xres = vinfo.xres; + yres = vinfo.yres; + } close(fd); } else { - qWarning("Failed to open %s to detect screen depth.", fbDeviceName()); + qWarning("EGLFS: Failed to open %s to detect screen resolution.", fbDeviceName()); + } + + const int defaultWidth = 800; + const int defaultHeight = 600; + size.setWidth(xres <= 0 ? defaultWidth : xres); + size.setHeight(yres <= 0 ? defaultHeight : yres); + + if (xres <= 0 || yres <= 0) { + qWarning("EGLFS: Unable to query screen resolution, defaulting to %dx%d.\n" + "EGLFS: To override, set QT_QPA_EGLFS_WIDTH and QT_QPA_EGLFS_HEIGHT.", + defaultWidth, defaultHeight); } // override fb0 from environment var setting @@ -149,17 +189,26 @@ int QEglFSHooks::screenDepth() const if (fd != -1) { if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) - qWarning("Could not query variable screen info."); + qWarning("EGLFS: Could not query variable screen info."); else depth = vinfo.bits_per_pixel; close(fd); } else { - qWarning("Failed to open %s to detect screen depth.", fbDeviceName()); + qWarning("EGLFS: Failed to open %s to detect screen depth.", fbDeviceName()); + } + + const int defaultDepth = 32; + + if (depth <= 0) { + depth = defaultDepth; + + qWarning("EGLFS: Unable to query screen depth, defaulting to %d.\n" + "EGLFS: To override, set QT_QPA_EGLFS_DEPTH.", defaultDepth); } } - return depth == 0 ? 32 : depth; + return depth; } QImage::Format QEglFSHooks::screenFormat() const -- cgit v1.2.3 From 2dd8e7cf2e24cd24e0e023d88cf345309df3afb0 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 4 Feb 2013 14:07:34 +0100 Subject: Introduce a native font dialog for GTK+ 2.x Change-Id: Ia5660c3e2c8c122187427ccb490d46e52ee3ad21 Reviewed-by: Friedemann Kleint Reviewed-by: Shawn Rutledge --- .../platformthemes/gtk2/qgtk2dialoghelpers.cpp | 132 +++++++++++++++++++++ .../platformthemes/gtk2/qgtk2dialoghelpers.h | 24 ++++ src/plugins/platformthemes/gtk2/qgtk2theme.cpp | 5 +- 3 files changed, 160 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp index 4f9210a3af..2a8815654f 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -52,6 +53,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -472,6 +474,136 @@ void QGtk2FileDialogHelper::setNameFilters(const QStringList& filters) } } +QGtk2FontDialogHelper::QGtk2FontDialogHelper() +{ + d.reset(new QGtk2Dialog(gtk_font_selection_dialog_new(""))); + connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted())); + connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject())); +} + +QGtk2FontDialogHelper::~QGtk2FontDialogHelper() +{ +} + +bool QGtk2FontDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + applyOptions(); + return d->show(flags, modality, parent); +} + +void QGtk2FontDialogHelper::exec() +{ + d->exec(); +} + +void QGtk2FontDialogHelper::hide() +{ + d->hide(); +} + +static QString qt_fontToString(const QFont& font) +{ + PangoFontDescription *desc = pango_font_description_new(); + pango_font_description_set_size(desc, font.pointSizeF() * PANGO_SCALE); + pango_font_description_set_family(desc, font.family().toUtf8()); + + int weight = font.weight(); + if (weight >= QFont::Black) + pango_font_description_set_weight(desc, PANGO_WEIGHT_HEAVY); + else if (weight >= QFont::Bold) + pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); + else if (weight >= QFont::DemiBold) + pango_font_description_set_weight(desc, PANGO_WEIGHT_SEMIBOLD); + else if (weight >= QFont::Normal) + pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); + else + pango_font_description_set_weight(desc, PANGO_WEIGHT_LIGHT); + + int style = font.style(); + if (style == QFont::StyleItalic) + pango_font_description_set_style(desc, PANGO_STYLE_ITALIC); + else if (style == QFont::StyleOblique) + pango_font_description_set_style(desc, PANGO_STYLE_OBLIQUE); + else + pango_font_description_set_style(desc, PANGO_STYLE_NORMAL); + + char *str = pango_font_description_to_string(desc); + QString name = QString::fromUtf8(str); + pango_font_description_free(desc); + g_free(str); + return name; +} + +static QFont qt_fontFromString(const QString &name) +{ + QFont font; + PangoFontDescription* desc = pango_font_description_from_string(name.toUtf8()); + font.setPointSizeF(static_cast(pango_font_description_get_size(desc)) / PANGO_SCALE); + + QString family = QString::fromUtf8(pango_font_description_get_family(desc)); + if (!family.isEmpty()) + font.setFamily(family); + + int weight = pango_font_description_get_weight(desc); + if (weight >= PANGO_WEIGHT_HEAVY) + font.setWeight(QFont::Black); + else if (weight >= PANGO_WEIGHT_BOLD) + font.setWeight(QFont::Bold); + else if (weight >= PANGO_WEIGHT_SEMIBOLD) + font.setWeight(QFont::DemiBold); + else if (weight >= PANGO_WEIGHT_NORMAL) + font.setWeight(QFont::Normal); + else + font.setWeight(QFont::Light); + + PangoStyle style = pango_font_description_get_style(desc); + if (style == PANGO_STYLE_ITALIC) + font.setStyle(QFont::StyleItalic); + else if (style == PANGO_STYLE_OBLIQUE) + font.setStyle(QFont::StyleOblique); + else + font.setStyle(QFont::StyleNormal); + + pango_font_description_free(desc); + return font; +} + +void QGtk2FontDialogHelper::setCurrentFont(const QFont &font) +{ + GtkFontSelectionDialog *gtkDialog = GTK_FONT_SELECTION_DIALOG(d->gtkDialog()); + gtk_font_selection_dialog_set_font_name(gtkDialog, qt_fontToString(font).toUtf8()); +} + +QFont QGtk2FontDialogHelper::currentFont() const +{ + GtkFontSelectionDialog *gtkDialog = GTK_FONT_SELECTION_DIALOG(d->gtkDialog()); + gchar *name = gtk_font_selection_dialog_get_font_name(gtkDialog); + QFont font = qt_fontFromString(QString::fromUtf8(name)); + g_free(name); + return font; +} + +void QGtk2FontDialogHelper::onAccepted() +{ + emit accept(); + emit fontSelected(currentFont()); +} + +void QGtk2FontDialogHelper::applyOptions() +{ + GtkDialog *gtkDialog = d->gtkDialog(); + const QSharedPointer &opts = options(); + + gtk_window_set_title(GTK_WINDOW(gtkDialog), opts->windowTitle().toUtf8()); + + GtkWidget *okButton = gtk_font_selection_dialog_get_ok_button(GTK_FONT_SELECTION_DIALOG(gtkDialog)); + GtkWidget *cancelButton = gtk_font_selection_dialog_get_cancel_button(GTK_FONT_SELECTION_DIALOG(gtkDialog)); + if (okButton) + gtk_widget_set_visible(okButton, !options()->testOption(QFontDialogOptions::NoButtons)); + if (cancelButton) + gtk_widget_set_visible(cancelButton, !options()->testOption(QFontDialogOptions::NoButtons)); +} + QT_END_NAMESPACE #include "qgtk2dialoghelpers.moc" diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h index 301a2aa6ae..2c5381aec8 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h @@ -114,6 +114,30 @@ private: mutable QScopedPointer d; }; +class QGtk2FontDialogHelper : public QPlatformFontDialogHelper +{ + Q_OBJECT + +public: + QGtk2FontDialogHelper(); + ~QGtk2FontDialogHelper(); + + virtual bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + virtual void exec(); + virtual void hide(); + + virtual void setCurrentFont(const QFont &font); + virtual QFont currentFont() const; + +private Q_SLOTS: + void onAccepted(); + +private: + void applyOptions(); + + mutable QScopedPointer d; +}; + QT_END_NAMESPACE #endif // QGTK2DIALOGHELPERS_P_H diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp index c685d7b13c..7bb538b888 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp @@ -56,7 +56,8 @@ QGtk2Theme::QGtk2Theme() bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const { - return type == ColorDialog || type == FileDialog; + Q_UNUSED(type); + return true; } QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) const @@ -66,6 +67,8 @@ QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) c return new QGtk2ColorDialogHelper; case FileDialog: return new QGtk2FileDialogHelper; + case FontDialog: + return new QGtk2FontDialogHelper; default: return 0; } -- cgit v1.2.3 From a19037cc9e66470f5e047390aa716930f168674b Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 19 Feb 2013 12:58:47 +0100 Subject: Don't build the bearer plugin if network is not available Change-Id: Ia706ac95570e903ae4fa0e47d2c850daf703bb04 Reviewed-by: Friedemann Kleint --- src/plugins/plugins.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 0dba5d14d0..516105401e 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs -SUBDIRS *= sqldrivers bearer +SUBDIRS *= sqldrivers +qtHaveModule(network): SUBDIRS += bearer qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic qtHaveModule(widgets): SUBDIRS += accessible -- cgit v1.2.3 From b92d951bb16bb690daa20d13f1638ff3500f41eb Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 20 Feb 2013 17:24:06 +0100 Subject: QGtk2XxxDialogHelper: cleanup unnecessary mutable keywords Change-Id: Ic0b72661e561e20d50de7aca6d8a681975100b56 Reviewed-by: Shawn Rutledge --- src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h index 2c5381aec8..08af59b2a4 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h @@ -74,7 +74,7 @@ private: static void onColorChanged(QGtk2ColorDialogHelper *helper); void applyOptions(); - mutable QScopedPointer d; + QScopedPointer d; }; class QGtk2FileDialogHelper : public QPlatformFileDialogHelper @@ -111,7 +111,7 @@ private: QStringList _selection; QHash _filters; QHash _filterNames; - mutable QScopedPointer d; + QScopedPointer d; }; class QGtk2FontDialogHelper : public QPlatformFontDialogHelper @@ -135,7 +135,7 @@ private Q_SLOTS: private: void applyOptions(); - mutable QScopedPointer d; + QScopedPointer d; }; QT_END_NAMESPACE -- cgit v1.2.3 From 4f14b42f7dc289cd73a5e7aa934d6052c708bac3 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 14 Jan 2013 16:26:03 +0100 Subject: Add support for forced VSYNC using the EGLFS platform plugin. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before a buffer swap the new QEglFSHooks::waitForVSync method is called which looks at QT_QPA_EGLFS_FORCEVSYNC and - if that is set and non-null - calls ioctl with the FBIO_WAITFORVSYNC request on the framebuffer device. This is required on some embedded platforms where the driver does not support VSYNC yet the Kernel provides a generic implementation. I tested this using QML_RENDER_TIMING=1 which proofs that the frame rate for an example of mine drops from >125fps to a straight ~60fps with a few frames that take ~33ms (i.e. 30fps) as expected for VSYNC. To prevent excessive open/close calls on the frame buffer device per frame, the file descriptor is now cached. To keep the QEglFSHooks interface as clean as possible this is done via a global static in qeglfshooks_stub.cpp and initialized and freed in platformInit and platformDestroy. Change-Id: I4d31b227c65ff22aa089db0fbc62c89a59cbb6c7 Reviewed-by: Sean Harmer Reviewed-by: Samuel Rødal --- src/plugins/platforms/eglfs/qeglfscontext.cpp | 1 + src/plugins/platforms/eglfs/qeglfshooks.h | 1 + src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 50 +++++++++++++----------- 3 files changed, 30 insertions(+), 22 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 06db4e02db..44bc9b2344 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -79,6 +79,7 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface) cursor->paintOnScreen(); } + hooks->waitForVSync(); QEGLPlatformContext::swapBuffers(surface); } diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index f3b6a28e70..fc1ee16073 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -69,6 +69,7 @@ public: virtual bool hasCapability(QPlatformIntegration::Capability cap) const; virtual QEglFSCursor *createCursor(QEglFSScreen *screen) const; virtual bool filterConfig(EGLDisplay display, EGLConfig config) const; + virtual void waitForVSync() const; virtual const char *fbDeviceName() const; }; diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index a8fa81a6ec..6c036cd680 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -47,9 +47,14 @@ #include #include +#include QT_BEGIN_NAMESPACE +// file descriptor for the frame buffer +// this is a global static to keep the QEglFSHooks interface as clean as possible +static int framebuffer = -1; + const char *QEglFSHooks::fbDeviceName() const { return "/dev/fb0"; @@ -58,10 +63,17 @@ const char *QEglFSHooks::fbDeviceName() const void QEglFSHooks::platformInit() { Q_UNUSED(hooks); + + framebuffer = qt_safe_open(fbDeviceName(), O_RDONLY); + + if (framebuffer == -1) + qWarning("EGLFS: Failed to open %s", fbDeviceName()); } void QEglFSHooks::platformDestroy() { + if (framebuffer != -1) + close(framebuffer); } EGLNativeDisplayType QEglFSHooks::platformDisplay() const @@ -86,22 +98,16 @@ QSizeF QEglFSHooks::physicalScreenSize() const } struct fb_var_screeninfo vinfo; - int fd = open(fbDeviceName(), O_RDONLY); - int w = -1; int h = -1; - if (fd != -1) { - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + if (framebuffer != -1) { + if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) { qWarning("EGLFS: Could not query variable screen info."); } else { w = vinfo.width; h = vinfo.height; } - - close(fd); - } else { - qWarning("EGLFS: Failed to open %s to detect physical screen size.", fbDeviceName()); } const int defaultPhysicalDpi = 100; @@ -140,22 +146,17 @@ QSize QEglFSHooks::screenSize() const } struct fb_var_screeninfo vinfo; - int fd = open(fbDeviceName(), O_RDONLY); int xres = -1; int yres = -1; - if (fd != -1) { - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + if (framebuffer != -1) { + if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) { qWarning("EGLFS: Could not query variable screen info."); } else { xres = vinfo.xres; yres = vinfo.yres; } - - close(fd); - } else { - qWarning("EGLFS: Failed to open %s to detect screen resolution.", fbDeviceName()); } const int defaultWidth = 800; @@ -185,17 +186,12 @@ int QEglFSHooks::screenDepth() const if (depth == 0) { struct fb_var_screeninfo vinfo; - int fd = open(fbDeviceName(), O_RDONLY); - if (fd != -1) { - if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) + if (framebuffer != -1) { + if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) qWarning("EGLFS: Could not query variable screen info."); else depth = vinfo.bits_per_pixel; - - close(fd); - } else { - qWarning("EGLFS: Failed to open %s to detect screen depth.", fbDeviceName()); } const int defaultDepth = 32; @@ -250,6 +246,16 @@ QEglFSCursor *QEglFSHooks::createCursor(QEglFSScreen *screen) const return 0; } +void QEglFSHooks::waitForVSync() const +{ + static const bool forceSync = qgetenv("QT_QPA_EGLFS_FORCEVSYNC").toInt(); + if (forceSync && framebuffer != -1) { + int arg = 0; + if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1) + qWarning("Could not wait for vsync."); + } +} + #ifndef EGLFS_PLATFORM_HOOKS QEglFSHooks stubHooks; #endif -- cgit v1.2.3 From 0575baac5e21cbe38a6ceabaa6b17862cbfee7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 22:22:56 +0100 Subject: Don't link QtPlatformSupport to CoreFoundation or Carbon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the Carbon dependency to the Cocoa platform plugin instead, where it's actually used. CoreFoundation was not used by any plugins and could be removed completely. Change-Id: I1c825cdf94e2cc348ea13519b894fd868be0d14a Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/cocoa.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 83e2a88e6a..6ed26f9e6c 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -78,7 +78,7 @@ HEADERS += qcocoaintegration.h \ RESOURCES += qcocoaresources.qrc -LIBS += -framework Cocoa -framework IOKit +LIBS += -framework Cocoa -framework Carbon -framework IOKit QT += core-private gui-private platformsupport-private -- cgit v1.2.3 From 7e5750101699a408356439126649e8f49010d1df Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 20 Feb 2013 14:00:52 +0100 Subject: Enforce OpenGL context creation under Cocoa We don't support other context types, so fail in those cases. Also, return OpenGL as the rendereable type of our surface. Change-Id: I3d5632eb8555d73ed14837b662c7450589a8681f Reviewed-by: Gunnar Sletta --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index d0f5a58e22..6c2fdf5470 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -49,11 +49,19 @@ #import QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share) - : m_format(format) + : m_context(nil), + m_shareContext(nil), + m_format(format) { + // we only support OpenGL contexts under Cocoa + if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType) + m_format.setRenderableType(QSurfaceFormat::OpenGL); + if (m_format.renderableType() != QSurfaceFormat::OpenGL) + return; + QCocoaAutoReleasePool pool; // For the SG Canvas render thread - NSOpenGLPixelFormat *pixelFormat = static_cast (qcgl_createNSOpenGLPixelFormat(format)); + NSOpenGLPixelFormat *pixelFormat = static_cast (qcgl_createNSOpenGLPixelFormat(m_format)); m_shareContext = share ? static_cast(share)->nsOpenGLContext() : nil; m_context = [NSOpenGLContext alloc]; -- cgit v1.2.3 From f2b26af2b4db25aeb74279a40365b76f0406a018 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 20 Feb 2013 14:00:52 +0100 Subject: Enforce OpenGL context creation under XCB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't support other context types, so fail in those cases. Also, return OpenGL as the rendereable type of our surface. Change-Id: Ic7b5ed0ec5eaf5c0f88f50f5bceb697ea414c696 Reviewed-by: Samuel Rødal Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qglxintegration.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 854f7bcd17..db942fc3ad 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -270,14 +270,19 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat : QPlatformOpenGLContext() , m_screen(screen) , m_context(0) + , m_shareContext(0) , m_format(format) , m_isPBufferCurrent(false) { - m_shareContext = 0; + if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType) + m_format.setRenderableType(QSurfaceFormat::OpenGL); + if (m_format.renderableType() != QSurfaceFormat::OpenGL) + return; + if (share) m_shareContext = static_cast(share)->glxContext(); - GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); + GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),m_format); XVisualInfo *visualInfo = 0; Window window = 0; // Temporary window used to query OpenGL context @@ -297,7 +302,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat // context format that that which was requested and is supported by the driver const int maxSupportedVersion = (defaultContextInfo->format.majorVersion() << 8) + defaultContextInfo->format.minorVersion(); - const int requestedVersion = qMin((format.majorVersion() << 8) + format.minorVersion(), + const int requestedVersion = qMin((m_format.majorVersion() << 8) + m_format.minorVersion(), maxSupportedVersion); const int majorVersion = requestedVersion >> 8; const int minorVersion = requestedVersion & 0xFF; -- cgit v1.2.3 From 7e3ee5400ee13796d045879a5bc9d0be23b1b8ff Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 20 Feb 2013 14:00:52 +0100 Subject: Enforce OpenGL context creation under Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't support other context types, so fail in those cases. Also, return OpenGL as the rendereable type of our surface. Change-Id: I22792a913b78b837da3d27cef69145076579b949 Reviewed-by: Samuel Rødal Reviewed-by: Gunnar Sletta Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsglcontext.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 081b42ce65..6f59b33e62 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -232,6 +232,7 @@ static QSurfaceFormat QWindowsOpenGLAdditionalFormat *additionalIn = 0) { QSurfaceFormat format; + format.setRenderableType(QSurfaceFormat::OpenGL); if (pfd.dwFlags & PFD_DOUBLEBUFFER) format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setDepthBufferSize(pfd.cDepthBits); @@ -500,6 +501,7 @@ static QSurfaceFormat enum { attribSize =40 }; QSurfaceFormat result; + result.setRenderableType(QSurfaceFormat::OpenGL); if (!staticContext.hasExtensions()) return result; int iAttributes[attribSize]; @@ -875,6 +877,12 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex m_renderingContext(0), m_pixelFormat(0), m_extensionsUsed(false) { + QSurfaceFormat format = context->format(); + if (format.renderableType() == QSurfaceFormat::DefaultRenderableType) + format.setRenderableType(QSurfaceFormat::OpenGL); + if (format.renderableType() != QSurfaceFormat::OpenGL) + return; + // workaround for matrox driver: // make a cheap call to opengl to force loading of DLL static bool opengl32dll = false; @@ -912,7 +920,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex QWindowsOpenGLAdditionalFormat obtainedAdditional; if (tryExtensions) { m_pixelFormat = - ARB::choosePixelFormat(hdc, *m_staticContext, context->format(), + ARB::choosePixelFormat(hdc, *m_staticContext, format, requestedAdditional, &m_obtainedPixelFormatDescriptor); if (m_pixelFormat > 0) { m_obtainedFormat = @@ -922,7 +930,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex } } // tryExtensions if (!m_pixelFormat) { // Failed, try GDI - m_pixelFormat = GDI::choosePixelFormat(hdc, context->format(), requestedAdditional, + m_pixelFormat = GDI::choosePixelFormat(hdc, format, requestedAdditional, &m_obtainedPixelFormatDescriptor); if (m_pixelFormat) m_obtainedFormat = @@ -945,7 +953,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex if (m_extensionsUsed) m_renderingContext = ARB::createContext(*m_staticContext, hdc, - context->format(), + format, requestedAdditional, sharingRenderingContext); if (!m_renderingContext) -- cgit v1.2.3 From 0077b5f30de7190227317247609c820f37466960 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 21 Feb 2013 16:07:46 +0100 Subject: Pass the surface format to qglx_surfaceFormatFromGLXFBConfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of creating a default-constructed format and filling its field in, pass a pointer to an instance. This way we won't lose the renderable type set on the surface, but just fill in the other parameters. Change-Id: I1fd403671f9c677cc74aaf3c116a05f213d5d556 Reviewed-by: Samuel Rødal --- src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp | 2 +- src/plugins/platforms/xcb/qglxintegration.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 4b27afd80f..6c6c516a4e 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -179,7 +179,7 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL // Get the basic surface format details if (d->context) - d->format = qglx_surfaceFormatFromGLXFBConfig(x11->display(), config, d->context); + qglx_surfaceFormatFromGLXFBConfig(&d->format, x11->display(), config, d->context); // Create a temporary window so that we can make the new context current d->window = createDummyWindow(x11, config); diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index db942fc3ad..2b18ecf7a4 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -355,7 +355,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat // Get the basic surface format details if (m_context) - m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + qglx_surfaceFormatFromGLXFBConfig(&m_format, DISPLAY_FROM_XCB(screen), config, m_context); // Create a temporary window so that we can make the new context current window = createDummyWindow(screen, config); @@ -499,7 +499,7 @@ QGLXPbuffer::QGLXPbuffer(QOffscreenSurface *offscreenSurface) m_pbuffer = glXCreatePbuffer(DISPLAY_FROM_XCB(m_screen), config, attributes); if (m_pbuffer) - m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(m_screen), config); + qglx_surfaceFormatFromGLXFBConfig(&m_format, DISPLAY_FROM_XCB(m_screen), config); } } -- cgit v1.2.3 From bc616641a1c3d2d79cf7c5ee9e80a59279edb756 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 20 Feb 2013 15:50:35 +0100 Subject: Make toplevel transparent windows work on Mac OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch includes a few different fixes to make transparent toplevels work on cocoa. - When setting alpha on the toplevel, it also needs setOpaque:NO - The OpenGL context needs a separate flag for this to work. - Make sure setOpaque fighting between setMask, setFormat and setOpacity ends up correctly Task-number: QTBUG-28214 Change-Id: Ic3a2d71193bb653e181c98787b4ebda002424092 Reviewed-by: Shawn Rutledge Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 4 ++++ src/plugins/platforms/cocoa/qcocoawindow.h | 2 ++ src/plugins/platforms/cocoa/qcocoawindow.mm | 24 ++++++++++++++++++++---- src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 5 +++++ 5 files changed, 32 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 6c2fdf5470..d4673baaef 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -78,6 +78,10 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo const GLint interval = 1; [m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval]; + if (format.alphaBufferSize() > 0) { + int zeroOpacity = 0; + [m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity]; + } } QCocoaGLContext::~QCocoaGLContext() diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 291c688915..70df7451f7 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -157,6 +157,8 @@ protected: QCocoaWindow *parentCocoaWindow() const; void syncWindowState(Qt::WindowState newState); + void updateOpaque(); + // private: public: // for QNSView friend class QCocoaBackingStore; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 56ca2e0b14..fe6a9ad50b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -516,20 +516,30 @@ void QCocoaWindow::propagateSizeHints() } } +void QCocoaWindow::updateOpaque() +{ + bool translucent = window()->format().alphaBufferSize() > 0 + || window()->opacity() < 1 + || (m_contentView && [m_contentView hasMask]); + [m_nsWindow setOpaque:!translucent]; +} + + void QCocoaWindow::setOpacity(qreal level) { - if (m_nsWindow) + if (m_nsWindow) { [m_nsWindow setAlphaValue:level]; + updateOpaque(); + } } void QCocoaWindow::setMask(const QRegion ®ion) { - if (m_nsWindow) { - [m_nsWindow setOpaque:NO]; + if (m_nsWindow) [m_nsWindow setBackgroundColor:[NSColor clearColor]]; - } [m_contentView setMaskRegion:®ion]; + updateOpaque(); } bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) @@ -726,6 +736,12 @@ NSWindow * QCocoaWindow::createNSWindow() NSInteger level = windowLevel(flags); [createdWindow setLevel:level]; + + if (window()->format().alphaBufferSize() > 0) { + [createdWindow setBackgroundColor:[NSColor clearColor]]; + [createdWindow setOpaque:NO]; + } + m_windowModality = window()->modality(); return createdWindow; } diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index eec0cfe5f6..5fe0861e0a 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -83,6 +83,7 @@ QT_END_NAMESPACE - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; - (BOOL)becomeFirstResponder; +- (BOOL)hasMask; - (void)resetMouseButtons; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index cdbaa235e4..a8d8baa942 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -254,6 +254,11 @@ static QTouchDevice *touchDevice = 0; [self setNeedsDisplayInRect:NSMakeRect(br.x(), br.y(), br.width(), br.height())]; } +- (BOOL) hasMask +{ + return m_maskData != 0; +} + - (void) setMaskRegion:(const QRegion *)region { if (m_maskImage) -- cgit v1.2.3 From 3fdc4ae0ed156851c99dee4b52340cfbc0f9aaf7 Mon Sep 17 00:00:00 2001 From: Alain Boyer Date: Sat, 9 Feb 2013 01:48:44 +0200 Subject: Fix primary screen selection. When selecting the primary screen, the m_primaryScreen value obtained from the xcb_connect() call should be respected. This ensures that the proper primary screen is selected when specifying the DISPLAY environment variable. Task-number: QTBUG-27220 Change-Id: I60aa207f13d919087d4d2913141c804928684731 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 32de54562a..a36f823b7c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -184,7 +184,7 @@ void QXcbConnection::updateScreens() activeScreens << screen; ++screenNumber; if (!primaryScreen && primary) { - if (primary->output == XCB_NONE || outputs[i] == primary->output) { + if (m_primaryScreen == xcbScreenNumber && (primary->output == XCB_NONE || outputs[i] == primary->output)) { primaryScreen = screen; siblings.prepend(siblings.takeLast()); #ifdef Q_XCB_DEBUG -- cgit v1.2.3 From 26149d057a464ddafcc9694cfa94525c01a45231 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 25 Feb 2013 16:34:37 +0100 Subject: Windows native dialogs: Handle libraries. Task-number: QTBUG-29447 Change-Id: I4e68e546a4eb6b5f9c3dbe6d98905109e72e600a Reviewed-by: Joerg Bornemann --- .../platforms/windows/qwindowsdialoghelpers.cpp | 119 ++++++++++++++++++++- 1 file changed, 114 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index e9c0cccc14..869e94b566 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -86,6 +86,8 @@ static const IID q_IID_IShellItem = {0x43826d1e, 0xe718, 0x42ee, {0xbc, 0 #define IID_IShellItem q_IID_IShellItem #else static const IID IID_IShellItem = {0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe}}; +static const IID IID_IShellItemArray = {0xb63ea76d, 0x1f85, 0x456f, {0xa1, 0x9c, 0x48, 0x15, 0x9e, 0xfa, 0x85, 0x8b}}; +# define LFF_FORCEFILESYSTEM 1 #endif static const IID IID_IFileDialogEvents = {0x973510db, 0x7d7f, 0x452b,{0x89, 0x75, 0x74, 0xa8, 0x58, 0x28, 0xd3, 0x54}}; static const CLSID CLSID_FileOpenDialog = {0xdc1c5a9c, 0xe88a, 0x4dde, {0xa5, 0xa1, 0x60, 0xf8, 0x2a, 0x20, 0xae, 0xf7}}; @@ -253,6 +255,34 @@ DECLARE_INTERFACE_(IShellItemArray, IUnknown) }; #endif +#ifndef __IShellLibrary_INTERFACE_DEFINED__ + +enum LIBRARYOPTIONFLAGS {}; +enum DEFAULTSAVEFOLDERTYPE { DSFT_DETECT = 1 }; +enum LIBRARYSAVEFLAGS {}; + +DECLARE_INTERFACE_(IShellLibrary, IUnknown) +{ + STDMETHOD(LoadLibraryFromItem)(THIS_ IShellItem *psiLibrary, DWORD grfMode) PURE; + STDMETHOD(LoadLibraryFromKnownFolder)(THIS_ const GUID &kfidLibrary, DWORD grfMode) PURE; + STDMETHOD(AddFolder)(THIS_ IShellItem *psiLocation) PURE; + STDMETHOD(RemoveFolder)(THIS_ IShellItem *psiLocation) PURE; + STDMETHOD(GetFolders)(THIS_ int lff, REFIID riid, void **ppv) PURE; + STDMETHOD(ResolveFolder)(THIS_ IShellItem *psiFolderToResolve, DWORD dwTimeout, REFIID riid, void **ppv) PURE; + STDMETHOD(GetDefaultSaveFolder)(THIS_ DEFAULTSAVEFOLDERTYPE dsft, REFIID riid, void **ppv) PURE; + STDMETHOD(SetDefaultSaveFolder)(THIS_ DEFAULTSAVEFOLDERTYPE dsft, IShellItem *psi) PURE; + STDMETHOD(GetOptions)(THIS_ LIBRARYOPTIONFLAGS *plofOptions) PURE; + STDMETHOD(SetOptions)(THIS_ LIBRARYOPTIONFLAGS lofMask, LIBRARYOPTIONFLAGS lofOptions) PURE; + STDMETHOD(GetFolderType)(THIS_ GUID *pftid) PURE; + STDMETHOD(SetFolderType)(THIS_ const GUID &ftid) PURE; + STDMETHOD(GetIcon)(THIS_ LPWSTR *ppszIcon) PURE; + STDMETHOD(SetIcon)(THIS_ LPCWSTR pszIcon) PURE; + STDMETHOD(Commit)(THIS_) PURE; + STDMETHOD(Save)(THIS_ IShellItem *psiFolderToSaveIn, LPCWSTR pszLibraryName, LIBRARYSAVEFLAGS lsf, IShellItem **ppsiSavedTo) PURE; + STDMETHOD(SaveInKnownFolder)(THIS_ const GUID &kfidToSaveIn, LPCWSTR pszLibraryName, LIBRARYSAVEFLAGS lsf,IShellItem **ppsiSavedTo) PURE; +}; +#endif + #ifndef __IModalWindow_INTERFACE_DEFINED__ DECLARE_INTERFACE_(IModalWindow, IUnknown) { @@ -829,6 +859,8 @@ protected: bool init(const CLSID &clsId, const IID &iid); inline IFileDialog * fileDialog() const { return m_fileDialog; } static QString itemPath(IShellItem *item); + static QStringList libraryItemFolders(IShellItem *item); + static QString libraryItemDefaultSaveFolder(IShellItem *item); static int itemPaths(IShellItemArray *items, QStringList *fileResult = 0); static IShellItem *shellItem(const QString &path); @@ -972,17 +1004,94 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, QF qErrnoWarning("%s: SetOptions() failed", __FUNCTION__); } -QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item) +#ifndef Q_OS_WINCE + +// Helper for "Libraries": collections of folders appearing from Windows 7 +// on, visible in the file dialogs. + +// Load a library from a IShellItem (sanitized copy of the inline function +// SHLoadLibraryFromItem from ShObjIdl.h, which does not exist for MinGW). +static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode) +{ + // ID symbols present from Windows 7 on: + static const CLSID classId_ShellLibrary = {0xd9b3211d, 0xe57f, 0x4426, {0xaa, 0xef, 0x30, 0xa8, 0x6, 0xad, 0xd3, 0x97}}; + static const IID iId_IShellLibrary = {0x11a66efa, 0x382e, 0x451a, {0x92, 0x34, 0x1e, 0xe, 0x12, 0xef, 0x30, 0x85}}; + + IShellLibrary *helper = 0; + IShellLibrary *result = 0; + if (SUCCEEDED(CoCreateInstance(classId_ShellLibrary, NULL, CLSCTX_INPROC_SERVER, iId_IShellLibrary, reinterpret_cast(&helper)))) + if (SUCCEEDED(helper->LoadLibraryFromItem(libraryItem, mode))) + helper->QueryInterface(iId_IShellLibrary, reinterpret_cast(&result)); + if (helper) + helper->Release(); + return result; +} + +// Return all folders of a library-type item. +QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item) +{ + QStringList result; + if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) { + IShellItemArray *itemArray = 0; + if (SUCCEEDED(library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, reinterpret_cast(&itemArray)))) { + QWindowsNativeFileDialogBase::itemPaths(itemArray, &result); + itemArray->Release(); + } + library->Release(); + } + return result; +} + +// Return default save folders of a library-type item. +QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *item) { QString result; - LPWSTR name = 0; - if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name))) { - result = QDir::cleanPath(QString::fromWCharArray(name)); - CoTaskMemFree(name); + if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) { + IShellItem *item = 0; + if (SUCCEEDED(library->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, reinterpret_cast(&item)))) { + result = QWindowsNativeFileDialogBase::itemPath(item); + item->Release(); + } + library->Release(); } return result; } +#else // !Q_OS_WINCE + +QStringList QWindowsNativeFileDialogBase::libraryItemPaths(IShellItem *) +{ + return QStringList(); +} + +QString QWindowsNativeFileDialogBase::libraryDefaultSaveFolder(IShellItem *) +{ + return QString(); +} + +#endif // Q_OS_WINCE + +QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item) +{ + SFGAOF attributes = 0; + // Check whether it has a file system representation? + if (FAILED(item->GetAttributes(SFGAO_FILESYSTEM, &attributes))) + return QString(); + if (attributes & SFGAO_FILESYSTEM) { + LPWSTR name = 0; + QString result; + if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name))) { + result = QDir::cleanPath(QString::fromWCharArray(name)); + CoTaskMemFree(name); + } + return result; + } + // Check for a "Library" item + if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) + return QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(item); + return QString(); +} + int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items, QStringList *result /* = 0 */) { -- cgit v1.2.3 From 1ee11474622e7da068fb1cd26f509ed10848a3b5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 21 Feb 2013 16:54:24 -0800 Subject: Rename the SQL driver header files to _p.h (make private) The drivers were never public API. They were exposed by mistake in public headers. What's more, they have #include'd a private header (qsqlcachedresult_p.h) since at least Qt 4.5.1. That means no one used those headers in Qt 4 (private headers weren't installed then) and it's unlikely anyone did in 5.0. Change-Id: Ie0a47bcf0260ee6bdd3d8494b78fd1eec28a2d6b Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint Reviewed-by: Mark Brand --- src/plugins/sqldrivers/db2/main.cpp | 2 +- src/plugins/sqldrivers/ibase/main.cpp | 2 +- src/plugins/sqldrivers/mysql/main.cpp | 2 +- src/plugins/sqldrivers/oci/main.cpp | 2 +- src/plugins/sqldrivers/odbc/main.cpp | 2 +- src/plugins/sqldrivers/psql/main.cpp | 2 +- src/plugins/sqldrivers/sqlite/smain.cpp | 2 +- src/plugins/sqldrivers/sqlite2/smain.cpp | 2 +- src/plugins/sqldrivers/tds/main.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/sqldrivers/db2/main.cpp b/src/plugins/sqldrivers/db2/main.cpp index abde11b178..6c796beff6 100644 --- a/src/plugins/sqldrivers/db2/main.cpp +++ b/src/plugins/sqldrivers/db2/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../sql/drivers/db2/qsql_db2.h" +#include "../../../sql/drivers/db2/qsql_db2_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/ibase/main.cpp b/src/plugins/sqldrivers/ibase/main.cpp index 1ce663d868..e7d1c38690 100644 --- a/src/plugins/sqldrivers/ibase/main.cpp +++ b/src/plugins/sqldrivers/ibase/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../sql/drivers/ibase/qsql_ibase.h" +#include "../../../sql/drivers/ibase/qsql_ibase_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/mysql/main.cpp b/src/plugins/sqldrivers/mysql/main.cpp index d313152cd7..8aaee6c268 100644 --- a/src/plugins/sqldrivers/mysql/main.cpp +++ b/src/plugins/sqldrivers/mysql/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../sql/drivers/mysql/qsql_mysql.h" +#include "../../../sql/drivers/mysql/qsql_mysql_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/oci/main.cpp b/src/plugins/sqldrivers/oci/main.cpp index fc069df534..f1b0266536 100644 --- a/src/plugins/sqldrivers/oci/main.cpp +++ b/src/plugins/sqldrivers/oci/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../sql/drivers/oci/qsql_oci.h" +#include "../../../sql/drivers/oci/qsql_oci_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/odbc/main.cpp b/src/plugins/sqldrivers/odbc/main.cpp index 215cbf6042..fda5c68fcc 100644 --- a/src/plugins/sqldrivers/odbc/main.cpp +++ b/src/plugins/sqldrivers/odbc/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../sql/drivers/odbc/qsql_odbc.h" +#include "../../../sql/drivers/odbc/qsql_odbc_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/psql/main.cpp b/src/plugins/sqldrivers/psql/main.cpp index b3cba82f3e..3851ba6bfe 100644 --- a/src/plugins/sqldrivers/psql/main.cpp +++ b/src/plugins/sqldrivers/psql/main.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../sql/drivers/psql/qsql_psql.h" +#include "../../../sql/drivers/psql/qsql_psql_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/sqlite/smain.cpp b/src/plugins/sqldrivers/sqlite/smain.cpp index e52c235c18..1835962331 100644 --- a/src/plugins/sqldrivers/sqlite/smain.cpp +++ b/src/plugins/sqldrivers/sqlite/smain.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../../src/sql/drivers/sqlite/qsql_sqlite.h" +#include "../../../../src/sql/drivers/sqlite/qsql_sqlite_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/sqlite2/smain.cpp b/src/plugins/sqldrivers/sqlite2/smain.cpp index 38eb8e7fed..e15834a18e 100644 --- a/src/plugins/sqldrivers/sqlite2/smain.cpp +++ b/src/plugins/sqldrivers/sqlite2/smain.cpp @@ -41,7 +41,7 @@ #include #include -#include "../../../../src/sql/drivers/sqlite2/qsql_sqlite2.h" +#include "../../../../src/sql/drivers/sqlite2/qsql_sqlite2_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/sqldrivers/tds/main.cpp b/src/plugins/sqldrivers/tds/main.cpp index 9066efa172..1cb04e9e07 100644 --- a/src/plugins/sqldrivers/tds/main.cpp +++ b/src/plugins/sqldrivers/tds/main.cpp @@ -47,7 +47,7 @@ #define _WINSCARD_H_ #include #endif -#include "../../../sql/drivers/tds/qsql_tds.h" +#include "../../../sql/drivers/tds/qsql_tds_p.h" QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 8cbdb25ee63ad702fdd91aae264b093bf3927a5c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 30 Oct 2012 14:55:46 +0100 Subject: iOS: copy brute-force port of Qt4 uikit plugin into Qt5. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin has been renamed from uikit to ios. Other than that, the plugin will now build, but do nothing. Most of the Qt4 code is preserved, with a rough translation into the Qt5 qpa API. A lot of code has simply been commented out so far, and most lacking at the moment is the event dispatcher which will need to be rewritten, and the opengl paint device implementation. But it should suffice as a starting ground. Also: The plugin will currently not automatically build when building Qt, this needs to be enabled from configure first. Change-Id: I0d229a453a8477618e06554655bffc5505203b44 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/ios.json | 3 + src/plugins/platforms/ios/ios.pro | 27 ++ src/plugins/platforms/ios/main.mm | 69 ++++ src/plugins/platforms/ios/qiosbackingstore.h | 65 +++ src/plugins/platforms/ios/qiosbackingstore.mm | 139 +++++++ src/plugins/platforms/ios/qioseventdispatcher.h | 110 +++++ src/plugins/platforms/ios/qioseventdispatcher.mm | 154 +++++++ src/plugins/platforms/ios/qiosintegration.h | 75 ++++ src/plugins/platforms/ios/qiosintegration.mm | 106 +++++ src/plugins/platforms/ios/qiosscreen.h | 76 ++++ src/plugins/platforms/ios/qiosscreen.mm | 120 ++++++ .../platforms/ios/qiossoftwareinputhandler.h | 73 ++++ src/plugins/platforms/ios/qioswindow.h | 135 +++++++ src/plugins/platforms/ios/qioswindow.mm | 449 +++++++++++++++++++++ 14 files changed, 1601 insertions(+) create mode 100644 src/plugins/platforms/ios/ios.json create mode 100644 src/plugins/platforms/ios/ios.pro create mode 100644 src/plugins/platforms/ios/main.mm create mode 100644 src/plugins/platforms/ios/qiosbackingstore.h create mode 100644 src/plugins/platforms/ios/qiosbackingstore.mm create mode 100644 src/plugins/platforms/ios/qioseventdispatcher.h create mode 100644 src/plugins/platforms/ios/qioseventdispatcher.mm create mode 100644 src/plugins/platforms/ios/qiosintegration.h create mode 100644 src/plugins/platforms/ios/qiosintegration.mm create mode 100644 src/plugins/platforms/ios/qiosscreen.h create mode 100644 src/plugins/platforms/ios/qiosscreen.mm create mode 100644 src/plugins/platforms/ios/qiossoftwareinputhandler.h create mode 100644 src/plugins/platforms/ios/qioswindow.h create mode 100644 src/plugins/platforms/ios/qioswindow.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.json b/src/plugins/platforms/ios/ios.json new file mode 100644 index 0000000000..f0b766dae1 --- /dev/null +++ b/src/plugins/platforms/ios/ios.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "ios" ] +} diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro new file mode 100644 index 0000000000..39f72e9719 --- /dev/null +++ b/src/plugins/platforms/ios/ios.pro @@ -0,0 +1,27 @@ +TARGET = qios +include(../../qpluginbase.pri) +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +QT += opengl +QT += core-private gui-private platformsupport-private opengl-private widgets-private +LIBS += -framework Cocoa -framework UIKit + +OBJECTIVE_SOURCES = main.mm \ + qiosintegration.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qioseventdispatcher.mm \ + qiosbackingstore.mm + +OBJECTIVE_HEADERS = qiosintegration.h \ + qioswindow.h \ + qiosscreen.h \ + qioseventdispatcher.h \ + qiosbackingstore.h + +#HEADERS = qiossoftwareinputhandler.h + +#include(../fontdatabases/coretext/coretext.pri) + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm new file mode 100644 index 0000000000..b09fbce1f4 --- /dev/null +++ b/src/plugins/platforms/ios/main.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 +#include "qiosintegration.h" + +QT_BEGIN_NAMESPACE + +class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") + public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "ios") + return new QIOSIntegration; + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" + + diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h new file mode 100644 index 0000000000..cb0e9cbedb --- /dev/null +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 QIOSBACKINGSTORE_H +#define QIOSBACKINGSTORE_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSBackingStore : public QPlatformBackingStore +{ +public: + QIOSBackingStore(QWindow *window); + + QPaintDevice *paintDevice(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + +private: + QPaintDevice *mPaintDevice; +}; + +QT_END_NAMESPACE + +#endif // QIOSBACKINGSTORE_H diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm new file mode 100644 index 0000000000..32ddce38d2 --- /dev/null +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 "qiosbackingstore.h" +#include "qioswindow.h" + +#include +#include + +#include + +class EAGLPaintDevice; + +@interface PaintDeviceHelper : NSObject { + EAGLPaintDevice *device; +} + +@property (nonatomic, assign) EAGLPaintDevice *device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; + +@end + +class EAGLPaintDevice : public QGLPaintDevice +{ +public: + EAGLPaintDevice(QWindow *window) + :QGLPaintDevice(), mWindow(window) + { +#if defined(QT_OPENGL_ES_2) + helper = [[PaintDeviceHelper alloc] init]; + helper.device = this; + EAGLView *view = static_cast(window->handle())->nativeView(); + view.delegate = helper; + m_thisFBO = view.fbo; +#endif + } + + ~EAGLPaintDevice() + { +#if defined(QT_OPENGL_ES_2) + [helper release]; +#endif + } + + void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } + int devType() const { return QInternal::OpenGL; } + QSize size() const { return mWindow->geometry().size(); } + QGLContext* context() const { + // Todo: siplify this: + return QGLContext::fromOpenGLContext( + static_cast(mWindow->handle())->glContext()->context()); + } + + QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } + +private: + QWindow *mWindow; + PaintDeviceHelper *helper; +}; + +@implementation PaintDeviceHelper +@synthesize device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +{ + Q_UNUSED(view) + if (device) + device->setFramebuffer(buffer); +} + +@end + +QT_BEGIN_NAMESPACE + +QIOSBackingStore::QIOSBackingStore(QWindow *window) + : QPlatformBackingStore(window), mPaintDevice(new EAGLPaintDevice(window)) +{ +} + +QPaintDevice *QIOSBackingStore::paintDevice() +{ + return mPaintDevice; +} + +void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(region); + Q_UNUSED(offset); + qDebug() << __FUNCTION__ << "not implemented"; + //static_cast(window->handle())->glContext()->swapBuffers(); +} + +void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(size); + Q_UNUSED(staticContents); + qDebug() << __FUNCTION__ << "not implemented"; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h new file mode 100644 index 0000000000..3e70397e63 --- /dev/null +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (c) 2007-2008, Apple, Inc. +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** +** * Neither the name of Apple, Inc. nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef QEVENTDISPATCHER_IOS_P_H +#define QEVENTDISPATCHER_IOS_P_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSEventDispatcher : public QAbstractEventDispatcher +{ + Q_OBJECT + +public: + explicit QIOSEventDispatcher(QObject *parent = 0); ~QIOSEventDispatcher(); + + bool processEvents(QEventLoop::ProcessEventsFlags flags); + bool hasPendingEvents(); + + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object); + bool unregisterTimer(int timerId); + bool unregisterTimers(QObject *object); + QList registeredTimers(QObject *object) const; + + int remainingTime(int timerId); + + void wakeUp(); + void interrupt(); + void flush(); +}; + +QT_END_NAMESPACE + +#endif // QEVENTDISPATCHER_IOS_P_H diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm new file mode 100644 index 0000000000..246c29adde --- /dev/null +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (c) 2007-2008, Apple, Inc. +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** +** * Neither the name of Apple, Inc. nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "qioseventdispatcher.h" +#include + +QT_BEGIN_NAMESPACE +QT_USE_NAMESPACE + +QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) +{ + Q_UNUSED(parent); + qDebug() << __FUNCTION__ << "eventdispatcher not implemented"; +} + +QIOSEventDispatcher::~QIOSEventDispatcher() +{} + +bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + Q_UNUSED(flags); + return false; +} + +bool QIOSEventDispatcher::hasPendingEvents() +{ + return false; +} + +void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) +{ + Q_UNUSED(notifier); +} + +void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) +{ + Q_UNUSED(notifier); +} + +void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) +{ + Q_UNUSED(timerId); + Q_UNUSED(interval); + Q_UNUSED(timerType); + Q_UNUSED(object); +} + +bool QIOSEventDispatcher::unregisterTimer(int timerId) +{ + Q_UNUSED(timerId); + return false; +} + +bool QIOSEventDispatcher::unregisterTimers(QObject *object) +{ + Q_UNUSED(object); + return false; +} + +QList QIOSEventDispatcher::registeredTimers(QObject *object) const +{ + Q_UNUSED(object); + return QList(); +} + +int QIOSEventDispatcher::remainingTime(int timerId) +{ + Q_UNUSED(timerId); + return 0; +} + +void QIOSEventDispatcher::wakeUp() +{} + +void QIOSEventDispatcher::interrupt() +{} + +void QIOSEventDispatcher::flush() +{} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h new file mode 100644 index 0000000000..b71379e417 --- /dev/null +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 QPLATFORMINTEGRATION_UIKIT_H +#define QPLATFORMINTEGRATION_UIKIT_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSIntegration : public QPlatformIntegration +{ +public: + QIOSIntegration(); + ~QIOSIntegration(); + + static QIOSIntegration *instance(); + + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + + QList screens() const; + + QPlatformFontDatabase *fontDatabase() const; + + QAbstractEventDispatcher *guiThreadEventDispatcher() const; + +private: + QList mScreens; + QPlatformFontDatabase *mFontDb; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm new file mode 100644 index 0000000000..bd63384004 --- /dev/null +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 "qiosIntegration.h" +#include "qioswindow.h" +#include "qiosbackingstore.h" +#include "qiosscreen.h" +#include "qioseventdispatcher.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +static QIOSIntegration *m_instance = 0; + +QIOSIntegration * QIOSIntegration::instance() +{ + return m_instance; +} + +QIOSIntegration::QIOSIntegration() + :mFontDb(new QCoreTextFontDatabase) +{ + if (!m_instance) + m_instance = this; + mScreens << new QIOSScreen(0); +} + +QIOSIntegration::~QIOSIntegration() +{ +} + +QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const +{ + Q_UNUSED(type); + qDebug() << __FUNCTION__ << "not yet implemented"; + return 0; + //return new QRasterPixmapData(type); +} + +QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const +{ + return new QIOSWindow(window); +} + +QList QIOSIntegration::screens() const +{ + return mScreens; +} + +QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QIOSBackingStore(window); +} + +QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const +{ + return new QIOSEventDispatcher(); +} + +QPlatformFontDatabase * QIOSIntegration::fontDatabase() const +{ + return mFontDb; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h new file mode 100644 index 0000000000..628d764f53 --- /dev/null +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 QIOSSCREEN_H +#define QIOSSCREEN_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QIOSScreen : public QPlatformScreen +{ +public: + QIOSScreen(int screenIndex); + ~QIOSScreen(); + + QRect geometry() const { return m_geometry; } + int depth() const { return m_depth; } + QImage::Format format() const { return m_format; } + QSizeF physicalSize() const { return m_physicalSize; } + + UIScreen *uiScreen() const; + + void updateInterfaceOrientation(); +private: + QRect m_geometry; + int m_depth; + QImage::Format m_format; + QSize m_physicalSize; + int m_index; +}; + +QT_END_NAMESPACE + + +#endif diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm new file mode 100644 index 0000000000..5d9841734a --- /dev/null +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 "qiosscreen.h" +#include "qioswindow.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +QIOSScreen::QIOSScreen(int screenIndex) + : QPlatformScreen(), + m_index(screenIndex) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + CGRect bounds = [uiScreen() bounds]; + CGFloat scale = [uiScreen() scale]; + updateInterfaceOrientation(); + + m_format = QImage::Format_ARGB32_Premultiplied; + + m_depth = 24; + + const qreal inch = 25.4; + qreal unscaledDpi = 160.; + int dragDistance = 12 * scale; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + unscaledDpi = 132.; + dragDistance = 10 * scale; + } + m_physicalSize = QSize(qRound(bounds.size.width * inch / unscaledDpi), qRound(bounds.size.height * inch / unscaledDpi)); + + //qApp->setStartDragDistance(dragDistance); + + /* + QFont font; // system font is helvetica, so that is fine already + font.setPixelSize([UIFont systemFontSize] * scale); + qApp->setFont(font); + */ + + [pool release]; +} + +QIOSScreen::~QIOSScreen() +{ +} + +UIScreen *QIOSScreen::uiScreen() const +{ + return [[UIScreen screens] objectAtIndex:m_index]; +} + +void QIOSScreen::updateInterfaceOrientation() +{ + qDebug() << __FUNCTION__ << "not implemented"; + /* + CGRect bounds = [uiScreen() bounds]; + CGFloat scale = [uiScreen() scale]; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, + bounds.size.width * scale, bounds.size.height * scale);; + break; + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, + bounds.size.height * scale, bounds.size.width * scale); + break; + } + foreach (QWidget *widget, qApp->topLevelWidgets()) { + QIOSWindow *platformWindow = static_cast(widget->platformWindow()); + if (platformWindow && platformWindow->platformScreen() == this) { + platformWindow->updateGeometryAndOrientation(); + } + } + */ +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h new file mode 100644 index 0000000000..bbad656b93 --- /dev/null +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -0,0 +1,73 @@ + + +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 QIOSSOFTWAREINPUTHANDLER_H +#define QIOSSOFTWAREINPUTHANDLER_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSSoftwareInputHandler : public QObject +{ + Q_OBJECT + +public: + QIOSSoftwareInputHandler() : mCurrentFocusWidget(0), mCurrentFocusObject(0) {} + bool eventFilter(QObject *obj, QEvent *event); + +private slots: + void activeFocusChanged(bool focus); + +private: + bool closeSoftwareInputPanel(QWidget *widget); + + QPointer mCurrentFocusWidget; + QPointer mCurrentFocusObject; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h new file mode 100644 index 0000000000..f43f3db4f9 --- /dev/null +++ b/src/plugins/platforms/ios/qioswindow.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 QIOSWINDOW_H +#define QIOSWINDOW_H + +#include + +#import +#import +#import +#import +#import +#import + +@interface EAGLView : UIView +{ + QPlatformWindow *mWindow; + EAGLContext *mContext; + + GLint mFramebufferWidth; + GLint mFramebufferHeight; + + GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + + id delegate; + // ------- Text Input ---------- + UITextAutocapitalizationType autocapitalizationType; + UITextAutocorrectionType autocorrectionType; + BOOL enablesReturnKeyAutomatically; + UIKeyboardAppearance keyboardAppearance; + UIKeyboardType keyboardType; + UIReturnKeyType returnKeyType; + BOOL secureTextEntry; +} + +- (void)setContext:(EAGLContext *)newContext; +- (void)presentFramebuffer; +- (void)deleteFramebuffer; +- (void)createFramebuffer; +- (void)makeCurrent; +- (void)setWindow:(QPlatformWindow *)window; +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; + +@property (readonly,getter=fbo) GLint fbo; +@property (nonatomic, assign) id delegate; + +// ------- Text Input ---------- + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; +@property(nonatomic) BOOL enablesReturnKeyAutomatically; +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; +@property(nonatomic) UIKeyboardType keyboardType; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; + +@end + +@protocol EAGLViewDelegate +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; +@end + +class EAGLPlatformContext; + +QT_BEGIN_NAMESPACE + +class QIOSScreen; + +class QIOSWindow : public QPlatformWindow +{ +public: + explicit QIOSWindow(QWindow *window); + ~QIOSWindow(); + + UIWindow *nativeWindow() const { return mWindow; } + EAGLView *nativeView() const { return mView; } + void setGeometry(const QRect &rect); + + UIWindow *ensureNativeWindow(); + + QPlatformOpenGLContext *glContext() const; + + QIOSScreen *platformScreen() const { return mScreen; } + + void updateGeometryAndOrientation(); +private: + QIOSScreen *mScreen; + UIWindow *mWindow; + CGRect mFrame; + EAGLView *mView; + mutable EAGLPlatformContext *mContext; +}; + +QT_END_NAMESPACE + +#endif // QIOSWINDOW_H diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm new file mode 100644 index 0000000000..c63c22dbaa --- /dev/null +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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$ +** +****************************************************************************/ + +#import + +#include "qioswindow.h" + +#include "qiosscreen.h" + +#include +#include +#include +#include + +#include + +static GLint stencilBits() +{ + static GLint bits; + static bool initialized = false; + if (!initialized) { + glGetIntegerv(GL_STENCIL_BITS, &bits); + initialized = true; + } + return bits; +} + +/* +static GLint depthBits() +{ + // we can choose between GL_DEPTH24_STENCIL8_OES and GL_DEPTH_COMPONENT16 + return stencilBits() > 0 ? 24 : 16; +} +*/ + +class EAGLPlatformContext : public QPlatformOpenGLContext +{ +public: + EAGLPlatformContext(EAGLView *view) + : mView(view) + { + /* + mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); + mFormat.setDepthBufferSize(depthBits()); + mFormat.setAccumBufferSize(0); + mFormat.setRedBufferSize(8); + mFormat.setGreenBufferSize(8); + mFormat.setBlueBufferSize(8); + mFormat.setAlphaBufferSize(8); + mFormat.setStencilBufferSize(stencilBits()); + mFormat.setSamples(0); + mFormat.setSampleBuffers(false); + mFormat.setDoubleBuffer(true); + mFormat.setDepth(true); + mFormat.setRgba(true); + mFormat.setAlpha(true); + mFormat.setAccum(false); + mFormat.setStencil(stencilBits() > 0); + mFormat.setStereo(false); + mFormat.setDirectRendering(false); + */ + +#if defined(QT_OPENGL_ES_2) + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; +#else + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; +#endif + [mView setContext:aContext]; + } + + ~EAGLPlatformContext() { } + + bool makeCurrent(QPlatformSurface *surface) + { + Q_UNUSED(surface); + qDebug() << __FUNCTION__ << "not implemented"; + //QPlatformOpenGLContext::makeCurrent(); + //[mView makeCurrent]; + return false; + } + + void doneCurrent() + { + qDebug() << __FUNCTION__ << "not implemented"; + //QPlatformOpenGLContext::doneCurrent(); + } + + void swapBuffers(QPlatformSurface *surface) + { + Q_UNUSED(surface); + qDebug() << __FUNCTION__ << "not implemented"; + //[mView presentFramebuffer]; + } + + QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } + + QSurfaceFormat format() const + { + return mFormat; + } + +private: + EAGLView *mView; + + QSurfaceFormat mFormat; +}; + +@implementation EAGLView + +@synthesize delegate; + ++ (Class)layerClass +{ + return [CAEAGLLayer class]; +} + +- (id)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) { + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, + nil]; + autocapitalizationType = UITextAutocapitalizationTypeNone; + autocorrectionType = UITextAutocorrectionTypeNo; + enablesReturnKeyAutomatically = NO; + keyboardAppearance = UIKeyboardAppearanceDefault; + keyboardType = UIKeyboardTypeDefault; + returnKeyType = UIReturnKeyDone; + secureTextEntry = NO; + } + return self; +} + +- (void)setContext:(EAGLContext *)newContext +{ + if (mContext != newContext) + { + [self deleteFramebuffer]; + [mContext release]; + mContext = [newContext retain]; + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)presentFramebuffer +{ + if (mContext) { + [EAGLContext setCurrentContext:mContext]; + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext presentRenderbuffer:GL_RENDERBUFFER]; + } +} + +- (void)deleteFramebuffer +{ + if (mContext) + { + [EAGLContext setCurrentContext:mContext]; + if (mFramebuffer) { + glDeleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + if (mColorRenderbuffer) { + glDeleteRenderbuffers(1, &mColorRenderbuffer); + mColorRenderbuffer = 0; + } + if (mDepthRenderbuffer) { + glDeleteRenderbuffers(1, &mDepthRenderbuffer); + mDepthRenderbuffer = 0; + } + } +} + +- (void)createFramebuffer +{ + if (mContext && !mFramebuffer) + { + [EAGLContext setCurrentContext:mContext]; + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + if (stencilBits() > 0) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + } else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFramebufferWidth, mFramebufferHeight); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { + [delegate eaglView:self usesFramebuffer:mFramebuffer]; + } + } +} + +- (void)makeCurrent +{ + if (mContext) + { + [EAGLContext setCurrentContext:mContext]; + if (!mFramebuffer) + [self createFramebuffer]; + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); + } +} + +- (GLint)fbo +{ + return mFramebuffer; +} + +- (void)setWindow:(QPlatformWindow *)window +{ + mWindow = window; +} + +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons +{ + UITouch *touch = [touches anyObject]; + CGPoint locationInView = [touch locationInView:self]; + CGFloat scaleFactor = [self contentScaleFactor]; + QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + // TODO handle global touch point? for status bar? + QWindowSystemInterface::handleMouseEvent(mWindow->window(), (ulong)(event.timestamp*1000), + p, p, buttons); +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; +} + +// ------- Text Input ---------- + +@synthesize autocapitalizationType; +@synthesize autocorrectionType; +@synthesize enablesReturnKeyAutomatically; +@synthesize keyboardAppearance; +@synthesize keyboardType; +@synthesize returnKeyType; +@synthesize secureTextEntry; + +- (BOOL)canBecomeFirstResponder +{ + return YES; +} + +- (BOOL)hasText +{ + return YES; +} + +- (void)insertText:(NSString *)text +{ + QString string = QString::fromUtf8([text UTF8String]); + int key = 0; + if ([text isEqualToString:@"\n"]) + key = (int)Qt::Key_Return; + + // Send key event to window system interface + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, key, Qt::NoModifier, string, false, int(string.length())); + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyRelease, key, Qt::NoModifier, string, false, int(string.length())); +} + +- (void)deleteBackward +{ + // Send key event to window system interface + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier); + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier); +} + +@end + +QT_BEGIN_NAMESPACE + +QIOSWindow::QIOSWindow(QWindow *window) : + QPlatformWindow(window), + mWindow(nil), + mContext(0) +{ + mScreen = static_cast(QPlatformScreen::platformScreenForWindow(window)); + mView = [[EAGLView alloc] init]; +} + +QIOSWindow::~QIOSWindow() +{ + delete mContext; mContext = 0; + [mView release]; + [mWindow release]; +} + +void QIOSWindow::setGeometry(const QRect &rect) +{ + // Not supported. Only a single "full screen" window is supported + QPlatformWindow::setGeometry(rect); +} + +UIWindow *QIOSWindow::ensureNativeWindow() +{ + if (!mWindow) { + mWindow = [[UIWindow alloc] init]; + updateGeometryAndOrientation(); + // window + mWindow.screen = mScreen->uiScreen(); + // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards + mWindow.frame = mFrame; + + // view + [mView deleteFramebuffer]; + mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill + [mView setContentScaleFactor:[mWindow.screen scale]]; + [mView setMultipleTouchEnabled:YES]; + [mView setWindow:this]; + [mWindow addSubview:mView]; + [mWindow setNeedsDisplay]; + [mWindow makeKeyAndVisible]; + } + return mWindow; +} + +void QIOSWindow::updateGeometryAndOrientation() +{ + if (!mWindow) + return; + mFrame = [mScreen->uiScreen() applicationFrame]; + CGRect screen = [mScreen->uiScreen() bounds]; + QRect geom; + CGFloat angle = 0; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + break; + case UIInterfaceOrientationPortraitUpsideDown: + geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, + screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.size.width, + mFrame.size.height); + angle = M_PI; + break; + case UIInterfaceOrientationLandscapeLeft: + geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.origin.x, + mFrame.size.height, + mFrame.size.width); + angle = -M_PI/2.; + break; + case UIInterfaceOrientationLandscapeRight: + geom = QRect(mFrame.origin.y, + screen.size.width - mFrame.origin.x - mFrame.size.width, + mFrame.size.height, + mFrame.size.width); + angle = +M_PI/2.; + break; + } + + CGFloat scale = [mScreen->uiScreen() scale]; + geom = QRect(geom.x() * scale, geom.y() * scale, + geom.width() * scale, geom.height() * scale); + + if (angle != 0) { + [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + } else { + [mView layer].transform = CATransform3DIdentity; + } + [mView setNeedsDisplay]; + window()->setGeometry(geom); +} + +QPlatformOpenGLContext *QIOSWindow::glContext() const +{ + if (!mContext) { + mContext = new EAGLPlatformContext(mView); + } + return mContext; +} + +QT_END_NAMESPACE -- cgit v1.2.3 From 5d6c57fcba2da07551277901300f98e12eb22020 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 29 Oct 2012 13:28:10 +0100 Subject: iOS: fix build issue, dont link against cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure the libraries dont depend on Cocoa. This will be picked up by libtool, and make all apps and examples link against cocoa too (which will ofcourse fail) Change-Id: I5654bb08c4ed376fc7ee74da422d903270a8af38 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioseventdispatcher.h | 2 +- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 3e70397e63..479ec1d0a0 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 246c29adde..12f448488e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. -- cgit v1.2.3 From 1b76cf017427a98bf4487f3cf576611d82097539 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 24 Feb 2013 09:14:20 -0800 Subject: EGLFS: Replace the global static 'hooks' variable with a function Having a global static variable in a header is a poor choice to start with. All .cpp including that header must use that variable or the compiler will warn of an unused static. Second, for the case of platform hooks, it's possible that it is reading the value of a variable that isn't initialised yet. Change-Id: Id823c2be9cfededb9c31fb76a9080d4122577ca4 Reviewed-by: Olivier Goffart Reviewed-by: Giuseppe D'Angelo Reviewed-by: Gunnar Sletta --- src/plugins/platforms/eglfs/qeglfscontext.cpp | 2 +- src/plugins/platforms/eglfs/qeglfshooks.h | 13 ++++++++----- src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 2 -- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 14 +++++++------- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 10 +++++----- src/plugins/platforms/eglfs/qeglfswindow.cpp | 8 ++++---- 6 files changed, 25 insertions(+), 24 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 44bc9b2344..6bd0d35191 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -79,7 +79,7 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface) cursor->paintOnScreen(); } - hooks->waitForVSync(); + QEglFSHooks::hooks()->waitForVSync(); QEGLPlatformContext::swapBuffers(surface); } diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h index fc1ee16073..c4ac7185fb 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ b/src/plugins/platforms/eglfs/qeglfshooks.h @@ -72,15 +72,18 @@ public: virtual void waitForVSync() const; virtual const char *fbDeviceName() const; -}; + static QEglFSHooks *hooks() + { #ifdef EGLFS_PLATFORM_HOOKS -extern QEglFSHooks *platformHooks; -static QEglFSHooks *hooks = platformHooks; + extern QEglFSHooks *platformHooks; + return platformHooks; #else -extern QEglFSHooks stubHooks; -static QEglFSHooks *hooks = &stubHooks; + extern QEglFSHooks stubHooks; + return &stubHooks; #endif + } +}; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index 6c036cd680..5298eb47ea 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -62,8 +62,6 @@ const char *QEglFSHooks::fbDeviceName() const void QEglFSHooks::platformInit() { - Q_UNUSED(hooks); - framebuffer = qt_safe_open(fbDeviceName(), O_RDONLY); if (framebuffer == -1) diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index dd212c80a0..0fc4c44629 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -83,7 +83,7 @@ QEglFSIntegration::QEglFSIntegration() new QEvdevTouchScreenHandlerThread(QString() /* spec */, this); #endif - hooks->platformInit(); + QEglFSHooks::hooks()->platformInit(); EGLint major, minor; @@ -92,7 +92,7 @@ QEglFSIntegration::QEglFSIntegration() qFatal("EGL error"); } - mDisplay = eglGetDisplay(hooks ? hooks->platformDisplay() : EGL_DEFAULT_DISPLAY); + mDisplay = eglGetDisplay(QEglFSHooks::hooks() ? QEglFSHooks::hooks()->platformDisplay() : EGL_DEFAULT_DISPLAY); if (mDisplay == EGL_NO_DISPLAY) { qWarning("Could not open egl display\n"); qFatal("EGL error"); @@ -122,13 +122,13 @@ QEglFSIntegration::~QEglFSIntegration() delete mScreen; eglTerminate(mDisplay); - hooks->platformDestroy(); + QEglFSHooks::hooks()->platformDestroy(); } bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const { // We assume that devices will have more and not less capabilities - if (hooks && hooks->hasCapability(cap)) + if (QEglFSHooks::hooks() && QEglFSHooks::hooks()->hasCapability(cap)) return true; switch (cap) { @@ -153,13 +153,13 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - return new QEglFSContext(hooks->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay); + return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay); } QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { QEglFSScreen *screen = static_cast(surface->screen()->handle()); - return new QEGLPbuffer(screen->display(), hooks->surfaceFormatFor(surface->requestedFormat()), surface); + return new QEGLPbuffer(screen->display(), QEglFSHooks::hooks()->surfaceFormatFor(surface->requestedFormat()), surface); } QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const @@ -230,7 +230,7 @@ EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceForm QEglFSHooks *m_hooks; }; - Chooser chooser(display, hooks); + Chooser chooser(display, QEglFSHooks::hooks()); chooser.setSurfaceFormat(format); return chooser.chooseConfig(); } diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 43d7cb3b1f..83f50dd382 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -56,7 +56,7 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy) static int hideCursor = qgetenv("QT_QPA_EGLFS_HIDECURSOR").toInt(); if (!hideCursor) { - if (QEglFSCursor *customCursor = hooks->createCursor(this)) + if (QEglFSCursor *customCursor = QEglFSHooks::hooks()->createCursor(this)) m_cursor = customCursor; else m_cursor = new QEglFSCursor(this); @@ -70,22 +70,22 @@ QEglFSScreen::~QEglFSScreen() QRect QEglFSScreen::geometry() const { - return QRect(QPoint(0, 0), hooks->screenSize()); + return QRect(QPoint(0, 0), QEglFSHooks::hooks()->screenSize()); } int QEglFSScreen::depth() const { - return hooks->screenDepth(); + return QEglFSHooks::hooks()->screenDepth(); } QImage::Format QEglFSScreen::format() const { - return hooks->screenFormat(); + return QEglFSHooks::hooks()->screenFormat(); } QSizeF QEglFSScreen::physicalSize() const { - return hooks->physicalScreenSize(); + return QEglFSHooks::hooks()->physicalScreenSize(); } QPlatformCursor *QEglFSScreen::cursor() const diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 26f701d7ba..4a0e2a9a7d 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -76,18 +76,18 @@ void QEglFSWindow::create() return; if (window()->type() == Qt::Desktop) { - QRect rect(QPoint(), hooks->screenSize()); + QRect rect(QPoint(), QEglFSHooks::hooks()->screenSize()); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); return; } EGLDisplay display = (static_cast(window()->screen()->handle()))->display(); - QSurfaceFormat platformFormat = hooks->surfaceFormatFor(window()->requestedFormat()); + QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat()); EGLConfig config = QEglFSIntegration::chooseConfig(display, platformFormat); m_format = q_glFormatFromConfig(display, config); - m_window = hooks->createNativeWindow(hooks->screenSize(), m_format); + m_window = QEglFSHooks::hooks()->createNativeWindow(QEglFSHooks::hooks()->screenSize(), m_format); m_surface = eglCreateWindowSurface(display, config, m_window, NULL); if (m_surface == EGL_NO_SURFACE) { EGLint error = eglGetError(); @@ -105,7 +105,7 @@ void QEglFSWindow::destroy() } if (m_window) { - hooks->destroyNativeWindow(m_window); + QEglFSHooks::hooks()->destroyNativeWindow(m_window); m_window = 0; } } -- cgit v1.2.3 From 7b2d98d90642ce7ac4ab0800bd7930f97ba6b10c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 Feb 2013 18:17:12 -0800 Subject: Fix some warnings that have crept up since I last fixed warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qgtkstyle.cpp:3177:103: error: suggest parentheses around ‘&&’ within ‘||’ [-Werror=parentheses] qcups.cpp:517:66: error: ‘QString::QString(const char*)’ is deprecated itemviews.cpp:795:13: error: unused parameter ‘actionName’ [-Werror=unused-parameter] qeglconvenience.cpp:268:9: error: ‘cfg’ may be used uninitialized in this function [-Werror=maybe-uninitialized] Change-Id: I9b8a175ff1c2ddc443363e08b92e09cf7c2f91cf Reviewed-by: Giuseppe D'Angelo Reviewed-by: John Layt Reviewed-by: Olivier Goffart --- src/plugins/accessible/widgets/itemviews.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 17764a3c2e..092278f7fb 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -792,7 +792,7 @@ void QAccessibleTableCell::doAction(const QString& actionName) } } -QStringList QAccessibleTableCell::keyBindingsForAction(const QString& actionName) const +QStringList QAccessibleTableCell::keyBindingsForAction(const QString &) const { return QStringList(); } -- cgit v1.2.3 From e5111d5e021e8168fa9deb00abae5c403a5313e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 16:11:35 +0100 Subject: iOS: Build ios platform plugin when appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defining QT_QPA_DEFAULT_PLATFORM_NAME in qplatformdefs.h is not neccecary, as qconfig.h will already have this define written by configure. Change-Id: I89d9191533f6b4e6bfd5eade6cc0dced02b50f81 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/platforms.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 173757568f..a60a3626fa 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -6,7 +6,10 @@ contains(QT_CONFIG, xcb) { SUBDIRS += xcb } -mac:!ios: SUBDIRS += cocoa +mac { + ios: SUBDIRS += ios + else: SUBDIRS += cocoa +} win32: SUBDIRS += windows -- cgit v1.2.3 From f2168f2688d44ccb604d761fdbe199c69de0dcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 16:31:06 +0100 Subject: iOS: Build platform plugin like other platform plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... by loading(qt_plugin) Change-Id: I9be438b72be986a991a81c2cf1a3e5047bcf0a60 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 39f72e9719..66af44cbe8 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,6 +1,7 @@ TARGET = qios -include(../../qpluginbase.pri) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +load(qt_plugin) +DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private @@ -21,7 +22,5 @@ OBJECTIVE_HEADERS = qiosintegration.h \ #HEADERS = qiossoftwareinputhandler.h -#include(../fontdatabases/coretext/coretext.pri) - target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target -- cgit v1.2.3 From cb25d67f01d129d877ffb56d15f7c5e32f4955ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 22:30:37 +0100 Subject: iOS: Don't link ios platform plugin to Cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2348b19617d3e342cd344bf7d0fa894118cbfae8 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 66af44cbe8..d274fda8bd 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -5,7 +5,7 @@ DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private -LIBS += -framework Cocoa -framework UIKit +LIBS += -framework UIKit OBJECTIVE_SOURCES = main.mm \ qiosintegration.mm \ -- cgit v1.2.3 From 8716c42ee2a3d5ca42eab5850f711fd5feabb9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 23:01:56 +0100 Subject: iOS: Add missing QuartzCore dependency to platform plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic69a5a7faa9b7f9907d0325260b6b6e2389a4c3a Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index d274fda8bd..2cc730f061 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -5,7 +5,7 @@ DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private -LIBS += -framework UIKit +LIBS += -framework UIKit -framework QuartzCore OBJECTIVE_SOURCES = main.mm \ qiosintegration.mm \ -- cgit v1.2.3 From 48d39a01a78cdbb6c78133ec958123d7a8f4ae53 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 26 Feb 2013 15:31:23 +0100 Subject: Cocoa: Remove qt_mac_toCGImage warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We got these because we were flushing the backing store with a null QImage. Change-Id: I372cb3fc7c82d3bdcfe735fcadfa72806d0ef39b Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 7f022da4c3..a2f6910688 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -90,8 +90,10 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint // m_cgImage is only a reference to the data inside m_qImage, it is not a copy. CGImageRelease(m_cgImage); m_cgImage = 0; - if (QCocoaWindow *cocoaWindow = static_cast(win->handle())) - [cocoaWindow->m_contentView flushBackingStore:this region:region offset:offset]; + if (!m_qImage.isNull()) { + if (QCocoaWindow *cocoaWindow = static_cast(win->handle())) + [cocoaWindow->m_contentView flushBackingStore:this region:region offset:offset]; + } } void QCocoaBackingStore::resize(const QSize &size, const QRegion &) -- cgit v1.2.3 From 9c8ce6afb0bb19e0cb5902b65efbd1a1b55344eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 2 Nov 2012 15:44:46 +0100 Subject: iOS: Don't add to OBJECTIVE_HEADERS, there's no such thing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should add to HEADERS, so that moc will realize it needs to run on the headers. Change-Id: I582e989e4faf0835c4bf9a677cbd8ac075559319 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 2cc730f061..c6c104f2f3 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -14,7 +14,7 @@ OBJECTIVE_SOURCES = main.mm \ qioseventdispatcher.mm \ qiosbackingstore.mm -OBJECTIVE_HEADERS = qiosintegration.h \ +HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ -- cgit v1.2.3 From 3020d06fdb9fd4e539876c9fb1945b50d55cc21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 17:19:09 +0100 Subject: iOS: Change member variable style to be consistent with Qt's de facto standard Change-Id: Idd65ad9cbb77114466c5b69a799b98a7fee5068f Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.h | 2 +- src/plugins/platforms/ios/qiosbackingstore.mm | 12 +- src/plugins/platforms/ios/qiosintegration.h | 4 +- src/plugins/platforms/ios/qiosintegration.mm | 8 +- .../platforms/ios/qiossoftwareinputhandler.h | 6 +- src/plugins/platforms/ios/qioswindow.h | 26 +-- src/plugins/platforms/ios/qioswindow.mm | 186 ++++++++++----------- 7 files changed, 122 insertions(+), 122 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index cb0e9cbedb..d83a5c21ad 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -57,7 +57,7 @@ public: void resize(const QSize &size, const QRegion &staticContents); private: - QPaintDevice *mPaintDevice; + QPaintDevice *m_paintDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 32ddce38d2..20f7c1f2d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -63,7 +63,7 @@ class EAGLPaintDevice : public QGLPaintDevice { public: EAGLPaintDevice(QWindow *window) - :QGLPaintDevice(), mWindow(window) + :QGLPaintDevice(), m_window(window) { #if defined(QT_OPENGL_ES_2) helper = [[PaintDeviceHelper alloc] init]; @@ -83,17 +83,17 @@ public: void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } int devType() const { return QInternal::OpenGL; } - QSize size() const { return mWindow->geometry().size(); } + QSize size() const { return m_window->geometry().size(); } QGLContext* context() const { // Todo: siplify this: return QGLContext::fromOpenGLContext( - static_cast(mWindow->handle())->glContext()->context()); + static_cast(m_window->handle())->glContext()->context()); } QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } private: - QWindow *mWindow; + QWindow *m_window; PaintDeviceHelper *helper; }; @@ -112,13 +112,13 @@ private: QT_BEGIN_NAMESPACE QIOSBackingStore::QIOSBackingStore(QWindow *window) - : QPlatformBackingStore(window), mPaintDevice(new EAGLPaintDevice(window)) + : QPlatformBackingStore(window), m_paintDevice(new EAGLPaintDevice(window)) { } QPaintDevice *QIOSBackingStore::paintDevice() { - return mPaintDevice; + return m_paintDevice; } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index b71379e417..f44403fbba 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -65,8 +65,8 @@ public: QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QList mScreens; - QPlatformFontDatabase *mFontDb; + QList m_screens; + QPlatformFontDatabase *m_fontDb; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index bd63384004..98b08ed72a 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -59,11 +59,11 @@ QIOSIntegration * QIOSIntegration::instance() } QIOSIntegration::QIOSIntegration() - :mFontDb(new QCoreTextFontDatabase) + :m_fontDb(new QCoreTextFontDatabase) { if (!m_instance) m_instance = this; - mScreens << new QIOSScreen(0); + m_screens << new QIOSScreen(0); } QIOSIntegration::~QIOSIntegration() @@ -85,7 +85,7 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const QList QIOSIntegration::screens() const { - return mScreens; + return m_screens; } QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const @@ -100,7 +100,7 @@ QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const QPlatformFontDatabase * QIOSIntegration::fontDatabase() const { - return mFontDb; + return m_fontDb; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h index bbad656b93..99e8fac61b 100644 --- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -55,7 +55,7 @@ class QIOSSoftwareInputHandler : public QObject Q_OBJECT public: - QIOSSoftwareInputHandler() : mCurrentFocusWidget(0), mCurrentFocusObject(0) {} + QIOSSoftwareInputHandler() : m_CurrentFocusWidget(0), m_CurrentFocusObject(0) {} bool eventFilter(QObject *obj, QEvent *event); private slots: @@ -64,8 +64,8 @@ private slots: private: bool closeSoftwareInputPanel(QWidget *widget); - QPointer mCurrentFocusWidget; - QPointer mCurrentFocusObject; + QPointer m_currentFocusWidget; + QPointer m_currentFocusObject; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index f43f3db4f9..2d3d5b072f 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -53,13 +53,13 @@ @interface EAGLView : UIView { - QPlatformWindow *mWindow; - EAGLContext *mContext; + QPlatformWindow *m_window; + EAGLContext *m_context; - GLint mFramebufferWidth; - GLint mFramebufferHeight; + GLint m_framebufferWidth; + GLint m_framebufferHeight; - GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + GLuint m_framebuffer, m_colorRenderbuffer, m_depthRenderbuffer; id delegate; // ------- Text Input ---------- @@ -111,23 +111,23 @@ public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - UIWindow *nativeWindow() const { return mWindow; } - EAGLView *nativeView() const { return mView; } + UIWindow *nativeWindow() const { return m_window; } + EAGLView *nativeView() const { return m_view; } void setGeometry(const QRect &rect); UIWindow *ensureNativeWindow(); QPlatformOpenGLContext *glContext() const; - QIOSScreen *platformScreen() const { return mScreen; } + QIOSScreen *platformScreen() const { return m_screen; } void updateGeometryAndOrientation(); private: - QIOSScreen *mScreen; - UIWindow *mWindow; - CGRect mFrame; - EAGLView *mView; - mutable EAGLPlatformContext *mContext; + QIOSScreen *m_screen; + UIWindow *m_window; + CGRect m_frame; + EAGLView *m_view; + mutable EAGLPlatformContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c63c22dbaa..28aaaf2189 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -75,7 +75,7 @@ class EAGLPlatformContext : public QPlatformOpenGLContext { public: EAGLPlatformContext(EAGLView *view) - : mView(view) + : m_view(view) { /* mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); @@ -103,7 +103,7 @@ public: #else EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; #endif - [mView setContext:aContext]; + [m_view setContext:aContext]; } ~EAGLPlatformContext() { } @@ -113,7 +113,7 @@ public: Q_UNUSED(surface); qDebug() << __FUNCTION__ << "not implemented"; //QPlatformOpenGLContext::makeCurrent(); - //[mView makeCurrent]; + //[m_view makeCurrent]; return false; } @@ -127,7 +127,7 @@ public: { Q_UNUSED(surface); qDebug() << __FUNCTION__ << "not implemented"; - //[mView presentFramebuffer]; + //[m_view presentFramebuffer]; } QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } @@ -138,7 +138,7 @@ public: } private: - EAGLView *mView; + EAGLView *m_view; QSurfaceFormat mFormat; }; @@ -174,97 +174,97 @@ private: - (void)setContext:(EAGLContext *)newContext { - if (mContext != newContext) + if (m_context != newContext) { [self deleteFramebuffer]; - [mContext release]; - mContext = [newContext retain]; + [m_context release]; + m_context = [newContext retain]; [EAGLContext setCurrentContext:nil]; } } - (void)presentFramebuffer { - if (mContext) { - [EAGLContext setCurrentContext:mContext]; - glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); - [mContext presentRenderbuffer:GL_RENDERBUFFER]; + if (m_context) { + [EAGLContext setCurrentContext:m_context]; + glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); + [m_context presentRenderbuffer:GL_RENDERBUFFER]; } } - (void)deleteFramebuffer { - if (mContext) + if (m_context) { - [EAGLContext setCurrentContext:mContext]; - if (mFramebuffer) { - glDeleteFramebuffers(1, &mFramebuffer); - mFramebuffer = 0; + [EAGLContext setCurrentContext:m_context]; + if (m_framebuffer) { + glDeleteFramebuffers(1, &m_framebuffer); + m_framebuffer = 0; } - if (mColorRenderbuffer) { - glDeleteRenderbuffers(1, &mColorRenderbuffer); - mColorRenderbuffer = 0; + if (m_colorRenderbuffer) { + glDeleteRenderbuffers(1, &m_colorRenderbuffer); + m_colorRenderbuffer = 0; } - if (mDepthRenderbuffer) { - glDeleteRenderbuffers(1, &mDepthRenderbuffer); - mDepthRenderbuffer = 0; + if (m_depthRenderbuffer) { + glDeleteRenderbuffers(1, &m_depthRenderbuffer); + m_depthRenderbuffer = 0; } } } - (void)createFramebuffer { - if (mContext && !mFramebuffer) + if (m_context && !m_framebuffer) { - [EAGLContext setCurrentContext:mContext]; - glGenFramebuffers(1, &mFramebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - - glGenRenderbuffers(1, &mColorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); - [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); - - glGenRenderbuffers(1, &mDepthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + [EAGLContext setCurrentContext:m_context]; + glGenFramebuffers(1, &m_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + + glGenRenderbuffers(1, &m_colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); + [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_framebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_framebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); + + glGenRenderbuffers(1, &m_depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); if (stencilBits() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebufferWidth, m_framebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFramebufferWidth, mFramebufferHeight); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebufferWidth, m_framebufferHeight); } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { - [delegate eaglView:self usesFramebuffer:mFramebuffer]; + [delegate eaglView:self usesFramebuffer:m_framebuffer]; } } } - (void)makeCurrent { - if (mContext) + if (m_context) { - [EAGLContext setCurrentContext:mContext]; - if (!mFramebuffer) + [EAGLContext setCurrentContext:m_context]; + if (!m_framebuffer) [self createFramebuffer]; - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glViewport(0, 0, m_framebufferWidth, m_framebufferHeight); } } - (GLint)fbo { - return mFramebuffer; + return m_framebuffer; } - (void)setWindow:(QPlatformWindow *)window { - mWindow = window; + m_window = window; } - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons @@ -274,7 +274,7 @@ private: CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(mWindow->window(), (ulong)(event.timestamp*1000), + QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); } @@ -347,18 +347,18 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window), - mWindow(nil), - mContext(0) + m_window(nil), + m_context(0) { - mScreen = static_cast(QPlatformScreen::platformScreenForWindow(window)); - mView = [[EAGLView alloc] init]; + m_screen = static_cast(QPlatformScreen::platformScreenForWindow(window)); + m_view = [[EAGLView alloc] init]; } QIOSWindow::~QIOSWindow() { - delete mContext; mContext = 0; - [mView release]; - [mWindow release]; + delete m_context; m_context = 0; + [m_view release]; + [m_window release]; } void QIOSWindow::setGeometry(const QRect &rect) @@ -369,81 +369,81 @@ void QIOSWindow::setGeometry(const QRect &rect) UIWindow *QIOSWindow::ensureNativeWindow() { - if (!mWindow) { - mWindow = [[UIWindow alloc] init]; + if (!m_window) { + m_window = [[UIWindow alloc] init]; updateGeometryAndOrientation(); // window - mWindow.screen = mScreen->uiScreen(); + m_window.screen = m_screen->uiScreen(); // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards - mWindow.frame = mFrame; + m_window.frame = m_frame; // view - [mView deleteFramebuffer]; - mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill - [mView setContentScaleFactor:[mWindow.screen scale]]; - [mView setMultipleTouchEnabled:YES]; - [mView setWindow:this]; - [mWindow addSubview:mView]; - [mWindow setNeedsDisplay]; - [mWindow makeKeyAndVisible]; + [m_view deleteFramebuffer]; + m_view.frame = CGRectMake(0, 0, m_window.bounds.size.width, m_window.bounds.size.height); // fill + [m_view setContentScaleFactor:[m_window.screen scale]]; + [m_view setMultipleTouchEnabled:YES]; + [m_view setWindow:this]; + [m_window addSubview:m_view]; + [m_window setNeedsDisplay]; + [m_window makeKeyAndVisible]; } - return mWindow; + return m_window; } void QIOSWindow::updateGeometryAndOrientation() { - if (!mWindow) + if (!m_window) return; - mFrame = [mScreen->uiScreen() applicationFrame]; - CGRect screen = [mScreen->uiScreen() bounds]; + m_frame = [m_screen->uiScreen() applicationFrame]; + CGRect screen = [m_screen->uiScreen() bounds]; QRect geom; CGFloat angle = 0; switch ([[UIApplication sharedApplication] statusBarOrientation]) { case UIInterfaceOrientationPortrait: - geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + geom = QRect(m_frame.origin.x, m_frame.origin.y, m_frame.size.width, m_frame.size.height); break; case UIInterfaceOrientationPortraitUpsideDown: - geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, - screen.size.height - mFrame.origin.y - mFrame.size.height, - mFrame.size.width, - mFrame.size.height); + geom = QRect(screen.size.width - m_frame.origin.x - m_frame.size.width, + screen.size.height - m_frame.origin.y - m_frame.size.height, + m_frame.size.width, + m_frame.size.height); angle = M_PI; break; case UIInterfaceOrientationLandscapeLeft: - geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, - mFrame.origin.x, - mFrame.size.height, - mFrame.size.width); + geom = QRect(screen.size.height - m_frame.origin.y - m_frame.size.height, + m_frame.origin.x, + m_frame.size.height, + m_frame.size.width); angle = -M_PI/2.; break; case UIInterfaceOrientationLandscapeRight: - geom = QRect(mFrame.origin.y, - screen.size.width - mFrame.origin.x - mFrame.size.width, - mFrame.size.height, - mFrame.size.width); + geom = QRect(m_frame.origin.y, + screen.size.width - m_frame.origin.x - m_frame.size.width, + m_frame.size.height, + m_frame.size.width); angle = +M_PI/2.; break; } - CGFloat scale = [mScreen->uiScreen() scale]; + CGFloat scale = [m_screen->uiScreen() scale]; geom = QRect(geom.x() * scale, geom.y() * scale, geom.width() * scale, geom.height() * scale); if (angle != 0) { - [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + [m_view layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); } else { - [mView layer].transform = CATransform3DIdentity; + [m_view layer].transform = CATransform3DIdentity; } - [mView setNeedsDisplay]; + [m_view setNeedsDisplay]; window()->setGeometry(geom); } QPlatformOpenGLContext *QIOSWindow::glContext() const { - if (!mContext) { - mContext = new EAGLPlatformContext(mView); + if (!m_context) { + m_context = new EAGLPlatformContext(m_view); } - return mContext; + return m_context; } QT_END_NAMESPACE -- cgit v1.2.3 From 6d36a83b419e0b0bc0270e45983ed2bbfa453996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 18:56:45 +0100 Subject: iOS: Get rid of singleton instance accessor in platform plugin None of the other platform plugins have one, and it's not used anywhere. Change-Id: Id46ab5f75c9819511c3e9d123d0338c3c8799869 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 -- src/plugins/platforms/ios/qiosintegration.mm | 9 --------- 2 files changed, 11 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index f44403fbba..ef839a89b0 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -52,8 +52,6 @@ public: QIOSIntegration(); ~QIOSIntegration(); - static QIOSIntegration *instance(); - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 98b08ed72a..1b03b410cb 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -51,18 +51,9 @@ QT_BEGIN_NAMESPACE -static QIOSIntegration *m_instance = 0; - -QIOSIntegration * QIOSIntegration::instance() -{ - return m_instance; -} - QIOSIntegration::QIOSIntegration() :m_fontDb(new QCoreTextFontDatabase) { - if (!m_instance) - m_instance = this; m_screens << new QIOSScreen(0); } -- cgit v1.2.3 From 14e93f7e8e0ef58b0e47bfe277d52b2fa8f24ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:01:44 +0100 Subject: iOS: Add screen like other platform plugins We may add support for external displays at a later point, but for now we follow the same pattern as the other platform plugins. Either way we should call screenAdded() to let the platform integration know about the screen. Change-Id: Id01785a5262df0180caf957c7de8ecbbf169f233 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 4 +--- src/plugins/platforms/ios/qiosintegration.mm | 9 ++------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index ef839a89b0..8b2ac70a9f 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -56,15 +56,13 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QList screens() const; - QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QList m_screens; QPlatformFontDatabase *m_fontDb; + QPlatformScreen *m_screen; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 1b03b410cb..68a9bf343f 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,9 +52,9 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase) + :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(0)) { - m_screens << new QIOSScreen(0); + screenAdded(m_screen); } QIOSIntegration::~QIOSIntegration() @@ -74,11 +74,6 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const return new QIOSWindow(window); } -QList QIOSIntegration::screens() const -{ - return m_screens; -} - QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { return new QIOSBackingStore(window); -- cgit v1.2.3 From 5e85aa9ab4c30c123de6431679d3870a4b7836c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:39:45 +0100 Subject: iOS: Keep UIScreen* for current QIOSScreen instead of looking up each time Also, add enum for screen numbers, for better code readability. Change-Id: Id5162c34e80ff5efb149ae86b49f51df183d1c1d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qiosscreen.h | 7 ++++--- src/plugins/platforms/ios/qiosscreen.mm | 12 ++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 68a9bf343f..7a6dec43d4 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(0)) + :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { screenAdded(m_screen); } diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 628d764f53..98771b9ac2 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -51,9 +51,11 @@ QT_BEGIN_NAMESPACE class QIOSScreen : public QPlatformScreen { public: - QIOSScreen(int screenIndex); + QIOSScreen(unsigned int screenIndex); ~QIOSScreen(); + enum ScreenIndex { MainScreen = 0 }; + QRect geometry() const { return m_geometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } @@ -63,14 +65,13 @@ public: void updateInterfaceOrientation(); private: + UIScreen *m_uiScreen; QRect m_geometry; int m_depth; QImage::Format m_format; QSize m_physicalSize; - int m_index; }; QT_END_NAMESPACE - #endif diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5d9841734a..64b9022a29 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE -QIOSScreen::QIOSScreen(int screenIndex) - : QPlatformScreen(), - m_index(screenIndex) +QIOSScreen::QIOSScreen(unsigned int screenIndex) + : QPlatformScreen() + , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGRect bounds = [uiScreen() bounds]; - CGFloat scale = [uiScreen() scale]; + CGRect bounds = [m_uiScreen bounds]; + CGFloat scale = [m_uiScreen scale]; updateInterfaceOrientation(); m_format = QImage::Format_ARGB32_Premultiplied; @@ -87,7 +87,7 @@ QIOSScreen::~QIOSScreen() UIScreen *QIOSScreen::uiScreen() const { - return [[UIScreen screens] objectAtIndex:m_index]; + return m_uiScreen; } void QIOSScreen::updateInterfaceOrientation() -- cgit v1.2.3 From 422eed16eb22772357aab06feb12c59f5d188b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:43:57 +0100 Subject: iOS: Style nitpicking, rename m_fontDb to m_fontDatabase Change-Id: I9d92843af9018d51b73fadcc7c20d792fad772fa Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 +- src/plugins/platforms/ios/qiosintegration.mm | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 8b2ac70a9f..d744cf377a 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -61,7 +61,7 @@ public: QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QPlatformFontDatabase *m_fontDb; + QPlatformFontDatabase *m_fontDatabase; QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 7a6dec43d4..d3e9572f83 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,7 +52,8 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(QIOSScreen::MainScreen)) + : m_fontDatabase(new QCoreTextFontDatabase) + , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { screenAdded(m_screen); } @@ -86,7 +87,7 @@ QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const QPlatformFontDatabase * QIOSIntegration::fontDatabase() const { - return m_fontDb; + return m_fontDatabase; } QT_END_NAMESPACE -- cgit v1.2.3 From a685df05841a3dd45095e40ca0f40ab796bfc86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 21:59:00 +0100 Subject: iOS: Add ability to get the UIView for a QWindow through QPlatformNativeInterface Change-Id: Iab2742bbaa97ff345871ad07ef0162b12248506a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 6 +++++- src/plugins/platforms/ios/qiosintegration.mm | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d744cf377a..d72eefa1fa 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -43,10 +43,11 @@ #define QPLATFORMINTEGRATION_UIKIT_H #include +#include QT_BEGIN_NAMESPACE -class QIOSIntegration : public QPlatformIntegration +class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface { public: QIOSIntegration(); @@ -59,6 +60,9 @@ public: QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QPlatformNativeInterface *nativeInterface() const; + + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); private: QPlatformFontDatabase *m_fontDatabase; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d3e9572f83..0c876bf1b2 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -90,4 +90,24 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformNativeInterface *QIOSIntegration::nativeInterface() const +{ + return const_cast(this); +} + +void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + if (!window || !window->handle()) + return 0; + + QByteArray lowerCaseResource = resource.toLower(); + + QIOSWindow *platformWindow = static_cast(window->handle()); + + if (lowerCaseResource == "uiview") + return platformWindow->nativeView(); + + return 0; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 145abdc4429f636b365ce6ebd51f81e216bc7fa3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Nov 2012 10:53:59 +0100 Subject: iOS: QIOSEventDispatcher: add runloop source for processing events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6cd649a493dab9a982d71921f19d2a9252fc14b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 9 +++- src/plugins/platforms/ios/qioseventdispatcher.mm | 61 +++++++++++++++++++++--- 2 files changed, 63 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 479ec1d0a0..db3eb85ffc 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -77,6 +77,7 @@ #define QEVENTDISPATCHER_IOS_P_H #include +#include QT_BEGIN_NAMESPACE @@ -85,7 +86,8 @@ class QIOSEventDispatcher : public QAbstractEventDispatcher Q_OBJECT public: - explicit QIOSEventDispatcher(QObject *parent = 0); ~QIOSEventDispatcher(); + explicit QIOSEventDispatcher(QObject *parent = 0); + ~QIOSEventDispatcher(); bool processEvents(QEventLoop::ProcessEventsFlags flags); bool hasPendingEvents(); @@ -103,6 +105,11 @@ public: void wakeUp(); void interrupt(); void flush(); + +private: + CFRunLoopSourceRef m_postedEventsSource; + static void postedEventsSourceCallback(void *info); + void processPostedEvents(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 12f448488e..85854f711e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -75,42 +75,80 @@ #include "qioseventdispatcher.h" #include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE +static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) +{ + return info1 == info2; +} + +void QIOSEventDispatcher::postedEventsSourceCallback(void *info) +{ + QIOSEventDispatcher *self = static_cast(info); + self->processPostedEvents(); +} + +void QIOSEventDispatcher::processPostedEvents() +{ + qDebug() << __FUNCTION__ << "called"; + QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents); +} + QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) + : QAbstractEventDispatcher(parent) { - Q_UNUSED(parent); - qDebug() << __FUNCTION__ << "eventdispatcher not implemented"; + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + + CFRunLoopSourceContext context; + bzero(&context, sizeof(CFRunLoopSourceContext)); + context.equal = runLoopSourceEqualCallback; + context.info = this; + + // source used to send posted events: + context.perform = QIOSEventDispatcher::postedEventsSourceCallback; + m_postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_postedEventsSource); + CFRunLoopAddSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); } QIOSEventDispatcher::~QIOSEventDispatcher() -{} +{ + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + CFRunLoopRemoveSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); + CFRelease(m_postedEventsSource); +} bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_UNUSED(flags); + qDebug() << __FUNCTION__ << "not implemented"; return false; } bool QIOSEventDispatcher::hasPendingEvents() { + qDebug() << __FUNCTION__ << "not implemented"; return false; } void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(notifier); } void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(notifier); } void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); Q_UNUSED(interval); Q_UNUSED(timerType); @@ -119,36 +157,47 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType bool QIOSEventDispatcher::unregisterTimer(int timerId) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); return false; } bool QIOSEventDispatcher::unregisterTimers(QObject *object) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(object); return false; } QList QIOSEventDispatcher::registeredTimers(QObject *object) const { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(object); return QList(); } int QIOSEventDispatcher::remainingTime(int timerId) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); return 0; } void QIOSEventDispatcher::wakeUp() -{} +{ + CFRunLoopSourceSignal(m_postedEventsSource); + CFRunLoopWakeUp(CFRunLoopGetMain()); +} void QIOSEventDispatcher::interrupt() -{} +{ + qDebug() << __FUNCTION__ << "not implemented"; +} void QIOSEventDispatcher::flush() -{} +{ + qDebug() << __FUNCTION__ << "not implemented"; +} QT_END_NAMESPACE -- cgit v1.2.3 From 407cf7341e70feeb24ff63ad11bd2e79dac5823f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Nov 2012 14:07:47 +0100 Subject: iOS: QIOSEventDispatcher: implement timer support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1966a64e6535f32005681db37b4fe5d89dafc70c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 15 ++- src/plugins/platforms/ios/qioseventdispatcher.mm | 136 ++++++++++++++++++++--- 2 files changed, 132 insertions(+), 19 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index db3eb85ffc..da8464f5ee 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -77,6 +77,7 @@ #define QEVENTDISPATCHER_IOS_P_H #include +#include #include QT_BEGIN_NAMESPACE @@ -107,9 +108,19 @@ public: void flush(); private: - CFRunLoopSourceRef m_postedEventsSource; - static void postedEventsSourceCallback(void *info); + CFRunLoopSourceRef m_postedEventsRunLoopSource; + CFRunLoopSourceRef m_blockingTimerRunLoopSource; + + QTimerInfoList m_timerInfoList; + CFRunLoopTimerRef m_runLoopTimerRef; + void processPostedEvents(); + void maybeStartCFRunLoopTimer(); + void maybeStopCFRunLoopTimer(); + + static void postedEventsRunLoopCallback(void *info); + static void nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info); + static void blockingTimerRunLoopCallback(void *info); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 85854f711e..191e80668d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -76,6 +76,7 @@ #include "qioseventdispatcher.h" #include #include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -85,40 +86,134 @@ static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) return info1 == info2; } -void QIOSEventDispatcher::postedEventsSourceCallback(void *info) +void QIOSEventDispatcher::postedEventsRunLoopCallback(void *info) { QIOSEventDispatcher *self = static_cast(info); self->processPostedEvents(); } +void QIOSEventDispatcher::nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info) +{ + // The (one and only) CFRunLoopTimer has fired, which means that at least + // one QTimer should now fire as well. Note that CFRunLoopTimer's callback will + // never recurse. So if the app starts a new QEventLoop within this callback, other + // timers will stop working. The work-around is to forward the callback to a + // dedicated CFRunLoopSource that can recurse: + QIOSEventDispatcher *self = static_cast(info); + CFRunLoopSourceSignal(self->m_blockingTimerRunLoopSource); +} + +void QIOSEventDispatcher::blockingTimerRunLoopCallback(void *info) +{ + // TODO: + // We also need to block this new timer source + // along with the posted event source when calling processEvents() + // "manually" to prevent livelock deep in CFRunLoop. + + QIOSEventDispatcher *self = static_cast(info); + self->m_timerInfoList.activateTimers(); + self->maybeStartCFRunLoopTimer(); +} + +void QIOSEventDispatcher::maybeStartCFRunLoopTimer() +{ + // Find out when the next registered timer should fire, and schedule + // runLoopTimer accordingly. If the runLoopTimer does not yet exist, and + // at least one timer is registered, start by creating the timer: + if (m_timerInfoList.isEmpty()) { + Q_ASSERT(m_runLoopTimerRef == 0); + return; + } + + CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent(); + CFTimeInterval interval; + + if (m_runLoopTimerRef == 0) { + // start the CFRunLoopTimer + CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.); + + // calculate when the next timer should fire: + struct timespec tv; + if (m_timerInfoList.timerWait(tv)) { + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + } else { + // this shouldn't really happen, but in case it does, set the timer + // to fire a some point in the distant future: + interval = oneyear; + } + + ttf += interval; + CFRunLoopTimerContext info = { 0, this, 0, 0, 0 }; + // create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate() + // documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working + m_runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QIOSEventDispatcher::nonBlockingTimerRunLoopCallback, &info); + Q_ASSERT(m_runLoopTimerRef != 0); + + CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimerRef, kCFRunLoopCommonModes); + } else { + struct timespec tv; + // Calculate when the next timer should fire: + if (m_timerInfoList.timerWait(tv)) { + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + } else { + // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some + // point in the distant future (the timer interval is one year) + interval = CFRunLoopTimerGetInterval(m_runLoopTimerRef); + } + + ttf += interval; + CFRunLoopTimerSetNextFireDate(m_runLoopTimerRef, ttf); + } +} + +void QIOSEventDispatcher::maybeStopCFRunLoopTimer() +{ + if (m_runLoopTimerRef == 0) + return; + + CFRunLoopTimerInvalidate(m_runLoopTimerRef); + CFRelease(m_runLoopTimerRef); + m_runLoopTimerRef = 0; +} + void QIOSEventDispatcher::processPostedEvents() { - qDebug() << __FUNCTION__ << "called"; QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents); } QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QAbstractEventDispatcher(parent) + , m_runLoopTimerRef(0) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); context.equal = runLoopSourceEqualCallback; context.info = this; - // source used to send posted events: - context.perform = QIOSEventDispatcher::postedEventsSourceCallback; - m_postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); - Q_ASSERT(m_postedEventsSource); - CFRunLoopAddSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); + // source used to handle timers: + context.perform = QIOSEventDispatcher::blockingTimerRunLoopCallback; + m_blockingTimerRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_blockingTimerRunLoopSource); + CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); + + // source used to handle posted events: + context.perform = QIOSEventDispatcher::postedEventsRunLoopCallback; + m_postedEventsRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_postedEventsRunLoopSource); + CFRunLoopAddSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes); } QIOSEventDispatcher::~QIOSEventDispatcher() { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopRemoveSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); - CFRelease(m_postedEventsSource); + CFRunLoopRemoveSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes); + CFRelease(m_postedEventsRunLoopSource); + + qDeleteAll(m_timerInfoList); + maybeStopCFRunLoopTimer(); + CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); + CFRelease(m_blockingTimerRunLoopSource); } bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) @@ -146,13 +241,20 @@ void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) Q_UNUSED(notifier); } -void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) +void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - Q_UNUSED(interval); - Q_UNUSED(timerType); - Q_UNUSED(object); +#ifndef QT_NO_DEBUG + if (timerId < 1 || interval < 0 || !obj) { + qWarning("QIOSEventDispatcher::registerTimer: invalid arguments"); + return; + } else if (obj->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QIOSEventDispatcher: timers cannot be started from another thread"); + return; + } +#endif + + m_timerInfoList.registerTimer(timerId, interval, timerType, obj); + maybeStartCFRunLoopTimer(); } bool QIOSEventDispatcher::unregisterTimer(int timerId) @@ -185,7 +287,7 @@ int QIOSEventDispatcher::remainingTime(int timerId) void QIOSEventDispatcher::wakeUp() { - CFRunLoopSourceSignal(m_postedEventsSource); + CFRunLoopSourceSignal(m_postedEventsRunLoopSource); CFRunLoopWakeUp(CFRunLoopGetMain()); } -- cgit v1.2.3 From 44c3ef790e6105b913b514dfda64fd5957df78af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 5 Nov 2012 13:59:53 +0100 Subject: iOS: Fix build on case sensitive filesystems Change-Id: Ic7a2b38ffcc2bd83e268c5caf5bec17006879969 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0c876bf1b2..0c324d5275 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qiosIntegration.h" +#include "qiosintegration.h" #include "qioswindow.h" #include "qiosbackingstore.h" #include "qiosscreen.h" -- cgit v1.2.3 From 05d0f60ebefaeb7721ac572f1253c2c7b2f42dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 23:30:50 +0100 Subject: iOS: Flesh out initial QPlatformScreen implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We check the device's model identifier to tweak the screen values based on the precense of older iPhone/iPod touch models, or the iPad Mini. This does not work when running under the simulator, which reports its model identifier as the architecture of the host platform. There doesn't appear to be any APIs to get the simulated device of the simulator, but if this becomes an issue we can always look at the UIDevice model and screen resolution and apply a few heuristics. We do not update the screen geometry on orientation-changes. This matches what UIScreen reports for bounds, but may not be the most intuitive solution from a Qt perspective compared to the way other platform-plugins work. Change-Id: I74783e053601de9ce805f8b52b944c116f9a1e3e Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosscreen.h | 13 ++-- src/plugins/platforms/ios/qiosscreen.mm | 105 +++++++++++++++++--------------- 2 files changed, 61 insertions(+), 57 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 98771b9ac2..8af7779f9d 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -52,24 +52,21 @@ class QIOSScreen : public QPlatformScreen { public: QIOSScreen(unsigned int screenIndex); - ~QIOSScreen(); enum ScreenIndex { MainScreen = 0 }; - QRect geometry() const { return m_geometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } - QSizeF physicalSize() const { return m_physicalSize; } + QRect geometry() const; + int depth() const; + QImage::Format format() const; + QSizeF physicalSize() const; UIScreen *uiScreen() const; - void updateInterfaceOrientation(); private: UIScreen *m_uiScreen; QRect m_geometry; int m_depth; - QImage::Format m_format; - QSize m_physicalSize; + QSizeF m_physicalSize; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 64b9022a29..93b22953e2 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -42,79 +42,86 @@ #include "qiosscreen.h" #include "qioswindow.h" -#include - -#include +#include QT_BEGIN_NAMESPACE +/*! + Returns the model identifier of the device. + + When running under the simulator, the identifier will not + match the simulated device, but will be x86_64 or i386. +*/ +static QString deviceModelIdentifier() +{ + static const char key[] = "hw.machine"; + + size_t size; + sysctlbyname(key, NULL, &size, NULL, 0); + + char value[size]; + sysctlbyname(key, &value, &size, NULL, 0); + + return QString::fromLatin1(value); +} + QIOSScreen::QIOSScreen(unsigned int screenIndex) : QPlatformScreen() , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGRect bounds = [m_uiScreen bounds]; - CGFloat scale = [m_uiScreen scale]; - updateInterfaceOrientation(); - m_format = QImage::Format_ARGB32_Premultiplied; + QString deviceIdentifier = deviceModelIdentifier(); - m_depth = 24; - - const qreal inch = 25.4; - qreal unscaledDpi = 160.; - int dragDistance = 12 * scale; - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { - unscaledDpi = 132.; - dragDistance = 10 * scale; + if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */ + || deviceIdentifier == QStringLiteral("iPod3,1") /* iPod touch 3G */) { + m_depth = 18; + } else { + m_depth = 24; } - m_physicalSize = QSize(qRound(bounds.size.width * inch / unscaledDpi), qRound(bounds.size.height * inch / unscaledDpi)); - //qApp->setStartDragDistance(dragDistance); + int unscaledDpi = 163; // Regular iPhone DPI + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad + && deviceIdentifier != QStringLiteral("iPad2,5") /* iPad Mini */) { + unscaledDpi = 132; + }; + + // UIScreen does not report different bounds for different orientations. We + // match this behavior by staying with a fixed QScreen geometry. + CGRect bounds = [m_uiScreen bounds]; + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); - /* - QFont font; // system font is helvetica, so that is fine already - font.setPixelSize([UIFont systemFontSize] * scale); - qApp->setFont(font); - */ + const qreal millimetersPerInch = 25.4; + m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; [pool release]; } -QIOSScreen::~QIOSScreen() +QRect QIOSScreen::geometry() const { + // FIXME: Do we need to reimplement availableGeometry() to take the + // system statusbar into account? + return m_geometry; } -UIScreen *QIOSScreen::uiScreen() const +int QIOSScreen::depth() const { - return m_uiScreen; + return m_depth; } -void QIOSScreen::updateInterfaceOrientation() +QImage::Format QIOSScreen::format() const { - qDebug() << __FUNCTION__ << "not implemented"; - /* - CGRect bounds = [uiScreen() bounds]; - CGFloat scale = [uiScreen() scale]; - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, - bounds.size.width * scale, bounds.size.height * scale);; - break; - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, - bounds.size.height * scale, bounds.size.width * scale); - break; - } - foreach (QWidget *widget, qApp->topLevelWidgets()) { - QIOSWindow *platformWindow = static_cast(widget->platformWindow()); - if (platformWindow && platformWindow->platformScreen() == this) { - platformWindow->updateGeometryAndOrientation(); - } - } - */ + return QImage::Format_ARGB32_Premultiplied; +} + +QSizeF QIOSScreen::physicalSize() const +{ + return m_physicalSize; +} + +UIScreen *QIOSScreen::uiScreen() const +{ + return m_uiScreen; } QT_END_NAMESPACE -- cgit v1.2.3 From 458382f35b62c98a283bb08770029f21827b9ae6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2012 11:00:58 +0100 Subject: iOS: call UIApplicationMain from event dispatcher, and add application delegate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will let you call QApplication::exec() instead of UiApplicationMain from main. Also added an application delegate that we will need sooner or later for catching application activation events. Change-Id: I4edba5ce2059a804782d67c160755fc0e2e5267d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/ios.pro | 6 +- .../platforms/ios/qiosapplicationdelegate.h | 50 ++++++++++++ .../platforms/ios/qiosapplicationdelegate.mm | 89 ++++++++++++++++++++++ src/plugins/platforms/ios/qioseventdispatcher.mm | 58 ++++++-------- 4 files changed, 165 insertions(+), 38 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosapplicationdelegate.h create mode 100644 src/plugins/platforms/ios/qiosapplicationdelegate.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index c6c104f2f3..76f5e3420e 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -12,13 +12,15 @@ OBJECTIVE_SOURCES = main.mm \ qioswindow.mm \ qiosscreen.mm \ qioseventdispatcher.mm \ - qiosbackingstore.mm + qiosbackingstore.mm \ + qiosapplicationdelegate.mm HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ - qiosbackingstore.h + qiosbackingstore.h \ + qiosapplicationdelegate.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h new file mode 100644 index 0000000000..10e415831d --- /dev/null +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import +#import + +@interface QIOSApplicationDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end + diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm new file mode 100644 index 0000000000..d88b2b83f1 --- /dev/null +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import "qiosapplicationdelegate.h" +#include + +@implementation QIOSApplicationDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + Q_UNUSED(application) + Q_UNUSED(launchOptions) + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + // Override point for customization after application launch. + self.window.backgroundColor = [UIColor whiteColor]; + [self.window makeKeyAndVisible]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + Q_UNUSED(application) +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + Q_UNUSED(application) +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + Q_UNUSED(application) + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + Q_UNUSED(application) + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + Q_UNUSED(application) + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end + + diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 191e80668d..64f853233d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -39,44 +39,13 @@ ** ****************************************************************************/ -/**************************************************************************** -** -** Copyright (c) 2007-2008, Apple, Inc. -** -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** -** * Neither the name of Apple, Inc. nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - #include "qioseventdispatcher.h" +#import "qiosapplicationdelegate.h" #include #include #include +#include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -218,8 +187,25 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { - Q_UNUSED(flags); - qDebug() << __FUNCTION__ << "not implemented"; + UIApplication *uiApplication = [UIApplication sharedApplication]; + bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; + bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); + bool useExecMode = execFlagSet && !excludeUserEvents; + + if (useExecMode) { + if (!uiApplication) { + // No UIApplication has been started yet. We therefore start it now. Note that application + // developers are free to call UIApplicationMain themselves instead of QApplication::exec() + @autoreleasepool { + QCoreApplicationPrivate *qAppPriv = static_cast(QObjectPrivate::get(qApp)); + return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); + } + } else { + // todo: start NSRunLoop... + } + } else { + // todo: manual processEvents... + } return false; } -- cgit v1.2.3 From ac8d906a3a61b3dd43aaf546e5f83e25d117631c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2012 14:52:22 +0100 Subject: iOS: support killing timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the remaining timer functions in the event dispatcher Change-Id: Ie323962c898a2ee95ea60a8ca63b93cbd4544fd1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 54 ++++++++++++++++++------ 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 64f853233d..a7f01a33a9 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -245,30 +245,60 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType bool QIOSEventDispatcher::unregisterTimer(int timerId) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - return false; +#ifndef QT_NO_DEBUG + if (timerId < 1) { + qWarning("QIOSEventDispatcher::unregisterTimer: invalid argument"); + return false; + } else if (thread() != QThread::currentThread()) { + qWarning("QObject::killTimer: timers cannot be stopped from another thread"); + return false; + } +#endif + + bool returnValue = m_timerInfoList.unregisterTimer(timerId); + m_timerInfoList.isEmpty() ? maybeStopCFRunLoopTimer() : maybeStartCFRunLoopTimer(); + return returnValue; } bool QIOSEventDispatcher::unregisterTimers(QObject *object) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(object); - return false; +#ifndef QT_NO_DEBUG + if (!object) { + qWarning("QIOSEventDispatcher::unregisterTimers: invalid argument"); + return false; + } else if (object->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QObject::killTimers: timers cannot be stopped from another thread"); + return false; + } +#endif + + bool returnValue = m_timerInfoList.unregisterTimers(object); + m_timerInfoList.isEmpty() ? maybeStopCFRunLoopTimer() : maybeStartCFRunLoopTimer(); + return returnValue; } QList QIOSEventDispatcher::registeredTimers(QObject *object) const { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(object); - return QList(); +#ifndef QT_NO_DEBUG + if (!object) { + qWarning("QIOSEventDispatcher:registeredTimers: invalid argument"); + return QList(); + } +#endif + + return m_timerInfoList.registeredTimers(object); } int QIOSEventDispatcher::remainingTime(int timerId) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - return 0; +#ifndef QT_NO_DEBUG + if (timerId < 1) { + qWarning("QIOSEventDispatcher::remainingTime: invalid argument"); + return -1; + } +#endif + + return m_timerInfoList.timerRemainingTime(timerId); } void QIOSEventDispatcher::wakeUp() -- cgit v1.2.3 From 3c4f48f9e2ad9163d012d4afb36037d7efea8e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2012 16:24:19 +0100 Subject: iOS: Implement QPlatformOpenGLContext The iOS platform GL context is an EAGLContext, which is wrapped by the new class QIOSContext. The class takes care of makeCurrent() and swapBuffers(), but defers framebuffer management to the corresponding QIOSWindow. At the moment only a single framebuffer is created, and changing the geometry of the QWindow does not trigger any sort of invalidation of the buffers. The implementation assumes OpenGL ES2.x support. Though strictly speaking we could support ES1 for QtGui, it serves little purpose as Qt Quick 2 requires ES2. This patch also disabled touch event synthesization until we have figured out where we will maintain the connection to UIWindow. QPlatformOpenGLContext::getProcAddress() for getting extensions is implemented by using dlsym() to look up the symbol. This should not present any issues for App Store deployment, like dlopen() would. Change-Id: I166f800f3ecc0d180133c590465371ac1642b0ec Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 6 +- src/plugins/platforms/ios/qiosbackingstore.mm | 1 + src/plugins/platforms/ios/qioscontext.h | 76 +++++ src/plugins/platforms/ios/qioscontext.mm | 124 ++++++++ src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 13 +- src/plugins/platforms/ios/qioswindow.h | 97 ++----- src/plugins/platforms/ios/qioswindow.mm | 400 +++++++------------------- 8 files changed, 343 insertions(+), 376 deletions(-) create mode 100644 src/plugins/platforms/ios/qioscontext.h create mode 100644 src/plugins/platforms/ios/qioscontext.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 76f5e3420e..22b0fec9e8 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -13,14 +13,16 @@ OBJECTIVE_SOURCES = main.mm \ qiosscreen.mm \ qioseventdispatcher.mm \ qiosbackingstore.mm \ - qiosapplicationdelegate.mm + qiosapplicationdelegate.mm \ + qioscontext.mm HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ qiosbackingstore.h \ - qiosapplicationdelegate.h + qiosapplicationdelegate.h \ + qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 20f7c1f2d1..2ffa43b5d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -133,6 +133,7 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) { Q_UNUSED(size); Q_UNUSED(staticContents); + qDebug() << __FUNCTION__ << "not implemented"; } diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h new file mode 100644 index 0000000000..102aaaa387 --- /dev/null +++ b/src/plugins/platforms/ios/qioscontext.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSCONTEXT_H +#define QIOSCONTEXT_H + +#include + +@class EAGLContext; + +QT_BEGIN_NAMESPACE + +class QIOSContext : public QPlatformOpenGLContext +{ +public: + QIOSContext(QOpenGLContext *context); + ~QIOSContext(); + + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + + GLuint defaultFramebufferObject(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); + + EAGLContext *nativeContext() const; + +private: + EAGLContext *m_eaglContext; + QSurfaceFormat m_format; +}; + +QT_END_NAMESPACE + +#endif // QIOSCONTEXT_H diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm new file mode 100644 index 0000000000..e512b3d4c8 --- /dev/null +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qioscontext.h" +#include "qioswindow.h" + +#include + +#include + +#import +#import + +QIOSContext::QIOSContext(QOpenGLContext *context) + : QPlatformOpenGLContext() + , m_eaglContext([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]) +{ + // Start out with the requested format + QSurfaceFormat format = context->format(); + + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setMajorVersion(2); + format.setMinorVersion(0); + + // Even though iOS internally double-buffers its rendering, we + // report single-buffered here since the buffer remains unchanged + // when swapping unlesss you manually clear it yourself. + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + + m_format = format; +} + +QIOSContext::~QIOSContext() +{ + [m_eaglContext release]; +} + +QSurfaceFormat QIOSContext::format() const +{ + return m_format; +} + +bool QIOSContext::makeCurrent(QPlatformSurface *surface) +{ + Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + + [EAGLContext setCurrentContext:m_eaglContext]; + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); + + return true; +} + +void QIOSContext::doneCurrent() +{ + [EAGLContext setCurrentContext:nil]; +} + +void QIOSContext::swapBuffers(QPlatformSurface *surface) +{ + Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + + [EAGLContext setCurrentContext:m_eaglContext]; + + GLint renderbuffer; + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + + [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; +} + +GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const +{ + return static_cast(surface)->framebufferObject(*const_cast(this)); +} + +QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) +{ + return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); +} + +EAGLContext *QIOSContext::nativeContext() const +{ + return m_eaglContext; +} diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d72eefa1fa..e411ce2905 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -57,6 +57,8 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0c324d5275..b9fef71abc 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -44,6 +44,7 @@ #include "qiosbackingstore.h" #include "qiosscreen.h" #include "qioseventdispatcher.h" +#include "qioscontext.h" #include @@ -65,21 +66,31 @@ QIOSIntegration::~QIOSIntegration() QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const { Q_UNUSED(type); + qDebug() << __FUNCTION__ << "not yet implemented"; return 0; - //return new QRasterPixmapData(type); } QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { + qDebug() << __FUNCTION__ << "Creating platform window"; return new QIOSWindow(window); } QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { + qDebug() << __FUNCTION__ << "Creating platform backingstore"; return new QIOSBackingStore(window); } +// Used when the QWindow's surface type is set by the client to QSurface::OpenGLSurface +QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + Q_UNUSED(context); + qDebug() << __FUNCTION__ << "Creating platform opengl context"; + return new QIOSContext(context); +} + QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const { return new QIOSEventDispatcher(); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2d3d5b072f..d8f49db55b 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -45,24 +45,11 @@ #include #import -#import -#import -#import -#import -#import + +class QIOSContext; @interface EAGLView : UIView { - QPlatformWindow *m_window; - EAGLContext *m_context; - - GLint m_framebufferWidth; - GLint m_framebufferHeight; - - GLuint m_framebuffer, m_colorRenderbuffer, m_depthRenderbuffer; - - id delegate; - // ------- Text Input ---------- UITextAutocapitalizationType autocapitalizationType; UITextAutocorrectionType autocorrectionType; BOOL enablesReturnKeyAutomatically; @@ -72,19 +59,8 @@ BOOL secureTextEntry; } -- (void)setContext:(EAGLContext *)newContext; -- (void)presentFramebuffer; -- (void)deleteFramebuffer; -- (void)createFramebuffer; -- (void)makeCurrent; -- (void)setWindow:(QPlatformWindow *)window; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; -@property (readonly,getter=fbo) GLint fbo; -@property (nonatomic, assign) id delegate; - -// ------- Text Input ---------- - @property(nonatomic) UITextAutocapitalizationType autocapitalizationType; @property(nonatomic) UITextAutocorrectionType autocorrectionType; @property(nonatomic) BOOL enablesReturnKeyAutomatically; @@ -95,39 +71,22 @@ @end -@protocol EAGLViewDelegate -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; -@end - -class EAGLPlatformContext; - QT_BEGIN_NAMESPACE -class QIOSScreen; - class QIOSWindow : public QPlatformWindow { public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - UIWindow *nativeWindow() const { return m_window; } - EAGLView *nativeView() const { return m_view; } void setGeometry(const QRect &rect); - UIWindow *ensureNativeWindow(); + GLuint framebufferObject(const QIOSContext &context) const; - QPlatformOpenGLContext *glContext() const; - - QIOSScreen *platformScreen() const { return m_screen; } + EAGLView *nativeView() const { return m_view; } - void updateGeometryAndOrientation(); private: - QIOSScreen *m_screen; - UIWindow *m_window; - CGRect m_frame; EAGLView *m_view; - mutable EAGLPlatformContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 28aaaf2189..46612ae699 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -1,152 +1,57 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#import - #include "qioswindow.h" - +#include "qioscontext.h" #include "qiosscreen.h" -#include +#import + #include -#include #include #include -static GLint stencilBits() -{ - static GLint bits; - static bool initialized = false; - if (!initialized) { - glGetIntegerv(GL_STENCIL_BITS, &bits); - initialized = true; - } - return bits; -} - -/* -static GLint depthBits() -{ - // we can choose between GL_DEPTH24_STENCIL8_OES and GL_DEPTH_COMPONENT16 - return stencilBits() > 0 ? 24 : 16; -} -*/ - -class EAGLPlatformContext : public QPlatformOpenGLContext -{ -public: - EAGLPlatformContext(EAGLView *view) - : m_view(view) - { - /* - mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); - mFormat.setDepthBufferSize(depthBits()); - mFormat.setAccumBufferSize(0); - mFormat.setRedBufferSize(8); - mFormat.setGreenBufferSize(8); - mFormat.setBlueBufferSize(8); - mFormat.setAlphaBufferSize(8); - mFormat.setStencilBufferSize(stencilBits()); - mFormat.setSamples(0); - mFormat.setSampleBuffers(false); - mFormat.setDoubleBuffer(true); - mFormat.setDepth(true); - mFormat.setRgba(true); - mFormat.setAlpha(true); - mFormat.setAccum(false); - mFormat.setStencil(stencilBits() > 0); - mFormat.setStereo(false); - mFormat.setDirectRendering(false); - */ - -#if defined(QT_OPENGL_ES_2) - EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; -#else - EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; -#endif - [m_view setContext:aContext]; - } - - ~EAGLPlatformContext() { } - - bool makeCurrent(QPlatformSurface *surface) - { - Q_UNUSED(surface); - qDebug() << __FUNCTION__ << "not implemented"; - //QPlatformOpenGLContext::makeCurrent(); - //[m_view makeCurrent]; - return false; - } - - void doneCurrent() - { - qDebug() << __FUNCTION__ << "not implemented"; - //QPlatformOpenGLContext::doneCurrent(); - } - - void swapBuffers(QPlatformSurface *surface) - { - Q_UNUSED(surface); - qDebug() << __FUNCTION__ << "not implemented"; - //[m_view presentFramebuffer]; - } - - QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } - - QSurfaceFormat format() const - { - return mFormat; - } - -private: - EAGLView *m_view; - - QSurfaceFormat mFormat; -}; - @implementation EAGLView -@synthesize delegate; - + (Class)layerClass { return [CAEAGLLayer class]; @@ -155,12 +60,14 @@ private: - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + // Set up EAGL layer + CAEAGLLayer *eaglLayer = static_cast(self.layer); eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, - kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, - nil]; + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + // Set up text input autocapitalizationType = UITextAutocapitalizationTypeNone; autocorrectionType = UITextAutocorrectionTypeNo; enablesReturnKeyAutomatically = NO; @@ -169,113 +76,28 @@ private: returnKeyType = UIReturnKeyDone; secureTextEntry = NO; } - return self; -} - -- (void)setContext:(EAGLContext *)newContext -{ - if (m_context != newContext) - { - [self deleteFramebuffer]; - [m_context release]; - m_context = [newContext retain]; - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)presentFramebuffer -{ - if (m_context) { - [EAGLContext setCurrentContext:m_context]; - glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); - [m_context presentRenderbuffer:GL_RENDERBUFFER]; - } -} -- (void)deleteFramebuffer -{ - if (m_context) - { - [EAGLContext setCurrentContext:m_context]; - if (m_framebuffer) { - glDeleteFramebuffers(1, &m_framebuffer); - m_framebuffer = 0; - } - if (m_colorRenderbuffer) { - glDeleteRenderbuffers(1, &m_colorRenderbuffer); - m_colorRenderbuffer = 0; - } - if (m_depthRenderbuffer) { - glDeleteRenderbuffers(1, &m_depthRenderbuffer); - m_depthRenderbuffer = 0; - } - } -} - -- (void)createFramebuffer -{ - if (m_context && !m_framebuffer) - { - [EAGLContext setCurrentContext:m_context]; - glGenFramebuffers(1, &m_framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); - - glGenRenderbuffers(1, &m_colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); - [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_framebufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_framebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); - - glGenRenderbuffers(1, &m_depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); - if (stencilBits() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebufferWidth, m_framebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebufferWidth, m_framebufferHeight); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { - [delegate eaglView:self usesFramebuffer:m_framebuffer]; - } - } -} - -- (void)makeCurrent -{ - if (m_context) - { - [EAGLContext setCurrentContext:m_context]; - if (!m_framebuffer) - [self createFramebuffer]; - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); - glViewport(0, 0, m_framebufferWidth, m_framebufferHeight); - } + return self; } -- (GLint)fbo +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { - return m_framebuffer; -} + Q_UNUSED(touches); + Q_UNUSED(event); + Q_UNUSED(buttons); -- (void)setWindow:(QPlatformWindow *)window -{ - m_window = window; -} + // FIXME: Reintroduce relation to UIWindow + qDebug() << __FUNCTION__ << "not implemented"; -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons -{ +#if 0 UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), - p, p, buttons); + QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); +#endif } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -298,8 +120,6 @@ private: [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; } -// ------- Text Input ---------- - @synthesize autocapitalizationType; @synthesize autocorrectionType; @synthesize enablesReturnKeyAutomatically; @@ -343,107 +163,79 @@ private: @end + QT_BEGIN_NAMESPACE -QIOSWindow::QIOSWindow(QWindow *window) : - QPlatformWindow(window), - m_window(nil), - m_context(0) +QIOSWindow::QIOSWindow(QWindow *window) + : QPlatformWindow(window) + , m_view([[EAGLView alloc] init]) { - m_screen = static_cast(QPlatformScreen::platformScreenForWindow(window)); - m_view = [[EAGLView alloc] init]; } QIOSWindow::~QIOSWindow() { - delete m_context; m_context = 0; [m_view release]; - [m_window release]; } void QIOSWindow::setGeometry(const QRect &rect) { - // Not supported. Only a single "full screen" window is supported QPlatformWindow::setGeometry(rect); -} -UIWindow *QIOSWindow::ensureNativeWindow() -{ - if (!m_window) { - m_window = [[UIWindow alloc] init]; - updateGeometryAndOrientation(); - // window - m_window.screen = m_screen->uiScreen(); - // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards - m_window.frame = m_frame; - - // view - [m_view deleteFramebuffer]; - m_view.frame = CGRectMake(0, 0, m_window.bounds.size.width, m_window.bounds.size.height); // fill - [m_view setContentScaleFactor:[m_window.screen scale]]; - [m_view setMultipleTouchEnabled:YES]; - [m_view setWindow:this]; - [m_window addSubview:m_view]; - [m_window setNeedsDisplay]; - [m_window makeKeyAndVisible]; - } - return m_window; + qDebug() << __FUNCTION__ << "not implemented"; } -void QIOSWindow::updateGeometryAndOrientation() +GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - if (!m_window) - return; - m_frame = [m_screen->uiScreen() applicationFrame]; - CGRect screen = [m_screen->uiScreen() bounds]; - QRect geom; - CGFloat angle = 0; - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - geom = QRect(m_frame.origin.x, m_frame.origin.y, m_frame.size.width, m_frame.size.height); - break; - case UIInterfaceOrientationPortraitUpsideDown: - geom = QRect(screen.size.width - m_frame.origin.x - m_frame.size.width, - screen.size.height - m_frame.origin.y - m_frame.size.height, - m_frame.size.width, - m_frame.size.height); - angle = M_PI; - break; - case UIInterfaceOrientationLandscapeLeft: - geom = QRect(screen.size.height - m_frame.origin.y - m_frame.size.height, - m_frame.origin.x, - m_frame.size.height, - m_frame.size.width); - angle = -M_PI/2.; - break; - case UIInterfaceOrientationLandscapeRight: - geom = QRect(m_frame.origin.y, - screen.size.width - m_frame.origin.x - m_frame.size.width, - m_frame.size.height, - m_frame.size.width); - angle = +M_PI/2.; - break; - } + static GLuint framebuffer = 0; - CGFloat scale = [m_screen->uiScreen() scale]; - geom = QRect(geom.x() * scale, geom.y() * scale, - geom.width() * scale, geom.height() * scale); + // FIXME: Cache context and recreate framebuffer if window + // is used with a different context then last time. - if (angle != 0) { - [m_view layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); - } else { - [m_view layer].transform = CATransform3DIdentity; - } - [m_view setNeedsDisplay]; - window()->setGeometry(geom); -} + if (!framebuffer) { + EAGLContext* eaglContext = context.nativeContext(); -QPlatformOpenGLContext *QIOSWindow::glContext() const -{ - if (!m_context) { - m_context = new EAGLPlatformContext(m_view); + [EAGLContext setCurrentContext:eaglContext]; + + // Create the framebuffer and bind it + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + GLint width; + GLint height; + + // Create a color renderbuffer, allocate storage for it, + // and attach it to the framebuffer’s color attachment point. + GLuint colorRenderbuffer; + glGenRenderbuffers(1, &colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); + + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + // Create a depth or depth/stencil renderbuffer, allocate storage for it, + // and attach it to the framebuffer’s depth attachment point. + GLuint depthRenderbuffer; + glGenRenderbuffers(1, &depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + + // FIXME: Support more fine grained control over depth/stencil buffer sizes + if (requestedFormat.stencilBufferSize() > 0) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + } else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return m_context; + + return framebuffer; } QT_END_NAMESPACE -- cgit v1.2.3 From 09187f602c8ac84c9982bb2e433af5524ac2d37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2012 12:01:50 +0100 Subject: iOS: Implement QIOSBackingStore in terms of a QOpenGLPaintDevice We build on top of the QPlatformOpenGLContext implementation to get automatic support for QBackingStore-based painting. Since the OpenGL renderer does not clear the backingstore between frames, we actually also get support for partial updates, and we get the benefit of an accelerated paint engine for Qt Quick 1 without setting a GLWidget as the viewport, which would cause issues such as an extra QWindow. This patch also removes the dependency to QtOpenGL and QtWidgets, which were leftovers from the Qt4 platform plugin. In Qt5 the needed GL bits are in QtGui. Change-Id: Id9b736bfb2e4aec56c0fa9f5b7b4d8bff8e3d1dc Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 3 +- src/plugins/platforms/ios/qiosbackingstore.h | 57 +++++----- src/plugins/platforms/ios/qiosbackingstore.mm | 147 ++++++++++---------------- src/plugins/platforms/ios/qiosintegration.mm | 1 + 4 files changed, 89 insertions(+), 119 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 22b0fec9e8..2fe6a4cb3f 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -3,8 +3,7 @@ TARGET = qios load(qt_plugin) DESTDIR = $$QT.gui.plugins/platforms -QT += opengl -QT += core-private gui-private platformsupport-private opengl-private widgets-private +QT += core-private gui-private platformsupport-private LIBS += -framework UIKit -framework QuartzCore OBJECTIVE_SOURCES = main.mm \ diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index d83a5c21ad..c110f0e4d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -42,7 +42,6 @@ #ifndef QIOSBACKINGSTORE_H #define QIOSBACKINGSTORE_H -#include #include QT_BEGIN_NAMESPACE @@ -51,13 +50,19 @@ class QIOSBackingStore : public QPlatformBackingStore { public: QIOSBackingStore(QWindow *window); + ~QIOSBackingStore(); QPaintDevice *paintDevice(); + + void beginPaint(const QRegion &); + void endPaint(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); private: - QPaintDevice *m_paintDevice; + QOpenGLContext *m_context; + QPaintDevice *m_device; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 2ffa43b5d1..71f14fdd91 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -42,91 +42,54 @@ #include "qiosbackingstore.h" #include "qioswindow.h" -#include -#include +#include +#include #include -class EAGLPaintDevice; - -@interface PaintDeviceHelper : NSObject { - EAGLPaintDevice *device; -} - -@property (nonatomic, assign) EAGLPaintDevice *device; - -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; - -@end - -class EAGLPaintDevice : public QGLPaintDevice +QIOSBackingStore::QIOSBackingStore(QWindow *window) + : QPlatformBackingStore(window) + , m_context(new QOpenGLContext) + , m_device(0) { -public: - EAGLPaintDevice(QWindow *window) - :QGLPaintDevice(), m_window(window) - { -#if defined(QT_OPENGL_ES_2) - helper = [[PaintDeviceHelper alloc] init]; - helper.device = this; - EAGLView *view = static_cast(window->handle())->nativeView(); - view.delegate = helper; - m_thisFBO = view.fbo; -#endif - } - - ~EAGLPaintDevice() - { -#if defined(QT_OPENGL_ES_2) - [helper release]; -#endif - } - - void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } - int devType() const { return QInternal::OpenGL; } - QSize size() const { return m_window->geometry().size(); } - QGLContext* context() const { - // Todo: siplify this: - return QGLContext::fromOpenGLContext( - static_cast(m_window->handle())->glContext()->context()); - } - - QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } - -private: - QWindow *m_window; - PaintDeviceHelper *helper; -}; - -@implementation PaintDeviceHelper -@synthesize device; + m_context->setFormat(window->requestedFormat()); + m_context->setScreen(window->screen()); + m_context->create(); +} -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +QIOSBackingStore::~QIOSBackingStore() { - Q_UNUSED(view) - if (device) - device->setFramebuffer(buffer); + delete m_context; } -@end - -QT_BEGIN_NAMESPACE - -QIOSBackingStore::QIOSBackingStore(QWindow *window) - : QPlatformBackingStore(window), m_paintDevice(new EAGLPaintDevice(window)) +void QIOSBackingStore::beginPaint(const QRegion &) { + // Needed to prevent QOpenGLContext::makeCurrent() from failing + window()->setSurfaceType(QSurface::OpenGLSurface); + + m_context->makeCurrent(window()); + m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { - return m_paintDevice; + return m_device; } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(region); Q_UNUSED(offset); - qDebug() << __FUNCTION__ << "not implemented"; - //static_cast(window->handle())->glContext()->swapBuffers(); + + m_context->swapBuffers(window); +} + +void QIOSBackingStore::endPaint() +{ + delete m_device; + + // Calling makeDone() on the context here would be an option, + // but is not needed, and would actually add some overhead. } void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) @@ -134,7 +97,9 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) Q_UNUSED(size); Q_UNUSED(staticContents); - qDebug() << __FUNCTION__ << "not implemented"; + // We don't need to resize the QOpenGLPaintDevice, as it's just a thin wrapper + // around the OpenGL paint-engine, and the real geometry is handled by the + // context and window. } QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b9fef71abc..8abe3c4273 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -77,6 +77,7 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const return new QIOSWindow(window); } +// Used when the QWindow's surface type is set by the client to QSurface::RasterSurface QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform backingstore"; -- cgit v1.2.3 From 19de726725dc123f478ecb2b122d03862c725650 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 09:31:00 +0100 Subject: iOS: create top-level UIWindow and UIViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a UIWIndow with a view controller and a view where we can reparent our QIOSWindow views inside. Change-Id: Ic90707d3ebe1af970a3aa2aa0f8c0f4be192456a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 18 ++++++++++++++++++ src/plugins/platforms/ios/qioswindow.mm | 6 ++++++ 2 files changed, 24 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index d88b2b83f1..6fed4c1a23 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #import "qiosapplicationdelegate.h" +#include "qioswindow.h" #include @implementation QIOSApplicationDelegate @@ -48,7 +49,24 @@ { Q_UNUSED(application) Q_UNUSED(launchOptions) + + // If this application delegate is instanciated, it means that + // this plugin also created UIApplication. We then also create a + // window with a view controller, and set all QWindow views + // as children of the controller view: self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + UIViewController *controller = [[UIViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; + + QWindowList windows = QGuiApplication::topLevelWindows(); + for (int i=0; i(windows[i]->handle())) { + UIView *winView = w->nativeView(); + if (winView && !winView.superview) + [controller.view addSubview:winView]; + } + } // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 46612ae699..2888228f18 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,6 +42,7 @@ #include "qioswindow.h" #include "qioscontext.h" #include "qiosscreen.h" +#include "qiosapplicationdelegate.h" #import @@ -170,6 +171,11 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] init]) { + UIApplication *uiApplication = [UIApplication sharedApplication]; + if (uiApplication) { + if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) + [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; + } } QIOSWindow::~QIOSWindow() -- cgit v1.2.3 From ea1e5ccd621115d8103ceac962ac89dc0db65b70 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 16:34:43 +0100 Subject: iOS: implement QEventLoop support in the event dispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this patch you can now expect the following code to work: QEventLoop l; QTimer::singleShot(1000, &l, SLOT(quit())); l.exec(); Change-Id: Ic73e37affaadf8a859787d84ac02c15621ac7a29 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 2 ++ src/plugins/platforms/ios/qioseventdispatcher.mm | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index da8464f5ee..88d5127855 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -108,6 +108,8 @@ public: void flush(); private: + bool m_interrupted; + CFRunLoopSourceRef m_postedEventsRunLoopSource; CFRunLoopSourceRef m_blockingTimerRunLoopSource; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index a7f01a33a9..4268b02b6d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -152,6 +152,7 @@ void QIOSEventDispatcher::processPostedEvents() QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QAbstractEventDispatcher(parent) + , m_interrupted(false) , m_runLoopTimerRef(0) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); @@ -187,6 +188,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { + m_interrupted = false; + UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); @@ -201,7 +204,8 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); } } else { - // todo: start NSRunLoop... + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); } } else { // todo: manual processEvents... @@ -309,7 +313,7 @@ void QIOSEventDispatcher::wakeUp() void QIOSEventDispatcher::interrupt() { - qDebug() << __FUNCTION__ << "not implemented"; + m_interrupted = true; } void QIOSEventDispatcher::flush() -- cgit v1.2.3 From 0dbee6a5e1e3945dab404f8784df24a9260f0d52 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 22:57:17 +0100 Subject: iOS: send mouse events (from touch events) from EAGLView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia6c955f2c5bcde8e41d5908bfb8fd52bd449b3ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 +++ src/plugins/platforms/ios/qioswindow.mm | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d8f49db55b..c2bf1bb6f0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -47,6 +47,7 @@ #import class QIOSContext; +class QIOSWindow; @interface EAGLView : UIView { @@ -57,8 +58,10 @@ class QIOSContext; UIKeyboardType keyboardType; UIReturnKeyType returnKeyType; BOOL secureTextEntry; + QIOSWindow *m_qioswindow; } +- (id)initWithQIOSWindow:(QIOSWindow *)qioswindow; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; @property(nonatomic) UITextAutocapitalizationType autocapitalizationType; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2888228f18..59508d83f3 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -58,6 +58,14 @@ return [CAEAGLLayer class]; } +-(id)initWithQIOSWindow:(QIOSWindow *)qioswindow +{ + if (self = [super init]) { + m_qioswindow = qioswindow; + } + return self; +} + - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { @@ -83,22 +91,13 @@ - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { - Q_UNUSED(touches); - Q_UNUSED(event); - Q_UNUSED(buttons); - - // FIXME: Reintroduce relation to UIWindow - qDebug() << __FUNCTION__ << "not implemented"; - -#if 0 UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); -#endif + QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -169,7 +168,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) - , m_view([[EAGLView alloc] init]) + , m_view([[EAGLView alloc] initWithQIOSWindow:this]) { UIApplication *uiApplication = [UIApplication sharedApplication]; if (uiApplication) { -- cgit v1.2.3 From 6bbe89e2b858564493468c7c5bd9c978c374751a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 19:48:38 +0100 Subject: iOS: support stand-alone qApp->processEvents calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rough implementation to support stand-alone processEvent calls. We probably need to revisit this code to fix corner-cases later on. Change-Id: I72d5639dab599b4d0017aaa52b922f4185a50337 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 4268b02b6d..252e375a54 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -189,6 +189,7 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { m_interrupted = false; + bool eventsProcessed = false; UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; @@ -207,10 +208,13 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); } + eventsProcessed = true; } else { - // todo: manual processEvents... + if (!(flags & QEventLoop::WaitForMoreEvents)) + wakeUp(); + eventsProcessed = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } - return false; + return eventsProcessed; } bool QIOSEventDispatcher::hasPendingEvents() @@ -313,6 +317,7 @@ void QIOSEventDispatcher::wakeUp() void QIOSEventDispatcher::interrupt() { + wakeUp(); m_interrupted = true; } -- cgit v1.2.3 From caacccaaf0fbc0a4f4f88af7dadbfece175776d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 7 Nov 2012 17:30:46 +0100 Subject: iOS: Unset EAGL context if it's current when destroying QIOSContext Change-Id: Ie0b27e6b0dafa2a7283b44d6676871fce15cc42a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index e512b3d4c8..8beb588b03 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -70,6 +70,9 @@ QIOSContext::QIOSContext(QOpenGLContext *context) QIOSContext::~QIOSContext() { + if ([EAGLContext currentContext] == m_eaglContext) + doneCurrent(); + [m_eaglContext release]; } -- cgit v1.2.3 From 231796c98d317f845209e2b470fa34e00aac3c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 14:48:18 +0100 Subject: iOS: Set background color of UIWindow and root UIView to burn your eyes Convenient to aid debugging during development of the platform plugin. Change-Id: Id429ca95e0452385ee8def1fe4a1bb7de175ba3e Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 6fed4c1a23..1b3dc18dd7 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -68,8 +68,10 @@ } } - // Override point for customization after application launch. - self.window.backgroundColor = [UIColor whiteColor]; + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + controller.view.backgroundColor = [UIColor magentaColor]; + [self.window makeKeyAndVisible]; return YES; } -- cgit v1.2.3 From 3bc6d7470a88bf1da12aa768c9527fe08d52757a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 15:09:00 +0100 Subject: iOS: Pass QWindow geometry to initWithFrame on window creation Allows the optimal pattern of setting the geometry of the QWindow before showing (and hence creating) it. Change-Id: I29206b5d9a70df0b01e8df8f7df8f35cced51121 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59508d83f3..ce0ea6e0e1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -51,6 +51,11 @@ #include +static CGRect toCGRect(const QRect &rect) +{ + return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); +} + @implementation EAGLView + (Class)layerClass @@ -58,11 +63,11 @@ return [CAEAGLLayer class]; } --(id)initWithQIOSWindow:(QIOSWindow *)qioswindow +-(id)initWithQIOSWindow:(QIOSWindow *)window { - if (self = [super init]) { - m_qioswindow = qioswindow; - } + if (self = [super initWithFrame:toCGRect(window->geometry())]) + m_qioswindow = window; + return self; } -- cgit v1.2.3 From e936561a164ce582785eafcfa70ed2924f7bc954 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Sun, 11 Nov 2012 10:22:20 +0100 Subject: iOS: Add Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) into the plugin itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the plugin will always be linked in statically, we add this necessary registration code into the plugin itself rather than putting this burden onto the client application. Change-Id: I8691d8080e41bdf0644bb960b5c7102e79a0f0d5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/main.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm index b09fbce1f4..6a04770e3e 100644 --- a/src/plugins/platforms/ios/main.mm +++ b/src/plugins/platforms/ios/main.mm @@ -66,4 +66,4 @@ QT_END_NAMESPACE #include "main.moc" - +Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) -- cgit v1.2.3 From 8d7238f57e9a85524ea550917f051b9eb9927922 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Wed, 7 Nov 2012 22:11:35 +0100 Subject: iOS: Use default createPlatformPixmap implementation No need to implement this one, the standard implementation creates a raster pixmap. Change-Id: I9bb25188bd95159d76e760b2be6870e0bede7b56 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 1 - src/plugins/platforms/ios/qiosintegration.mm | 8 -------- 2 files changed, 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index e411ce2905..11c17aced9 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -53,7 +53,6 @@ public: QIOSIntegration(); ~QIOSIntegration(); - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 8abe3c4273..d00d4a077f 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -63,14 +63,6 @@ QIOSIntegration::~QIOSIntegration() { } -QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const -{ - Q_UNUSED(type); - - qDebug() << __FUNCTION__ << "not yet implemented"; - return 0; -} - QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform window"; -- cgit v1.2.3 From 3d81b43aa462c66e11f772398550e76ce4cee6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 17:12:54 +0100 Subject: iOS: Implement QPlatformScreen::availableGeometry() This will sadly not work as expected until we've found a way to kick off the iOS event loop before QApplication is initialized, as UIScreen does not seem to report the correct applicationFrame (taking the status bar into account) until after the UIApplication has been set up by UIApplicationMain(). Change-Id: I0eaa3b8bca4129d1c4183a202ad2ecd0d8bc52d0 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 8af7779f9d..8d67b1ecdf 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -56,6 +56,7 @@ public: enum ScreenIndex { MainScreen = 0 }; QRect geometry() const; + QRect availableGeometry() const; int depth() const; QImage::Format format() const; QSizeF physicalSize() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 93b22953e2..effd19070a 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -99,11 +99,15 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) QRect QIOSScreen::geometry() const { - // FIXME: Do we need to reimplement availableGeometry() to take the - // system statusbar into account? return m_geometry; } +QRect QIOSScreen::availableGeometry() const +{ + CGRect frame = m_uiScreen.applicationFrame; + return QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); +} + int QIOSScreen::depth() const { return m_depth; -- cgit v1.2.3 From e123056c47e33759e740ea2e25771e0cc1899c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Nov 2012 17:08:46 +0100 Subject: iOS: Implement QIOSWindow::setGeometry() and pick up UIView geometry changes The best way to pick up geometry changes of the UIView seems to be to override layoutSubviews(), but that will only be called if the size of the UIView changes, not when the position (center) changes. This means that the position reflected by the QWindow will not always be in sync with the position of the native UIView. Fortunately the position of a QWindow is not used for anything critical in Qt itself. Another issue is that the frame property of a UIView is only valid if the transform of the UIView is set to the identity transform. We try to catch cases where this is not the case, and warn the user about this. We could in theory react to changes in the UIView geometry by only updating the size, since this is also reflected through the bounds property of the UIView. This is left for when we know more about how these things interact in practice. Change-Id: I079162c059d377a77569fe3974e261d2e0671fd5 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index c2bf1bb6f0..d16e17124d 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,6 +83,7 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); + void updateGeometry(const QRect &rect); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index ce0ea6e0e1..feabaeb47a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -56,6 +56,11 @@ static CGRect toCGRect(const QRect &rect) return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); } +static QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + @implementation EAGLView + (Class)layerClass @@ -94,6 +99,24 @@ static CGRect toCGRect(const QRect &rect) return self; } +- (void)layoutSubviews +{ + // This method is the de facto way to know that view has been resized, + // or otherwise needs invalidation of its buffers. Note though that we + // do not get this callback when the view just changes its position, so + // the position of our QWindow (and platform window) will only get updated + // when the size is also changed. + + if (CGAffineTransformIsIdentity(self.transform)) { + // Reflect the new size (and possibly also position) in the QWindow + m_qioswindow->updateGeometry(fromCGRect(self.frame)); + } else { + qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; + } + + [super layoutSubviews]; +} + - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { UITouch *touch = [touches anyObject]; @@ -189,9 +212,27 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { + if (!CGAffineTransformIsIdentity(m_view.transform)) { + qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; + return; + } + + // Since we don't support transformations on the UIView, we can set the frame + // directly and let UIKit deal with translating that into bounds and center. + m_view.frame = toCGRect(rect); + + updateGeometry(rect); +} + +void QIOSWindow::updateGeometry(const QRect &rect) +{ + // The baseclass implementation will store the geometry, and allows use to + // re-use the baseclass geometry() implementation, which just returns rect. QPlatformWindow::setGeometry(rect); - qDebug() << __FUNCTION__ << "not implemented"; + // We inform Qt about new geometry, which will trigger resize and + // expose events for the application. + QWindowSystemInterface::handleGeometryChange(window(), rect); } GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const -- cgit v1.2.3 From 3241f37711bd35988c7a21cc8a4833ec2fa3132d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Nov 2012 17:20:47 +0100 Subject: iOS: Implement QPlatformWindow::setWindowState() In both maximized and fullscreen modes we assume that we can use the availableGeometry() of the QScreen, but of course this depends on us showing or hiding the statusbar first, as well as QScreen actually returning the right availableGeometry when the statusbar is shown. The latter is not the case right now, as we initialize QScreen before UIApplication has been set up and UIScreen has had a chance to init itself based on the precense of a statusbar or not. Change-Id: Id44dee3550f7135ffe2852b377bb6c7b6d522d68 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d16e17124d..4e1970d4d4 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -85,6 +85,8 @@ public: void setGeometry(const QRect &rect); void updateGeometry(const QRect &rect); + void setWindowState(Qt::WindowState state); + GLuint framebufferObject(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index feabaeb47a..cccd5ab133 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -203,6 +203,8 @@ QIOSWindow::QIOSWindow(QWindow *window) if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; } + + setWindowState(window->windowState()); } QIOSWindow::~QIOSWindow() @@ -235,6 +237,22 @@ void QIOSWindow::updateGeometry(const QRect &rect) QWindowSystemInterface::handleGeometryChange(window(), rect); } +void QIOSWindow::setWindowState(Qt::WindowState state) +{ + // FIXME: Figure out where or how we should disable/enable the statusbar. + // Perhaps setting QWindow to maximized should also mean that we'll show + // the statusbar, and vice versa for fullscreen? + + switch (state) { + case Qt::WindowMaximized: + case Qt::WindowFullScreen: + setGeometry(QRect(QPoint(0, 0), window()->screen()->availableSize())); + break; + default: + break; + } +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From e71ca36161626020f7c641dcc83c0c02dc4d561b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 11 Nov 2012 16:32:54 +0100 Subject: iOS: Ensure UIApplicationMain is started before QApplication by wrapping main() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the typical Qt app the developer will have an existing main() that looks something like: int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); return app.exec(); } To support this, we provide our own 'main' function in the qtmain static library that we link into the application, which calls UIApplicationMain and redirects to the 'main' function of the application after the event loop has started spinning. For this to work, the applications 'main' function needs to manually be renamed 'qt_main' for now. In a later patch, this renaming will happen automatically by redefining main from either a header file, or more likely, from the Makefile created by qmake. For the case of an iOS developer wanting to use Qt in their existing app the main will look something like: int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } This is supported right now by just linking in libqios.a without libqiosmain.a. QGuiApplication should then be created e.g inside the native apps application delegate (but QGuiApplication::exec should not be called). In the future, we plan to but use a wrapper library that brings in all the Qt dependencies into one single static library. This library will not link against qtmain, so there won't be a symbol clash if the -ObjC linker option is used. We should then add the required magic to the future Objective-C convenience wrapper for QML to bring up a QGuiApplication, which would allow using Qt from storyboards and NIBs. This would also be the place to inject our own application delegate into the mix, while proxying the delegate callbacks to the user's application delegate. Change-Id: Iba5ade114b27216be8285f36100fd735a08b9d59 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 30 +------ src/plugins/platforms/ios/main.mm | 69 --------------- src/plugins/platforms/ios/plugin.mm | 69 +++++++++++++++ src/plugins/platforms/ios/plugin.pro | 30 +++++++ .../platforms/ios/qiosapplicationdelegate.h | 3 + .../platforms/ios/qiosapplicationdelegate.mm | 31 ++----- src/plugins/platforms/ios/qioseventdispatcher.mm | 14 +--- src/plugins/platforms/ios/qiosintegration.mm | 12 +++ src/plugins/platforms/ios/qioswindow.mm | 9 +- src/plugins/platforms/ios/qtmain.mm | 98 ++++++++++++++++++++++ src/plugins/platforms/ios/qtmain.pro | 8 ++ 11 files changed, 234 insertions(+), 139 deletions(-) delete mode 100644 src/plugins/platforms/ios/main.mm create mode 100644 src/plugins/platforms/ios/plugin.mm create mode 100644 src/plugins/platforms/ios/plugin.pro create mode 100644 src/plugins/platforms/ios/qtmain.mm create mode 100644 src/plugins/platforms/ios/qtmain.pro (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 2fe6a4cb3f..842ff17f1c 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,29 +1,3 @@ -TARGET = qios +TEMPLATE = subdirs -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/platforms - -QT += core-private gui-private platformsupport-private -LIBS += -framework UIKit -framework QuartzCore - -OBJECTIVE_SOURCES = main.mm \ - qiosintegration.mm \ - qioswindow.mm \ - qiosscreen.mm \ - qioseventdispatcher.mm \ - qiosbackingstore.mm \ - qiosapplicationdelegate.mm \ - qioscontext.mm - -HEADERS = qiosintegration.h \ - qioswindow.h \ - qiosscreen.h \ - qioseventdispatcher.h \ - qiosbackingstore.h \ - qiosapplicationdelegate.h \ - qioscontext.h - -#HEADERS = qiossoftwareinputhandler.h - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target +SUBDIRS += plugin.pro qtmain.pro diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm deleted file mode 100644 index 6a04770e3e..0000000000 --- a/src/plugins/platforms/ios/main.mm +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** 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 -#include "qiosintegration.h" - -QT_BEGIN_NAMESPACE - -class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") - public: - QPlatformIntegration *create(const QString&, const QStringList&); -}; - -QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) -{ - Q_UNUSED(paramList); - if (system.toLower() == "ios") - return new QIOSIntegration; - - return 0; -} - -QT_END_NAMESPACE - -#include "main.moc" - -Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm new file mode 100644 index 0000000000..3701ac7e28 --- /dev/null +++ b/src/plugins/platforms/ios/plugin.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** 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 +#include "qiosintegration.h" + +QT_BEGIN_NAMESPACE + +class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") + public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "ios") + return new QIOSIntegration; + + return 0; +} + +QT_END_NAMESPACE + +#include "plugin.moc" + +Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro new file mode 100644 index 0000000000..8a2f63442d --- /dev/null +++ b/src/plugins/platforms/ios/plugin.pro @@ -0,0 +1,30 @@ +TARGET = qios + +load(qt_plugin) + +QT += core-private gui-private platformsupport-private +LIBS += -framework UIKit -framework QuartzCore + +OBJECTIVE_SOURCES = \ + plugin.mm \ + qiosintegration.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qioseventdispatcher.mm \ + qiosbackingstore.mm \ + qiosapplicationdelegate.mm \ + qioscontext.mm + +HEADERS = \ + qiosintegration.h \ + qioswindow.h \ + qiosscreen.h \ + qioseventdispatcher.h \ + qiosbackingstore.h \ + qiosapplicationdelegate.h \ + qioscontext.h + +#HEADERS = qiossoftwareinputhandler.h + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h index 10e415831d..442b37f1b3 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.h +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -48,3 +48,6 @@ @end +@interface QIOSMainWrapperApplicationDelegate : QIOSApplicationDelegate +@end + diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 1b3dc18dd7..41a3fff84f 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -45,34 +45,13 @@ @implementation QIOSApplicationDelegate +@synthesize window; + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(application) Q_UNUSED(launchOptions) - // If this application delegate is instanciated, it means that - // this plugin also created UIApplication. We then also create a - // window with a view controller, and set all QWindow views - // as children of the controller view: - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIViewController *controller = [[UIViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; - - QWindowList windows = QGuiApplication::topLevelWindows(); - for (int i=0; i(windows[i]->handle())) { - UIView *winView = w->nativeView(); - if (winView && !winView.superview) - [controller.view addSubview:winView]; - } - } - - // Aid debugging during development - self.window.backgroundColor = [UIColor cyanColor]; - controller.view.backgroundColor = [UIColor magentaColor]; - - [self.window makeKeyAndVisible]; return YES; } @@ -104,6 +83,12 @@ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } +- (void)dealloc +{ + [window release]; + [super dealloc]; +} + @end diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 252e375a54..9d455370c0 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -191,23 +191,13 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) m_interrupted = false; bool eventsProcessed = false; - UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); bool useExecMode = execFlagSet && !excludeUserEvents; if (useExecMode) { - if (!uiApplication) { - // No UIApplication has been started yet. We therefore start it now. Note that application - // developers are free to call UIApplicationMain themselves instead of QApplication::exec() - @autoreleasepool { - QCoreApplicationPrivate *qAppPriv = static_cast(QObjectPrivate::get(qApp)); - return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); - } - } else { - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); - } + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); eventsProcessed = true; } else { if (!(flags & QEventLoop::WaitForMoreEvents)) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d00d4a077f..fed278bffe 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -56,6 +56,18 @@ QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { + if (![UIApplication sharedApplication]) { + qWarning() + << "Error: You are creating QApplication before calling UIApplicationMain.\n" + << "If you are writing a native iOS application, and only want to use Qt for\n" + << "parts of the application, a good place to create QApplication is from within\n" + << "'applicationDidFinishLaunching' inside your UIApplication delegate.\n" + << "If you instead create a cross-platform Qt application and do not intend to call\n" + << "UIApplicationMain, you need to link in libqtmain.a, and substitute main with qt_main.\n" + << "This is normally done automatically by qmake.\n"; + exit(-1); + } + screenAdded(m_screen); } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cccd5ab133..5701ac8aa2 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -198,13 +198,8 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) { - UIApplication *uiApplication = [UIApplication sharedApplication]; - if (uiApplication) { - if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) - [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; - } - - setWindowState(window->windowState()); + if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) + [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; } QIOSWindow::~QIOSWindow() diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm new file mode 100644 index 0000000000..9b4ce9918e --- /dev/null +++ b/src/plugins/platforms/ios/qtmain.mm @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosapplicationdelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSMainWrapperApplicationDelegate class])); + } +} + +extern int qt_main(int argc, char *argv[]); + +@implementation QIOSMainWrapperApplicationDelegate + +- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + // We may have a window already from a NIB or storyboard + if (!self.window) { + // If not, we create one ourselves + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + UIViewController *controller = [[UIViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; + + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; + + [self.window makeKeyAndVisible]; + } + + // We schedule the main-redirection for the next eventloop pass so that we + // can return from this function and let UIApplicationMain finish its job. + [NSTimer scheduledTimerWithTimeInterval:.01f target:self + selector:@selector(runUserMain) userInfo:nil repeats:NO]; + + if ([QIOSApplicationDelegate instancesRespondToSelector:_cmd]) + return [super application:application willFinishLaunchingWithOptions:launchOptions]; + else + return YES; +} + +- (void)runUserMain +{ + NSArray *arguments = [[NSProcessInfo processInfo] arguments]; + int argc = arguments.count; + char **argv = new char*[argc]; + for (int i = 0; i < argc; ++i) { + NSString *arg = [arguments objectAtIndex:i]; + argv[i] = reinterpret_cast(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]])); + strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + + qt_main(argc, argv); + delete[] argv; +} + +@end diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro new file mode 100644 index 0000000000..7835c88eac --- /dev/null +++ b/src/plugins/platforms/ios/qtmain.pro @@ -0,0 +1,8 @@ +TARGET = qiosmain + +load(qt_plugin) + +OBJECTIVE_SOURCES = qtmain.mm + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target -- cgit v1.2.3 From f124e098ced89c3014d8bbc08a20db658d1cc7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Nov 2012 14:58:11 +0100 Subject: iOS: Set PLUGIN_TYPE = platforms before loading(qt_plugins) This takes care of setting INSTALLS for us, so we can skip that. Change-Id: I351cb9ec08b632fd9867d85e2c5fa59d8e5acc9d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/plugin.pro | 4 +--- src/plugins/platforms/ios/qtmain.pro | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 8a2f63442d..222d8c8445 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -1,5 +1,6 @@ TARGET = qios +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private @@ -25,6 +26,3 @@ HEADERS = \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 7835c88eac..49ada385bb 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -1,8 +1,6 @@ TARGET = qiosmain +PLUGIN_TYPE = platforms load(qt_plugin) OBJECTIVE_SOURCES = qtmain.mm - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target -- cgit v1.2.3 From 9d2e623451d4a4d695bc41e750a3218608c2546c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 12 Nov 2012 15:20:06 +0100 Subject: iOS: insert Digia license headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove Nokia. Change-Id: Iec7095ef4e3099453b6103814e826039b377ecce Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.mm | 48 ++++++++++----------- src/plugins/platforms/ios/qiosintegration.h | 48 ++++++++++----------- src/plugins/platforms/ios/qiosintegration.mm | 48 ++++++++++----------- src/plugins/platforms/ios/qiosscreen.h | 48 ++++++++++----------- src/plugins/platforms/ios/qiosscreen.mm | 48 ++++++++++----------- .../platforms/ios/qiossoftwareinputhandler.h | 50 +++++++++++----------- 6 files changed, 144 insertions(+), 146 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm index 3701ac7e28..a93b6037ad 100644 --- a/src/plugins/platforms/ios/plugin.mm +++ b/src/plugins/platforms/ios/plugin.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 11c17aced9..d5f79857f7 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index fed278bffe..a417021cbd 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 8d67b1ecdf..f17f1c1d70 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index effd19070a..efeacb8cb6 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h index 99e8fac61b..5dad6b8d86 100644 --- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -1,40 +1,38 @@ - - /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** 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. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** 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. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ -- cgit v1.2.3 From b3eccb0c15a3d4c9bee236c82c9a155c8752b66c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 13 Nov 2012 17:15:19 +0100 Subject: iOS: add QIOSOrientationListener MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QIOSScreen will use this to listen for orientation changes from UIDevice. Change-Id: I5a30f3808f8b9b885303608ce2fc1316c962898b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 + .../platforms/ios/qiosorientationlistener.h | 65 +++++++++++++ .../platforms/ios/qiosorientationlistener.mm | 108 +++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 src/plugins/platforms/ios/qiosorientationlistener.h create mode 100644 src/plugins/platforms/ios/qiosorientationlistener.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 222d8c8445..ab49115ed3 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -14,6 +14,7 @@ OBJECTIVE_SOURCES = \ qioseventdispatcher.mm \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ + qiosorientationlistener.mm \ qioscontext.mm HEADERS = \ @@ -23,6 +24,7 @@ HEADERS = \ qioseventdispatcher.h \ qiosbackingstore.h \ qiosapplicationdelegate.h \ + qiosorientationlistener.h \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h new file mode 100644 index 0000000000..c7b481a03a --- /dev/null +++ b/src/plugins/platforms/ios/qiosorientationlistener.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSORIENTATIONLISTENER_H +#define QIOSORIENTATIONLISTENER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSScreen; +Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); + +QT_END_NAMESPACE + +@interface QIOSOrientationListener : NSObject { + @public + QIOSScreen *m_screen; + Qt::ScreenOrientation m_orientation; +} +- (id) initWithQIOSScreen:(QIOSScreen *)screen; + +@end + +#endif + diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm new file mode 100644 index 0000000000..626e43129b --- /dev/null +++ b/src/plugins/platforms/ios/qiosorientationlistener.mm @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosorientationlistener.h" +#include "qiosscreen.h" +#include + +QT_BEGIN_NAMESPACE + +Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +QT_END_NAMESPACE + +@implementation QIOSOrientationListener + +- (id) initWithQIOSScreen:(QIOSScreen *)screen +{ + self = [super init]; + if (self) { + m_screen = screen; + m_orientation = convertToQtOrientation([UIDevice currentDevice].orientation); + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [super dealloc]; +} + +- (void) orientationChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + Qt::ScreenOrientation qtOrientation = convertToQtOrientation([UIDevice currentDevice].orientation); + if (qtOrientation != -1) { + m_orientation = qtOrientation; + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); + } +} + +@end + -- cgit v1.2.3 From 92252bcb93b2e8ba8cefeadf8cc0330c8ff1c47b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 13:06:22 +0100 Subject: iOS: let QIOSScreen start/stop listening for device orientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the qpa docs, we only need to listen for device orientation if orientationUpdateMask is non-zero Change-Id: Id5e828cdff9a08794c8a029e11763cc037e1b959 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.h | 7 +++++++ src/plugins/platforms/ios/qiosscreen.mm | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index f17f1c1d70..ed21e54f4a 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -45,6 +45,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -52,6 +53,7 @@ class QIOSScreen : public QPlatformScreen { public: QIOSScreen(unsigned int screenIndex); + ~QIOSScreen(); enum ScreenIndex { MainScreen = 0 }; @@ -61,6 +63,10 @@ public: QImage::Format format() const; QSizeF physicalSize() const; + Qt::ScreenOrientation nativeOrientation() const; + Qt::ScreenOrientation orientation() const; + void setOrientationUpdateMask(Qt::ScreenOrientations mask); + UIScreen *uiScreen() const; private: @@ -68,6 +74,7 @@ private: QRect m_geometry; int m_depth; QSizeF m_physicalSize; + QIOSOrientationListener *m_orientationListener; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index efeacb8cb6..00deaa2fc0 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -41,6 +41,7 @@ #include "qiosscreen.h" #include "qioswindow.h" +#include #include @@ -68,6 +69,7 @@ static QString deviceModelIdentifier() QIOSScreen::QIOSScreen(unsigned int screenIndex) : QPlatformScreen() , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) + , m_orientationListener(0) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -97,6 +99,11 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) [pool release]; } +QIOSScreen::~QIOSScreen() +{ + [m_orientationListener release]; +} + QRect QIOSScreen::geometry() const { return m_geometry; @@ -123,6 +130,26 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } +Qt::ScreenOrientation QIOSScreen::nativeOrientation() const +{ + return Qt::PortraitOrientation; +} + +Qt::ScreenOrientation QIOSScreen::orientation() const +{ + return m_orientationListener ? m_orientationListener->m_orientation : nativeOrientation(); +} + +void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) +{ + if (m_orientationListener && mask == Qt::PrimaryOrientation) { + [m_orientationListener release]; + m_orientationListener = 0; + } else if (!m_orientationListener) { + m_orientationListener = [[QIOSOrientationListener alloc] initWithQIOSScreen:this]; + } +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; -- cgit v1.2.3 From 72f66a8ee57ad3865d25e0157179d042a474cfff Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 14:02:04 +0100 Subject: iOS: add function convertToUIOrientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6145121d49eb3f5bab3f2a1ba57c779ec0b01023 Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosorientationlistener.h | 1 + .../platforms/ios/qiosorientationlistener.mm | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h index c7b481a03a..9d2e902ce1 100644 --- a/src/plugins/platforms/ios/qiosorientationlistener.h +++ b/src/plugins/platforms/ios/qiosorientationlistener.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class QIOSScreen; Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm index 626e43129b..264b77f14f 100644 --- a/src/plugins/platforms/ios/qiosorientationlistener.mm +++ b/src/plugins/platforms/ios/qiosorientationlistener.mm @@ -69,6 +69,28 @@ Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrienta return qtOrientation; } +UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + QT_END_NAMESPACE @implementation QIOSOrientationListener -- cgit v1.2.3 From fa731cddd16aed426f7c73bf4807475f0b087d4c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 16 Nov 2012 09:24:41 +0100 Subject: iOS: add QIOSViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need our own viewcontroller to better control which orientations iOS can enter, and also ito be able to stop auto-rotation. We stop auto-rotation to happend by default, since this is how Qt wants it (it is seen as the responsibility of the application). Change-Id: Id07a96e355396752fffd28984af528aeb0b7c3e3 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 + src/plugins/platforms/ios/qiosviewcontroller.h | 46 +++++++++++++++++++ src/plugins/platforms/ios/qiosviewcontroller.mm | 60 +++++++++++++++++++++++++ src/plugins/platforms/ios/qtmain.mm | 3 +- src/plugins/platforms/ios/qtmain.pro | 5 ++- 5 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosviewcontroller.h create mode 100644 src/plugins/platforms/ios/qiosviewcontroller.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index ab49115ed3..12c5c6db01 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -15,6 +15,7 @@ OBJECTIVE_SOURCES = \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ qiosorientationlistener.mm \ + qiosviewcontroller.mm \ qioscontext.mm HEADERS = \ @@ -25,6 +26,7 @@ HEADERS = \ qiosbackingstore.h \ qiosapplicationdelegate.h \ qiosorientationlistener.h \ + qiosviewcontroller.h \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h new file mode 100644 index 0000000000..d5a61cb3f4 --- /dev/null +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import + +@interface QIOSViewController : UIViewController +@end + diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm new file mode 100644 index 0000000000..5381b3a21e --- /dev/null +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import "qiosviewcontroller.h" + +@implementation QIOSViewController + +- (BOOL)shouldAutorotate +{ + return NO; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + // We need to tell iOS that we support all orientations in order to set + // status bar orientation when application content orientation changes. + // But we return 'NO' above when asked if we 'shouldAutorotate': + return UIInterfaceOrientationMaskAll; +} + +@end + diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 9b4ce9918e..61756edc93 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" int main(int argc, char *argv[]) { @@ -58,7 +59,7 @@ extern int qt_main(int argc, char *argv[]); if (!self.window) { // If not, we create one ourselves self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIViewController *controller = [[UIViewController alloc] init]; + QIOSViewController *controller = [[QIOSViewController alloc] init]; self.window.rootViewController = controller; controller.view = [[UIView alloc] init]; diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 49ada385bb..7c4c4ab398 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -3,4 +3,7 @@ TARGET = qiosmain PLUGIN_TYPE = platforms load(qt_plugin) -OBJECTIVE_SOURCES = qtmain.mm +OBJECTIVE_SOURCES = qtmain.mm \ + qiosviewcontroller.mm + +HEADERS = qiosviewcontroller.h -- cgit v1.2.3 From 575d28a6fd62c83c82de5dfc0c34013948c0c9bd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 13:28:59 +0100 Subject: iOS: handle content orientation feedback from application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2bfb4ee4840086dcd3ec85c2ee7e8769e76d2700 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4e1970d4d4..b20c1c4fc5 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,7 @@ public: void updateGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); + void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5701ac8aa2..e220312d15 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -43,6 +43,7 @@ #include "qioscontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" +#include "qiosorientationlistener.h" #import @@ -248,6 +249,14 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) +{ + // Keep the status bar in sync with content orientation. This will ensure + // that the task bar (and associated gestures) are aligned correctly: + UIDeviceOrientation uiOrientation = convertToUIOrientation(orientation); + [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 55f0bce0945a2f2b28e2454fbc03b1efd61819e4 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 16 Nov 2012 11:14:34 +0100 Subject: iOS: implement requestWindowOrientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The application is normally supposed to rotate the content on its own, but can call requestWindowOrientation to ask the window manager to do it instead. This way of integrating orientation with the OS is fragile, because: 1. In some cases, you cannot stop the OS from rotating at all (tablets). 2. It would be more safe to inform the window manager up-front which orientations it could rotate into, rather that relying on a function you call call to force this later on. 3. When the QML application starts, its a bit late to inform the platform plugin that it supports e.g landscape. If the OS is in landscape already, the plugin must still assume that the app operates in portrait (doing rotating on its own) until requestWindowOrientation is called. This might cause the app to first start up in portrait, just to rotate into landscape. On iOS, it seems like we can handle the first two cases. The third need some more investigation. We should anyway investigate if we need some adjustment to the Qt API. Change-Id: I50638b78d469ab70820a787de86a2f1981470786 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.h | 8 +++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 26 ++++++++++++++++++++++--- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 17 ++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index d5a61cb3f4..780ec7adab 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,7 +40,13 @@ ****************************************************************************/ #import +#import -@interface QIOSViewController : UIViewController +@interface QIOSViewController : UIViewController { +@public + bool m_shouldAutorotate; +} + +-(bool)rotateToDeviceOrientation; @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 5381b3a21e..8b1a085cc5 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,12 +43,32 @@ @implementation QIOSViewController -- (BOOL)shouldAutorotate +-(id)init { - return NO; + self = [super init]; + if (self) { + m_shouldAutorotate = NO; + } + return self; } -- (NSUInteger)supportedInterfaceOrientations +-(bool)rotateToDeviceOrientation +{ + if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) { + m_shouldAutorotate = YES; + [UIViewController attemptRotationToDeviceOrientation]; + m_shouldAutorotate = NO; + return true; + } + return false; +} + +-(BOOL)shouldAutorotate +{ + return m_shouldAutorotate; +} + +-(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b20c1c4fc5..e4c3a6a17c 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,6 +87,7 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); + Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e220312d15..c1f14f22ef 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -44,6 +44,7 @@ #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosorientationlistener.h" +#include "qiosviewcontroller.h" #import @@ -257,6 +258,22 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } +Qt::ScreenOrientation QIOSWindow::requestWindowOrientation(Qt::ScreenOrientation orientation) +{ + if (!m_view.window) + return Qt::PortraitOrientation; + UIViewController *viewController = m_view.window.rootViewController; + if (!viewController || [viewController isKindOfClass:[QIOSViewController class]] == false) { + return convertToQtOrientation(viewController.interfaceOrientation); + } else { + QIOSViewController *qiosViewController = static_cast(viewController); + if ([qiosViewController rotateToDeviceOrientation]) + return orientation; + else + return convertToQtOrientation(viewController.interfaceOrientation); + } +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 7f7d75201271bc1b87a8607a78c04aeab1ad3513 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 19 Nov 2012 13:58:11 +0100 Subject: iOS: use 'self' rather than 'super' pointer in initWithQIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we use super, our own initWithFrame override will never be called. Change-Id: I606beb653239cdfc46f41db4ec0791dfa5d4edea Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c1f14f22ef..4e10c19ecc 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -72,7 +72,7 @@ static QRect fromCGRect(const CGRect &rect) -(id)initWithQIOSWindow:(QIOSWindow *)window { - if (self = [super initWithFrame:toCGRect(window->geometry())]) + if (self = [self initWithFrame:toCGRect(window->geometry())]) m_qioswindow = window; return self; -- cgit v1.2.3 From ad4cf5068cd39b9ca16bdd9705d0a3ef61783d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 16 Nov 2012 07:36:49 +0100 Subject: iOS: Don't recreate paint device on beginPaint() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This causes painting errors. Use one lazily-created device that is used for the lifetime of the backing store. Change-Id: Ib36b6f1d6c9f958304dc8403cf17e5d71136469a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 71f14fdd91..6cefc03377 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -60,6 +60,7 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window) QIOSBackingStore::~QIOSBackingStore() { delete m_context; + delete m_device; } void QIOSBackingStore::beginPaint(const QRegion &) @@ -68,7 +69,8 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); - m_device = new QOpenGLPaintDevice(window()->size()); + if (!m_device) + m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() @@ -86,8 +88,6 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin void QIOSBackingStore::endPaint() { - delete m_device; - // Calling makeDone() on the context here would be an option, // but is not needed, and would actually add some overhead. } -- cgit v1.2.3 From 5d878cae1d090b9c7d5730a85667e569e67c17d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 14:13:40 +0100 Subject: iOS: Remove requestWindowOrientation from QIOSWindow The API is scheduled to be removed in qtbase in time for Qt 5.0. Change-Id: Ie34d6cb79fcd81b0ce02892529e3e7184ddfa096 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.h | 7 +------ src/plugins/platforms/ios/qiosviewcontroller.mm | 22 +--------------------- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 16 ---------------- 4 files changed, 2 insertions(+), 44 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 780ec7adab..605f0f5b4c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -42,11 +42,6 @@ #import #import -@interface QIOSViewController : UIViewController { -@public - bool m_shouldAutorotate; -} - --(bool)rotateToDeviceOrientation; +@interface QIOSViewController : UIViewController @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 8b1a085cc5..a807dc2132 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,29 +43,9 @@ @implementation QIOSViewController --(id)init -{ - self = [super init]; - if (self) { - m_shouldAutorotate = NO; - } - return self; -} - --(bool)rotateToDeviceOrientation -{ - if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) { - m_shouldAutorotate = YES; - [UIViewController attemptRotationToDeviceOrientation]; - m_shouldAutorotate = NO; - return true; - } - return false; -} - -(BOOL)shouldAutorotate { - return m_shouldAutorotate; + return NO; } -(NSUInteger)supportedInterfaceOrientations diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index e4c3a6a17c..b20c1c4fc5 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,7 +87,6 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); - Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4e10c19ecc..0b2b5fcfd7 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -258,22 +258,6 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -Qt::ScreenOrientation QIOSWindow::requestWindowOrientation(Qt::ScreenOrientation orientation) -{ - if (!m_view.window) - return Qt::PortraitOrientation; - UIViewController *viewController = m_view.window.rootViewController; - if (!viewController || [viewController isKindOfClass:[QIOSViewController class]] == false) { - return convertToQtOrientation(viewController.interfaceOrientation); - } else { - QIOSViewController *qiosViewController = static_cast(viewController); - if ([qiosViewController rotateToDeviceOrientation]) - return orientation; - else - return convertToQtOrientation(viewController.interfaceOrientation); - } -} - GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 599c7a5ab91f44cb9ed5f12f65d58ff9d543c930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 15:50:20 +0100 Subject: iOS: Set initial window state on window creation When showing a QWindow the window state is set first, and then the window is made visible. The latter is the step that creates the platform window, so we need to pick up the already set window state in our constructor and respect that. Change-Id: I54fe6c4ebcd3c9504614d2d48bd21f0d76adf3b7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 0b2b5fcfd7..daeb86fb62 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -202,6 +202,8 @@ QIOSWindow::QIOSWindow(QWindow *window) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; + + setWindowState(window->windowState()); } QIOSWindow::~QIOSWindow() -- cgit v1.2.3 From 189503933a9e59da22d6415e588a44c87d67c2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 16:42:56 +0100 Subject: iOS: Enable the ShowIsFullScreen style-hint so that show() implies fullscreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may need to qualify this setting for UC2, so that the user may still create windows as sub-controls of a regular iOS user interface, but for UC1 it makes sense. Change-Id: I1a7019f901fabed8b5b9cbb18a929913780e6595 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ src/plugins/platforms/ios/qiosintegration.mm | 10 ++++++++++ 2 files changed, 12 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d5f79857f7..363d267716 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -60,6 +60,8 @@ public: QPlatformFontDatabase *fontDatabase() const; + QVariant styleHint(StyleHint hint) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index a417021cbd..b37e803455 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -106,6 +106,16 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QVariant QIOSIntegration::styleHint(StyleHint hint) const +{ + switch (hint) { + case ShowIsFullScreen: + return true; + default: + return QPlatformIntegration::styleHint(hint); + } +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast(this); -- cgit v1.2.3 From 3a59fc4c97a3658b9712fa214778008bbf914cf9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 13:34:51 +0100 Subject: iOS: when in fullscreen, dont respond to geometry changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QWindow is told to be in fullscreen, we should not respond to geometry changes. Instead we should bookkeep the requested geometry and set it when/if the window enters Qt::WindowNoState later. Change-Id: Ieaf4756b2a966212c8e1738af9df175a58786a75 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 34 ++++++++++++++------------------- 2 files changed, 14 insertions(+), 21 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b20c1c4fc5..df632e672e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,7 +83,6 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); - void updateGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index daeb86fb62..c91c0b2f35 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -109,13 +109,11 @@ static QRect fromCGRect(const CGRect &rect) // the position of our QWindow (and platform window) will only get updated // when the size is also changed. - if (CGAffineTransformIsIdentity(self.transform)) { - // Reflect the new size (and possibly also position) in the QWindow - m_qioswindow->updateGeometry(fromCGRect(self.frame)); - } else { - qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; - } + if (!CGAffineTransformIsIdentity(self.transform)) + qWarning() << m_qioswindow->window() + << "is backed by a UIView that has a transform set. This is not supported."; + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), fromCGRect(self.frame)); [super layoutSubviews]; } @@ -218,22 +216,17 @@ void QIOSWindow::setGeometry(const QRect &rect) return; } + // If the window is in fullscreen, just bookkeep the requested + // geometry in case the window goes into Qt::WindowNoState later: + QPlatformWindow::setGeometry(rect); + if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) + return; + // Since we don't support transformations on the UIView, we can set the frame // directly and let UIKit deal with translating that into bounds and center. + // Changing the size of the view will end up in a call to -[EAGLView layoutSubviews] + // which will update QWindowSystemInterface with the new size. m_view.frame = toCGRect(rect); - - updateGeometry(rect); -} - -void QIOSWindow::updateGeometry(const QRect &rect) -{ - // The baseclass implementation will store the geometry, and allows use to - // re-use the baseclass geometry() implementation, which just returns rect. - QPlatformWindow::setGeometry(rect); - - // We inform Qt about new geometry, which will trigger resize and - // expose events for the application. - QWindowSystemInterface::handleGeometryChange(window(), rect); } void QIOSWindow::setWindowState(Qt::WindowState state) @@ -245,9 +238,10 @@ void QIOSWindow::setWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMaximized: case Qt::WindowFullScreen: - setGeometry(QRect(QPoint(0, 0), window()->screen()->availableSize())); + m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); break; default: + m_view.frame = toCGRect(geometry()); break; } } -- cgit v1.2.3 From 2d4e96352a0f52351e0fa69273b064a66d460c04 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 15:15:21 +0100 Subject: iOS: one 'transform' warning per window is sufficient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The layoutSubviews function will be called when the geometry changes, and we will catch the transform issue there for both UC1 and UC2 Change-Id: I29578bbc5b3091c86fbe69c7095ff280a64be458 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c91c0b2f35..7f03e0d46a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -211,11 +211,6 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { - if (!CGAffineTransformIsIdentity(m_view.transform)) { - qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; - return; - } - // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: QPlatformWindow::setGeometry(rect); -- cgit v1.2.3 From 0d9a50380c2d3ecc33f632f9f0e158c3a8cd2099 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 15:28:13 +0100 Subject: iOS: when in fullscreen, autoresize the view when the device rotates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tell the view that backs QWindow to autoresize itself when the superview (view of the root view controller) changes size. This will typically happen when the device changes orientation. Change-Id: Ib7c4dff9112d57f60012d3f0837677e09088bcaf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7f03e0d46a..2b97695a10 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -234,9 +234,11 @@ void QIOSWindow::setWindowState(Qt::WindowState state) case Qt::WindowMaximized: case Qt::WindowFullScreen: m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); + m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; default: m_view.frame = toCGRect(geometry()); + m_view.autoresizingMask = UIViewAutoresizingNone; break; } } -- cgit v1.2.3 From b1cfa62ff45cc4b5c035fc5dbe49461e9fe6052a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 16:22:48 +0100 Subject: iOS: let fullscreen geometry take orientation into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since UIScreen is orientation agnostic, we need to look at the view of the top level view controller instead to determine available geometry. Change-Id: I3789ab7972a9970e46fbc8af81f2b7199e5ca5d1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2b97695a10..266000d2de 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -232,10 +232,13 @@ void QIOSWindow::setWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMaximized: - case Qt::WindowFullScreen: - m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); + case Qt::WindowFullScreen: { + // Since UIScreen does not take orientation into account when + // reporting geometry, we need to look at the top view instead: + CGSize fullscreenSize = m_view.window.rootViewController.view.bounds.size; + m_view.frame = CGRectMake(0, 0, fullscreenSize.width, fullscreenSize.height); m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - break; + break; } default: m_view.frame = toCGRect(geometry()); m_view.autoresizingMask = UIViewAutoresizingNone; -- cgit v1.2.3 From a1c9f565521f971adbb1e6aad6b82d194f1a1905 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 10 Dec 2012 10:18:59 +0100 Subject: iOS: update QPlatformWindow::geometry() when UIView changes size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that QWindow::geometry needs to be updated manually by the platform plugin, and not indirectly trough QWindowSystemInterface::handleGeometryChange as first assumed. We now always report the _actual_ geometry of the UIView (which also takes the status bar into account) to QWindow, and remember the _requested_ geometry of the window to use whenever the state of the window changes. Change-Id: Iea940173d26fb6af701234379cae914215dae984 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index df632e672e..2a762d2bdc 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -93,6 +93,7 @@ public: private: EAGLView *m_view; + QRect m_requestedGeometry; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 266000d2de..b209bbc159 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -113,7 +113,9 @@ static QRect fromCGRect(const CGRect &rect) qWarning() << m_qioswindow->window() << "is backed by a UIView that has a transform set. This is not supported."; - QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), fromCGRect(self.frame)); + QRect geometry = fromCGRect(self.frame); + m_qioswindow->QPlatformWindow::setGeometry(geometry); + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); [super layoutSubviews]; } @@ -197,6 +199,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_requestedGeometry(QPlatformWindow::geometry()) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -213,7 +216,7 @@ void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: - QPlatformWindow::setGeometry(rect); + m_requestedGeometry = rect; if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) return; @@ -240,7 +243,7 @@ void QIOSWindow::setWindowState(Qt::WindowState state) m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; } default: - m_view.frame = toCGRect(geometry()); + m_view.frame = toCGRect(m_requestedGeometry); m_view.autoresizingMask = UIViewAutoresizingNone; break; } -- cgit v1.2.3 From 8dde67fcd33fc35fe95262bd7acb6f7b5143fead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 16:40:40 +0100 Subject: iOS: Create QIOSBackingStore paint device lazily in paintDevice() Instead of constructor. Change-Id: I98cddd3f39add3e6f787c858b4d629325cc0f852 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 6cefc03377..dfa41f0003 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -69,12 +69,13 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); - if (!m_device) - m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { + if (!m_device) + m_device = new QOpenGLPaintDevice(window()->size()); + return m_device; } -- cgit v1.2.3 From d059866eb43a7415dd786a2bcba14f729d938675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 17:11:15 +0100 Subject: iOS: Keep QIOSBackingStore's paint device size in sync with the window Treating the paint-device as a thing wrapper around the OpenGL paint engine failed when the window was resized, as the paint engine would clip the drawing to the old size. We need to update the size in beginPaint. QBackingStore resize still behaves like before, and we emit a warning if the user tries to resize the backing-store to some other size than the window size, as that's not a supported use-case for our iOS backing store. Change-Id: I1a0eeb65fa9db8b5538dc69963d6fc84be6e63f1 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.mm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index dfa41f0003..6bae08ce2b 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -69,12 +69,14 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); + + static_cast(paintDevice())->setSize(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { if (!m_device) - m_device = new QOpenGLPaintDevice(window()->size()); + m_device = new QOpenGLPaintDevice; return m_device; } @@ -95,12 +97,16 @@ void QIOSBackingStore::endPaint() void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) { - Q_UNUSED(size); Q_UNUSED(staticContents); - // We don't need to resize the QOpenGLPaintDevice, as it's just a thin wrapper - // around the OpenGL paint-engine, and the real geometry is handled by the - // context and window. + // Resizing the backing store would in our case mean resizing the QWindow, + // as we cheat and use an QOpenGLPaintDevice that we target at the window. + // That's probably not what the user intended, so we ignore resizes of the + // backing store and always keep the paint device's size in sync with the + // window size in beginPaint(). + + if (size != window()->size()) + qWarning() << "QIOSBackingStore needs to have the same size as its window"; } QT_END_NAMESPACE -- cgit v1.2.3 From 21965187096f8bde7866b05459444793e1a6c1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 17:49:53 +0100 Subject: iOS: Update GL render buffers when the accociated window is resized We keep track of the with and height of the FBO's buffers, and update their storage if the window size has changed since last time. Change-Id: I97788b69e7067a5b5b9f28e8498cf1bc5d2cf6ea Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 2 + src/plugins/platforms/ios/qioscontext.mm | 16 +++---- src/plugins/platforms/ios/qioswindow.h | 9 ++++ src/plugins/platforms/ios/qioswindow.mm | 82 ++++++++++++++++++-------------- 4 files changed, 66 insertions(+), 43 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 102aaaa387..b45917832c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -62,6 +62,8 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; + GLuint defaultColorRenderbuffer(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); EAGLContext *nativeContext() const; diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 8beb588b03..68db28212b 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -88,7 +88,8 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - return true; + // Ensures render buffers are set up and match the size of the window + return defaultColorRenderbuffer(surface) != 0; } void QIOSContext::doneCurrent() @@ -101,13 +102,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); [EAGLContext setCurrentContext:m_eaglContext]; - - GLint renderbuffer; - glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - + glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } @@ -116,6 +111,11 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const return static_cast(surface)->framebufferObject(*const_cast(this)); } +GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +{ + return static_cast(surface)->colorRenderbuffer(*const_cast(this)); +} + QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) { return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2a762d2bdc..4c55249046 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -88,12 +88,21 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; + GLuint colorRenderbuffer(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } private: EAGLView *m_view; QRect m_requestedGeometry; + + mutable struct GLData { + GLuint framebufferObject; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + } m_glData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b209bbc159..90734e58e8 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -116,6 +116,10 @@ static QRect fromCGRect(const CGRect &rect) QRect geometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); + + // If we have a new size here we need to resize the FBO's corresponding buffers, + // but we defer that to when the application calls makeCurrent. + [super layoutSubviews]; } @@ -200,6 +204,7 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_glData() { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -209,6 +214,13 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { + if (m_glData.framebufferObject) + glDeleteFramebuffers(1, &m_glData.framebufferObject); + if (m_glData.colorRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); + if (m_glData.depthRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view release]; } @@ -259,56 +271,56 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - static GLuint framebuffer = 0; + if (!m_glData.framebufferObject) { + [EAGLContext setCurrentContext:context.nativeContext()]; - // FIXME: Cache context and recreate framebuffer if window - // is used with a different context then last time. + glGenFramebuffers(1, &m_glData.framebufferObject); + glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - if (!framebuffer) { - EAGLContext* eaglContext = context.nativeContext(); + glGenRenderbuffers(1, &m_glData.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [EAGLContext setCurrentContext:eaglContext]; + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &m_glData.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - // Create the framebuffer and bind it - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + if (requestedFormat.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); + } + } - GLint width; - GLint height; + return m_glData.framebufferObject; +} - // Create a color renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s color attachment point. - GLuint colorRenderbuffer; - glGenRenderbuffers(1, &colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); - [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); +GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +{ + if (!m_glData.colorRenderbuffer || + m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - // Create a depth or depth/stencil renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s depth attachment point. - GLuint depthRenderbuffer; - glGenRenderbuffers(1, &depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); + + if (m_glData.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (requestedFormat.stencilBufferSize() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + if (context.format().stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return framebuffer; + return m_glData.colorRenderbuffer; } QT_END_NAMESPACE -- cgit v1.2.3 From 31a76b978b3f1c08787e3f88987e3a396d5eec45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 19:27:30 +0100 Subject: iOS: Enable auto-rotation if no orientation update-mask has been set This is an intermediate heuristic until we have a proper API in Qt to deal with auto-rotation and orientation locking. Change-Id: I433992fa1c18d1670987f79e405a4501b6e5d365 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a807dc2132..3121597dba 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -41,18 +41,27 @@ #import "qiosviewcontroller.h" +#include +#include + @implementation QIOSViewController -(BOOL)shouldAutorotate { - return NO; + // For now we assume that if the application doesn't listen to orientation + // updates it means it would like to enable auto-rotation, and vice versa. + if (QGuiApplication *guiApp = qobject_cast(qApp)) + return !guiApp->primaryScreen()->orientationUpdateMask(); + else + return NO; + + // FIXME: Investigate a proper Qt API for auto-rotation and orientation locking } -(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. - // But we return 'NO' above when asked if we 'shouldAutorotate': return UIInterfaceOrientationMaskAll; } -- cgit v1.2.3 From 509697adc30f858ee3483c2b74e292c60b75ba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 20:00:27 +0100 Subject: iOS: Remove unnecessary const-trickery when passing QIOSContext to the window Change-Id: I56b3873342c1572ea6a651027e8f1a684cbe2a5a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 68db28212b..00629a84ab 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -108,12 +108,12 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { - return static_cast(surface)->framebufferObject(*const_cast(this)); + return static_cast(surface)->framebufferObject(*this); } GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const { - return static_cast(surface)->colorRenderbuffer(*const_cast(this)); + return static_cast(surface)->colorRenderbuffer(*this); } QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) -- cgit v1.2.3 From d07bd1b22f6da2fcf961618b59f10f59d0a95d16 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 12:07:05 +0100 Subject: iOS: remove the view from the view hierarchy upon destruction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to remove the view that backs QWindow when the window is destroyed. Otherwise the view will still be visible on screen, but now with a dangling QWindow pointer. This fixes a crash that happens when closing dialogs. Change-Id: I9053c83c6db80a39f4f71a63993cc7ae73fc4196 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 90734e58e8..871a046c71 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -221,6 +221,7 @@ QIOSWindow::~QIOSWindow() if (m_glData.depthRenderbuffer) glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view removeFromSuperview]; [m_view release]; } -- cgit v1.2.3 From 60294e0aa381419b897317e3eec208d98ca8b4aa Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 12:01:17 +0100 Subject: iOS: implement in QIOSWindow::setVisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QWindow is told to show/hide, we need to show/hide the backing UIView as well, otherwise the window will still be visible on screen. Change-Id: I806fdd8bb4afacbbc1c9c7381ba0a31195ee04ac Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4c55249046..3a05901ae7 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,7 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); + void setVisible(bool visible); GLuint framebufferObject(const QIOSContext &context) const; GLuint colorRenderbuffer(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 871a046c71..a2901efd1d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -225,6 +225,12 @@ QIOSWindow::~QIOSWindow() [m_view release]; } +void QIOSWindow::setVisible(bool visible) +{ + QPlatformWindow::setVisible(visible); + [m_view setHidden:!visible]; +} + void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested -- cgit v1.2.3 From c558c5c1b82256fc8c8e9e6f947eda6164ea59e8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 15:12:40 +0100 Subject: iOS: add class QIOSInputContext (to handle keyboard) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will add an initial implementation of the QPlatformInputContext for dealing with the keyboard. Change-Id: I29c1cfbbebb8456977b8a1db0e966973cd2c24a5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 6 +- src/plugins/platforms/ios/qiosinputcontext.h | 69 +++++++++++++ src/plugins/platforms/ios/qiosinputcontext.mm | 134 ++++++++++++++++++++++++++ src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 7 ++ 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosinputcontext.h create mode 100644 src/plugins/platforms/ios/qiosinputcontext.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 12c5c6db01..d4fe25ef08 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -16,7 +16,8 @@ OBJECTIVE_SOURCES = \ qiosapplicationdelegate.mm \ qiosorientationlistener.mm \ qiosviewcontroller.mm \ - qioscontext.mm + qioscontext.mm \ + qiosinputcontext.mm HEADERS = \ qiosintegration.h \ @@ -27,6 +28,7 @@ HEADERS = \ qiosapplicationdelegate.h \ qiosorientationlistener.h \ qiosviewcontroller.h \ - qioscontext.h + qioscontext.h \ + qiosinputcontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h new file mode 100644 index 0000000000..22782d183c --- /dev/null +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSINPUTCONTEXT_H +#define QIOSINPUTCONTEXT_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +@class QIOSKeyboardListener; + +class QIOSInputContext : public QPlatformInputContext +{ +public: + QIOSInputContext(); + ~QIOSInputContext(); + + void showInputPanel(); + void hideInputPanel(); + bool isInputPanelVisible() const; + +private: + QIOSKeyboardListener *m_keyboardListener; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm new file mode 100644 index 0000000000..7937337e4a --- /dev/null +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosinputcontext.h" +#include "qioswindow.h" +#include + +@interface QIOSKeyboardListener : NSObject { +@public + QIOSInputContext *m_context; + BOOL m_keyboardVisible; +} +@end + +@implementation QIOSKeyboardListener + +- (id)initWithQIOSInputContext:(QIOSInputContext *)context +{ + self = [super init]; + if (self) { + m_context = context; + m_keyboardVisible = NO; + // After the keyboard became undockable (iOS5), UIKeyboardWillShow/UIKeyboardWillHide + // no longer works for all cases. So listen to keyboard frame changes instead: + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardDidChangeFrame:) + name:@"UIKeyboardDidChangeFrameNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIKeyboardDidChangeFrameNotification" object:nil]; + [super dealloc]; +} + +- (void) keyboardDidChangeFrame:(NSNotification *)notification +{ + CGRect frame; + [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); + if (m_keyboardVisible != visible) { + m_keyboardVisible = visible; + m_context->emitInputPanelVisibleChanged(); + } +} + +@end + +QIOSInputContext::QIOSInputContext() + : QPlatformInputContext(), + m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) +{ +} + +QIOSInputContext::~QIOSInputContext() +{ + [m_keyboardListener release]; +} + +void QIOSInputContext::showInputPanel() +{ + if (isInputPanelVisible()) + return; + + // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder + // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first + // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt + // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible + // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of + // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. + if (QWindow *window = QGuiApplication::focusWindow()) { + QIOSWindow *qiosWindow = static_cast(window->handle()); + [qiosWindow->nativeView() becomeFirstResponder]; + } +} + +void QIOSInputContext::hideInputPanel() +{ + if (!isInputPanelVisible()) + return; + + if (QWindow *window = QGuiApplication::focusWindow()) { + QIOSWindow *qiosWindow = static_cast(window->handle()); + [qiosWindow->nativeView() resignFirstResponder]; + } +} + +bool QIOSInputContext::isInputPanelVisible() const +{ + return m_keyboardListener->m_keyboardVisible; +} diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 363d267716..9e6dadc5a1 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -59,6 +59,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QPlatformFontDatabase *fontDatabase() const; + QPlatformInputContext *inputContext() const; QVariant styleHint(StyleHint hint) const; @@ -69,6 +70,7 @@ public: private: QPlatformFontDatabase *m_fontDatabase; + QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b37e803455..9d603da150 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -45,6 +45,7 @@ #include "qiosscreen.h" #include "qioseventdispatcher.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include @@ -54,6 +55,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) + , m_inputContext(new QIOSInputContext) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { if (![UIApplication sharedApplication]) { @@ -106,6 +108,11 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformInputContext *QIOSIntegration::inputContext() const +{ + return m_inputContext; +} + QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { -- cgit v1.2.3 From 72c1ada86f8aed0109936542b66ab66981ec39ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 12 Dec 2012 15:23:21 +0100 Subject: iOS: Make fusion style the default style on iOS, not the windows style Change-Id: I81b6049ff666bf23ac58d60e10d7c3d8713a19ea Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/plugin.pro | 6 ++- src/plugins/platforms/ios/qiosintegration.h | 3 ++ src/plugins/platforms/ios/qiosintegration.mm | 14 ++++++ src/plugins/platforms/ios/qiostheme.h | 62 +++++++++++++++++++++++++ src/plugins/platforms/ios/qiostheme.mm | 69 ++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiostheme.h create mode 100644 src/plugins/platforms/ios/qiostheme.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index d4fe25ef08..1be24d920d 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -17,7 +17,8 @@ OBJECTIVE_SOURCES = \ qiosorientationlistener.mm \ qiosviewcontroller.mm \ qioscontext.mm \ - qiosinputcontext.mm + qiosinputcontext.mm \ + qiostheme.mm HEADERS = \ qiosintegration.h \ @@ -29,6 +30,7 @@ HEADERS = \ qiosorientationlistener.h \ qiosviewcontroller.h \ qioscontext.h \ - qiosinputcontext.h + qiosinputcontext.h \ + qiostheme.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 9e6dadc5a1..5ba97bff6e 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -63,6 +63,9 @@ public: QVariant styleHint(StyleHint hint) const; + QStringList themeNames() const; + QPlatformTheme *createPlatformTheme(const QString &name) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 9d603da150..8008c5c0b0 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -46,6 +46,7 @@ #include "qioseventdispatcher.h" #include "qioscontext.h" #include "qiosinputcontext.h" +#include "qiostheme.h" #include @@ -123,6 +124,19 @@ QVariant QIOSIntegration::styleHint(StyleHint hint) const } } +QStringList QIOSIntegration::themeNames() const +{ + return QStringList(QLatin1String(QIOSTheme::name)); +} + +QPlatformTheme *QIOSIntegration::createPlatformTheme(const QString &name) const +{ + if (name == QLatin1String(QIOSTheme::name)) + return new QIOSTheme; + + return QPlatformIntegration::createPlatformTheme(name); +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast(this); diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h new file mode 100644 index 0000000000..d21d8804fa --- /dev/null +++ b/src/plugins/platforms/ios/qiostheme.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSTHEME_H +#define QIOSTHEME_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSTheme : public QPlatformTheme +{ +public: + QIOSTheme(); + ~QIOSTheme(); + + QVariant themeHint(ThemeHint hint) const; + + static const char *name; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm new file mode 100644 index 0000000000..6e54b9cb3b --- /dev/null +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiostheme.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +const char *QIOSTheme::name = "ios"; + +QIOSTheme::QIOSTheme() +{ +} + +QIOSTheme::~QIOSTheme() +{ +} + +QVariant QIOSTheme::themeHint(ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::StyleNames: + return QStringList(QStringLiteral("fusion")); + default: + return QPlatformTheme::themeHint(hint); + } +} + +QT_END_NAMESPACE -- cgit v1.2.3 From 70b21ec3c12c655354676778e087182f20aadbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Dec 2012 15:20:30 +0100 Subject: iOS: Make default system font Helvetica Without a platform theme implementatin we were relying on QCoreTextFontDatabase::defaultFont() to return the system font. This didn't work because it reported the system font that iOS reports, '.Helvetica Neue UI', which is a private font that does not get added to our font database. The result was that we picked the first font in the list of known fonts -- in this case 'Academy Engraved LET'. We now implement QIOSTheme::font(), which takes precedence over the font database's default font, and hard-code the system font to 'Helvetica', since Qt does not yet have the concept of private system fonts. Change-Id: I901cf9c2b662ea2795212376b84b8391be2efbbe Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiostheme.h | 2 ++ src/plugins/platforms/ios/qiostheme.mm | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h index d21d8804fa..5ccbcac710 100644 --- a/src/plugins/platforms/ios/qiostheme.h +++ b/src/plugins/platforms/ios/qiostheme.h @@ -54,6 +54,8 @@ public: QVariant themeHint(ThemeHint hint) const; + const QFont *font(Font type = SystemFont) const; + static const char *name; }; diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm index 6e54b9cb3b..f98781f8a7 100644 --- a/src/plugins/platforms/ios/qiostheme.mm +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -44,6 +44,11 @@ #include #include +#include + +#include +#include + QT_BEGIN_NAMESPACE const char *QIOSTheme::name = "ios"; @@ -66,4 +71,26 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const } } +const QFont *QIOSTheme::font(Font type) const +{ + static QHash fonts; + if (fonts.isEmpty()) { + // The real system font on iOS is '.Helvetica Neue UI', as returned by both [UIFont systemFontOfSize] + // and CTFontCreateUIFontForLanguage(kCTFontSystemFontType, ...), but this font is not included when + // populating the available fonts in QCoreTextFontDatabase::populateFontDatabase(), since the font + // is internal to iOS and not supposed to be used by applications. We could potentially add this + // font to the font-database, but it would then show up when enumerating user fonts from Qt + // applications since we don't have a flag in Qt to mark a font as a private system font. + // For now we hard-code the font to Helvetica, which should be very close to the actual + // system font. + QLatin1String systemFontFamilyName("Helvetica"); + fonts.insert(QPlatformTheme::SystemFont, new QFont(systemFontFamilyName, [UIFont systemFontSize])); + fonts.insert(QPlatformTheme::SmallFont, new QFont(systemFontFamilyName, [UIFont smallSystemFontSize])); + fonts.insert(QPlatformTheme::LabelFont, new QFont(systemFontFamilyName, [UIFont labelFontSize])); + fonts.insert(QPlatformTheme::PushButtonFont, new QFont(systemFontFamilyName, [UIFont buttonFontSize])); + } + + return fonts.value(type, 0); +} + QT_END_NAMESPACE -- cgit v1.2.3 From d5d3f5ea8e6620e1ae06488a9e35a36550367726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Feb 2013 13:49:03 +0100 Subject: iOS: let QIOSScreen change geometry according to interface rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt expects the screen to change geometry when the "desktop" rotates. On iOS, we interpret this as when the root view controller changes orientation, since after all, this is the surface we place QWindows on top of. Change-Id: Ia00e68c8f9f0a65aefcc60518ee544fb260d4595 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 3 +++ src/plugins/platforms/ios/qiosscreen.mm | 32 +++++++++++++++++++++---- src/plugins/platforms/ios/qiosviewcontroller.h | 1 - src/plugins/platforms/ios/qiosviewcontroller.mm | 12 ++++++++++ src/plugins/platforms/ios/qtmain.pro | 2 ++ 5 files changed, 45 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index ed21e54f4a..e05a6cd6a1 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -69,9 +69,12 @@ public: UIScreen *uiScreen() const; + void setPrimaryOrientation(Qt::ScreenOrientation orientation); + private: UIScreen *m_uiScreen; QRect m_geometry; + QRect m_availableGeometry; int m_depth; QSizeF m_physicalSize; QIOSOrientationListener *m_orientationListener; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 00deaa2fc0..f4cade2e6d 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -88,11 +88,12 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) unscaledDpi = 132; }; - // UIScreen does not report different bounds for different orientations. We - // match this behavior by staying with a fixed QScreen geometry. CGRect bounds = [m_uiScreen bounds]; m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); + CGRect frame = m_uiScreen.applicationFrame; + m_availableGeometry = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; @@ -111,8 +112,7 @@ QRect QIOSScreen::geometry() const QRect QIOSScreen::availableGeometry() const { - CGRect frame = m_uiScreen.applicationFrame; - return QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + return m_availableGeometry; } int QIOSScreen::depth() const @@ -150,6 +150,30 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) } } +void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) +{ + // Note that UIScreen never changes orientation, but QScreen should. To work around + // this, we let QIOSViewController call us whenever interface orientation changes, and + // use that as primary orientation. After all, the viewcontrollers geometry is what we + // place QWindows on top of. A problem with this approach is that QIOSViewController is + // not in use in a mixed environment, which results in no change to primary orientation. + // We see that as acceptable since Qt should most likely not interfere with orientation + // for that case anyway. + bool portrait = screen()->isPortrait(orientation); + if (portrait && m_geometry.width() < m_geometry.height()) + return; + + // Switching portrait/landscape means swapping width/height (and adjusting x/y): + CGRect frame = m_uiScreen.applicationFrame; + m_availableGeometry = portrait ? QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) + : QRect(frame.origin.y, m_geometry.width() - frame.size.width - frame.origin.x, frame.size.height, frame.size.width); + m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); + m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); + + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 605f0f5b4c..d5a61cb3f4 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,7 +40,6 @@ ****************************************************************************/ #import -#import @interface QIOSViewController : UIViewController @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 3121597dba..fe9e02666f 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,6 +43,7 @@ #include #include +#include "qiosscreen.h" @implementation QIOSViewController @@ -65,5 +66,16 @@ return UIInterfaceOrientationMaskAll; } +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +{ + Q_UNUSED(fromInterfaceOrientation); + Qt::ScreenOrientation orientation = convertToQtOrientation(self.interfaceOrientation); + if (orientation == -1) + return; + + QIOSScreen *qiosScreen = static_cast(QGuiApplication::primaryScreen()->handle()); + qiosScreen->setPrimaryOrientation(orientation); +} + @end diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 7c4c4ab398..5c290b6c00 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -3,6 +3,8 @@ TARGET = qiosmain PLUGIN_TYPE = platforms load(qt_plugin) +QT += gui-private + OBJECTIVE_SOURCES = qtmain.mm \ qiosviewcontroller.mm -- cgit v1.2.3 From 70774d021a4ddb6437646ab09bde0928e30c8a90 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Dec 2012 10:59:45 +0100 Subject: iOS: refactor QIOSOrientationListener into QIOSScreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up a bit. The orientation conversion functions belongs to QIOSScreen more than QIOSOrientationListener. And rename them in the same go to follow toQRect/fromQRect standard. The orientation listener itself is tightly coupled to QIOSScreen, and does not make much sense on its own, so move it into QIOSScreen to follow the same patteren already implemented for QIOSInputContext. Change-Id: I8b6b4d08a42349b4232749d59d46748297083536 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 - .../platforms/ios/qiosorientationlistener.h | 66 ----------- .../platforms/ios/qiosorientationlistener.mm | 130 --------------------- src/plugins/platforms/ios/qiosscreen.h | 6 +- src/plugins/platforms/ios/qiosscreen.mm | 90 +++++++++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 3 +- 7 files changed, 96 insertions(+), 203 deletions(-) delete mode 100644 src/plugins/platforms/ios/qiosorientationlistener.h delete mode 100644 src/plugins/platforms/ios/qiosorientationlistener.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 1be24d920d..a51ac39e03 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -14,7 +14,6 @@ OBJECTIVE_SOURCES = \ qioseventdispatcher.mm \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ - qiosorientationlistener.mm \ qiosviewcontroller.mm \ qioscontext.mm \ qiosinputcontext.mm \ @@ -27,7 +26,6 @@ HEADERS = \ qioseventdispatcher.h \ qiosbackingstore.h \ qiosapplicationdelegate.h \ - qiosorientationlistener.h \ qiosviewcontroller.h \ qioscontext.h \ qiosinputcontext.h \ diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h deleted file mode 100644 index 9d2e902ce1..0000000000 --- a/src/plugins/platforms/ios/qiosorientationlistener.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QIOSORIENTATIONLISTENER_H -#define QIOSORIENTATIONLISTENER_H - -#include -#include - -QT_BEGIN_NAMESPACE - -class QIOSScreen; -Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); -UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation); - -QT_END_NAMESPACE - -@interface QIOSOrientationListener : NSObject { - @public - QIOSScreen *m_screen; - Qt::ScreenOrientation m_orientation; -} -- (id) initWithQIOSScreen:(QIOSScreen *)screen; - -@end - -#endif - diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm deleted file mode 100644 index 264b77f14f..0000000000 --- a/src/plugins/platforms/ios/qiosorientationlistener.mm +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qiosorientationlistener.h" -#include "qiosscreen.h" -#include - -QT_BEGIN_NAMESPACE - -Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation) -{ - Qt::ScreenOrientation qtOrientation; - switch (uiDeviceOrientation) { - case UIDeviceOrientationPortraitUpsideDown: - qtOrientation = Qt::InvertedPortraitOrientation; - break; - case UIDeviceOrientationLandscapeLeft: - qtOrientation = Qt::InvertedLandscapeOrientation; - break; - case UIDeviceOrientationLandscapeRight: - qtOrientation = Qt::LandscapeOrientation; - break; - case UIDeviceOrientationFaceUp: - case UIDeviceOrientationFaceDown: - qtOrientation = static_cast(-1); // not supported ATM. - break; - default: - qtOrientation = Qt::PortraitOrientation; - break; - } - return qtOrientation; -} - -UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation) -{ - UIDeviceOrientation uiOrientation; - switch (qtOrientation) { - case Qt::LandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeRight; - break; - case Qt::InvertedLandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeLeft; - break; - case Qt::InvertedPortraitOrientation: - uiOrientation = UIDeviceOrientationPortraitUpsideDown; - break; - case Qt::PrimaryOrientation: - case Qt::PortraitOrientation: - default: - uiOrientation = UIDeviceOrientationPortrait; - break; - } - return uiOrientation; -} - -QT_END_NAMESPACE - -@implementation QIOSOrientationListener - -- (id) initWithQIOSScreen:(QIOSScreen *)screen -{ - self = [super init]; - if (self) { - m_screen = screen; - m_orientation = convertToQtOrientation([UIDevice currentDevice].orientation); - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(orientationChanged:) - name:@"UIDeviceOrientationDidChangeNotification" object:nil]; - } - return self; -} - -- (void) dealloc -{ - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [super dealloc]; -} - -- (void) orientationChanged:(NSNotification *)notification -{ - Q_UNUSED(notification); - Qt::ScreenOrientation qtOrientation = convertToQtOrientation([UIDevice currentDevice].orientation); - if (qtOrientation != -1) { - m_orientation = qtOrientation; - QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); - } -} - -@end - diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index e05a6cd6a1..17a5c3149a 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -45,10 +45,14 @@ #include #include -#include + +@class QIOSOrientationListener; QT_BEGIN_NAMESPACE +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); + class QIOSScreen : public QPlatformScreen { public: diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f4cade2e6d..02d719eaf1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -45,8 +45,96 @@ #include +@interface QIOSOrientationListener : NSObject { + @public + QIOSScreen *m_screen; +} +- (id) initWithQIOSScreen:(QIOSScreen *)screen; +@end + +@implementation QIOSOrientationListener + +- (id) initWithQIOSScreen:(QIOSScreen *)screen +{ + self = [super init]; + if (self) { + m_screen = screen; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + [super dealloc]; +} + +- (void) orientationChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + Qt::ScreenOrientation orientation = toQtScreenOrientation([UIDevice currentDevice].orientation); + if (orientation != -1) + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), orientation); +} + +@end + QT_BEGIN_NAMESPACE +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + /*! Returns the model identifier of the device. @@ -137,7 +225,7 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const Qt::ScreenOrientation QIOSScreen::orientation() const { - return m_orientationListener ? m_orientationListener->m_orientation : nativeOrientation(); + return toQtScreenOrientation([UIDevice currentDevice].orientation); } void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index fe9e02666f..8c280d11d9 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -69,7 +69,7 @@ - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { Q_UNUSED(fromInterfaceOrientation); - Qt::ScreenOrientation orientation = convertToQtOrientation(self.interfaceOrientation); + Qt::ScreenOrientation orientation = toQtScreenOrientation(self.interfaceOrientation); if (orientation == -1) return; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index a2901efd1d..cc016da106 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -43,7 +43,6 @@ #include "qioscontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" -#include "qiosorientationlistener.h" #include "qiosviewcontroller.h" #import @@ -272,7 +271,7 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio { // Keep the status bar in sync with content orientation. This will ensure // that the task bar (and associated gestures) are aligned correctly: - UIDeviceOrientation uiOrientation = convertToUIOrientation(orientation); + UIDeviceOrientation uiOrientation = fromQtScreenOrientation(orientation); [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -- cgit v1.2.3 From d665ba2a9454dbd2ed9f4384e04c31d232b0c5eb Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Dec 2012 13:39:59 +0100 Subject: iOS: let QIOSScreen use correct orientation at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QScreen is created, we need to check if the application is already in landscape. Change-Id: I653c622154a5c23ec93e89ec3e80fefb6b1f1bdd Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.mm | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 02d719eaf1..a2fd10bdd4 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -42,6 +42,7 @@ #include "qiosscreen.h" #include "qioswindow.h" #include +#include "qiosapplicationdelegate.h" #include @@ -185,6 +186,12 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; + if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) { + // When in a non-mixed environment, let QScreen follow the current interface orientation: + UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; + setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); + } + [pool release]; } -- cgit v1.2.3 From a593de41edfac04f3e3c6dd5bb024254e7e6ff4e Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Fri, 14 Dec 2012 17:25:56 +0100 Subject: iOS: Retina display support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scale the OpenGL paint device size and physical dpi by the device pixel ratio. Change-Id: I8b576f23129aafc47371795151c548663e94ad52 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 10 ++++++++-- src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 21 ++++++++++++++++++--- 3 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 6bae08ce2b..5ee048cb2f 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -71,12 +71,18 @@ void QIOSBackingStore::beginPaint(const QRegion &) m_context->makeCurrent(window()); static_cast(paintDevice())->setSize(window()->size()); + QIOSWindow *iosWindow = static_cast(window()->handle()); + static_cast(paintDevice())->setSize(window()->size() * iosWindow->devicePixelRatio()); } QPaintDevice *QIOSBackingStore::paintDevice() { - if (!m_device) - m_device = new QOpenGLPaintDevice; + if (!m_device) { + QIOSWindow *iosWindow = static_cast(window()->handle()); + QOpenGLPaintDevice *openGLDevice = new QOpenGLPaintDevice(window()->size() * iosWindow->devicePixelRatio()); + openGLDevice->setDevicePixelRatio(iosWindow->devicePixelRatio()); + m_device = openGLDevice; + } return m_device; } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 3a05901ae7..cb2854d60e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -90,6 +90,7 @@ public: GLuint framebufferObject(const QIOSContext &context) const; GLuint colorRenderbuffer(const QIOSContext &context) const; + qreal devicePixelRatio() const; EAGLView *nativeView() const { return m_view; } @@ -104,6 +105,7 @@ private: GLint renderbufferWidth; GLint renderbufferHeight; } m_glData; + qreal m_devicePixelRatio; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cc016da106..e3da694bac 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -126,8 +126,7 @@ static QRect fromCGRect(const CGRect &rect) { UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; - CGFloat scaleFactor = [self contentScaleFactor]; - QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + QPoint p(locationInView.x , locationInView.y); // TODO handle global touch point? for status bar? QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); @@ -204,11 +203,21 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) , m_glData() + , m_devicePixelRatio(1.0) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; setWindowState(window->windowState()); + + // Retina support: get screen scale factor and set it in the content view. + // This will make framebufferObject() create a 2x frame buffer on retina + // displays. Also set m_devicePixelRatio which is used for scaling the + // paint device. + if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { + m_devicePixelRatio = [[UIScreen mainScreen] scale]; + [m_view setContentScaleFactor : m_devicePixelRatio]; + } } QIOSWindow::~QIOSWindow() @@ -304,7 +313,8 @@ GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const { if (!m_glData.colorRenderbuffer || - m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { + m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || + m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) { glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; @@ -329,4 +339,9 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const return m_glData.colorRenderbuffer; } +qreal QIOSWindow::devicePixelRatio() const +{ + return m_devicePixelRatio; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 54448b2f9fb7501e9d4a8e2c8b75acb9de8f7ae0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 12 Dec 2012 11:16:13 +0100 Subject: iOS: remove warning from unused function in QIOSEventDispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the documentation for QAbstractEventDispatcher::flush(), this function does only make sense for X11. Change-Id: I7f445b67b283f60c9a30ac00837beb44e8205d8b Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 9d455370c0..f6f60387d4 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -313,7 +313,7 @@ void QIOSEventDispatcher::interrupt() void QIOSEventDispatcher::flush() { - qDebug() << __FUNCTION__ << "not implemented"; + // X11 only. } QT_END_NAMESPACE -- cgit v1.2.3 From 5abe9aa435c316b845f4cf5f6a930eefd449f4e1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 10:15:39 +0100 Subject: iOS: refactor general convenience functions into new file 'qiosglobal' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some functions are needed across several files and classes. Lets place them in a common file for all to use. Change-Id: I5f9b578f948d66d10e57a835b80b5c493e07fb4c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 6 +- src/plugins/platforms/ios/qiosglobal.h | 59 ++++++++++++++ src/plugins/platforms/ios/qiosglobal.mm | 104 ++++++++++++++++++++++++ src/plugins/platforms/ios/qiosscreen.h | 3 - src/plugins/platforms/ios/qiosscreen.mm | 49 +---------- src/plugins/platforms/ios/qiosviewcontroller.mm | 1 + src/plugins/platforms/ios/qioswindow.mm | 11 +-- 7 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosglobal.h create mode 100644 src/plugins/platforms/ios/qiosglobal.mm (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index a51ac39e03..591a0a67ed 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -17,7 +17,8 @@ OBJECTIVE_SOURCES = \ qiosviewcontroller.mm \ qioscontext.mm \ qiosinputcontext.mm \ - qiostheme.mm + qiostheme.mm \ + qiosglobal.mm HEADERS = \ qiosintegration.h \ @@ -29,6 +30,7 @@ HEADERS = \ qiosviewcontroller.h \ qioscontext.h \ qiosinputcontext.h \ - qiostheme.h + qiostheme.h \ + qiosglobal.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h new file mode 100644 index 0000000000..cf4c89cfad --- /dev/null +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSGLOBAL_H +#define QIOSGLOBAL_H + +#import +#import +#import +#import "qiosscreen.h" + +QT_BEGIN_NAMESPACE + +CGRect toCGRect(const QRect &rect); +QRect fromCGRect(const CGRect &rect); +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); + +QT_END_NAMESPACE + +#endif // QIOSGLOBAL_H diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm new file mode 100644 index 0000000000..30138acc1b --- /dev/null +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosglobal.h" +#include + +QT_BEGIN_NAMESPACE + +CGRect toCGRect(const QRect &rect) +{ + return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); +} + +QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 17a5c3149a..762c60e6da 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -50,9 +50,6 @@ QT_BEGIN_NAMESPACE -Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); -UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); - class QIOSScreen : public QPlatformScreen { public: diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index a2fd10bdd4..87ddc63f4a 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qiosscreen.h" #include "qioswindow.h" #include @@ -88,54 +89,6 @@ @end -QT_BEGIN_NAMESPACE - -Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) -{ - Qt::ScreenOrientation qtOrientation; - switch (uiDeviceOrientation) { - case UIDeviceOrientationPortraitUpsideDown: - qtOrientation = Qt::InvertedPortraitOrientation; - break; - case UIDeviceOrientationLandscapeLeft: - qtOrientation = Qt::InvertedLandscapeOrientation; - break; - case UIDeviceOrientationLandscapeRight: - qtOrientation = Qt::LandscapeOrientation; - break; - case UIDeviceOrientationFaceUp: - case UIDeviceOrientationFaceDown: - qtOrientation = static_cast(-1); // not supported ATM. - break; - default: - qtOrientation = Qt::PortraitOrientation; - break; - } - return qtOrientation; -} - -UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) -{ - UIDeviceOrientation uiOrientation; - switch (qtOrientation) { - case Qt::LandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeRight; - break; - case Qt::InvertedLandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeLeft; - break; - case Qt::InvertedPortraitOrientation: - uiOrientation = UIDeviceOrientationPortraitUpsideDown; - break; - case Qt::PrimaryOrientation: - case Qt::PortraitOrientation: - default: - uiOrientation = UIDeviceOrientationPortrait; - break; - } - return uiOrientation; -} - /*! Returns the model identifier of the device. diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 8c280d11d9..6950288912 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -44,6 +44,7 @@ #include #include #include "qiosscreen.h" +#include "qiosglobal.h" @implementation QIOSViewController diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e3da694bac..9b10ba4e1c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" #include "qiosscreen.h" @@ -52,16 +53,6 @@ #include -static CGRect toCGRect(const QRect &rect) -{ - return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); -} - -static QRect fromCGRect(const CGRect &rect) -{ - return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); -} - @implementation EAGLView + (Class)layerClass -- cgit v1.2.3 From b960424195634c00673d499e4719ccb4f8704ad0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 12:50:50 +0100 Subject: iOS: add global function 'isQtApplication' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several places in the code we need to check if the plugin is running as a cross-platform Qt application or inside a native app. So we refactor this function to qiosglobal so we can access it from everywhere. Change-Id: I78db0dcde71b7d281868ce304867c8f876caef2a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 13 +++++++++++++ src/plugins/platforms/ios/qiosscreen.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index cf4c89cfad..7a23a2a485 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE +bool isQtApplication(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 30138acc1b..a8a89a1637 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -40,10 +40,23 @@ ****************************************************************************/ #include "qiosglobal.h" +#include "qiosapplicationdelegate.h" #include QT_BEGIN_NAMESPACE +bool isQtApplication() +{ + // Returns true if the plugin is in full control of the whole application. This means + // that we control the application delegate and the top view controller, and can take + // actions that impacts all parts of the application. The opposite means that we are + // embedded inside a native iOS application, and should be more focused on playing along + // with native UIControls, and less inclined to change structures that lies outside the + // scope of our QWindows/UIViews. + static bool isQt = ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]); + return isQt; +} + CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 87ddc63f4a..fdf2f31ea1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -139,7 +139,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; - if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) { + if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9b10ba4e1c..af184e2e7b 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -196,7 +196,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_glData() , m_devicePixelRatio(1.0) { - if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) + if (isQtApplication()) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; setWindowState(window->windowState()); -- cgit v1.2.3 From 31796ca8abb8878165c7099145b08abfdf8bf1e3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 09:50:28 +0100 Subject: iOS: report changes to keyboard rect back to Qt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QInputContext expects us to report whenever the input panel changes geometry. This patch implements this. Change-Id: I9162f0d48da6925274a7489c9bcb6adab9afae82 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 9 +++++++++ src/plugins/platforms/ios/qiosinputcontext.h | 1 + src/plugins/platforms/ios/qiosinputcontext.mm | 15 +++++++++++++-- src/plugins/platforms/ios/qiosscreen.mm | 4 +--- 5 files changed, 25 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 7a23a2a485..849d9bce37 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -54,6 +54,7 @@ CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); +QRect fromPortraitToPrimary(const QRect &rect); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index a8a89a1637..f9b4b14a19 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -113,5 +113,14 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } +QRect fromPortraitToPrimary(const QRect &rect) +{ + // UIScreen is always in portrait. Use this function to convert CGRects + // aligned with UIScreen into whatever is the current orientation of QScreen. + QScreen *screen = QGuiApplication::primaryScreen(); + return screen->isPortrait(screen->primaryOrientation()) ? rect + : QRect(rect.y(), screen->geometry().width() - rect.width() - rect.x(), rect.height(), rect.width()); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 22782d183c..ceed5ffaf2 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -56,6 +56,7 @@ public: QIOSInputContext(); ~QIOSInputContext(); + QRectF keyboardRect() const; void showInputPanel(); void hideInputPanel(); bool isInputPanelVisible() const; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 7937337e4a..89d210cb54 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qiosinputcontext.h" #include "qioswindow.h" #include @@ -47,6 +48,7 @@ @public QIOSInputContext *m_context; BOOL m_keyboardVisible; + QRectF m_keyboardRect; } @end @@ -80,6 +82,10 @@ { CGRect frame; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + + m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame)); + m_context->emitKeyboardRectChanged(); + BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); if (m_keyboardVisible != visible) { m_keyboardVisible = visible; @@ -90,8 +96,8 @@ @end QIOSInputContext::QIOSInputContext() - : QPlatformInputContext(), - m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + : QPlatformInputContext() + , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) { } @@ -100,6 +106,11 @@ QIOSInputContext::~QIOSInputContext() [m_keyboardListener release]; } +QRectF QIOSInputContext::keyboardRect() const +{ + return m_keyboardListener->m_keyboardRect; +} + void QIOSInputContext::showInputPanel() { if (isInputPanelVisible()) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index fdf2f31ea1..a0403a0d69 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -212,11 +212,9 @@ void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) return; // Switching portrait/landscape means swapping width/height (and adjusting x/y): - CGRect frame = m_uiScreen.applicationFrame; - m_availableGeometry = portrait ? QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) - : QRect(frame.origin.y, m_geometry.width() - frame.size.width - frame.origin.x, frame.size.height, frame.size.width); m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); + m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame)); QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -- cgit v1.2.3 From 5b452a502214a927c54b7cc6e4fb81a7c2141267 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 12:58:43 +0100 Subject: iOS: update primary orientation when the rotation starts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to update primary orientation when the rotation starts, and not when it ends, so that we are in sync with the resize that happens to the backingstore upon layoutSubviews. Change-Id: I466a2d135e6c15550c6207c9659871629d748b73 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 6950288912..a441258f4e 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -67,10 +67,10 @@ return UIInterfaceOrientationMaskAll; } -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - Q_UNUSED(fromInterfaceOrientation); - Qt::ScreenOrientation orientation = toQtScreenOrientation(self.interfaceOrientation); + Q_UNUSED(duration); + Qt::ScreenOrientation orientation = toQtScreenOrientation(toInterfaceOrientation); if (orientation == -1) return; -- cgit v1.2.3 From cbdd73d25d4c4aa6436591b259dec10aa4f74b0d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 13:52:13 +0100 Subject: iOS: bugfix portraitToPrimary global function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QScreen geometry and orientation is updated a bit after we change geometry in QPlatformScreen, which this time was enough to break availableGeometry. Since this function is for internal use, we let it be based on internal data. Change-Id: I7701b0a6043839c89c01e87242decb8a739d00f1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index f9b4b14a19..69547fb2a1 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -117,9 +117,9 @@ QRect fromPortraitToPrimary(const QRect &rect) { // UIScreen is always in portrait. Use this function to convert CGRects // aligned with UIScreen into whatever is the current orientation of QScreen. - QScreen *screen = QGuiApplication::primaryScreen(); - return screen->isPortrait(screen->primaryOrientation()) ? rect - : QRect(rect.y(), screen->geometry().width() - rect.width() - rect.x(), rect.height(), rect.width()); + QRect geometry = QGuiApplication::primaryScreen()->handle()->geometry(); + return geometry.width() < geometry.height() ? rect + : QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width()); } QT_END_NAMESPACE -- cgit v1.2.3 From 2dea9fdc3a04ccc9759427c6450e88cb78003381 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 09:15:27 +0100 Subject: iOS: add convenience function to get to the root QIOSViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that we need to access our view controller from many places, and the syntax to do so is tricky to remember. So lets just add it to our global functions, with the added bonus of a using a little cache. Note: many of these functions could be made inline, but since one concern of the plugin will be the end size of the app, I prefer to trade size for speed at this point. We can always change this later. Change-Id: I578ea9ae8218d23d635b7728a930763ca53c4eaa Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 ++++ src/plugins/platforms/ios/qiosglobal.mm | 8 ++++++++ src/plugins/platforms/ios/qiosscreen.mm | 4 ++-- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 849d9bce37..86377e7c64 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -47,9 +47,13 @@ #import #import "qiosscreen.h" +@class QIOSViewController; + QT_BEGIN_NAMESPACE bool isQtApplication(); +QIOSViewController *rootViewController(); + CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 69547fb2a1..cf69d8fdef 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -41,6 +41,7 @@ #include "qiosglobal.h" #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" #include QT_BEGIN_NAMESPACE @@ -57,6 +58,13 @@ bool isQtApplication() return isQt; } +QIOSViewController *rootViewController() +{ + static QIOSViewController *c = isQtApplication() ? + static_cast([UIApplication sharedApplication].delegate.window.rootViewController) : nil; + return c; +} + CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index a0403a0d69..5905f1630e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -44,6 +44,7 @@ #include "qioswindow.h" #include #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" #include @@ -141,8 +142,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: - UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; - setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); + setPrimaryOrientation(toQtScreenOrientation(rootViewController().interfaceOrientation)); } [pool release]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index af184e2e7b..71816f7d94 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -197,7 +197,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_devicePixelRatio(1.0) { if (isQtApplication()) - [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; + [rootViewController().view addSubview:m_view]; setWindowState(window->windowState()); -- cgit v1.2.3 From bbb8db9bdb503f4f2c558e5f081c201c09d33d77 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 10:46:22 +0100 Subject: iOS: make EAGLView private in QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not the biggest gain, but since all the members of EAGLView are declared private, we might as well move the whole interface into the source file. We can then make the members public without caring about interface readability. We will make use of this in a following patch. Change-Id: I144fb5748573ca6faf257d72597907b5c17b1e05 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 29 ++--------------------------- src/plugins/platforms/ios/qioswindow.mm | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 28 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index cb2854d60e..d0df791cf0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -49,31 +49,6 @@ class QIOSContext; class QIOSWindow; -@interface EAGLView : UIView -{ - UITextAutocapitalizationType autocapitalizationType; - UITextAutocorrectionType autocorrectionType; - BOOL enablesReturnKeyAutomatically; - UIKeyboardAppearance keyboardAppearance; - UIKeyboardType keyboardType; - UIReturnKeyType returnKeyType; - BOOL secureTextEntry; - QIOSWindow *m_qioswindow; -} - -- (id)initWithQIOSWindow:(QIOSWindow *)qioswindow; -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; - -@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; -@property(nonatomic) UITextAutocorrectionType autocorrectionType; -@property(nonatomic) BOOL enablesReturnKeyAutomatically; -@property(nonatomic) UIKeyboardAppearance keyboardAppearance; -@property(nonatomic) UIKeyboardType keyboardType; -@property(nonatomic) UIReturnKeyType returnKeyType; -@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; - -@end - QT_BEGIN_NAMESPACE class QIOSWindow : public QPlatformWindow @@ -92,10 +67,10 @@ public: GLuint colorRenderbuffer(const QIOSContext &context) const; qreal devicePixelRatio() const; - EAGLView *nativeView() const { return m_view; } + UIView *nativeView() const { return m_view; } private: - EAGLView *m_view; + UIView *m_view; QRect m_requestedGeometry; mutable struct GLData { diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 71816f7d94..220f30c485 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -53,6 +53,29 @@ #include +@interface EAGLView : UIView +{ +@public + UITextAutocapitalizationType autocapitalizationType; + UITextAutocorrectionType autocorrectionType; + BOOL enablesReturnKeyAutomatically; + UIKeyboardAppearance keyboardAppearance; + UIKeyboardType keyboardType; + UIReturnKeyType returnKeyType; + BOOL secureTextEntry; + QIOSWindow *m_qioswindow; +} + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; +@property(nonatomic) BOOL enablesReturnKeyAutomatically; +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; +@property(nonatomic) UIKeyboardType keyboardType; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; + +@end + @implementation EAGLView + (Class)layerClass @@ -186,7 +209,6 @@ @end - QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) -- cgit v1.2.3 From 646b1fd2b65f42327ff81b92ead96c634bec6468 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 10:23:54 +0100 Subject: iOS: add UIView category to get the QWindow it represents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding a simple way to get the QWindow pointer from any UIView makes writing code where you only have UIView pointers a bit easier. Perhaps we should also investigate if it is worthwhile to make this category public to the application, to further enhance working in a mixed environment. Change-Id: Ic263003dc7683a8d976024cbbbc2558e8472a790 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 4 ++++ src/plugins/platforms/ios/qioswindow.mm | 11 +++++++++++ 2 files changed, 15 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d0df791cf0..63099682f1 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -49,6 +49,10 @@ class QIOSContext; class QIOSWindow; +@interface UIView (QIOS) +@property(readonly) QWindow *qwindow; +@end + QT_BEGIN_NAMESPACE class QIOSWindow : public QPlatformWindow diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 220f30c485..d79c1de461 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -209,6 +209,17 @@ @end +@implementation UIView (QIOS) + +- (QWindow *)qwindow +{ + if ([self isKindOfClass:[EAGLView class]]) + return static_cast(self)->m_qioswindow->window(); + return nil; +} + +@end + QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) -- cgit v1.2.3 From 1ff571142d5c06e91a1698d635ab092bbcf393cf Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 11:05:27 +0100 Subject: iOS: activate next window when active window hides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the OS does not handle window management for us, we need to handle this ourselves. So when a QWindow is closed or hidden, we transfer activation to the top-most visible window. This will fix application unresponsive after closing a dialog. Change-Id: I83f836ebafa71edca5ab5ae3a2bdba7cd1decbc1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d79c1de461..53da97e12d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -260,7 +260,21 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setVisible(bool visible) { QPlatformWindow::setVisible(visible); - [m_view setHidden:!visible]; + m_view.hidden = !visible; + + if (isQtApplication() && !visible) { + // Activate top-most visible QWindow: + NSArray *subviews = rootViewController().view.subviews; + for (int i = int(subviews.count) - 1; i >= 0; --i) { + UIView *view = [subviews objectAtIndex:i]; + if (!view.hidden) { + if (QWindow *window = view.qwindow) { + QWindowSystemInterface::handleWindowActivated(window); + break; + } + } + } + } } void QIOSWindow::setGeometry(const QRect &rect) -- cgit v1.2.3 From 9acae5ce0bfe94bde2711986ccebadf12e9a8a7a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 11:19:37 +0100 Subject: iOS: clean-up header includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to keep qiosglobal.h free from unnecessary includes, since its typically included from many different locations. Change-Id: I6638bcaef1189b3eee3dbd5f744c15f8f7858d71 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 +--- src/plugins/platforms/ios/qiosglobal.mm | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 86377e7c64..3fe426c901 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -43,9 +43,7 @@ #define QIOSGLOBAL_H #import -#import -#import -#import "qiosscreen.h" +#include @class QIOSViewController; diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index cf69d8fdef..712968d216 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -42,7 +42,7 @@ #include "qiosglobal.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" -#include +#include "qiosscreen.h" QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 25ce3a021ba3007ec0d2f059c5ec7fa259bdae83 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 12:06:10 +0100 Subject: iOS: make QWindow views hidden by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt will tell us when the window should be visible. Showing all windows by default makes e.g the desktop widget visible as well, which causes problems with activation of windows. Change-Id: Ibf2283bc5f009df7ff23126f4dd04ec898141720 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 53da97e12d..4b4871dd64 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -109,6 +109,9 @@ keyboardType = UIKeyboardTypeDefault; returnKeyType = UIReturnKeyDone; secureTextEntry = NO; + + if (isQtApplication()) + self.hidden = YES; } return self; -- cgit v1.2.3 From e30659aaf500a2186dfe67f29ce57bea5bf86b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Dec 2012 15:06:55 +0100 Subject: iOS: Fix style nitpicks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I670567f1793b5548393a3b315650bf34a0a3880e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioswindow.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4b4871dd64..9c814ac924 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -243,7 +243,7 @@ QIOSWindow::QIOSWindow(QWindow *window) // paint device. if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { m_devicePixelRatio = [[UIScreen mainScreen] scale]; - [m_view setContentScaleFactor : m_devicePixelRatio]; + [m_view setContentScaleFactor: m_devicePixelRatio]; } } @@ -355,7 +355,7 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const { if (!m_glData.colorRenderbuffer || m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || - m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) { + m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) { glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; -- cgit v1.2.3 From b05c20b4f33b35c8b3428caf2ee59675d858d5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 21:44:13 +0100 Subject: iOS: Don't check for existing window in QIOSMainWrapperApplicationDelegate The delegate is only used when we control the application, so we know that there isn't any window yet. Change-Id: Ibd774cb4fd8ceaab6a181769d2792b569f490495 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 61756edc93..7cc96f54b1 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -55,20 +55,16 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // We may have a window already from a NIB or storyboard - if (!self.window) { - // If not, we create one ourselves - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - QIOSViewController *controller = [[QIOSViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + QIOSViewController *controller = [[QIOSViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; - // Aid debugging during development - self.window.backgroundColor = [UIColor cyanColor]; - self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; - [self.window makeKeyAndVisible]; - } + [self.window makeKeyAndVisible]; // We schedule the main-redirection for the next eventloop pass so that we // can return from this function and let UIApplicationMain finish its job. -- cgit v1.2.3 From 78fec3372ad819cc93b9cfb5bd3df2da6d792cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 21:55:10 +0100 Subject: iOS: Auto-release the UIWindow and root view-controller They are retained properties. Change-Id: Id1808d93fe30950fc05e41375f00183e098bff0b Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 7cc96f54b1..04151cd720 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -55,10 +55,9 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - QIOSViewController *controller = [[QIOSViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; + self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; + self.window.rootViewController.view = [[UIView alloc] init]; // Aid debugging during development self.window.backgroundColor = [UIColor cyanColor]; -- cgit v1.2.3 From 8a854ea804c500c2f0425784fd6a24b843016077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:27:27 +0100 Subject: iOS: Don't init our own base view for the root viewcontroller This is handled automatically by the default implementation. Change-Id: Ia9bd0143490e6f2507ede03f3654a2b0b00e3e3d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 04151cd720..00bb581535 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -57,7 +57,6 @@ extern int qt_main(int argc, char *argv[]); { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; - self.window.rootViewController.view = [[UIView alloc] init]; // Aid debugging during development self.window.backgroundColor = [UIColor cyanColor]; -- cgit v1.2.3 From c77d3d78e448f519c1770c863bb0fccc6c9b7263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:31:43 +0100 Subject: iOS: Move debug background color setting and guard for release builds Change-Id: Ie9131c3dfe16045805b37bf8af9381f4f9929da6 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 8 ++++++++ src/plugins/platforms/ios/qtmain.mm | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a441258f4e..c85058743c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -48,6 +48,14 @@ @implementation QIOSViewController +- (void)viewDidLoad +{ +#ifdef QT_DEBUG + if (!self.nibName) + self.view.backgroundColor = [UIColor magentaColor]; +#endif +} + -(BOOL)shouldAutorotate { // For now we assume that if the application doesn't listen to orientation diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 00bb581535..10c83f4b18 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -58,9 +58,9 @@ extern int qt_main(int argc, char *argv[]); self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; - // Aid debugging during development +#ifdef QT_DEBUG self.window.backgroundColor = [UIColor cyanColor]; - self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; +#endif [self.window makeKeyAndVisible]; -- cgit v1.2.3 From 157d690b8c190f341f1fa4cb6aff4c044456e99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:56:42 +0100 Subject: iOS: Don't build qiosviewcontroller.mm into qtmain plugin It's already built as part of the iOS platform plugin. Change-Id: I5a97e8723b566b9ef15aafce374be35f01e6cf08 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.pro | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 5c290b6c00..cbcb272217 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -5,7 +5,4 @@ load(qt_plugin) QT += gui-private -OBJECTIVE_SOURCES = qtmain.mm \ - qiosviewcontroller.mm - -HEADERS = qiosviewcontroller.h +OBJECTIVE_SOURCES = qtmain.mm -- cgit v1.2.3 From 847ac6008ca02a9acb1f4bd2159c6e4cfa332961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 00:21:25 +0100 Subject: iOS: Move handling of FBOs to QIOSContext instead of QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lifetime of an FBO is tied to its context, so letting each window manage its own FBO failed when the window tried to delete the FBO at destruction time without the proper context being current, or even available anymore. We solve this by moving all handling of FBOs to the context itself, which is fine as we're exposing the necessary bits from the window to allocate storage based on its layer. Change-Id: I8c7c96cf63d6b667527c816f10ac2f4ff6a05e0c Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 21 +++++-- src/plugins/platforms/ios/qioscontext.mm | 100 +++++++++++++++++++++++++++---- src/plugins/platforms/ios/qioswindow.h | 11 +--- src/plugins/platforms/ios/qioswindow.mm | 65 ++------------------ 4 files changed, 113 insertions(+), 84 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index b45917832c..082ec4794c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -48,8 +48,10 @@ QT_BEGIN_NAMESPACE -class QIOSContext : public QPlatformOpenGLContext +class QIOSContext : public QObject, public QPlatformOpenGLContext { + Q_OBJECT + public: QIOSContext(QOpenGLContext *context); ~QIOSContext(); @@ -62,15 +64,26 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; - GLuint defaultColorRenderbuffer(QPlatformSurface *) const; - QFunctionPointer getProcAddress(const QByteArray &procName); - EAGLContext *nativeContext() const; +private Q_SLOTS: + void windowDestroyed(QObject *object); private: EAGLContext *m_eaglContext; QSurfaceFormat m_format; + + struct FramebufferObject { + GLuint handle; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + }; + + static void deleteBuffers(const FramebufferObject &framebufferObject); + + mutable QHash m_framebufferObjects; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 00629a84ab..dc431b57dd 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -70,12 +70,25 @@ QIOSContext::QIOSContext(QOpenGLContext *context) QIOSContext::~QIOSContext() { - if ([EAGLContext currentContext] == m_eaglContext) - doneCurrent(); + [EAGLContext setCurrentContext:m_eaglContext]; + + foreach (const FramebufferObject &framebufferObject, m_framebufferObjects) + deleteBuffers(framebufferObject); + [EAGLContext setCurrentContext:nil]; [m_eaglContext release]; } +void QIOSContext::deleteBuffers(const FramebufferObject &framebufferObject) +{ + if (framebufferObject.handle) + glDeleteFramebuffers(1, &framebufferObject.handle); + if (framebufferObject.colorRenderbuffer) + glDeleteRenderbuffers(1, &framebufferObject.colorRenderbuffer); + if (framebufferObject.depthRenderbuffer) + glDeleteRenderbuffers(1, &framebufferObject.depthRenderbuffer); +} + QSurfaceFormat QIOSContext::format() const { return m_format; @@ -88,8 +101,7 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - // Ensures render buffers are set up and match the size of the window - return defaultColorRenderbuffer(surface) != 0; + return true; } void QIOSContext::doneCurrent() @@ -100,20 +112,86 @@ void QIOSContext::doneCurrent() void QIOSContext::swapBuffers(QPlatformSurface *surface) { Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); + QWindow *window = static_cast(surface->surface()); + Q_ASSERT(m_framebufferObjects.contains(window)); [EAGLContext setCurrentContext:m_eaglContext]; - glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); + glBindRenderbuffer(GL_RENDERBUFFER, m_framebufferObjects[window].colorRenderbuffer); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { - return static_cast(surface)->framebufferObject(*this); + Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window); + QWindow *window = static_cast(surface->surface()); + + FramebufferObject &framebufferObject = m_framebufferObjects[window]; + + // Set up an FBO for the window if it hasn't been created yet + if (!framebufferObject.handle) { + [EAGLContext setCurrentContext:m_eaglContext]; + + glGenFramebuffers(1, &framebufferObject.handle); + glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle); + + glGenRenderbuffers(1, &framebufferObject.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + framebufferObject.colorRenderbuffer); + + if (m_format.depthBufferSize() > 0 || m_format.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &framebufferObject.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + framebufferObject.depthRenderbuffer); + + if (m_format.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + framebufferObject.depthRenderbuffer); + } + + connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*))); + } + + // Ensure that the FBO's buffers match the size of the window + QIOSWindow *platformWindow = static_cast(surface); + if (framebufferObject.renderbufferWidth != platformWindow->effectiveWidth() || + framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) { + + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); + CAEAGLLayer *layer = static_cast(platformWindow->nativeView().layer); + [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferObject.renderbufferHeight); + + if (framebufferObject.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer); + + // FIXME: Support more fine grained control over depth/stencil buffer sizes + if (m_format.stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, + framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, + framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } + + return framebufferObject.handle; } -GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +void QIOSContext::windowDestroyed(QObject *object) { - return static_cast(surface)->colorRenderbuffer(*this); + QWindow *window = static_cast(object); + if (m_framebufferObjects.contains(window)) { + deleteBuffers(m_framebufferObjects[window]); + m_framebufferObjects.remove(window); + } } QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) @@ -121,7 +199,5 @@ QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); } -EAGLContext *QIOSContext::nativeContext() const -{ - return m_eaglContext; -} +#include "moc_qioscontext.cpp" + diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 63099682f1..1f36c525ce 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -67,9 +67,9 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); - GLuint framebufferObject(const QIOSContext &context) const; - GLuint colorRenderbuffer(const QIOSContext &context) const; qreal devicePixelRatio() const; + int effectiveWidth() const; + int effectiveHeight() const; UIView *nativeView() const { return m_view; } @@ -77,13 +77,6 @@ private: UIView *m_view; QRect m_requestedGeometry; - mutable struct GLData { - GLuint framebufferObject; - GLuint colorRenderbuffer; - GLuint depthRenderbuffer; - GLint renderbufferWidth; - GLint renderbufferHeight; - } m_glData; qreal m_devicePixelRatio; }; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9c814ac924..88debb7c33 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -229,7 +229,6 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) - , m_glData() , m_devicePixelRatio(1.0) { if (isQtApplication()) @@ -249,13 +248,6 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { - if (m_glData.framebufferObject) - glDeleteFramebuffers(1, &m_glData.framebufferObject); - if (m_glData.colorRenderbuffer) - glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); - if (m_glData.depthRenderbuffer) - glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); - [m_view removeFromSuperview]; [m_view release]; } @@ -325,64 +317,19 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const +qreal QIOSWindow::devicePixelRatio() const { - if (!m_glData.framebufferObject) { - [EAGLContext setCurrentContext:context.nativeContext()]; - - glGenFramebuffers(1, &m_glData.framebufferObject); - glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - - glGenRenderbuffers(1, &m_glData.colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - glGenRenderbuffers(1, &m_glData.depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - - if (requestedFormat.stencilBufferSize() > 0) - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - } - } - - return m_glData.framebufferObject; + return m_devicePixelRatio; } -GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +int QIOSWindow::effectiveWidth() const { - if (!m_glData.colorRenderbuffer || - m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || - m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) { - - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; - - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); - - if (m_glData.depthRenderbuffer) { - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); - - // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (context.format().stencilBufferSize() > 0) - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); - else - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); - } - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - } - - return m_glData.colorRenderbuffer; + return geometry().width() * m_devicePixelRatio; } -qreal QIOSWindow::devicePixelRatio() const +int QIOSWindow::effectiveHeight() const { - return m_devicePixelRatio; + return geometry().height() * m_devicePixelRatio; } QT_END_NAMESPACE -- cgit v1.2.3 From 16e8eca3621b89730f13e07c258fb8a4ae68a1ce Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 2 Jan 2013 11:03:59 +0100 Subject: iOS: transfer focus to the window touched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since our QWindows are UIViews rather than UIWindows, we need to implement window activation manually. This patch will ensure that the window touched by the user also gets keyboard focus. Change-Id: I9390c5c8e50a4b066cd1320a2a044e02f2a9f75d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 88debb7c33..c7c27c08ce 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -151,6 +151,11 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + // Transfer focus to the touched window: + QWindow *window = m_qioswindow->window(); + if (window != QGuiApplication::focusWindow()) + QWindowSystemInterface::handleWindowActivated(window); + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } -- cgit v1.2.3 From 7150e8f51f44b6299728c5bdfb8cb5b54b8d1141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 14 Jan 2013 15:41:33 +0100 Subject: iOS: Use 72 DPI for font size conversion This matches how UIKit behaves Change-Id: I13fd2578cac84e57b6be29c42ddee414b7ee9cb9 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 762c60e6da..bbc3eb7432 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -63,6 +63,7 @@ public: int depth() const; QImage::Format format() const; QSizeF physicalSize() const; + QDpi logicalDpi() const; Qt::ScreenOrientation nativeOrientation() const; Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5905f1630e..f3585407ce 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -178,6 +178,11 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } +QDpi QIOSScreen::logicalDpi() const +{ + return QDpi(72, 72); +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { return Qt::PortraitOrientation; -- cgit v1.2.3 From 355f064ec97cf61c7041a6d32f198a6bde800e6e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 2 Jan 2013 12:53:43 +0100 Subject: iOS: implement QPlatformWindow::raise() and lower() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probably not going to be the most used functions on iOS, but implemented to support old widget apps out of the box. The implementation stacks both staysOnTop and popup windows on the same level for simplicity, since iOS does not have a concept of z-ordering UIViews (UILayer has z-order, but layers belong in a different hierarchy, and cannot be used in this respect). Change-Id: Idd68e5ceea7d4eaeb3066486c47400930cebb1b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 5 +++++ src/plugins/platforms/ios/qioswindow.mm | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 1f36c525ce..e7b04c53eb 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -67,6 +67,9 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); + void raise() { raiseOrLower(true); } + void lower() { raiseOrLower(false); } + qreal devicePixelRatio() const; int effectiveWidth() const; int effectiveHeight() const; @@ -78,6 +81,8 @@ private: QRect m_requestedGeometry; qreal m_devicePixelRatio; + + void raiseOrLower(bool raise); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c7c27c08ce..5bb5048b0a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,8 +153,10 @@ { // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); - if (window != QGuiApplication::focusWindow()) + if (window != QGuiApplication::focusWindow()) { + m_qioswindow->raise(); QWindowSystemInterface::handleWindowActivated(window); + } [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } @@ -314,6 +316,34 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::raiseOrLower(bool raise) +{ + // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure + // that window flags (staysOnTop, popup) are respected. This function assumes that all + // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at + // the same level: + if (!isQtApplication()) + return; + + NSArray *subviews = m_view.superview.subviews; + if (subviews.count == 1) + return; + + const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog; + bool thisWindowIsTop = topFlag & window()->flags(); + + for (int i = int(subviews.count) - 1; i >= 0; --i) { + UIView *view = static_cast([subviews objectAtIndex:i]); + bool otherWindowIsTop = topFlag & view.qwindow->flags(); + if ((raise && (thisWindowIsTop || !otherWindowIsTop)) + || (!raise && (thisWindowIsTop && !otherWindowIsTop))) { + [m_view.superview insertSubview:m_view aboveSubview:view]; + return; + } + } + [m_view.superview insertSubview:m_view atIndex:0]; +} + void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { // Keep the status bar in sync with content orientation. This will ensure -- cgit v1.2.3 From e83bed82c1b58cde1f9a49ad4e4b86d8a13304f1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 15 Jan 2013 13:22:01 +0100 Subject: iOS: raise windows that becomes visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a QWindow becomes visible, it should move to front and be active. Change-Id: Icab12c6031c0cc8d791e4f8cc49b9c2d5c73100d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5bb5048b0a..488962ab66 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -264,7 +264,15 @@ void QIOSWindow::setVisible(bool visible) QPlatformWindow::setVisible(visible); m_view.hidden = !visible; - if (isQtApplication() && !visible) { + if (!isQtApplication()) + return; + + // Since iOS doesn't do window management the way a Qt application + // expects, we need to raise and activate windows ourselves: + if (visible) { + raise(); + QWindowSystemInterface::handleWindowActivated(window()); + } else { // Activate top-most visible QWindow: NSArray *subviews = rootViewController().view.subviews; for (int i = int(subviews.count) - 1; i >= 0; --i) { -- cgit v1.2.3 From 73e879660376a40fd21ded84020f2e527f22cd13 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 15 Jan 2013 14:30:20 +0100 Subject: iOS: implement QPlatformWindow::requestActivateWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window. Change-Id: Ib97321ed7ec8da90e924ff8155a95896c12160c9 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index e7b04c53eb..01c1978a56 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -69,6 +69,7 @@ public: void raise() { raiseOrLower(true); } void lower() { raiseOrLower(false); } + void requestActivateWindow(); qreal devicePixelRatio() const; int effectiveWidth() const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 488962ab66..59f82fb64e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,10 +153,8 @@ { // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); - if (window != QGuiApplication::focusWindow()) { - m_qioswindow->raise(); - QWindowSystemInterface::handleWindowActivated(window); - } + if (window != QGuiApplication::focusWindow()) + m_qioswindow->requestActivateWindow(); [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } @@ -270,8 +268,7 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: if (visible) { - raise(); - QWindowSystemInterface::handleWindowActivated(window()); + requestActivateWindow(); } else { // Activate top-most visible QWindow: NSArray *subviews = rootViewController().view.subviews; @@ -279,7 +276,7 @@ void QIOSWindow::setVisible(bool visible) UIView *view = [subviews objectAtIndex:i]; if (!view.hidden) { if (QWindow *window = view.qwindow) { - QWindowSystemInterface::handleWindowActivated(window); + static_cast(window->handle())->requestActivateWindow(); break; } } @@ -324,6 +321,15 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::requestActivateWindow() +{ + // Note that several windows can be active at the same time if they exist in the same + // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). + // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: + raise(); + QPlatformWindow::requestActivateWindow(); +} + void QIOSWindow::raiseOrLower(bool raise) { // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure -- cgit v1.2.3 From 0a9a4e826fc0a3909481f40d77708a86be55a345 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 16 Jan 2013 10:42:31 +0100 Subject: iOS: let first responder follow the view of the focus window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This to ensure that the keyboard does not close prematurly. This can happen if the user opens up the keyboard while typing inside one window, then switch window, continue typing while the other window gets deleted. Change-Id: I5cfb1673ccbe4d5aaa14167b7aa53451031089a1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 3 +++ src/plugins/platforms/ios/qiosinputcontext.mm | 33 ++++++++++++--------------- src/plugins/platforms/ios/qioswindow.mm | 5 ++++ 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index ceed5ffaf2..176ad05733 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -61,8 +61,11 @@ public: void hideInputPanel(); bool isInputPanelVisible() const; + void focusViewChanged(UIView *view); + private: QIOSKeyboardListener *m_keyboardListener; + UIView *m_focusView; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 89d210cb54..c0ff3b2531 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -98,12 +98,14 @@ QIOSInputContext::QIOSInputContext() : QPlatformInputContext() , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + , m_focusView(0) { } QIOSInputContext::~QIOSInputContext() { [m_keyboardListener release]; + [m_focusView release]; } QRectF QIOSInputContext::keyboardRect() const @@ -113,33 +115,28 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { - if (isInputPanelVisible()) - return; - // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first - // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt - // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible - // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of - // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() becomeFirstResponder]; - } + // responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use. + // Note that Qt will forward keyevents to whichever QObject that needs it, regardless of which UIView the input + // actually came from. So in this respect, we're undermining iOS' responder chain. + [m_focusView becomeFirstResponder]; } void QIOSInputContext::hideInputPanel() { - if (!isInputPanelVisible()) - return; - - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() resignFirstResponder]; - } + [m_focusView resignFirstResponder]; } bool QIOSInputContext::isInputPanelVisible() const { return m_keyboardListener->m_keyboardVisible; } + +void QIOSInputContext::focusViewChanged(UIView *view) +{ + if ([m_focusView isFirstResponder]) + [view becomeFirstResponder]; + [m_focusView release]; + m_focusView = [view retain]; +} diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59f82fb64e..c5d9cbe323 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,9 +42,12 @@ #include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include +#include #import @@ -327,6 +330,8 @@ void QIOSWindow::requestActivateWindow() // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: raise(); + QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); + static_cast(context)->focusViewChanged(m_view); QPlatformWindow::requestActivateWindow(); } -- cgit v1.2.3 From f2c52d65608d238ad35ca91099a8751e0c37ef52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 22 Jan 2013 12:00:19 +0100 Subject: iOS: Implement touch events. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track touch events during the standard [Began -> Moved -> Ended] event sequence based on the UITouch pointer which stays constant. Enable multiTouch on Qt's UIView. Mouse events should now be automatically created from (unhanded) touch events by QGuiApplication. Reviewed by: Ada Sørvig (fingerpaint app approved) Change-Id: I2aeb48c962c697d8b8337f8ceab062070c2a4240 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 3 + src/plugins/platforms/ios/qiosintegration.mm | 11 +++ src/plugins/platforms/ios/qioswindow.h | 9 +++ src/plugins/platforms/ios/qioswindow.mm | 106 ++++++++++++++++++++++++--- 4 files changed, 118 insertions(+), 11 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 5ba97bff6e..054933ea44 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -71,10 +72,12 @@ public: void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); + QTouchDevice *touchDevice(); private: QPlatformFontDatabase *m_fontDatabase; QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; + QTouchDevice *m_touchDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 8008c5c0b0..cbe2717c34 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -72,10 +72,16 @@ QIOSIntegration::QIOSIntegration() } screenAdded(m_screen); + + m_touchDevice = new QTouchDevice; + m_touchDevice->setType(QTouchDevice::TouchScreen); + m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(m_touchDevice); } QIOSIntegration::~QIOSIntegration() { + delete m_touchDevice; } QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const @@ -157,4 +163,9 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind return 0; } +QTouchDevice *QIOSIntegration::touchDevice() +{ + return m_touchDevice; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 01c1978a56..b3a94a8d0e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -43,6 +43,7 @@ #define QIOSWINDOW_H #include +#include #import @@ -77,8 +78,16 @@ public: UIView *nativeView() const { return m_view; } + QList &touchPoints() { return m_touchPoints; } + QHash &activeTouches() { return m_activeTouches; } + int &touchId() { return m_touchId; } + private: UIView *m_view; + QList m_touchPoints; + QHash m_activeTouches; + int m_touchId; + QRect m_requestedGeometry; qreal m_devicePixelRatio; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c5d9cbe323..91e75bc660 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -46,6 +46,7 @@ #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include "qiosintegration.h" #include #include @@ -115,6 +116,8 @@ if (isQtApplication()) self.hidden = YES; + + self.multipleTouchEnabled = YES; } return self; @@ -142,39 +145,119 @@ [super layoutSubviews]; } -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons +/* + Touch handling: + + UIKit generates [Began -> Moved -> Ended] event sequences for + each touch point. The iOS plugin tracks each individual + touch and assigns it an id for use by Qt. The id counter is + incremented on each began and decrement as follows: + 1) by one when the most recent touch ends. + 2) to zero when all touches ends. + + The TouchPoint list is reused between events. +*/ +- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { - UITouch *touch = [touches anyObject]; - CGPoint locationInView = [touch locationInView:self]; - QPoint p(locationInView.x , locationInView.y); + QList &touchPoints = m_qioswindow->touchPoints(); + QHash &activeTouches = m_qioswindow->activeTouches(); + + // Mark all touch points as stationary + for (QList::iterator it = touchPoints.begin(); it != touchPoints.end(); ++it) + it->state = Qt::TouchPointStationary; + + // Update changed touch points with the new state + for (UITouch *touch in touches) { + const int touchId = activeTouches.value(touch); + QWindowSystemInterface::TouchPoint &touchPoint = touchPoints[touchId]; + touchPoint.state = state; + if (state == Qt::TouchPointPressed) + touchPoint.pressure = 1.0; + else if (state == Qt::TouchPointReleased) + touchPoint.pressure = 0.0; + + // Set position + CGPoint location = [touch locationInView:self]; + touchPoint.area = QRectF(location.x, location.y, 0, 0); + QSize viewSize = fromCGRect(self.frame).size(); + touchPoint.normalPosition = QPointF(location.x / viewSize.width(), location.y / viewSize.height()); + } +} - // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); +- (void) sendTouchEventWithTimestamp:(ulong)timeStamp +{ + // Send touch event synchronously + QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, + iosIntegration->touchDevice(), m_qioswindow->touchPoints()); + QWindowSystemInterface::flushWindowSystemEvents(); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); + + // Transfer focus to the touched window: if (window != QGuiApplication::focusWindow()) m_qioswindow->requestActivateWindow(); - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; + // Track Cocoa touch id to Qt touch id. The UITouch pointer is constant + // for the touch duration. + QHash &activeTouches = m_qioswindow->activeTouches(); + QList &touchPoints = m_qioswindow->touchPoints(); + for (UITouch *touch in touches) + activeTouches.insert(touch, m_qioswindow->touchId()++); + + // Create new touch points if needed. + int newTouchPointsNeeded = m_qioswindow->touchId() - touchPoints.count(); + for (int i = 0; i < newTouchPointsNeeded; ++i) { + QWindowSystemInterface::TouchPoint touchPoint; + touchPoint.id = touchPoints.count(); // id is the index in the touchPoints list. + touchPoints.append(touchPoint); + } + + [self updateTouchList:touches withState:Qt::TouchPointPressed]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; + [self updateTouchList:touches withState:Qt::TouchPointMoved]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; + [self updateTouchList:touches withState:Qt::TouchPointReleased]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + + // Remove ended touch points from the active set (event processing has completed at this point) + QHash &activeTouches = m_qioswindow->activeTouches(); + for (UITouch *touch in touches) { + int id = activeTouches.take(touch); + + // If this touch is the most recent touch we can reuse its id + if (id == m_qioswindow->touchId() - 1) + --m_qioswindow->touchId(); + } + + // Reset the touch id when there are no more active touches + if (activeTouches.isEmpty()) + m_qioswindow->touchId() = 0; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; + Q_UNUSED(touches) // ### can a subset of the active touches be cancelled? + + // Clear current touch points + m_qioswindow->activeTouches().clear(); + m_qioswindow->touchId() = 0; + + // Send cancel touch event synchronously + QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(event.timestamp * 1000), iosIntegration->touchDevice()); + QWindowSystemInterface::flushWindowSystemEvents(); } @synthesize autocapitalizationType; @@ -236,6 +319,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_touchId(0) , m_requestedGeometry(QPlatformWindow::geometry()) , m_devicePixelRatio(1.0) { -- cgit v1.2.3 From 38e6d5a91588bfe823ff6bcb19bd356965d328f7 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 25 Jan 2013 11:49:34 +0100 Subject: iOS: add QIOSWindow::windowLevel() to simplify window stacking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adding modal windows into the mix, raiseOrLower became even more messy to write. So do it the usual way instead, and add a windowLevel variable to each QIOSWindow that we can sort on. The code becomes more readable, and we can handle more window types correctly. Change-Id: I348352473a7d8cf9909c17c1b074b2fe3fab9819 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 ++- src/plugins/platforms/ios/qioswindow.mm | 42 +++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b3a94a8d0e..2d7c4c9103 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -89,10 +89,11 @@ private: int m_touchId; QRect m_requestedGeometry; - + int m_windowLevel; qreal m_devicePixelRatio; void raiseOrLower(bool raise); + void updateWindowLevel(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 91e75bc660..4aa6b8a24e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -321,6 +321,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_touchId(0) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_windowLevel(0) , m_devicePixelRatio(1.0) { if (isQtApplication()) @@ -355,6 +356,7 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: if (visible) { + updateWindowLevel(); requestActivateWindow(); } else { // Activate top-most visible QWindow: @@ -421,10 +423,8 @@ void QIOSWindow::requestActivateWindow() void QIOSWindow::raiseOrLower(bool raise) { - // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure - // that window flags (staysOnTop, popup) are respected. This function assumes that all - // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at - // the same level: + // Re-insert m_view at the correct index among its sibling views + // (QWindows) according to their current m_windowLevel: if (!isQtApplication()) return; @@ -432,14 +432,12 @@ void QIOSWindow::raiseOrLower(bool raise) if (subviews.count == 1) return; - const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog; - bool thisWindowIsTop = topFlag & window()->flags(); - for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = static_cast([subviews objectAtIndex:i]); - bool otherWindowIsTop = topFlag & view.qwindow->flags(); - if ((raise && (thisWindowIsTop || !otherWindowIsTop)) - || (!raise && (thisWindowIsTop && !otherWindowIsTop))) { + if (view.hidden || view == m_view) + continue; + int level = static_cast(view.qwindow->handle())->m_windowLevel; + if (m_windowLevel > level || (raise && m_windowLevel == level)) { [m_view.superview insertSubview:m_view aboveSubview:view]; return; } @@ -447,6 +445,30 @@ void QIOSWindow::raiseOrLower(bool raise) [m_view.superview insertSubview:m_view atIndex:0]; } +void QIOSWindow::updateWindowLevel() +{ + Qt::WindowType type = static_cast(int(window()->flags() & Qt::WindowType_Mask)); + + if (type == Qt::ToolTip) + m_windowLevel = 120; + else if (window()->flags() & Qt::WindowStaysOnTopHint) + m_windowLevel = 100; + else if (window()->isModal()) + m_windowLevel = 30; + else if (type & Qt::Popup & ~Qt::Window) + m_windowLevel = 20; + else if (type == Qt::Tool) + m_windowLevel = 10; + else + m_windowLevel = 0; + + // A window should be in at least the same m_windowLevel as its parent: + QWindow *transientParent = window()->transientParent(); + QIOSWindow *transientParentWindow = transientParent ? static_cast(transientParent->handle()) : 0; + if (transientParentWindow) + m_windowLevel = qMax(transientParentWindow->m_windowLevel, m_windowLevel); +} + void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { // Keep the status bar in sync with content orientation. This will ensure -- cgit v1.2.3 From 58415530aacc5ef92f0076f7dff04d4f5074c4da Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 25 Jan 2013 11:00:54 +0100 Subject: iOS: avoid activating modally blocked windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the user cannot activate a window that is modally shaddowed. Change-Id: Ib92be319d017460bbc1ef63ad7556cb4758dfa6c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2d7c4c9103..31fd8d3185 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -94,6 +94,7 @@ private: void raiseOrLower(bool raise); void updateWindowLevel(); + bool blockedByModal(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4aa6b8a24e..9bc2541715 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -345,6 +345,12 @@ QIOSWindow::~QIOSWindow() [m_view release]; } +bool QIOSWindow::blockedByModal() +{ + QWindow *modalWindow = QGuiApplication::modalWindow(); + return modalWindow && modalWindow != window(); +} + void QIOSWindow::setVisible(bool visible) { QPlatformWindow::setVisible(visible); @@ -355,8 +361,16 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: - if (visible) { + if (visible) updateWindowLevel(); + + if (blockedByModal()) { + if (visible) + raise(); + return; + } + + if (visible) { requestActivateWindow(); } else { // Activate top-most visible QWindow: @@ -415,6 +429,9 @@ void QIOSWindow::requestActivateWindow() // Note that several windows can be active at the same time if they exist in the same // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: + if (blockedByModal()) + return; + raise(); QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); static_cast(context)->focusViewChanged(m_view); -- cgit v1.2.3 From 60685407c208466c67830744808b8a902bd2377b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 30 Jan 2013 20:31:06 +0100 Subject: iOS: Enable retina resolution for styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QStyle code uses the global qApp->devicePixelRatio(), which queries the screen, not the window. Implement QIOSScreen::devicePixelRatio(). Change-Id: I0091e5793f8d07ab7a46b6de443edd9457dcff85 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index bbc3eb7432..40c7a3ccf7 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -64,6 +64,7 @@ public: QImage::Format format() const; QSizeF physicalSize() const; QDpi logicalDpi() const; + qreal devicePixelRatio() const; Qt::ScreenOrientation nativeOrientation() const; Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f3585407ce..5cee5a3362 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -183,6 +183,11 @@ QDpi QIOSScreen::logicalDpi() const return QDpi(72, 72); } +qreal QIOSScreen::devicePixelRatio() const +{ + return [m_uiScreen scale]; +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { return Qt::PortraitOrientation; -- cgit v1.2.3 From 4993d3ed6bff681889faec3711fffa2400b7a601 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 6 Feb 2013 11:34:14 +0100 Subject: iOS: implement QIOSWindow::winId() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I3dd7accae43bcf7d4d6dfd8b272ab65d67bd935c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioscontext.mm | 3 ++- src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qioswindow.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index dc431b57dd..d3966964e0 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -160,7 +160,8 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) { glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); - CAEAGLLayer *layer = static_cast(platformWindow->nativeView().layer); + UIView *view = reinterpret_cast(platformWindow->winId()); + CAEAGLLayer *layer = static_cast(view.layer); [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth); diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index cbe2717c34..c5fef243ce 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -158,7 +158,7 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind QIOSWindow *platformWindow = static_cast(window->handle()); if (lowerCaseResource == "uiview") - return platformWindow->nativeView(); + return reinterpret_cast(platformWindow->winId()); return 0; } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 31fd8d3185..7a0224dab0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -76,7 +76,7 @@ public: int effectiveWidth() const; int effectiveHeight() const; - UIView *nativeView() const { return m_view; } + WId winId() const { return WId(m_view); }; QList &touchPoints() { return m_touchPoints; } QHash &activeTouches() { return m_activeTouches; } -- cgit v1.2.3 From 029029fa97b8f11b2384040f12dc1ca6b31e03a6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 4 Feb 2013 12:42:59 +0100 Subject: iOS: QIOSWindow::setParent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1a413d898d10b55a4d0653eae719f5bd909a01ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 7a0224dab0..cefb6f9388 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -65,6 +65,7 @@ public: void setGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); + void setParent(const QPlatformWindow *window); void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9bc2541715..e95f392655 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -324,9 +324,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_windowLevel(0) , m_devicePixelRatio(1.0) { - if (isQtApplication()) - [rootViewController().view addSubview:m_view]; - + setParent(parent()); setWindowState(window->windowState()); // Retina support: get screen scale factor and set it in the content view. @@ -424,6 +422,16 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::setParent(const QPlatformWindow *parentWindow) +{ + if (parentWindow) { + UIView *parentView = reinterpret_cast(parentWindow->winId()); + [parentView addSubview:m_view]; + } else if (isQtApplication()) { + [rootViewController().view addSubview:m_view]; + } +} + void QIOSWindow::requestActivateWindow() { // Note that several windows can be active at the same time if they exist in the same -- cgit v1.2.3 From 3eeb388b429242da8bfd9b9dc70660980f62090a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 8 Feb 2013 13:36:24 +0100 Subject: iOS: Skip flushing child windows in QIOSBackingStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We skip flushing raster-based child windows, to avoid the extra cost of copying from the parent FBO into the child FBO. Since the child is already drawn inside the parent FBO, it will become visible when flushing the parent. The only case we end up not supporting is if the child window overlaps a sibling window that's draws using a separate QOpenGLContext. Change-Id: Ib10414f4494747e5fe67f84b06575fe16ffddf96 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 5ee048cb2f..566ff3a672 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -92,6 +92,13 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin Q_UNUSED(region); Q_UNUSED(offset); + if (window != this->window()) { + // We skip flushing raster-based child windows, to avoid the extra cost of copying from the + // parent FBO into the child FBO. Since the child is already drawn inside the parent FBO, it + // will become visible when flushing the parent. The only case we end up not supporting is if + // the child window overlaps a sibling window that's draws using a separate QOpenGLContext. + return; + } m_context->swapBuffers(window); } -- cgit v1.2.3 From 11d50be6dd8bbfe695408ccd011cbf63f1b4324a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 13:09:08 +0100 Subject: iOS: Set touch point position in screen coords. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the position was set in window coordinates, which would break for non-fullscreen windows. Change-Id: Iefa2f590c6d62b09fc3e7fe60a882c1acd33e029 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 2 ++ src/plugins/platforms/ios/qiosglobal.mm | 10 ++++++++++ src/plugins/platforms/ios/qioswindow.mm | 11 +++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 3fe426c901..cd265c0603 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -54,6 +54,8 @@ QIOSViewController *rootViewController(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); +CGPoint toCGPoint(const QPoint &point); +QPoint fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); QRect fromPortraitToPrimary(const QRect &rect); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 712968d216..4657b73a10 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -75,6 +75,16 @@ QRect fromCGRect(const CGRect &rect) return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } +CGPoint toCGPoint(const QPoint &point) +{ + return CGPointMake(point.x(), point.y()); +} + +QPoint fromCGPoint(const CGPoint &point) +{ + return QPoint(point.x, point.y); +} + Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) { Qt::ScreenOrientation qtOrientation; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e95f392655..e4fb5e2e1c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -177,10 +177,13 @@ touchPoint.pressure = 0.0; // Set position - CGPoint location = [touch locationInView:self]; - touchPoint.area = QRectF(location.x, location.y, 0, 0); - QSize viewSize = fromCGRect(self.frame).size(); - touchPoint.normalPosition = QPointF(location.x / viewSize.width(), location.y / viewSize.height()); + QRect viewGeometry = fromCGRect(self.frame); + QPoint touchViewLocation = fromCGPoint([touch locationInView:self]); + QPoint touchScreenLocation = touchViewLocation + viewGeometry.topLeft(); + touchPoint.area = QRectF(touchScreenLocation , QSize(0, 0)); + + CGSize fullscreenSize = self.window.rootViewController.view.bounds.size; + touchPoint.normalPosition = QPointF(touchScreenLocation.x() / fullscreenSize.width, touchScreenLocation.y() / fullscreenSize.height); } } -- cgit v1.2.3 From c75bc5b532479e8dbe6b7f07dcc5f9fcc915f5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 14:08:09 +0100 Subject: iOS: Don't crash on landscape mode startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromPortraitToPrimary is called from the QIOSScreen constructor. This is probably to early to call QGuiApplication functions. Change-Id: I882304fd641df13dc530491990245ba9ad495377 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 +++- src/plugins/platforms/ios/qiosglobal.mm | 4 ++-- src/plugins/platforms/ios/qiosinputcontext.mm | 2 +- src/plugins/platforms/ios/qiosscreen.mm | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index cd265c0603..3be9f8bb21 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE +class QPlatformScreen; + bool isQtApplication(); QIOSViewController *rootViewController(); @@ -58,7 +60,7 @@ CGPoint toCGPoint(const QPoint &point); QPoint fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); -QRect fromPortraitToPrimary(const QRect &rect); +QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 4657b73a10..5860078372 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -131,11 +131,11 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } -QRect fromPortraitToPrimary(const QRect &rect) +QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen) { // UIScreen is always in portrait. Use this function to convert CGRects // aligned with UIScreen into whatever is the current orientation of QScreen. - QRect geometry = QGuiApplication::primaryScreen()->handle()->geometry(); + QRect geometry = screen->geometry(); return geometry.width() < geometry.height() ? rect : QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width()); } diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index c0ff3b2531..1d3ab12de9 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -83,7 +83,7 @@ CGRect frame; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; - m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame)); + m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame), QGuiApplication::primaryScreen()->handle()); m_context->emitKeyboardRectChanged(); BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5cee5a3362..3265ed8e37 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -224,7 +224,7 @@ void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) // Switching portrait/landscape means swapping width/height (and adjusting x/y): m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); - m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame)); + m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame), this); QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -- cgit v1.2.3 From fecc1554080aa58167b8cc7018b2ccd037d05cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 19:45:48 +0100 Subject: iOS: Enable autorotate on startup. The qobject_cast to QGuiAppplication will always fail at startup since QGuiApplication is not ready yet. Return YES in that case. Allowed orientations can then be controlled by setting "Supported Interface Orientations" in Xcode or the Info.plist file. Change-Id: Ifd86bbcedabc716e63563bbb7cb0c1c6833fd6c7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index c85058743c..c52bfd7345 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -63,7 +63,7 @@ if (QGuiApplication *guiApp = qobject_cast(qApp)) return !guiApp->primaryScreen()->orientationUpdateMask(); else - return NO; + return YES; // Startup case: QGuiApplication is not ready yet. // FIXME: Investigate a proper Qt API for auto-rotation and orientation locking } -- cgit v1.2.3 From aa5528b050472d1d1097e2665fb346232cbfa7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 15 Feb 2013 11:25:39 +0100 Subject: iOS: Implement socket notifiers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create the QCFSocketNotifier class in platform support which contains shared socket notifier support for the Cocoa and iOS plugins. Remove the old code from the Cocoa plugin. The Cocoa code had one QCocoaEventDispatcher-specific call: maybeCancelWaitForMoreEvents. Create a forwarding function that is passed to QCFSocketNotifier. Change-Id: Ibf9bd4745ba4f577a55f13d0cc00f5ae04447405 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- .../platforms/cocoa/qcocoaeventdispatcher.h | 12 +- .../platforms/cocoa/qcocoaeventdispatcher.mm | 193 ++------------------- src/plugins/platforms/ios/qioseventdispatcher.h | 3 + src/plugins/platforms/ios/qioseventdispatcher.mm | 10 +- 4 files changed, 24 insertions(+), 194 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index f63ac0d205..93476ee1b4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -93,6 +93,7 @@ #include #include #include +#include #include @@ -132,16 +133,9 @@ public: void wakeUp(); void interrupt(); void flush(); -}; -struct MacSocketInfo { - MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {} - CFSocketRef socket; - CFRunLoopSourceRef runloop; - QObject *readNotifier; - QObject *writeNotifier; + friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; -typedef QHash MacSocketHash; class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate { @@ -183,7 +177,7 @@ public: void maybeCancelWaitForMoreEvents(); void ensureNSAppInitialized(); - MacSocketHash macSockets; + QCFSocketNotifier cfSocketNotifier; QList queuedUserInputEvents; // NSEvent * CFRunLoopSourceRef postedEventsSource; CFRunLoopObserverRef waitingObserver; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 987600c6b4..ed4f8cd1fb 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -270,58 +270,6 @@ QCocoaEventDispatcher::registeredTimers(QObject *object) const return d->timerInfoList.registeredTimers(object); } -/************************************************************************** - Socket Notifiers - *************************************************************************/ -void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef, - const void *, void *info) { - QCocoaEventDispatcherPrivate *const eventDispatcher - = static_cast(info); - int nativeSocket = CFSocketGetNative(s); - MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket); - QEvent notifierEvent(QEvent::SockAct); - - // There is a race condition that happen where we disable the notifier and - // the kernel still has a notification to pass on. We then get this - // notification after we've successfully disabled the CFSocket, but our Qt - // notifier is now gone. The upshot is we have to check the notifier - // everytime. - if (callbackType == kCFSocketReadCallBack) { - if (socketInfo->readNotifier) - QGuiApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); - } else if (callbackType == kCFSocketWriteCallBack) { - if (socketInfo->writeNotifier) - QGuiApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); - } - - eventDispatcher->maybeCancelWaitForMoreEvents(); -} - -/* - Adds a loop source for the given socket to the current run loop. -*/ -CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket) -{ - CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0); - if (!loopSource) - return 0; - - CFRunLoopAddSource(mainRunLoop(), loopSource, kCFRunLoopCommonModes); - return loopSource; -} - -/* - Removes the loop source for the given socket from the current run loop. -*/ -void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop) -{ - Q_ASSERT(runloop); - CFRunLoopRemoveSource(mainRunLoop(), runloop, kCFRunLoopCommonModes); - CFSocketDisableCallBacks(socket, kCFSocketReadCallBack); - CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack); - CFRunLoopSourceInvalidate(runloop); -} - /* Register a QSocketNotifier with the mac event system by creating a CFSocket with with a read/write callback. @@ -331,130 +279,14 @@ void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSource */ void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { - Q_ASSERT(notifier); - int nativeSocket = notifier->socket(); - int type = notifier->type(); -#ifndef QT_NO_DEBUG - if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { - qWarning("QSocketNotifier: Internal error"); - return; - } else if (notifier->thread() != thread() - || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); - return; - } -#endif - Q_D(QCocoaEventDispatcher); - - if (type == QSocketNotifier::Exception) { - qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); - return; - } - - // Check if we have a CFSocket for the native socket, create one if not. - MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); - if (!socketInfo) { - socketInfo = new MacSocketInfo(); - - // Create CFSocket, specify that we want both read and write callbacks (the callbacks - // are enabled/disabled later on). - const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; - CFSocketContext context = {0, d, 0, 0, 0}; - socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); - if (CFSocketIsValid(socketInfo->socket) == false) { - qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); - return; - } - - CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket); - flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write - flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation - CFSocketSetSocketFlags(socketInfo->socket, flags); - - // Add CFSocket to runloop. - if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) { - qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop"); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - return; - } - - // Disable both callback types by default. This must be done after - // we add the CFSocket to the runloop, or else these calls will have - // no effect. - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - - d->macSockets.insert(nativeSocket, socketInfo); - } - - // Increment read/write counters and select enable callbacks if necessary. - if (type == QSocketNotifier::Read) { - Q_ASSERT(socketInfo->readNotifier == 0); - socketInfo->readNotifier = notifier; - CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - } else if (type == QSocketNotifier::Write) { - Q_ASSERT(socketInfo->writeNotifier == 0); - socketInfo->writeNotifier = notifier; - CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - } + d->cfSocketNotifier.registerSocketNotifier(notifier); } -/* - Unregister QSocketNotifer. The CFSocket correspoding to this notifier is - removed from the runloop of this is the last notifier that users - that CFSocket. -*/ void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { - Q_ASSERT(notifier); - int nativeSocket = notifier->socket(); - int type = notifier->type(); -#ifndef QT_NO_DEBUG - if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { - qWarning("QSocketNotifier: Internal error"); - return; - } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); - return; - } -#endif - Q_D(QCocoaEventDispatcher); - - if (type == QSocketNotifier::Exception) { - qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); - return; - } - MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); - if (!socketInfo) { - qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier"); - return; - } - - // Decrement read/write counters and disable callbacks if necessary. - if (type == QSocketNotifier::Read) { - Q_ASSERT(notifier == socketInfo->readNotifier); - socketInfo->readNotifier = 0; - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - } else if (type == QSocketNotifier::Write) { - Q_ASSERT(notifier == socketInfo->writeNotifier); - socketInfo->writeNotifier = 0; - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - } - - // Remove CFSocket from runloop if this was the last QSocketNotifier. - if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) { - if (CFSocketIsValid(socketInfo->socket)) - qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); - CFRunLoopSourceInvalidate(socketInfo->runloop); - CFRelease(socketInfo->runloop); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - delete socketInfo; - d->macSockets.remove(nativeSocket); - } + d->cfSocketNotifier.unregisterSocketNotifier(notifier); } bool QCocoaEventDispatcher::hasPendingEvents() @@ -940,11 +772,19 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() { } +void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher) +{ + static_cast(eventDispatcher)->d_func()->maybeCancelWaitForMoreEvents(); +} + QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent) : QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent) { Q_D(QCocoaEventDispatcher); + d->cfSocketNotifier.setHostEventDispatcher(this); + d->cfSocketNotifier.setMaybeCancelWaitForMoreEventsCallback(qt_mac_maybeCancelWaitForMoreEventsForwarder); + // keep our sources running when modal loops are running CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode); @@ -1127,17 +967,8 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher() [nsevent release]; } - // Remove CFSockets from the runloop. - for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) { - MacSocketInfo *socketInfo = (*it); - if (CFSocketIsValid(socketInfo->socket)) { - qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); - CFRunLoopSourceInvalidate(socketInfo->runloop); - CFRelease(socketInfo->runloop); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - } - } + d->cfSocketNotifier.removeSocketNotifiers(); + CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes); CFRelease(d->postedEventsSource); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 88d5127855..53a75618ce 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -78,6 +78,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -116,6 +117,8 @@ private: QTimerInfoList m_timerInfoList; CFRunLoopTimerRef m_runLoopTimerRef; + QCFSocketNotifier m_cfSocketNotifier; + void processPostedEvents(); void maybeStartCFRunLoopTimer(); void maybeStopCFRunLoopTimer(); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f6f60387d4..e9bf039047 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -155,6 +155,8 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) , m_interrupted(false) , m_runLoopTimerRef(0) { + m_cfSocketNotifier.setHostEventDispatcher(this); + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); @@ -184,6 +186,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher() maybeStopCFRunLoopTimer(); CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); CFRelease(m_blockingTimerRunLoopSource); + + m_cfSocketNotifier.removeSocketNotifiers(); } bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) @@ -215,14 +219,12 @@ bool QIOSEventDispatcher::hasPendingEvents() void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(notifier); + m_cfSocketNotifier.registerSocketNotifier(notifier); } void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(notifier); + m_cfSocketNotifier.unregisterSocketNotifier(notifier); } void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) -- cgit v1.2.3 From 76e4b6d2f24f7f88250db34fb03838a30fc43eec Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 14:41:12 +0100 Subject: iOS: Add QIOSIntegration::hasCapability function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the missing override, and report that we support OpenGL (and multiple windows). Change-Id: If95138cab9099b547d12d3dfed008bd63b6d2acf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ src/plugins/platforms/ios/qiosintegration.mm | 12 ++++++++++++ 2 files changed, 14 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 054933ea44..329a0a3d9b 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -54,6 +54,8 @@ public: QIOSIntegration(); ~QIOSIntegration(); + bool hasCapability(Capability cap) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index c5fef243ce..adb33da344 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -84,6 +84,18 @@ QIOSIntegration::~QIOSIntegration() delete m_touchDevice; } +bool QIOSIntegration::hasCapability(Capability cap) const +{ + switch (cap) { + case OpenGL: + return true; + case MultipleWindows: + return true; + default: + return QPlatformIntegration::hasCapability(cap); + } +} + QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform window"; -- cgit v1.2.3 From 75a7dc7a574e0c949214feecc711e385f38060e9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 14:59:30 +0100 Subject: iOS: Remove debug output noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This debug information is not needed anymore, and only causes noise when trying to debug other stuff. Change-Id: I076826e251b84a3883e63aa7669f6e1bb55a0d1f Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index adb33da344..c7541c3e38 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -98,14 +98,12 @@ bool QIOSIntegration::hasCapability(Capability cap) const QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { - qDebug() << __FUNCTION__ << "Creating platform window"; return new QIOSWindow(window); } // Used when the QWindow's surface type is set by the client to QSurface::RasterSurface QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { - qDebug() << __FUNCTION__ << "Creating platform backingstore"; return new QIOSBackingStore(window); } @@ -113,7 +111,6 @@ QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *wind QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); - qDebug() << __FUNCTION__ << "Creating platform opengl context"; return new QIOSContext(context); } -- cgit v1.2.3 From dedec0b305baabe894e53bf3b70560cec68e3464 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 27 Feb 2013 17:08:03 +0100 Subject: EGLFS: Enablers for Android plugin These are some changes that are needed to make the Android plugin as a subclass of the EGLFS plugin. Change-Id: I7c77931f311d8a07f9292715d2abc256c5d552d8 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/eglfs/eglfs.pri | 44 +++++++++++++++++++++++ src/plugins/platforms/eglfs/eglfs.pro | 46 ++---------------------- src/plugins/platforms/eglfs/qeglfscontext.cpp | 2 +- src/plugins/platforms/eglfs/qeglfshooks_stub.cpp | 2 ++ src/plugins/platforms/eglfs/qeglfsintegration.h | 3 ++ src/plugins/platforms/eglfs/qeglfswindow.cpp | 28 +++++++++++---- src/plugins/platforms/eglfs/qeglfswindow.h | 4 +++ 7 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 src/plugins/platforms/eglfs/eglfs.pri (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri new file mode 100644 index 0000000000..eb66e17479 --- /dev/null +++ b/src/plugins/platforms/eglfs/eglfs.pri @@ -0,0 +1,44 @@ +QT += core-private gui-private platformsupport-private + +#DEFINES += QEGL_EXTRA_DEBUG + +#Avoid X11 header collision +DEFINES += MESA_EGL_NO_X11_HEADERS + +#To test the hooks on x11 (xlib), comment the above define too +#EGLFS_PLATFORM_HOOKS_SOURCES += qeglfshooks_x11.cpp +#LIBS += -lX11 + +SOURCES += $$PWD/qeglfsintegration.cpp \ + $$PWD/qeglfswindow.cpp \ + $$PWD/qeglfsbackingstore.cpp \ + $$PWD/qeglfsscreen.cpp \ + $$PWD/qeglfshooks_stub.cpp \ + $$PWD/qeglfscursor.cpp \ + $$PWD/qeglfscontext.cpp + +HEADERS += $$PWD/qeglfsintegration.h \ + $$PWD/qeglfswindow.h \ + $$PWD/qeglfsbackingstore.h \ + $$PWD/qeglfsscreen.h \ + $$PWD/qeglfscursor.h \ + $$PWD/qeglfshooks.h \ + $$PWD/qeglfscontext.h + +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +INCLUDEPATH += $$PWD + +!isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) { + HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS + SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES + LIBS += $$EGLFS_PLATFORM_HOOKS_LIBS + DEFINES += EGLFS_PLATFORM_HOOKS +} + +CONFIG += egl qpa/genericunixfontdatabase + +RESOURCES += $$PWD/cursor.qrc + +OTHER_FILES += \ + $$PWD/eglfs.json diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 45059a9cb9..8827f7680c 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -4,48 +4,6 @@ PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin load(qt_plugin) -QT += core-private gui-private platformsupport-private +SOURCES += $$PWD/main.cpp -#DEFINES += QEGL_EXTRA_DEBUG - -#Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS - -#To test the hooks on x11 (xlib), comment the above define too -#EGLFS_PLATFORM_HOOKS_SOURCES += qeglfshooks_x11.cpp -#LIBS += -lX11 - -SOURCES = main.cpp \ - qeglfsintegration.cpp \ - qeglfswindow.cpp \ - qeglfsbackingstore.cpp \ - qeglfsscreen.cpp \ - qeglfshooks_stub.cpp \ - qeglfscursor.cpp \ - qeglfscontext.cpp - -HEADERS = qeglfsintegration.h \ - qeglfswindow.h \ - qeglfsbackingstore.h \ - qeglfsscreen.h \ - qeglfscursor.h \ - qeglfshooks.h \ - qeglfscontext.h - -QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF - -INCLUDEPATH += $$PWD - -!isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) { - HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS - SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES - LIBS += $$EGLFS_PLATFORM_HOOKS_LIBS - DEFINES += EGLFS_PLATFORM_HOOKS -} - -CONFIG += egl qpa/genericunixfontdatabase - -RESOURCES += cursor.qrc - -OTHER_FILES += \ - eglfs.json +include(eglfs.pri) diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 6bd0d35191..51439646c6 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLenum eglApi) - : QEGLPlatformContext(format, share, display, QEglFSIntegration::chooseConfig(display, format), eglApi) + : QEGLPlatformContext(QEglFSHooks::hooks()->surfaceFormatFor(format), share, display, QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)), eglApi) { } diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index 5298eb47ea..8200fa70b2 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -246,12 +246,14 @@ QEglFSCursor *QEglFSHooks::createCursor(QEglFSScreen *screen) const void QEglFSHooks::waitForVSync() const { +#if defined(FBIO_WAITFORVSYNC) static const bool forceSync = qgetenv("QT_QPA_EGLFS_FORCEVSYNC").toInt(); if (forceSync && framebuffer != -1) { int arg = 0; if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1) qWarning("Could not wait for vsync."); } +#endif } #ifndef EGLFS_PLATFORM_HOOKS diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index e048c5d310..5427137463 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -74,8 +74,11 @@ public: void *nativeResourceForIntegration(const QByteArray &resource); void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); + QPlatformScreen *screen() const { return mScreen; } static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); + EGLDisplay display() const { return mDisplay; } + private: EGLDisplay mDisplay; QAbstractEventDispatcher *mEventDispatcher; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 4a0e2a9a7d..68cef6253e 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -84,11 +84,28 @@ void QEglFSWindow::create() EGLDisplay display = (static_cast(window()->screen()->handle()))->display(); QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat()); - EGLConfig config = QEglFSIntegration::chooseConfig(display, platformFormat); + m_config = QEglFSIntegration::chooseConfig(display, platformFormat); + m_format = q_glFormatFromConfig(display, m_config); + resetSurface(); +} + +void QEglFSWindow::invalidateSurface() +{ + // Native surface has been deleted behind our backs + m_window = 0; + if (m_surface != 0) { + EGLDisplay display = (static_cast(window()->screen()->handle()))->display(); + eglDestroySurface(display, m_surface); + m_surface = 0; + } +} + +void QEglFSWindow::resetSurface() +{ + EGLDisplay display = static_cast(screen())->display(); - m_format = q_glFormatFromConfig(display, config); m_window = QEglFSHooks::hooks()->createNativeWindow(QEglFSHooks::hooks()->screenSize(), m_format); - m_surface = eglCreateWindowSurface(display, config, m_window, NULL); + m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL); if (m_surface == EGL_NO_SURFACE) { EGLint error = eglGetError(); eglTerminate(display); @@ -99,7 +116,7 @@ void QEglFSWindow::create() void QEglFSWindow::destroy() { if (m_surface) { - EGLDisplay display = (static_cast(window()->screen()->handle()))->display(); + EGLDisplay display = static_cast(screen())->display(); eglDestroySurface(display, m_surface); m_surface = 0; } @@ -114,9 +131,8 @@ void QEglFSWindow::setGeometry(const QRect &) { // We only support full-screen windows QRect rect(screen()->availableGeometry()); - QWindowSystemInterface::handleGeometryChange(window(), rect); - QPlatformWindow::setGeometry(rect); + QWindowSystemInterface::handleGeometryChange(window(), rect); } void QEglFSWindow::setWindowState(Qt::WindowState) diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index 706bbddd22..a351b4a6f4 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -65,10 +65,14 @@ public: void create(); void destroy(); + virtual void invalidateSurface(); + virtual void resetSurface(); + private: WId m_winid; EGLSurface m_surface; EGLNativeWindowType m_window; + EGLConfig m_config; QSurfaceFormat m_format; }; QT_END_NAMESPACE -- cgit v1.2.3 From 439002cddeb32766ea9806ac8b5cf9a973ed0f13 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Mon, 25 Feb 2013 19:45:02 -0300 Subject: BlackBerry: handle window state navigator events Change-Id: I925b1c53c5e251111469501056ee162a23e36faf Reviewed-by: Kevin Krammer Reviewed-by: Sean Harmer --- src/plugins/platforms/qnx/qqnxbpseventfilter.cpp | 20 +++++++++++ src/plugins/platforms/qnx/qqnxintegration.cpp | 2 ++ .../platforms/qnx/qqnxnavigatoreventhandler.cpp | 6 ++++ .../platforms/qnx/qqnxnavigatoreventhandler.h | 2 ++ src/plugins/platforms/qnx/qqnxscreen.cpp | 41 ++++++++++++++++++---- src/plugins/platforms/qnx/qqnxscreen.h | 3 ++ 6 files changed, 67 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp index 2d19537896..542833473d 100644 --- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp +++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp @@ -210,6 +210,26 @@ bool QQnxBpsEventFilter::handleNavigatorEvent(bps_event_t *event) m_navigatorEventHandler->handleExit(); break; + case NAVIGATOR_WINDOW_STATE: { + qBpsEventFilterDebug() << Q_FUNC_INFO << "WINDOW STATE event"; + const navigator_window_state_t state = navigator_event_get_window_state(event); + const QByteArray id(navigator_event_get_groupid(event)); + + switch (state) { + case NAVIGATOR_WINDOW_FULLSCREEN: + m_navigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowFullScreen); + break; + case NAVIGATOR_WINDOW_THUMBNAIL: + m_navigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowMinimized); + break; + case NAVIGATOR_WINDOW_INVISIBLE: + m_navigatorEventHandler->handleWindowGroupDeactivated(id); + break; + } + + break; + } + case NAVIGATOR_WINDOW_ACTIVE: { qBpsEventFilterDebug() << Q_FUNC_INFO << "WINDOW ACTIVE event"; const QByteArray id(navigator_event_get_groupid(event)); diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index f3cfdab9c6..2d5c2e54e7 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -495,6 +495,8 @@ void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary) QObject::connect(m_navigatorEventHandler, SIGNAL(rotationChanged(int)), screen, SLOT(setRotation(int))); QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupActivated(QByteArray)), screen, SLOT(activateWindowGroup(QByteArray))); QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupDeactivated(QByteArray)), screen, SLOT(deactivateWindowGroup(QByteArray))); + QObject::connect(m_navigatorEventHandler, SIGNAL(windowGroupStateChanged(QByteArray,Qt::WindowState)), + screen, SLOT(windowGroupStateChanged(QByteArray,Qt::WindowState))); } void QQnxIntegration::removeDisplay(QQnxScreen *screen) diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp index 19fa9c5a9f..d561482b47 100644 --- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp @@ -106,4 +106,10 @@ void QQnxNavigatorEventHandler::handleWindowGroupDeactivated(const QByteArray &i Q_EMIT windowGroupDeactivated(id); } +void QQnxNavigatorEventHandler::handleWindowGroupStateChanged(const QByteArray &id, Qt::WindowState state) +{ + qNavigatorEventHandlerDebug() << Q_FUNC_INFO << id; + Q_EMIT windowGroupStateChanged(id, state); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h index 2068163473..cce3921a27 100644 --- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h +++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h @@ -58,11 +58,13 @@ public: void handleExit(); void handleWindowGroupActivated(const QByteArray &id); void handleWindowGroupDeactivated(const QByteArray &id); + void handleWindowGroupStateChanged(const QByteArray &id, Qt::WindowState state); Q_SIGNALS: void rotationChanged(int angle); void windowGroupActivated(const QByteArray &id); void windowGroupDeactivated(const QByteArray &id); + void windowGroupStateChanged(const QByteArray &id, Qt::WindowState state); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index fc8b3bb167..bd60c6b71d 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -551,6 +551,21 @@ void QQnxScreen::windowClosed(void *window) removeOverlayWindow(windowHandle); } +void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState state) +{ + qScreenDebug() << Q_FUNC_INFO; + + if (!rootWindow() || id != rootWindow()->groupName()) + return; + + QWindow * const window = topMostChildWindow(); + + if (!window) + return; + + QWindowSystemInterface::handleWindowStateChanged(window, state); +} + void QQnxScreen::activateWindowGroup(const QByteArray &id) { qScreenDebug() << Q_FUNC_INFO; @@ -558,13 +573,12 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id) if (!rootWindow() || id != rootWindow()->groupName()) return; - if (!m_childWindows.isEmpty()) { - // We're picking up the last window of the list here - // because this list is ordered by stacking order. - // Last window is effectively the one on top. - QWindow * const window = m_childWindows.last()->window(); - QWindowSystemInterface::handleWindowActivated(window); - } + QWindow * const window = topMostChildWindow(); + + if (!window) + return; + + QWindowSystemInterface::handleWindowActivated(window); } void QQnxScreen::deactivateWindowGroup(const QByteArray &id) @@ -586,4 +600,17 @@ QSharedPointer QQnxScreen::rootWindow() const return m_rootWindow; } +QWindow * QQnxScreen::topMostChildWindow() const +{ + if (!m_childWindows.isEmpty()) { + + // We're picking up the last window of the list here + // because this list is ordered by stacking order. + // Last window is effectively the one on top. + return m_childWindows.last()->window(); + } + + return 0; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index 39cd4159d1..41dc675599 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -101,6 +101,7 @@ public Q_SLOTS: void setRotation(int rotation); void newWindowCreated(void *window); void windowClosed(void *window); + void windowGroupStateChanged(const QByteArray &id, Qt::WindowState state); void activateWindowGroup(const QByteArray &id); void deactivateWindowGroup(const QByteArray &id); @@ -114,6 +115,8 @@ private: void addOverlayWindow(screen_window_t window); void removeOverlayWindow(screen_window_t window); + QWindow *topMostChildWindow() const; + screen_context_t m_screenContext; screen_display_t m_display; mutable QSharedPointer m_rootWindow; -- cgit v1.2.3 From 078b3419bd33031923c791f9286686d2babb1b61 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 28 Feb 2013 17:34:07 +0100 Subject: QGtk2Theme: use GtkSettings to fetch the icon theme name Change-Id: Ib486d65276512a94299650adfbf3d87108ae5845 Reviewed-by: Dmitry Shachnev Reviewed-by: Jens Bache-Wiig --- src/plugins/platformthemes/gtk2/qgtk2theme.cpp | 23 +++++++++++++++++++++++ src/plugins/platformthemes/gtk2/qgtk2theme.h | 2 ++ 2 files changed, 25 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp index 7bb538b888..b26ab94b83 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp @@ -41,6 +41,7 @@ #include "qgtk2theme.h" #include "qgtk2dialoghelpers.h" +#include #undef signals #include @@ -49,11 +50,33 @@ QT_BEGIN_NAMESPACE const char *QGtk2Theme::name = "gtk2"; +static QString gtkSetting(const gchar *propertyName) +{ + GtkSettings *settings = gtk_settings_get_default(); + gchararray value; + g_object_get(settings, propertyName, &value, NULL); + QString str = QString::fromUtf8(value); + g_free(value); + return str; +} + QGtk2Theme::QGtk2Theme() { gtk_init(0, 0); } +QVariant QGtk2Theme::themeHint(QPlatformTheme::ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::SystemIconThemeName: + return QVariant(gtkSetting("gtk-icon-theme-name")); + case QPlatformTheme::SystemIconFallbackThemeName: + return QVariant(gtkSetting("gtk-fallback-icon-theme")); + default: + return QGnomeTheme::themeHint(hint); + } +} + bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const { Q_UNUSED(type); diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.h b/src/plugins/platformthemes/gtk2/qgtk2theme.h index 6d8768dd8e..a351b5b738 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.h +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.h @@ -51,6 +51,8 @@ class QGtk2Theme : public QGnomeTheme public: QGtk2Theme(); + virtual QVariant themeHint(ThemeHint hint) const; + virtual bool usePlatformNativeDialog(DialogType type) const; virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; -- cgit v1.2.3 From c63e7f576609e90e7cb6d1b4c107182ae8c2d6c6 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 2 Mar 2013 22:29:48 +0200 Subject: Fix selection of fonts that require OpenType features HB_Face's supported_scripts[] expects HB_Script, so QChar::Script should be remapped via script_to_hbscript(). Change-Id: Ib068c35ab76567fe9a61da7d8ab01133a6f58bc0 Reviewed-by: Lars Knoll --- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index c1c906523f..6fdb10288a 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1883,8 +1883,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ // for scripts that do not require OpenType we should just look at the list of // supported writing systems in the font's OS/2 table. if (scriptRequiresOpenType(script)) { - HB_Face hbFace = few->harfbuzzFace(); - if (!hbFace || !hbFace->supported_scripts[script]) { + if (!few->supportsScript(QChar::Script(script))) { qWarning(" OpenType support missing for script\n"); delete few; return 0; -- cgit v1.2.3 From 97fcf3bc987a18f32233fea550eb4a5a22e2b822 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 4 Mar 2013 10:16:42 +0100 Subject: Introducing the Qt Android port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on the Necessitas project by Bogdan Vatra. Contributors to the Qt5 project: BogDan Vatra Eskil Abrahamsen Blomfeldt hjk Oswald Buddenhagen Paul Olav Tvete Robin Burchell Samuel Rødal Yoann Lopes The full history of the Qt5 port can be found in refs/old-heads/android, SHA-1 249ca9ca2c7d876b91b31df9434dde47f9065d0d Change-Id: Iff1a7b2dbb707c986f2639e65e39ed8f22430120 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/plugins/platforms/android/android.pro | 3 + src/plugins/platforms/android/opengl/opengl.pro | 30 + src/plugins/platforms/android/raster/raster.pro | 19 + src/plugins/platforms/android/src/android.json | 3 + .../platforms/android/src/androidjniclipboard.cpp | 120 +++ .../platforms/android/src/androidjniclipboard.h | 61 ++ .../platforms/android/src/androidjniinput.cpp | 480 ++++++++++++ .../platforms/android/src/androidjniinput.h | 59 ++ .../platforms/android/src/androidjnimain.cpp | 839 +++++++++++++++++++++ src/plugins/platforms/android/src/androidjnimain.h | 120 +++ .../platforms/android/src/androidjnimenu.cpp | 405 ++++++++++ src/plugins/platforms/android/src/androidjnimenu.h | 69 ++ .../android/src/androidplatformplugin.cpp | 66 ++ .../android/src/opengl/qandroidopenglcontext.cpp | 78 ++ .../android/src/opengl/qandroidopenglcontext.h | 68 ++ .../src/opengl/qandroidopenglplatformwindow.cpp | 72 ++ .../src/opengl/qandroidopenglplatformwindow.h | 73 ++ .../android/src/opengl/qeglfshooks_android.cpp | 132 ++++ .../src/qandroidassetsfileenginehandler.cpp | 288 +++++++ .../android/src/qandroidassetsfileenginehandler.h | 60 ++ .../platforms/android/src/qandroidinputcontext.cpp | 644 ++++++++++++++++ .../platforms/android/src/qandroidinputcontext.h | 130 ++++ .../android/src/qandroidplatformclipboard.cpp | 79 ++ .../android/src/qandroidplatformclipboard.h | 63 ++ .../android/src/qandroidplatformfontdatabase.cpp | 79 ++ .../android/src/qandroidplatformfontdatabase.h | 58 ++ .../android/src/qandroidplatformintegration.cpp | 283 +++++++ .../android/src/qandroidplatformintegration.h | 158 ++++ .../platforms/android/src/qandroidplatformmenu.cpp | 167 ++++ .../platforms/android/src/qandroidplatformmenu.h | 91 +++ .../android/src/qandroidplatformmenubar.cpp | 109 +++ .../android/src/qandroidplatformmenubar.h | 74 ++ .../android/src/qandroidplatformmenuitem.cpp | 180 +++++ .../android/src/qandroidplatformmenuitem.h | 99 +++ .../android/src/qandroidplatformservices.cpp | 83 ++ .../android/src/qandroidplatformservices.h | 61 ++ .../android/src/qandroidplatformtheme.cpp | 78 ++ .../platforms/android/src/qandroidplatformtheme.h | 56 ++ .../android/src/raster/qandroidplatformscreen.cpp | 71 ++ .../android/src/raster/qandroidplatformscreen.h | 59 ++ .../android/src/raster/qandroidplatformwindow.cpp | 56 ++ .../android/src/raster/qandroidplatformwindow.h | 60 ++ .../platforms/android/src/raster/raster.pri | 7 + src/plugins/platforms/android/src/src.pri | 47 ++ src/plugins/platforms/eglfs/qeglfsintegration.cpp | 4 +- src/plugins/platforms/platforms.pro | 2 + 46 files changed, 5841 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/android/android.pro create mode 100644 src/plugins/platforms/android/opengl/opengl.pro create mode 100644 src/plugins/platforms/android/raster/raster.pro create mode 100644 src/plugins/platforms/android/src/android.json create mode 100644 src/plugins/platforms/android/src/androidjniclipboard.cpp create mode 100644 src/plugins/platforms/android/src/androidjniclipboard.h create mode 100644 src/plugins/platforms/android/src/androidjniinput.cpp create mode 100644 src/plugins/platforms/android/src/androidjniinput.h create mode 100644 src/plugins/platforms/android/src/androidjnimain.cpp create mode 100644 src/plugins/platforms/android/src/androidjnimain.h create mode 100644 src/plugins/platforms/android/src/androidjnimenu.cpp create mode 100644 src/plugins/platforms/android/src/androidjnimenu.h create mode 100644 src/plugins/platforms/android/src/androidplatformplugin.cpp create mode 100644 src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp create mode 100644 src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h create mode 100644 src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp create mode 100644 src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h create mode 100644 src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp create mode 100644 src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp create mode 100644 src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h create mode 100644 src/plugins/platforms/android/src/qandroidinputcontext.cpp create mode 100644 src/plugins/platforms/android/src/qandroidinputcontext.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformclipboard.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformclipboard.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformfontdatabase.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformintegration.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformintegration.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformmenu.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformmenu.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformmenubar.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformmenubar.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformmenuitem.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformservices.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformservices.h create mode 100644 src/plugins/platforms/android/src/qandroidplatformtheme.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformtheme.h create mode 100644 src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp create mode 100644 src/plugins/platforms/android/src/raster/qandroidplatformscreen.h create mode 100644 src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp create mode 100644 src/plugins/platforms/android/src/raster/qandroidplatformwindow.h create mode 100644 src/plugins/platforms/android/src/raster/raster.pri create mode 100644 src/plugins/platforms/android/src/src.pri (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro new file mode 100644 index 0000000000..aa5ab4ddbd --- /dev/null +++ b/src/plugins/platforms/android/android.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS += raster opengl diff --git a/src/plugins/platforms/android/opengl/opengl.pro b/src/plugins/platforms/android/opengl/opengl.pro new file mode 100644 index 0000000000..301c8e6e4c --- /dev/null +++ b/src/plugins/platforms/android/opengl/opengl.pro @@ -0,0 +1,30 @@ +TARGET = qtforandroidGL + +PLUGIN_TYPE = platforms +load(qt_plugin) + +# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp +# Yes, the plugin imports itself statically +DEFINES += QT_STATICPLUGIN ANDROID_PLUGIN_OPENGL + +!equals(ANDROID_PLATFORM, android-9) { + INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include + LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid +} else { + LIBS += -ljnigraphics -landroid +} + +EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/../src/opengl/qeglfshooks_android.cpp + +INCLUDEPATH += $$PWD/../src/opengl/ + +HEADERS += \ + $$PWD/../src/opengl/qandroidopenglcontext.h \ + $$PWD/../src/opengl/qandroidopenglplatformwindow.h + +SOURCES += \ + $$PWD/../src/opengl/qandroidopenglcontext.cpp \ + $$PWD/../src/opengl/qandroidopenglplatformwindow.cpp + +include($$PWD/../../eglfs/eglfs.pri) +include($$PWD/../src/src.pri) diff --git a/src/plugins/platforms/android/raster/raster.pro b/src/plugins/platforms/android/raster/raster.pro new file mode 100644 index 0000000000..53d8ee7a2b --- /dev/null +++ b/src/plugins/platforms/android/raster/raster.pro @@ -0,0 +1,19 @@ +TARGET = qtforandroid + +PLUGIN_TYPE = platforms + +# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp +# Yes, the plugin imports itself statically +DEFINES += QT_STATICPLUGIN + +load(qt_plugin) + +!contains(ANDROID_PLATFORM, android-9) { + INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include + LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid +} else { + LIBS += -ljnigraphics -landroid +} + +include($$PWD/../src/src.pri) +include($$PWD/../src/raster/raster.pri) diff --git a/src/plugins/platforms/android/src/android.json b/src/plugins/platforms/android/src/android.json new file mode 100644 index 0000000000..6843bd3301 --- /dev/null +++ b/src/plugins/platforms/android/src/android.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "android" ] +} diff --git a/src/plugins/platforms/android/src/androidjniclipboard.cpp b/src/plugins/platforms/android/src/androidjniclipboard.cpp new file mode 100644 index 0000000000..05270ac374 --- /dev/null +++ b/src/plugins/platforms/android/src/androidjniclipboard.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "androidjniclipboard.h" +#include "androidjnimain.h" + +using namespace QtAndroid; +namespace QtAndroidClipboard +{ + // Clipboard support + static jmethodID m_registerClipboardManagerMethodID = 0; + static jmethodID m_setClipboardTextMethodID = 0; + static jmethodID m_hasClipboardTextMethodID = 0; + static jmethodID m_getClipboardTextMethodID = 0; + // Clipboard support + + void setClipboardListener(QAndroidPlatformClipboard *listener) + { + Q_UNUSED(listener); + + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + env.jniEnv->CallStaticVoidMethod(applicationClass(), m_registerClipboardManagerMethodID); + } + + void setClipboardText(const QString &text) + { + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + jstring jtext = env.jniEnv->NewString(reinterpret_cast(text.data()), + text.length()); + env.jniEnv->CallStaticVoidMethod(applicationClass(), m_setClipboardTextMethodID, jtext); + env.jniEnv->DeleteLocalRef(jtext); + } + + bool hasClipboardText() + { + AttachedJNIEnv env; + if (!env.jniEnv) + return false; + + return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_hasClipboardTextMethodID); + } + + QString clipboardText() + { + AttachedJNIEnv env; + if (!env.jniEnv) + return QString(); + + jstring text = reinterpret_cast(env.jniEnv->CallStaticObjectMethod(applicationClass(), + m_getClipboardTextMethodID)); + const jchar *jstr = env.jniEnv->GetStringChars(text, 0); + QString str(reinterpret_cast(jstr), env.jniEnv->GetStringLength(text)); + env.jniEnv->ReleaseStringChars(text, jstr); + return str; + } + + +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ + VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \ + return false; \ + } + + bool registerNatives(JNIEnv *env) + { + jclass appClass = QtAndroid::applicationClass(); + + GET_AND_CHECK_STATIC_METHOD(m_registerClipboardManagerMethodID, appClass, "registerClipboardManager", "()V"); + GET_AND_CHECK_STATIC_METHOD(m_setClipboardTextMethodID, appClass, "setClipboardText", "(Ljava/lang/String;)V"); + GET_AND_CHECK_STATIC_METHOD(m_hasClipboardTextMethodID, appClass, "hasClipboardText", "()Z"); + GET_AND_CHECK_STATIC_METHOD(m_getClipboardTextMethodID, appClass, "getClipboardText", "()Ljava/lang/String;"); + + return true; + } +} diff --git a/src/plugins/platforms/android/src/androidjniclipboard.h b/src/plugins/platforms/android/src/androidjniclipboard.h new file mode 100644 index 0000000000..15cd93202e --- /dev/null +++ b/src/plugins/platforms/android/src/androidjniclipboard.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDJNICLIPBOARD_H +#define ANDROIDJNICLIPBOARD_H + +#include +#include + +class QAndroidPlatformClipboard; +namespace QtAndroidClipboard +{ + // Clipboard support + void setClipboardListener(QAndroidPlatformClipboard *listener); + void setClipboardText(const QString &text); + bool hasClipboardText(); + QString clipboardText(); + // Clipboard support + + bool registerNatives(JNIEnv *env); +} + +#endif // ANDROIDJNICLIPBOARD_H diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp new file mode 100644 index 0000000000..6a3dd1f349 --- /dev/null +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -0,0 +1,480 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "androidjniinput.h" +#include "androidjnimain.h" + +#include +#include +#include + +using namespace QtAndroid; + +namespace QtAndroidInput +{ + static jmethodID m_showSoftwareKeyboardMethodID = 0; + static jmethodID m_resetSoftwareKeyboardMethodID = 0; + static jmethodID m_hideSoftwareKeyboardMethodID = 0; + static jmethodID m_isSoftwareKeyboardVisibleMethodID = 0; + static jmethodID m_updateSelectionMethodID = 0; + + static bool m_ignoreMouseEvents = false; + + static QList m_touchPoints; + + static QPointer m_mouseGrabber; + + void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd) + { + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID, + selStart, selEnd, candidatesStart, candidatesEnd); + } + + void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints) + { + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + env.jniEnv->CallStaticVoidMethod(applicationClass(), + m_showSoftwareKeyboardMethodID, + left, + top, + width, + height, + inputHints); + } + + void resetSoftwareKeyboard() + { + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + env.jniEnv->CallStaticVoidMethod(applicationClass(), m_resetSoftwareKeyboardMethodID); + } + + void hideSoftwareKeyboard() + { + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + env.jniEnv->CallStaticVoidMethod(applicationClass(), m_hideSoftwareKeyboardMethodID); + } + + bool isSoftwareKeyboardVisible() + { + AttachedJNIEnv env; + if (!env.jniEnv) + return false; + + return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_isSoftwareKeyboardVisibleMethodID); + } + + + static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) + { + if (m_ignoreMouseEvents) + return; + + QPoint globalPos(x,y); + QWindow *tlw = topLevelWindowAt(globalPos); + m_mouseGrabber = tlw; + QPoint localPos = tlw ? (globalPos - tlw->position()) : globalPos; + QWindowSystemInterface::handleMouseEvent(tlw, + localPos, + globalPos, + Qt::MouseButtons(Qt::LeftButton)); + } + + static void mouseUp(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) + { + QPoint globalPos(x,y); + QWindow *tlw = m_mouseGrabber.data(); + if (!tlw) + tlw = topLevelWindowAt(globalPos); + QPoint localPos = tlw ? (globalPos -tlw->position()) : globalPos; + QWindowSystemInterface::handleMouseEvent(tlw, localPos, globalPos + , Qt::MouseButtons(Qt::NoButton)); + m_ignoreMouseEvents = false; + m_mouseGrabber = 0; + } + + static void mouseMove(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) + { + + if (m_ignoreMouseEvents) + return; + + QPoint globalPos(x,y); + QWindow *tlw = m_mouseGrabber.data(); + if (!tlw) + tlw = topLevelWindowAt(globalPos); + QPoint localPos = tlw ? (globalPos-tlw->position()) : globalPos; + QWindowSystemInterface::handleMouseEvent(tlw, + localPos, + globalPos, + Qt::MouseButtons(Qt::LeftButton)); + } + + static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) + { + m_ignoreMouseEvents = true; + QPoint globalPos(x,y); + QWindow *tlw = topLevelWindowAt(globalPos); + QPoint localPos = tlw ? (globalPos-tlw->position()) : globalPos; + + // Release left button + QWindowSystemInterface::handleMouseEvent(tlw, + localPos, + globalPos, + Qt::MouseButtons(Qt::NoButton)); + + // Press right button + QWindowSystemInterface::handleMouseEvent(tlw, + localPos, + globalPos, + Qt::MouseButtons(Qt::RightButton)); + } + + static void touchBegin(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/) + { + m_touchPoints.clear(); + } + + static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean /*primary*/, jint x, jint y, jfloat size, jfloat pressure) + { + Qt::TouchPointState state = Qt::TouchPointStationary; + switch (action) { + case 0: + state = Qt::TouchPointPressed; + break; + case 1: + state = Qt::TouchPointMoved; + break; + case 2: + state = Qt::TouchPointStationary; + break; + case 3: + state = Qt::TouchPointReleased; + break; + } + + const int dw = desktopWidthPixels(); + const int dh = desktopHeightPixels(); + QWindowSystemInterface::TouchPoint touchPoint; + touchPoint.id = id; + touchPoint.pressure = pressure; + touchPoint.normalPosition = QPointF(double(x / dw), double(y / dh)); + touchPoint.state = state; + touchPoint.area = QRectF(x - double(dw*size) / 2.0, + y - double(dh*size) / 2.0, + double(dw*size), + double(dh*size)); + m_touchPoints.push_back(touchPoint); + } + + static void touchEnd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint action) + { + QEvent::Type eventType = QEvent::None; + switch (action) { + case 0: + eventType = QEvent::TouchBegin; + break; + case 1: + eventType = QEvent::TouchUpdate; + break; + case 2: + eventType = QEvent::TouchEnd; + break; + } + + // FIXME + // QWindowSystemInterface::handleTouchEvent(0, 0, eventType, QTouchEvent::TouchScreen, m_touchPoints); + } + + static int mapAndroidKey(int key) + { + // 0--9 0x00000007 -- 0x00000010 + if (key >= 0x00000007 && key <= 0x00000010) + return Qt::Key_0 + key - 0x00000007; + + // A--Z 0x0000001d -- 0x00000036 + if (key >= 0x0000001d && key <= 0x00000036) + return Qt::Key_A + key - 0x0000001d; + + switch (key) { + case 0x00000039: + case 0x0000003a: + return Qt::Key_Alt; + + case 0x0000004b: + return Qt::Key_Apostrophe; + + case 0x00000004: // KEYCODE_BACK + return Qt::Key_Back; + + case 0x00000049: + return Qt::Key_Backslash; + + case 0x00000005: + return Qt::Key_Call; + + case 0x0000001b: + return Qt::Key_WebCam; + + case 0x0000001c: + return Qt::Key_Clear; + + case 0x00000037: + return Qt::Key_Comma; + + case 0x00000043: + return Qt::Key_Backspace; + + case 0x00000017: // KEYCODE_DPAD_CENTER + return Qt::Key_Enter; + + case 0x00000014: // KEYCODE_DPAD_DOWN + return Qt::Key_Down; + + case 0x00000015: //KEYCODE_DPAD_LEFT + return Qt::Key_Left; + + case 0x00000016: //KEYCODE_DPAD_RIGHT + return Qt::Key_Right; + + case 0x00000013: //KEYCODE_DPAD_UP + return Qt::Key_Up; + + case 0x00000006: //KEYCODE_ENDCALL + return Qt::Key_Hangup; + + case 0x00000042: + return Qt::Key_Return; + + case 0x00000041: //KEYCODE_ENVELOPE + return Qt::Key_LaunchMail; + + case 0x00000046: + return Qt::Key_Equal; + + case 0x00000040: + return Qt::Key_Explorer; + + case 0x00000003: + return Qt::Key_Home; + + case 0x00000047: + return Qt::Key_BracketLeft; + + case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD + return Qt::Key_Forward; + + case 0x00000057: + return Qt::Key_MediaNext; + + case 0x00000055: + return Qt::Key_MediaPlay; + + case 0x00000058: + return Qt::Key_MediaPrevious; + + case 0x00000059: + return Qt::Key_AudioRewind; + + case 0x00000056: + return Qt::Key_MediaStop; + + case 0x00000052: //KEYCODE_MENU + return Qt::Key_Menu; + + case 0x00000045: + return Qt::Key_Minus; + + case 0x0000005b: + return Qt::Key_VolumeMute; + + case 0x0000004e: + return Qt::Key_NumLock; + + case 0x00000038: + return Qt::Key_Period; + + case 0x00000051: + return Qt::Key_Plus; + + case 0x0000001a: + return Qt::Key_PowerOff; + + case 0x00000048: + return Qt::Key_BracketRight; + + case 0x00000054: + return Qt::Key_Search; + + case 0x0000004a: + return Qt::Key_Semicolon; + + case 0x0000003b: + case 0x0000003c: + return Qt::Key_Shift; + + case 0x0000004c: + return Qt::Key_Slash; + + case 0x00000001: + return Qt::Key_Left; + + case 0x00000002: + return Qt::Key_Right; + + case 0x0000003e: + return Qt::Key_Space; + + case 0x0000003f: // KEYCODE_SYM + return Qt::Key_Meta; + + case 0x0000003d: + return Qt::Key_Tab; + + case 0x00000019: + return Qt::Key_VolumeDown; + + case 0x00000018: + return Qt::Key_VolumeUp; + + case 0x00000000: // KEYCODE_UNKNOWN + case 0x00000011: // KEYCODE_STAR ?!?!? + case 0x00000012: // KEYCODE_POUND ?!?!? + case 0x00000053: // KEYCODE_NOTIFICATION ?!?!? + case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!? + case 0x00000044: // KEYCODE_GRAVE ?!?!? + case 0x00000050: // KEYCODE_FOCUS ?!?!? + return Qt::Key_Any; + + default: + return 0; + } + } + + static void keyDown(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier) + { + Qt::KeyboardModifiers modifiers; + if (modifier & 1) + modifiers |= Qt::ShiftModifier; + + if (modifier & 2) + modifiers |= Qt::AltModifier; + + if (modifier & 4) + modifiers |= Qt::MetaModifier; + + QWindowSystemInterface::handleKeyEvent(0, + QEvent::KeyPress, + mapAndroidKey(key), + modifiers, + QChar(unicode), + true); + } + + static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier) + { + Qt::KeyboardModifiers modifiers; + if (modifier & 1) + modifiers |= Qt::ShiftModifier; + + if (modifier & 2) + modifiers |= Qt::AltModifier; + + if (modifier & 4) + modifiers |= Qt::MetaModifier; + + QWindowSystemInterface::handleKeyEvent(0, + QEvent::KeyRelease, + mapAndroidKey(key), + modifiers, + QChar(unicode), + true); + } + + + static JNINativeMethod methods[] = { + {"touchBegin","(I)V",(void*)touchBegin}, + {"touchAdd","(IIIZIIFF)V",(void*)touchAdd}, + {"touchEnd","(II)V",(void*)touchEnd}, + {"mouseDown", "(III)V", (void *)mouseDown}, + {"mouseUp", "(III)V", (void *)mouseUp}, + {"mouseMove", "(III)V", (void *)mouseMove}, + {"longPress", "(III)V", (void *)longPress}, + {"keyDown", "(III)V", (void *)keyDown}, + {"keyUp", "(III)V", (void *)keyUp} + }; + +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ + VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \ + return false; \ + } + + bool registerNatives(JNIEnv *env) + { + jclass appClass = QtAndroid::applicationClass(); + + if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { + __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed"); + return false; + } + + GET_AND_CHECK_STATIC_METHOD(m_showSoftwareKeyboardMethodID, appClass, "showSoftwareKeyboard", "(IIIII)V"); + GET_AND_CHECK_STATIC_METHOD(m_resetSoftwareKeyboardMethodID, appClass, "resetSoftwareKeyboard", "()V"); + GET_AND_CHECK_STATIC_METHOD(m_hideSoftwareKeyboardMethodID, appClass, "hideSoftwareKeyboard", "()V"); + GET_AND_CHECK_STATIC_METHOD(m_isSoftwareKeyboardVisibleMethodID, appClass, "isSoftwareKeyboardVisible", "()Z"); + GET_AND_CHECK_STATIC_METHOD(m_updateSelectionMethodID, appClass, "updateSelection", "(IIII)V"); + return true; + } +} diff --git a/src/plugins/platforms/android/src/androidjniinput.h b/src/plugins/platforms/android/src/androidjniinput.h new file mode 100644 index 0000000000..a78c7519db --- /dev/null +++ b/src/plugins/platforms/android/src/androidjniinput.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDJNIINPUT_H +#define ANDROIDJNIINPUT_H +#include + +namespace QtAndroidInput +{ + // Software keyboard support + void showSoftwareKeyboard(int top, int left, int width, int height, int inputHints); + void resetSoftwareKeyboard(); + void hideSoftwareKeyboard(); + bool isSoftwareKeyboardVisible(); + void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd); + // Software keyboard support + + bool registerNatives(JNIEnv *env); +} + +#endif // ANDROIDJNIINPUT_H diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp new file mode 100644 index 0000000000..2a4c48df3c --- /dev/null +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -0,0 +1,839 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "androidjnimain.h" +#include "androidjniinput.h" +#include "androidjniclipboard.h" +#include "androidjnimenu.h" +#include "qandroidplatformintegration.h" +#include + +#include + +#include +#include +#include "qandroidassetsfileenginehandler.h" +#include + +#include + +#ifdef ANDROID_PLUGIN_OPENGL +# include "qandroidopenglplatformwindow.h" +#endif + +#if __ANDROID_API__ > 8 +# include +#endif + +static jmethodID m_redrawSurfaceMethodID = 0; + +Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin) + +static JavaVM *m_javaVM = NULL; +static jclass m_applicationClass = NULL; +static jobject m_classLoaderObject = NULL; +static jmethodID m_loadClassMethodID = NULL; +static AAssetManager *m_assetManager = NULL; +static jobject m_resourcesObj; +static jobject m_activityObject = NULL; + +static jclass m_bitmapClass = 0; +static jmethodID m_createBitmapMethodID = 0; +static jobject m_ARGB_8888_BitmapConfigValue = 0; +static jobject m_RGB_565_BitmapConfigValue = 0; + +static jclass m_bitmapDrawableClass = 0; +static jmethodID m_bitmapDrawableConstructorMethodID = 0; + +extern "C" typedef int (*Main)(int, char **); //use the standard main method to start the application +static Main m_main = NULL; +static void *m_mainLibraryHnd = NULL; +static QList m_applicationParams; + +#ifndef ANDROID_PLUGIN_OPENGL +static jobject m_surface = NULL; +#else +static EGLNativeWindowType m_nativeWindow = 0; +static QSemaphore m_waitForWindowSemaphore; +static bool m_waitForWindow = false; + +static jfieldID m_surfaceFieldID = 0; +#endif + + +static QSemaphore m_quitAppSemaphore; +static QMutex m_surfaceMutex(QMutex::Recursive); +static QSemaphore m_pauseApplicationSemaphore; +static QMutex m_pauseApplicationMutex; + +static QAndroidPlatformIntegration *m_androidPlatformIntegration = 0; + +static int m_desktopWidthPixels = 0; +static int m_desktopHeightPixels = 0; + +static volatile bool m_pauseApplication; + +static jmethodID m_setFullScreenMethodID = 0; + +static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = 0; + + + +static const char m_qtTag[] = "Qt"; +static const char m_classErrorMsg[] = "Can't find class \"%s\""; +static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; + +static inline void checkPauseApplication() +{ + m_pauseApplicationMutex.lock(); + if (m_pauseApplication) { + m_pauseApplicationMutex.unlock(); + m_pauseApplicationSemaphore.acquire(); // wait until surface is created + + m_pauseApplicationMutex.lock(); + m_pauseApplication = false; + m_pauseApplicationMutex.unlock(); + + //FIXME +// QWindowSystemInterface::handleScreenAvailableGeometryChange(0); +// QWindowSystemInterface::handleScreenGeometryChange(0); + } else { + m_pauseApplicationMutex.unlock(); + } +} + +namespace QtAndroid +{ +#ifndef ANDROID_PLUGIN_OPENGL + void flushImage(const QPoint &pos, const QImage &image, const QRect &destinationRect) + { + checkPauseApplication(); + QMutexLocker locker(&m_surfaceMutex); + if (!m_surface) + return; + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + int bpp = 2; + AndroidBitmapInfo info; + int ret; + + if ((ret = AndroidBitmap_getInfo(env.jniEnv, m_surface, &info)) < 0) { + qWarning() << "AndroidBitmap_getInfo() failed ! error=" << ret; + m_javaVM->DetachCurrentThread(); + return; + } + + if (info.format != ANDROID_BITMAP_FORMAT_RGB_565) { + qWarning() << "Bitmap format is not RGB_565!"; + m_javaVM->DetachCurrentThread(); + return; + } + + void *pixels; + unsigned char *screenBits; + if ((ret = AndroidBitmap_lockPixels(env.jniEnv, m_surface, &pixels)) < 0) { + qWarning() << "AndroidBitmap_lockPixels() failed! error=" << ret; + m_javaVM->DetachCurrentThread(); + return; + } + + screenBits = static_cast(pixels); + int sbpl = info.stride; + int swidth = info.width; + int sheight = info.height; + + unsigned sposx = pos.x() + destinationRect.x(); + unsigned sposy = pos.y() + destinationRect.y(); + + screenBits += sposy * sbpl; + + unsigned ibpl = image.bytesPerLine(); + unsigned iposx = destinationRect.x(); + unsigned iposy = destinationRect.y(); + + const unsigned char *imageBits = static_cast(image.bits()); + imageBits += iposy * ibpl; + + unsigned width = swidth - sposx < unsigned(destinationRect.width()) + ? (swidth-sposx) + : destinationRect.width(); + unsigned height = sheight - sposy < unsigned(destinationRect.height()) + ? (sheight - sposy) + : destinationRect.height(); + + for (unsigned y = 0; y < height; y++) { + memcpy(screenBits + y*sbpl + sposx*bpp, + imageBits + y*ibpl + iposx*bpp, + width*bpp); + } + AndroidBitmap_unlockPixels(env.jniEnv, m_surface); + + env.jniEnv->CallStaticVoidMethod(m_applicationClass, + m_redrawSurfaceMethodID, + jint(destinationRect.left()), + jint(destinationRect.top()), + jint(destinationRect.right() + 1), + jint(destinationRect.bottom() + 1)); +#warning FIXME dirty hack, figure out why it needs to add 1 to right and bottom !!!! + } + +#else // for #ifndef ANDROID_PLUGIN_OPENGL + EGLNativeWindowType nativeWindow(bool waitForWindow) + { + m_surfaceMutex.lock(); + if (!m_nativeWindow && waitForWindow) { + m_waitForWindow = true; + m_surfaceMutex.unlock(); + m_waitForWindowSemaphore.acquire(); + m_waitForWindow = false; + return m_nativeWindow; + } + m_surfaceMutex.unlock(); + return m_nativeWindow; + } + + QSize nativeWindowSize() + { + if (m_nativeWindow == 0) + return QAndroidPlatformIntegration::defaultDesktopSize(); + + int width = ANativeWindow_getWidth(m_nativeWindow); + int height = ANativeWindow_getHeight(m_nativeWindow); + + return QSize(width, height); + } +#endif + + void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration) + { + m_surfaceMutex.lock(); + m_androidPlatformIntegration = androidPlatformIntegration; + m_surfaceMutex.unlock(); + } + + void setFullScreen(QWidget *widget) + { + AttachedJNIEnv env; + if (!env.jniEnv) + return; + + bool fullScreen = widget->isFullScreen(); + if (!fullScreen) { + foreach (QWidget *w, qApp->topLevelWidgets()) { + fullScreen |= w->isFullScreen(); + if (fullScreen) + break; + } + } + + env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, fullScreen); + } + + QWindow *topLevelWindowAt(const QPoint &globalPos) + { + return m_androidPlatformIntegration + ? m_androidPlatformIntegration->screen()->topLevelAt(globalPos) + : 0; + } + + int desktopWidthPixels() + { + return m_desktopWidthPixels; + } + + int desktopHeightPixels() + { + return m_desktopHeightPixels; + } + + JavaVM *javaVM() + { + return m_javaVM; + } + + jclass findClass(const QString &className, JNIEnv *env) + { + return static_cast(env->CallObjectMethod(m_classLoaderObject, + m_loadClassMethodID, + env->NewString(reinterpret_cast(className.constData()), + jsize(className.length())))); + } + + AAssetManager *assetManager() + { + return m_assetManager; + } + + jclass applicationClass() + { + return m_applicationClass; + } + + jobject activity() + { + return m_activityObject; + } + + jobject createBitmap(QImage img, JNIEnv *env) + { + if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16) + img = img.convertToFormat(QImage::Format_ARGB32); + + jobject bitmap = env->CallStaticObjectMethod(m_bitmapClass, + m_createBitmapMethodID, + img.width(), + img.height(), + img.format() == QImage::Format_ARGB32 + ? m_ARGB_8888_BitmapConfigValue + : m_RGB_565_BitmapConfigValue); + if (!bitmap) + return 0; + + AndroidBitmapInfo info; + if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) { + env->DeleteLocalRef(bitmap); + return 0; + } + + void *pixels; + if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) { + env->DeleteLocalRef(bitmap); + return 0; + } + + if (info.stride == uint(img.bytesPerLine()) + && info.width == uint(img.width()) + && info.height == uint(img.height())) { + memcpy(pixels, img.constBits(), info.stride * info.height); + } else { + uchar *bmpPtr = static_cast(pixels); + const unsigned width = qMin(info.width, (uint)img.width()); //should be the same + const unsigned height = qMin(info.height, (uint)img.height()); //should be the same + for (unsigned y = 0; y < height; y++, bmpPtr += info.stride) + memcpy(bmpPtr, img.constScanLine(y), width); + } + AndroidBitmap_unlockPixels(env, bitmap); + return bitmap; + } + + jobject createBitmapDrawable(jobject bitmap, JNIEnv *env) + { + if (!bitmap) + return 0; + + return env->NewObject(m_bitmapDrawableClass, + m_bitmapDrawableConstructorMethodID, + m_resourcesObj, + bitmap); + } + + const char *classErrorMsgFmt() + { + return m_classErrorMsg; + } + + const char *methodErrorMsgFmt() + { + return m_methodErrorMsg; + } + + const char *qtTagText() + { + return m_qtTag; + } +} + +static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/) +{ +#ifndef ANDROID_PLUGIN_OPENGL + m_surface = 0; +#else + m_nativeWindow = 0; + m_waitForWindow = false; +#endif + + m_androidPlatformIntegration = 0; + m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler(); + +#ifdef ANDROID_PLUGIN_OPENGL + return true; +#else + return false; +#endif +} + +static void *startMainMethod(void */*data*/) +{ + char const **params; + params = static_cast(malloc(m_applicationParams.length() * sizeof(char *))); + for (int i = 0; i < m_applicationParams.size(); i++) + params[i] = static_cast(m_applicationParams[i].constData()); + + int ret = m_main(m_applicationParams.length(), const_cast(params)); + + free(params); + Q_UNUSED(ret); + + if (m_mainLibraryHnd) { + int res = dlclose(m_mainLibraryHnd); + if (res < 0) + qWarning() << "dlclose failed:" << dlerror(); + } + + QtAndroid::AttachedJNIEnv env; + if (!env.jniEnv) + return 0; + + if (m_applicationClass) { + jmethodID quitApp = env.jniEnv->GetStaticMethodID(m_applicationClass, "quitApp", "()V"); + env.jniEnv->CallStaticVoidMethod(m_applicationClass, quitApp); + } + + return 0; +} + +static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString) +{ + m_mainLibraryHnd = NULL; + const char *nativeString = env->GetStringUTFChars(environmentString, 0); + QByteArray string = nativeString; + env->ReleaseStringUTFChars(environmentString, nativeString); + m_applicationParams=string.split('\t'); + foreach (string, m_applicationParams) { + if (putenv(string.constData())) + qWarning() << "Can't set environment" << string; + } + + nativeString = env->GetStringUTFChars(paramsString, 0); + string = nativeString; + env->ReleaseStringUTFChars(paramsString, nativeString); + + m_applicationParams=string.split('\t'); + + // Go home + QDir::setCurrent(QDir::homePath()); + + //look for main() + if (m_applicationParams.length()) { + // Obtain a handle to the main library (the library that contains the main() function). + // This library should already be loaded, and calling dlopen() will just return a reference to it. + m_mainLibraryHnd = dlopen(m_applicationParams.first().data(), 0); + if (m_mainLibraryHnd == NULL) { + qCritical() << "dlopen failed:" << dlerror(); + return false; + } + m_main = (Main)dlsym(m_mainLibraryHnd, "main"); + } else { + qWarning() << "No main library was specified; searching entire process (this is slow!)"; + m_main = (Main)dlsym(RTLD_DEFAULT, "main"); + } + + if (!m_main) { + qCritical() << "dlsym failed:" << dlerror(); + qCritical() << "Could not find main method"; + return false; + } + + pthread_t appThread; + return pthread_create(&appThread, NULL, startMainMethod, NULL) == 0; +} + +static void pauseQtApp(JNIEnv */*env*/, jobject /*thiz*/) +{ + m_surfaceMutex.lock(); + m_pauseApplicationMutex.lock(); + + if (m_androidPlatformIntegration) + m_androidPlatformIntegration->pauseApp(); + m_pauseApplication = true; + + m_pauseApplicationMutex.unlock(); + m_surfaceMutex.unlock(); +} + +static void resumeQtApp(JNIEnv */*env*/, jobject /*thiz*/) +{ + m_surfaceMutex.lock(); + m_pauseApplicationMutex.lock(); + if (m_androidPlatformIntegration) + m_androidPlatformIntegration->resumeApp(); + + if (m_pauseApplication) + m_pauseApplicationSemaphore.release(); + + m_pauseApplicationMutex.unlock(); + m_surfaceMutex.unlock(); +} + +static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/) +{ +#ifndef ANDROID_PLUGIN_OPENGL + if (m_surface) { + env->DeleteGlobalRef(m_surface); + m_surface = 0; + } +#else + Q_UNUSED(env); +#endif + + m_androidPlatformIntegration = 0; + delete m_androidAssetsFileEngineHandler; +} + +static void terminateQt(JNIEnv *env, jclass /*clazz*/) +{ +#ifndef ANDROID_PLUGIN_OPENGL + if (m_surface) + env->DeleteGlobalRef(m_surface); +#endif + env->DeleteGlobalRef(m_applicationClass); + env->DeleteGlobalRef(m_classLoaderObject); + env->DeleteGlobalRef(m_resourcesObj); + env->DeleteGlobalRef(m_activityObject); + env->DeleteGlobalRef(m_bitmapClass); + env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue); + env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue); + env->DeleteGlobalRef(m_bitmapDrawableClass); +} + +#ifdef ANDROID_PLUGIN_OPENGL +#if __ANDROID_API__ < 9 +struct FakeNativeWindow +{ + long long dummyNativeWindow;// force 64 bits alignment +}; + +class FakeSurface: public FakeNativeWindow +{ +public: + virtual void FakeSurfaceMethod() + { + fakeSurface = 0; + } + + int fakeSurface; +}; + +EGLNativeWindowType ANativeWindow_fromSurface(JNIEnv *env, jobject jSurface) +{ + FakeSurface *surface = static_cast(env->GetIntField(jSurface, m_surfaceFieldID)); + return static_cast(static_cast(surface)); +} +#endif // __ANDROID_API__ < 9 +#endif // ANDROID_PLUGIN_OPENGL + +static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface) +{ +#ifndef ANDROID_PLUGIN_OPENGL + if (m_surface) + env->DeleteGlobalRef(m_surface); + m_surface = env->NewGlobalRef(jSurface); +#else + m_surfaceMutex.lock(); + EGLNativeWindowType nativeWindow = ANativeWindow_fromSurface(env, jSurface); + bool sameNativeWindow = (nativeWindow != 0 && nativeWindow == m_nativeWindow); + + m_nativeWindow = nativeWindow; + if (m_waitForWindow) + m_waitForWindowSemaphore.release(); + if (m_androidPlatformIntegration && !sameNativeWindow) { + m_surfaceMutex.unlock(); + m_androidPlatformIntegration->surfaceChanged(); + } else if (m_androidPlatformIntegration && sameNativeWindow) { + QAndroidOpenGLPlatformWindow *window = m_androidPlatformIntegration->primaryWindow(); + QPlatformScreen *screen = m_androidPlatformIntegration->screen(); + QSize size = QtAndroid::nativeWindowSize(); + + QRect geometry(QPoint(0, 0), size); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry); + QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry); + + if (window != 0) { + window->lock(); + window->scheduleResize(size); + + QWindowSystemInterface::handleExposeEvent(window->window(), + QRegion(window->window()->geometry())); + window->unlock(); + } + + m_surfaceMutex.unlock(); + } else { + m_surfaceMutex.unlock(); + } +#endif // for #ifndef ANDROID_PLUGIN_OPENGL +} + +static void destroySurface(JNIEnv *env, jobject /*thiz*/) +{ +#ifndef ANDROID_PLUGIN_OPENGL + if (m_surface) { + env->DeleteGlobalRef(m_surface); + m_surface = 0; + } +#else + Q_UNUSED(env); + m_nativeWindow = 0; + if (m_androidPlatformIntegration != 0) + m_androidPlatformIntegration->invalidateNativeSurface(); +#endif +} + +static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, + jint /*widthPixels*/, jint /*heightPixels*/, + jint desktopWidthPixels, jint desktopHeightPixels, + jdouble xdpi, jdouble ydpi) +{ + m_desktopWidthPixels = desktopWidthPixels; + m_desktopHeightPixels = desktopHeightPixels; + + if (!m_androidPlatformIntegration) { + QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,desktopHeightPixels, + qRound(double(desktopWidthPixels) / xdpi * 25.4), + qRound(double(desktopHeightPixels) / ydpi * 25.4)); + } else { + m_androidPlatformIntegration->setDisplayMetrics(qRound(double(desktopWidthPixels) / xdpi * 25.4), + qRound(double(desktopHeightPixels) / ydpi * 25.4)); + m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels); + } +} + +static void lockSurface(JNIEnv */*env*/, jobject /*thiz*/) +{ + m_surfaceMutex.lock(); +} + +static void unlockSurface(JNIEnv */*env*/, jobject /*thiz*/) +{ + m_surfaceMutex.unlock(); +} + +static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidPlatformIntegration) + return; + + if (qApp != 0) { + foreach (QWidget *w, qApp->topLevelWidgets()) + w->update(); + } + +#ifndef ANDROID_PLUGIN_OPENGL + QAndroidPlatformScreen *screen = static_cast(m_androidPlatformIntegration->screen()); + QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry())); +#else + qWarning("updateWindow: Dirty screen not implemented yet on OpenGL"); +#endif +} + +static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation) +{ + if (m_androidPlatformIntegration == 0) + return; + + Qt::ScreenOrientation screenOrientation = newOrientation == 1 + ? Qt::PortraitOrientation + : Qt::LandscapeOrientation; + QPlatformScreen *screen = m_androidPlatformIntegration->screen(); + QWindowSystemInterface::handleScreenOrientationChange(screen->screen(), + screenOrientation); +} + +static JNINativeMethod methods[] = { + {"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin}, + {"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication}, + {"pauseQtApp", "()V", (void *)pauseQtApp}, + {"resumeQtApp", "()V", (void *)resumeQtApp}, + {"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin}, + {"terminateQt", "()V", (void *)terminateQt}, + {"setDisplayMetrics", "(IIIIDD)V", (void *)setDisplayMetrics}, + {"setSurface", "(Ljava/lang/Object;)V", (void *)setSurface}, + {"destroySurface", "()V", (void *)destroySurface}, + {"lockSurface", "()V", (void *)lockSurface}, + {"unlockSurface", "()V", (void *)unlockSurface}, + {"updateWindow", "()V", (void *)updateWindow}, + {"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged} +}; + +#define FIND_AND_CHECK_CLASS(CLASS_NAME) \ +clazz = env->FindClass(CLASS_NAME); \ +if (!clazz) { \ + __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_classErrorMsg, CLASS_NAME); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ +VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ +VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \ +VAR = env->GetFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, FIELD_NAME, FIELD_SIGNATURE); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_STATIC_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \ +VAR = env->GetStaticFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, FIELD_NAME, FIELD_SIGNATURE); \ + return JNI_FALSE; \ +} + +static int registerNatives(JNIEnv *env) +{ + jclass clazz; + FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative"); + m_applicationClass = static_cast(env->NewGlobalRef(clazz)); + + if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { + __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed"); + return JNI_FALSE; + } + + GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V"); + GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V"); + +#ifdef ANDROID_PLUGIN_OPENGL + FIND_AND_CHECK_CLASS("android/view/Surface"); +#if __ANDROID_API__ < 9 +# define ANDROID_VIEW_SURFACE_JNI_ID "mSurface" +#else +# define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface" +#endif + GET_AND_CHECK_FIELD(m_surfaceFieldID, clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I"); +#endif + + jmethodID methodID; + GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;"); + jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID); + m_activityObject = env->NewGlobalRef(activityObject); + GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "classLoader", "()Ljava/lang/ClassLoader;"); + m_classLoaderObject = env->NewGlobalRef(env->CallStaticObjectMethod(m_applicationClass, methodID)); + + clazz = env->GetObjectClass(m_classLoaderObject); + GET_AND_CHECK_METHOD(m_loadClassMethodID, clazz, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); + + FIND_AND_CHECK_CLASS("android/content/ContextWrapper"); + GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;"); + m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID)); + + GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;"); + m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID)); + + FIND_AND_CHECK_CLASS("android/graphics/Bitmap"); + m_bitmapClass = static_cast(env->NewGlobalRef(clazz)); + GET_AND_CHECK_STATIC_METHOD(m_createBitmapMethodID, m_bitmapClass + , "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;"); + + FIND_AND_CHECK_CLASS("android/graphics/Bitmap$Config"); + jfieldID fieldId; + GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "ARGB_8888", "Landroid/graphics/Bitmap$Config;"); + m_ARGB_8888_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId)); + GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "RGB_565", "Landroid/graphics/Bitmap$Config;"); + m_RGB_565_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId)); + + FIND_AND_CHECK_CLASS("android/graphics/drawable/BitmapDrawable"); + m_bitmapDrawableClass = static_cast(env->NewGlobalRef(clazz)); + GET_AND_CHECK_METHOD(m_bitmapDrawableConstructorMethodID, + m_bitmapDrawableClass, + "", + "(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V"); + + return JNI_TRUE; +} + +Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) +{ + typedef union { + JNIEnv *nativeEnvironment; + void *venv; + } UnionJNIEnvToVoid; + + __android_log_print(ANDROID_LOG_INFO, "Qt", "qt start"); + UnionJNIEnvToVoid uenv; + uenv.venv = NULL; + m_javaVM = 0; + + if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) { + __android_log_print(ANDROID_LOG_FATAL, "Qt", "GetEnv failed"); + return -1; + } + + JNIEnv *env = uenv.nativeEnvironment; + if (!registerNatives(env) + || !QtAndroidInput::registerNatives(env) + || !QtAndroidClipboard::registerNatives(env) + || !QtAndroidMenu::registerNatives(env)) { + __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); + return -1; + } + + m_javaVM = vm; + return JNI_VERSION_1_4; +} diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h new file mode 100644 index 0000000000..36699f15b8 --- /dev/null +++ b/src/plugins/platforms/android/src/androidjnimain.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROID_APP_H +#define ANDROID_APP_H + +#include + +#ifdef ANDROID_PLUGIN_OPENGL +# include +#endif + +#include + +#include +#include + +class QImage; +class QRect; +class QPoint; +class QThread; +class QAndroidPlatformIntegration; +class QWidget; +class QString; +class QWindow; + +namespace QtAndroid +{ + void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration); + void setQtThread(QThread *thread); + + void setFullScreen(QWidget *widget); + +#ifndef ANDROID_PLUGIN_OPENGL + void flushImage(const QPoint &pos, const QImage &image, const QRect &rect); +#else + EGLNativeWindowType nativeWindow(bool waitToCreate = true); + QSize nativeWindowSize(); +#endif + + QWindow *topLevelWindowAt(const QPoint &globalPos); + int desktopWidthPixels(); + int desktopHeightPixels(); + JavaVM *javaVM(); + jclass findClass(const QString &className, JNIEnv *env); + AAssetManager *assetManager(); + jclass applicationClass(); + jobject activity(); + + jobject createBitmap(QImage img, JNIEnv *env = 0); + jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0); + + struct AttachedJNIEnv + { + AttachedJNIEnv() + { + attached = false; + if (QtAndroid::javaVM()->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) { + if (QtAndroid::javaVM()->AttachCurrentThread(&jniEnv, NULL) < 0) { + __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed"); + jniEnv = 0; + return; + } + attached = true; + } + } + + ~AttachedJNIEnv() + { + if (attached) + QtAndroid::javaVM()->DetachCurrentThread(); + } + bool attached; + JNIEnv *jniEnv; + }; + const char *classErrorMsgFmt(); + const char *methodErrorMsgFmt(); + const char *qtTagText(); + +} +#endif // ANDROID_APP_H diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp new file mode 100644 index 0000000000..e49af0fdac --- /dev/null +++ b/src/plugins/platforms/android/src/androidjnimenu.cpp @@ -0,0 +1,405 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "androidjnimenu.h" +#include "androidjnimain.h" +#include +#include +#include +#include +#include "qandroidplatformmenubar.h" +#include "qandroidplatformmenu.h" +#include + +using namespace QtAndroid; + +namespace QtAndroidMenu +{ + static QQueue pendingContextMenus; + static QAndroidPlatformMenu *visibleMenu = 0; + static QMutex visibleMenuMutex(QMutex::Recursive); + + static QSet menuBars; + static QAndroidPlatformMenuBar *visibleMenuBar = 0; + static QWindow *activeTopLevelWindow = 0; + static QMutex menuBarMutex(QMutex::Recursive); + + static jmethodID openContextMenuMethodID = 0; + static jmethodID closeContextMenuMethodID = 0; + static jmethodID resetOptionsMenuMethodID = 0; + + static jmethodID clearMenuMethodID = 0; + static jmethodID addMenuItemMethodID = 0; + static int menuNoneValue = 0; + static jmethodID setHeaderTitleContextMenuMethodID = 0; + + static jmethodID setCheckableMenuItemMethodID = 0; + static jmethodID setCheckedMenuItemMethodID = 0; + static jmethodID setEnabledMenuItemMethodID = 0; + static jmethodID setIconMenuItemMethodID = 0; + static jmethodID setVisibleMenuItemMethodID = 0; + + void resetMenuBar() + { + AttachedJNIEnv env; + if (env.jniEnv) + env.jniEnv->CallStaticVoidMethod(applicationClass(), resetOptionsMenuMethodID); + } + + void showContextMenu(QAndroidPlatformMenu *menu, JNIEnv *env) + { + QMutexLocker lock(&visibleMenuMutex); + if (visibleMenu) { + pendingContextMenus.enqueue(menu); + } else { + visibleMenu = menu; + menu->aboutToShow(); + if (env) { + env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID); + } else { + AttachedJNIEnv aenv; + if (aenv.jniEnv) + aenv.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID); + } + } + } + + void hideContextMenu(QAndroidPlatformMenu *menu) + { + QMutexLocker lock(&visibleMenuMutex); + if (visibleMenu == menu) { + AttachedJNIEnv env; + if (env.jniEnv) + env.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID); + } else { + pendingContextMenus.removeOne(menu); + } + } + + void syncMenu(QAndroidPlatformMenu */*menu*/) + { +// QMutexLocker lock(&visibleMenuMutex); +// if (visibleMenu == menu) +// { +// hideContextMenu(menu); +// showContextMenu(menu); +// } + } + + void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu) + { + QMutexLocker lock(&visibleMenuMutex); + if (visibleMenu == menu) + visibleMenu = 0; + } + + void setMenuBar(QAndroidPlatformMenuBar *menuBar, QWindow *window) + { + if (activeTopLevelWindow == window && visibleMenuBar != menuBar) { + visibleMenuBar = menuBar; + resetMenuBar(); + } + } + + void setActiveTopLevelWindow(QWindow *window) + { + QMutexLocker lock(&menuBarMutex); + if (activeTopLevelWindow == window) + return; + + visibleMenuBar = 0; + activeTopLevelWindow = window; +#ifdef ANDROID_PLUGIN_OPENGL + //only one toplevel window, so the menu bar always belongs to us + if (menuBars.size() == 1) { + visibleMenuBar = *menuBars.constBegin(); //since QSet doesn't have first() + } else +#endif + foreach (QAndroidPlatformMenuBar *menuBar, menuBars) { + if (menuBar->parentWindow() == window) { + visibleMenuBar = menuBar; + break; + } + } + + resetMenuBar(); + } + + void addMenuBar(QAndroidPlatformMenuBar *menuBar) + { + QMutexLocker lock(&menuBarMutex); + menuBars.insert(menuBar); + } + + void removeMenuBar(QAndroidPlatformMenuBar *menuBar) + { + QMutexLocker lock(&menuBarMutex); + menuBars.remove(menuBar); + if (visibleMenuBar == menuBar) + resetMenuBar(); + } + + static void fillMenuItem(JNIEnv *env, jobject menuItem, bool checkable, bool checked, bool enabled, bool visible, const QIcon &icon=QIcon()) + { + env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable); + env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked); + env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled); + + if (!icon.isNull()) { + int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt()); + QImage img = icon.pixmap(QSize(sz,sz), + enabled + ? QIcon::Normal + : QIcon::Disabled, + QIcon::On).toImage(); + env->CallObjectMethod(menuItem, + setIconMenuItemMethodID, + createBitmapDrawable(createBitmap(img, env), env)); + } + + env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible); + } + + static int addAllMenuItemsToMenu(JNIEnv *env, jobject menu, QAndroidPlatformMenu *platformMenu) { + int order = 0; + QMutexLocker lock(platformMenu->menuItemsMutex()); + foreach (QAndroidPlatformMenuItem *item, platformMenu->menuItems()) { + if (item->isSeparator()) + continue; + jstring jtext = env->NewString(reinterpret_cast(item->text().data()), + item->text().length()); + jobject menuItem = env->CallObjectMethod(menu, + addMenuItemMethodID, + menuNoneValue, + int(item->tag()), + order++, + jtext); + env->DeleteLocalRef(jtext); + fillMenuItem(env, + menuItem, + item->isCheckable(), + item->isChecked(), + item->isEnabled(), + item->isVisible(), + item->icon()); + } + + return order; + } + + static jboolean onPrepareOptionsMenu(JNIEnv *env, jobject /*thiz*/, jobject menu) + { + env->CallVoidMethod(menu, clearMenuMethodID); + QMutexLocker lock(&menuBarMutex); + if (!visibleMenuBar) + return JNI_FALSE; + + const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus(); + int order = 0; + QMutexLocker lockMenuBarMutex(visibleMenuBar->menusListMutex()); + if (menus.size() == 1) { // Expand the menu + order = addAllMenuItemsToMenu(env, menu, static_cast(menus.front())); + } else { + foreach (QAndroidPlatformMenu *item, menus) { + jstring jtext = env->NewString(reinterpret_cast(item->text().data()), + item->text().length()); + jobject menuItem = env->CallObjectMethod(menu, + addMenuItemMethodID, + menuNoneValue, + int(item->tag()), + order++, + jtext); + env->DeleteLocalRef(jtext); + + fillMenuItem(env, + menuItem, + false, + false, + item->isEnabled(), + item->isVisible(), + item->icon()); + } + } + return order ? JNI_TRUE : JNI_FALSE; + } + + static jboolean onOptionsItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked) + { + QMutexLocker lock(&menuBarMutex); + if (!visibleMenuBar) + return JNI_FALSE; + + const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus(); + if (menus.size() == 1) { // Expanded menu + QAndroidPlatformMenuItem *item = static_cast(menus.front()->menuItemForTag(menuId)); + if (item) { + if (item->menu()) { + showContextMenu(item->menu(), env); + } else { + if (item->isCheckable()) + item->setChecked(checked); + item->activated(); + } + } + } else { + QAndroidPlatformMenu *menu = static_cast(visibleMenuBar->menuForTag(menuId)); + if (menu) + showContextMenu(menu, env); + } + + return JNI_TRUE; + } + + static void onOptionsMenuClosed(JNIEnv */*env*/, jobject /*thiz*/, jobject /*menu*/) + { + } + + static void onCreateContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu) + { + env->CallVoidMethod(menu, clearMenuMethodID); + QMutexLocker lock(&visibleMenuMutex); + if (!visibleMenu) + return; + + jstring jtext = env->NewString(reinterpret_cast(visibleMenu->text().data()), + visibleMenu->text().length()); + env->CallObjectMethod(menu, setHeaderTitleContextMenuMethodID, jtext); + env->DeleteLocalRef(jtext); + addAllMenuItemsToMenu(env, menu, visibleMenu); + } + + static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked) + { + QMutexLocker lock(&visibleMenuMutex); + QAndroidPlatformMenuItem * item = static_cast(visibleMenu->menuItemForTag(menuId)); + if (item) { + if (item->menu()) { + showContextMenu(item->menu(), env); + } else { + if (item->isCheckable()) + item->setChecked(checked); + item->activated(); + } + } + return JNI_TRUE; + } + + static void onContextMenuClosed(JNIEnv *env, jobject /*thiz*/, jobject /*menu*/) + { + QMutexLocker lock(&visibleMenuMutex); + if (!visibleMenu) + return; + visibleMenu->aboutToHide(); + visibleMenu = 0; + if (!pendingContextMenus.empty()) + showContextMenu(pendingContextMenus.dequeue(), env); + } + + static JNINativeMethod methods[] = { + {"onPrepareOptionsMenu", "(Landroid/view/Menu;)Z", (void *)onPrepareOptionsMenu}, + {"onOptionsItemSelected", "(IZ)Z", (void *)onOptionsItemSelected}, + {"onOptionsMenuClosed", "(Landroid/view/Menu;)V", (void*)onOptionsMenuClosed}, + {"onCreateContextMenu", "(Landroid/view/ContextMenu;)V", (void *)onCreateContextMenu}, + {"onContextItemSelected", "(IZ)Z", (void *)onContextItemSelected}, + {"onContextMenuClosed", "(Landroid/view/Menu;)V", (void*)onContextMenuClosed}, + }; + +#define FIND_AND_CHECK_CLASS(CLASS_NAME) \ + clazz = env->FindClass(CLASS_NAME); \ + if (!clazz) { \ + __android_log_print(ANDROID_LOG_FATAL, qtTagText(), classErrorMsgFmt(), CLASS_NAME); \ + return false; \ + } + +#define GET_AND_CHECK_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ + VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \ + return false; \ + } + +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ + VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \ + return false; \ + } + +#define GET_AND_CHECK_STATIC_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \ + VAR = env->GetStaticFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), FIELD_NAME, FIELD_SIGNATURE); \ + return false; \ + } + + bool registerNatives(JNIEnv *env) + { + jclass appClass = applicationClass(); + + if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { + __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed"); + return false; + } + + GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "()V"); + GET_AND_CHECK_STATIC_METHOD(closeContextMenuMethodID, appClass, "closeContextMenu", "()V"); + GET_AND_CHECK_STATIC_METHOD(resetOptionsMenuMethodID, appClass, "resetOptionsMenu", "()V"); + + jclass clazz; + FIND_AND_CHECK_CLASS("android/view/Menu"); + GET_AND_CHECK_METHOD(clearMenuMethodID, clazz, "clear", "()V"); + GET_AND_CHECK_METHOD(addMenuItemMethodID, clazz, "add", "(IIILjava/lang/CharSequence;)Landroid/view/MenuItem;"); + jfieldID menuNoneFiledId; + GET_AND_CHECK_STATIC_FIELD(menuNoneFiledId, clazz, "NONE", "I"); + menuNoneValue = env->GetStaticIntField(clazz, menuNoneFiledId); + + FIND_AND_CHECK_CLASS("android/view/ContextMenu"); + GET_AND_CHECK_METHOD(setHeaderTitleContextMenuMethodID, clazz, "setHeaderTitle","(Ljava/lang/CharSequence;)Landroid/view/ContextMenu;"); + + FIND_AND_CHECK_CLASS("android/view/MenuItem"); + GET_AND_CHECK_METHOD(setCheckableMenuItemMethodID, clazz, "setCheckable", "(Z)Landroid/view/MenuItem;"); + GET_AND_CHECK_METHOD(setCheckedMenuItemMethodID, clazz, "setChecked", "(Z)Landroid/view/MenuItem;"); + GET_AND_CHECK_METHOD(setEnabledMenuItemMethodID, clazz, "setEnabled", "(Z)Landroid/view/MenuItem;"); + GET_AND_CHECK_METHOD(setIconMenuItemMethodID, clazz, "setIcon", "(Landroid/graphics/drawable/Drawable;)Landroid/view/MenuItem;"); + GET_AND_CHECK_METHOD(setVisibleMenuItemMethodID, clazz, "setVisible", "(Z)Landroid/view/MenuItem;"); + return true; + } +} diff --git a/src/plugins/platforms/android/src/androidjnimenu.h b/src/plugins/platforms/android/src/androidjnimenu.h new file mode 100644 index 0000000000..7c5422f67b --- /dev/null +++ b/src/plugins/platforms/android/src/androidjnimenu.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDJNIMENU_H +#define ANDROIDJNIMENU_H + +#include + +class QAndroidPlatformMenuBar; +class QAndroidPlatformMenu; +class QAndroidPlatformMenuItem; +class QWindow; + +namespace QtAndroidMenu +{ + // Menu support + void showContextMenu(QAndroidPlatformMenu *menu, JNIEnv *env = 0); + void hideContextMenu(QAndroidPlatformMenu *menu); + void syncMenu(QAndroidPlatformMenu *menu); + void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu); + + void setMenuBar(QAndroidPlatformMenuBar *menuBar, QWindow *window); + void setActiveTopLevelWindow(QWindow *window); + void addMenuBar(QAndroidPlatformMenuBar *menuBar); + void removeMenuBar(QAndroidPlatformMenuBar *menuBar); + + // Menu support + bool registerNatives(JNIEnv *env); +} + +#endif // ANDROIDJNIMENU_H diff --git a/src/plugins/platforms/android/src/androidplatformplugin.cpp b/src/plugins/platforms/android/src/androidplatformplugin.cpp new file mode 100644 index 0000000000..71c5096e16 --- /dev/null +++ b/src/plugins/platforms/android/src/androidplatformplugin.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qandroidplatformintegration.h" + +QT_BEGIN_NAMESPACE + +class QAndroidPlatformIntegrationPlugin: public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "android.json") +public: + QPlatformIntegration *create(const QString &key, const QStringList ¶mList); +}; + + +QPlatformIntegration *QAndroidPlatformIntegrationPlugin::create(const QString &key, const QStringList ¶mList) +{ + Q_UNUSED(paramList); + if (key.toLower() == "android") + return new QAndroidPlatformIntegration(paramList); + return 0; +} + +QT_END_NAMESPACE +#include "androidplatformplugin.moc" + diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp new file mode 100644 index 0000000000..aa8ee57341 --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidopenglcontext.h" +#include "qandroidopenglplatformwindow.h" +#include "qandroidplatformintegration.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +QAndroidOpenGLContext::QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration, + const QSurfaceFormat &format, + QPlatformOpenGLContext *share, + EGLDisplay display, + EGLenum eglApi) + : QEglFSContext(format, share, display, eglApi) + , m_platformIntegration(integration) +{ +} + +void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface) +{ + QEglFSContext::swapBuffers(surface); + + QAndroidOpenGLPlatformWindow *primaryWindow = m_platformIntegration->primaryWindow(); + if (primaryWindow == surface) { + primaryWindow->lock(); + QSize size = primaryWindow->scheduledResize(); + if (size.isValid()) { + QRect geometry(QPoint(0, 0), size); + primaryWindow->setGeometry(geometry); + primaryWindow->scheduleResize(QSize()); + } + primaryWindow->unlock(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h new file mode 100644 index 0000000000..c4c5a430ad --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDOPENGLCONTEXT_H +#define QANDROIDOPENGLCONTEXT_H + +#include +#include "qeglfscontext.h" + +QT_BEGIN_NAMESPACE + +class QAndroidPlatformIntegration; +class QAndroidOpenGLContext : public QEglFSContext +{ +public: + QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration, + const QSurfaceFormat &format, + QPlatformOpenGLContext *share, + EGLDisplay display, + EGLenum eglApi = EGL_OPENGL_ES_API); + + void swapBuffers(QPlatformSurface *surface); + +private: + const QAndroidPlatformIntegration *m_platformIntegration; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDOPENGLCONTEXT_H diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp new file mode 100644 index 0000000000..15c6559157 --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidopenglplatformwindow.h" +#include "androidjnimain.h" +#include + +QT_BEGIN_NAMESPACE + +QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window) + : QEglFSWindow(window) +{ +} + +bool QAndroidOpenGLPlatformWindow::isExposed() const +{ + return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed(); +} + +void QAndroidOpenGLPlatformWindow::invalidateSurface() +{ + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event + QWindowSystemInterface::flushWindowSystemEvents(); + QEglFSWindow::invalidateSurface(); +} + +void QAndroidOpenGLPlatformWindow::resetSurface() +{ + QEglFSWindow::resetSurface(); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event + QWindowSystemInterface::flushWindowSystemEvents(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h new file mode 100644 index 0000000000..b835cb3246 --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDOPENGLPLATFORMWINDOW_H +#define QANDROIDOPENGLPLATFORMWINDOW_H + +#include "qeglfswindow.h" +#include + +QT_BEGIN_NAMESPACE + +class QAndroidOpenGLPlatformWindow : public QEglFSWindow +{ +public: + QAndroidOpenGLPlatformWindow(QWindow *window); + + QSize scheduledResize() const { return m_scheduledResize; } + void scheduleResize(const QSize &size) { m_scheduledResize = size; } + + void lock() { m_lock.lock(); } + void unlock() { m_lock.unlock(); } + + bool isExposed() const; + + void invalidateSurface(); + void resetSurface(); + +private: + QSize m_scheduledResize; + QMutex m_lock; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDOPENGLPLATFORMWINDOW_H diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp new file mode 100644 index 0000000000..cd415843a7 --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfshooks.h" +#include "androidjnimain.h" +#include "qandroidplatformintegration.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class QEglFSAndroidHooks: public QEglFSHooks +{ +public: + void platformInit(); + void platformDestroy(); + EGLNativeDisplayType platformDisplay() const; + QSize screenSize() const; + QSizeF physicalScreenSize() const; + int screenDepth() const; + QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; + EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format); + void destroyNativeWindow(EGLNativeWindowType window); + bool hasCapability(QPlatformIntegration::Capability cap) const; +}; + +void QEglFSAndroidHooks::platformInit() +{ +} + +void QEglFSAndroidHooks::platformDestroy() +{ +} + +EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const +{ + return EGL_DEFAULT_DISPLAY; +} + +QSize QEglFSAndroidHooks::screenSize() const +{ + return QtAndroid::nativeWindowSize(); +} + +QSizeF QEglFSAndroidHooks::physicalScreenSize() const +{ + return QSizeF(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth, QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight); +} + + +EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format) +{ + ANativeWindow *window = QtAndroid::nativeWindow(); + if (window != 0) + ANativeWindow_acquire(window); + + return window; +} + +void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window) +{ + ANativeWindow_release(window); +} + +bool QEglFSAndroidHooks::hasCapability(QPlatformIntegration::Capability capability) const +{ + switch (capability) { + case QPlatformIntegration::OpenGL: return true; + case QPlatformIntegration::ThreadedOpenGL: return true; + default: return false; + }; +} + +int QEglFSAndroidHooks::screenDepth() const +{ + // ### Hardcoded + return 32; +} + +QSurfaceFormat QEglFSAndroidHooks::surfaceFormatFor(const QSurfaceFormat &inputFormat) const +{ + QSurfaceFormat ret(inputFormat); + ret.setAlphaBufferSize(8); + ret.setRedBufferSize(8); + ret.setGreenBufferSize(8); + ret.setBlueBufferSize(8); + return ret; +} + +static QEglFSAndroidHooks eglFSAndroidHooks; +QEglFSHooks *platformHooks = &eglFSAndroidHooks; + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp new file mode 100644 index 0000000000..f3cb2586cc --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp @@ -0,0 +1,288 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidassetsfileenginehandler.h" +#include "androidjnimain.h" + +#include + +class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator +{ +public: + AndroidAbstractFileEngineIterator(QDir::Filters filters, + const QStringList &nameFilters, + AAssetDir *asset, + const QString &path) + : QAbstractFileEngineIterator(filters, nameFilters) + { + AAssetDir_rewind(asset); + const char *fileName; + while ((fileName = AAssetDir_getNextFileName(asset))) + m_items << fileName; + m_index = -1; + m_path = path; + } + + virtual QFileInfo currentFileInfo() const + { + return QFileInfo(currentFilePath()); + } + + virtual QString currentFileName() const + { + if (m_index < 0 || m_index >= m_items.size()) + return QString(); + return m_items[m_index]; + } + + virtual QString currentFilePath() const + { + return m_path + currentFileName(); + } + + virtual bool hasNext() const + { + return m_items.size() && (m_index < m_items.size() - 1); + } + + virtual QString next() + { + if (!hasNext()) + return QString(); + m_index++; + return currentFileName(); + } + +private: + QString m_path; + QStringList m_items; + int m_index; +}; + +class AndroidAbstractFileEngine: public QAbstractFileEngine +{ +public: + explicit AndroidAbstractFileEngine(AAsset *asset, const QString &fileName) + { + m_assetDir = 0; + m_assetFile = asset; + m_fileName = fileName; + } + + explicit AndroidAbstractFileEngine(AAssetDir *asset, const QString &fileName) + { + m_assetFile = 0; + m_assetDir = asset; + m_fileName = fileName; + if (!m_fileName.endsWith(QChar(QLatin1Char('/')))) + m_fileName += "/"; + } + + ~AndroidAbstractFileEngine() + { + close(); + if (m_assetDir) + AAssetDir_close(m_assetDir); + } + + virtual bool open(QIODevice::OpenMode openMode) + { + if (m_assetFile) + return openMode & QIODevice::ReadOnly; + return false; + } + + virtual bool close() + { + if (m_assetFile) { + AAsset_close(m_assetFile); + m_assetFile = 0; + return true; + } + return false; + } + + virtual qint64 size() const + { + if (m_assetFile) + return AAsset_getLength(m_assetFile); + return -1; + } + + virtual qint64 pos() const + { + if (m_assetFile) + return AAsset_seek(m_assetFile, 0, SEEK_CUR); + return -1; + } + + virtual bool seek(qint64 pos) + { + if (m_assetFile) + return pos == AAsset_seek(m_assetFile, pos, SEEK_SET); + return false; + } + + virtual qint64 read(char *data, qint64 maxlen) + { + if (m_assetFile) + return AAsset_read(m_assetFile, data, maxlen); + return -1; + } + + virtual bool isSequential() const + { + return false; + } + + virtual bool caseSensitive() const + { + return true; + } + + virtual bool isRelativePath() const + { + return false; + } + + virtual FileFlags fileFlags(FileFlags type = FileInfoAll) const + { + FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag); + if (m_assetFile) + flags |= FileType; + if (m_assetDir) + flags |= DirectoryType; + + return type & flags; + } + + virtual QString fileName(FileName file = DefaultName) const + { + int pos; + switch (file) { + case DefaultName: + case AbsoluteName: + case CanonicalName: + return m_fileName; + case BaseName: + if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1) + return m_fileName.mid(pos); + else + return m_fileName; + case PathName: + case AbsolutePathName: + case CanonicalPathName: + if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1) + return m_fileName.left(pos); + else + return m_fileName; + default: + return QString(); + } + } + + virtual void setFileName(const QString &file) + { + if (file == m_fileName) + return; + + m_fileName = file; + if (!m_fileName.endsWith(QChar(QLatin1Char('/')))) + m_fileName += "/"; + + close(); + } + + virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) + { + if (m_assetDir) + return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName); + return 0; + } + +private: + AAsset *m_assetFile; + AAssetDir *m_assetDir; + QString m_fileName; +}; + + +AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler() +{ + m_assetManager = QtAndroid::assetManager(); +} + +AndroidAssetsFileEngineHandler::~AndroidAssetsFileEngineHandler() +{ +} + +QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &fileName) const +{ + if (fileName.isEmpty()) + return 0; + + if (!fileName.startsWith(QLatin1String("assets:/"))) + return 0; + + int prefixSize=8; + + m_path.clear(); + if (!fileName.endsWith(QLatin1Char('/'))) { + m_path = fileName.toUtf8(); + AAsset *asset = AAssetManager_open(m_assetManager, + m_path.constData() + prefixSize, + AASSET_MODE_BUFFER); + if (asset) + return new AndroidAbstractFileEngine(asset, fileName); + } + + if (!m_path.size()) + m_path = fileName.left(fileName.length() - 1).toUtf8(); + + AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, m_path.constData() + prefixSize); + if (assetDir) { + if (AAssetDir_getNextFileName(assetDir)) + return new AndroidAbstractFileEngine(assetDir, fileName); + else + AAssetDir_close(assetDir); + } + return 0; +} diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h new file mode 100644 index 0000000000..9bff6a012e --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDASSETSFILEENGINEHANDLER_H +#define QANDROIDASSETSFILEENGINEHANDLER_H + +#include +#include + +class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler +{ +public: + AndroidAssetsFileEngineHandler(); + virtual ~AndroidAssetsFileEngineHandler(); + QAbstractFileEngine *create(const QString &fileName) const; + +private: + AAssetManager *m_assetManager; + mutable QByteArray m_path; +}; + +#endif // QANDROIDASSETSFILEENGINEHANDLER_H diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/src/qandroidinputcontext.cpp new file mode 100644 index 0000000000..37fb605ea8 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidinputcontext.cpp @@ -0,0 +1,644 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qandroidinputcontext.h" +#include "androidjnimain.h" +#include "androidjniinput.h" +#include +#include +#include +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +static QAndroidInputContext *m_androidInputContext = 0; +static char const *const QtNativeInputConnectionClassName = "org/qtproject/qt5/android/QtNativeInputConnection"; +static char const *const QtExtractedTextClassName = "org/qtproject/qt5/android/QtExtractedText"; +static jclass m_extractedTextClass = 0; +static jmethodID m_classConstructorMethodID = 0; +static jfieldID m_partialEndOffsetFieldID = 0; +static jfieldID m_partialStartOffsetFieldID = 0; +static jfieldID m_selectionEndFieldID = 0; +static jfieldID m_selectionStartFieldID = 0; +static jfieldID m_startOffsetFieldID = 0; +static jfieldID m_textFieldID = 0; + +static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + jboolean isCopy; + const jchar *jstr = env->GetStringChars(text, &isCopy); + QString str(reinterpret_cast(jstr), env->GetStringLength(text)); + env->ReleaseStringChars(text, jstr); + + return m_androidInputContext->commitText(str, newCursorPosition); +} + +static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint leftLength, jint rightLength) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->deleteSurroundingText(leftLength, rightLength); +} + +static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->finishComposingText(); +} + +static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes) +{ + if (!m_androidInputContext) + return 0; + + return m_androidInputContext->getCursorCapsMode(reqModes); +} + +static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars, int hintMaxLines, jint flags) +{ + if (!m_androidInputContext) + return 0; + + const QAndroidInputContext::ExtractedText &extractedText = + m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags); + + jobject object = env->NewObject(m_extractedTextClass, m_classConstructorMethodID); + env->SetIntField(object, m_partialStartOffsetFieldID, extractedText.partialStartOffset); + env->SetIntField(object, m_partialEndOffsetFieldID, extractedText.partialEndOffset); + env->SetIntField(object, m_selectionStartFieldID, extractedText.selectionStart); + env->SetIntField(object, m_selectionEndFieldID, extractedText.selectionEnd); + env->SetIntField(object, m_startOffsetFieldID, extractedText.startOffset); + env->SetObjectField(object, + m_textFieldID, + env->NewString(reinterpret_cast(extractedText.text.constData()), + jsize(extractedText.text.length()))); + + return object; +} + +static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags) +{ + if (!m_androidInputContext) + return 0; + + const QString &text = m_androidInputContext->getSelectedText(flags); + return env->NewString(reinterpret_cast(text.constData()), jsize(text.length())); +} + +static jstring getTextAfterCursor(JNIEnv *env, jobject /*thiz*/, jint length, jint flags) +{ + if (!m_androidInputContext) + return 0; + + const QString &text = m_androidInputContext->getTextAfterCursor(length, flags); + return env->NewString(reinterpret_cast(text.constData()), jsize(text.length())); +} + +static jstring getTextBeforeCursor(JNIEnv *env, jobject /*thiz*/, jint length, jint flags) +{ + if (!m_androidInputContext) + return 0; + + const QString &text = m_androidInputContext->getTextBeforeCursor(length, flags); + return env->NewString(reinterpret_cast(text.constData()), jsize(text.length())); +} + +static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + jboolean isCopy; + const jchar *jstr = env->GetStringChars(text, &isCopy); + QString str(reinterpret_cast(jstr), env->GetStringLength(text)); + env->ReleaseStringChars(text, jstr); + + return m_androidInputContext->setComposingText(str, newCursorPosition); +} + +static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint end) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->setSelection(start, end); +} + +static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->selectAll(); +} + +static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->cut(); +} + +static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->copy(); +} + +static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->copyURL(); +} + +static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/) +{ + if (!m_androidInputContext) + return JNI_FALSE; + + return m_androidInputContext->paste(); +} + + +static JNINativeMethod methods[] = { + {"commitText", "(Ljava/lang/String;I)Z", (void *)commitText}, + {"deleteSurroundingText", "(II)Z", (void *)deleteSurroundingText}, + {"finishComposingText", "()Z", (void *)finishComposingText}, + {"getCursorCapsMode", "(I)I", (void *)getCursorCapsMode}, + {"getExtractedText", "(III)Lorg/qtproject/qt5/android/QtExtractedText;", (void *)getExtractedText}, + {"getSelectedText", "(I)Ljava/lang/String;", (void *)getSelectedText}, + {"getTextAfterCursor", "(II)Ljava/lang/String;", (void *)getTextAfterCursor}, + {"getTextBeforeCursor", "(II)Ljava/lang/String;", (void *)getTextBeforeCursor}, + {"setComposingText", "(Ljava/lang/String;I)Z", (void *)setComposingText}, + {"setSelection", "(II)Z", (void *)setSelection}, + {"selectAll", "()Z", (void *)selectAll}, + {"cut", "()Z", (void *)cut}, + {"copy", "()Z", (void *)copy}, + {"copyURL", "()Z", (void *)copyURL}, + {"paste", "()Z", (void *)paste} +}; + + +QAndroidInputContext::QAndroidInputContext():QPlatformInputContext() +{ + JNIEnv *env = 0; + if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) { + qCritical() << "AttachCurrentThread failed"; + return; + } + + jclass clazz = QtAndroid::findClass(QtNativeInputConnectionClassName, env); + if (clazz == NULL) { + qCritical() << "Native registration unable to find class '" + << QtNativeInputConnectionClassName + << "'"; + return; + } + + if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) { + qCritical() << "RegisterNatives failed for '" + << QtNativeInputConnectionClassName + << "'"; + return; + } + + clazz = QtAndroid::findClass(QtExtractedTextClassName, env); + if (clazz == NULL) { + qCritical() << "Native registration unable to find class '" + << QtExtractedTextClassName + << "'"; + return; + } + + m_extractedTextClass = static_cast(env->NewGlobalRef(clazz)); + m_classConstructorMethodID = env->GetMethodID(m_extractedTextClass, "", "()V"); + if (m_classConstructorMethodID == NULL) { + qCritical() << "GetMethodID failed"; + return; + } + + m_partialEndOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialEndOffset", "I"); + if (m_partialEndOffsetFieldID == NULL) { + qCritical() << "Can't find field partialEndOffset"; + return; + } + + m_partialStartOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialStartOffset", "I"); + if (m_partialStartOffsetFieldID == NULL) { + qCritical() << "Can't find field partialStartOffset"; + return; + } + + m_selectionEndFieldID = env->GetFieldID(m_extractedTextClass, "selectionEnd", "I"); + if (m_selectionEndFieldID == NULL) { + qCritical() << "Can't find field selectionEnd"; + return; + } + + m_selectionStartFieldID = env->GetFieldID(m_extractedTextClass, "selectionStart", "I"); + if (m_selectionStartFieldID == NULL) { + qCritical() << "Can't find field selectionStart"; + return; + } + + m_startOffsetFieldID = env->GetFieldID(m_extractedTextClass, "startOffset", "I"); + if (m_startOffsetFieldID == NULL) { + qCritical() << "Can't find field startOffset"; + return; + } + + m_textFieldID = env->GetFieldID(m_extractedTextClass, "text", "Ljava/lang/String;"); + if (m_textFieldID == NULL) { + qCritical() << "Can't find field text"; + return; + } + qRegisterMetaType("QInputMethodEvent*"); + qRegisterMetaType("QInputMethodQueryEvent*"); + m_androidInputContext = this; +} + +QAndroidInputContext::~QAndroidInputContext() +{ + m_androidInputContext = 0; + m_extractedTextClass = 0; + m_partialEndOffsetFieldID = 0; + m_partialStartOffsetFieldID = 0; + m_selectionEndFieldID = 0; + m_selectionStartFieldID = 0; + m_startOffsetFieldID = 0; + m_textFieldID = 0; +} + +void QAndroidInputContext::reset() +{ + clear(); + if (qGuiApp->focusObject()) + QtAndroidInput::resetSoftwareKeyboard(); + else + QtAndroidInput::hideSoftwareKeyboard(); +} + +void QAndroidInputContext::commit() +{ + finishComposingText(); + + QSharedPointer query = focusObjectInputMethodQuery(); + if (!query.isNull()) { + const int cursorPos = query->value(Qt::ImCursorPosition).toInt(); + QtAndroidInput::updateSelection(cursorPos, cursorPos, -1, -1); //selection empty and no pre-edit text + } +} + +void QAndroidInputContext::update(Qt::InputMethodQueries queries) +{ + QSharedPointer query = focusObjectInputMethodQuery(queries); + if (query.isNull()) + return; +#warning TODO extract the needed data from query +} + +void QAndroidInputContext::invokeAction(QInputMethod::Action action, int cursorPosition) +{ +#warning TODO Handle at least QInputMethod::ContextMenu action + Q_UNUSED(action) + Q_UNUSED(cursorPosition) + + if (action == QInputMethod::Click) + commit(); +} + +QRectF QAndroidInputContext::keyboardRect() const +{ + return QPlatformInputContext::keyboardRect(); +} + +bool QAndroidInputContext::isAnimating() const +{ + return false; +} + +void QAndroidInputContext::showInputPanel() +{ + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return; + QRectF itemRect = qGuiApp->inputMethod()->inputItemRectangle(); + QRect rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(itemRect).toRect(); + QWindow *window = qGuiApp->focusWindow(); + if (window) + rect = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); + + QtAndroidInput::showSoftwareKeyboard(rect.left(), + rect.top(), + rect.width(), + rect.height(), + query->value(Qt::ImHints).toUInt()); +} + +void QAndroidInputContext::hideInputPanel() +{ + QtAndroidInput::hideSoftwareKeyboard(); +} + +bool QAndroidInputContext::isInputPanelVisible() const +{ + return QtAndroidInput::isSoftwareKeyboardVisible(); +} + +bool QAndroidInputContext::isComposing() const +{ + return m_composingText.length(); +} + +void QAndroidInputContext::clear() +{ + m_composingText.clear(); + m_extractedText.clear(); +} + +void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodEvent *event) +{ + QCoreApplication::sendEvent(receiver, event); +} + +void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodQueryEvent *event) +{ + QCoreApplication::sendEvent(receiver, event); +} + +jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/) +{ + m_composingText = text; + return finishComposingText(); +} + +jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint rightLength) +{ + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_TRUE; + + m_composingText.clear(); + + QInputMethodEvent event; + event.setCommitString(QString(), -leftLength, leftLength+rightLength); + sendInputMethodEvent(&event); + clear(); + + return JNI_TRUE; +} + +jboolean QAndroidInputContext::finishComposingText() +{ + QInputMethodEvent event; + event.setCommitString(m_composingText); + sendInputMethodEvent(&event); + clear(); + + return JNI_TRUE; +} + +jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/) +{ + jint res = 0; + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return res; + + const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt(); + + if (qtInputMethodHints & Qt::ImhPreferUppercase) + res = CAP_MODE_SENTENCES; + + if (qtInputMethodHints & Qt::ImhUppercaseOnly) + res = CAP_MODE_CHARACTERS; + + return res; +} + +const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/) +{ + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return m_extractedText; + + if (hintMaxChars) + m_extractedText.text = query->value(Qt::ImSurroundingText).toString().right(hintMaxChars); + + m_extractedText.startOffset = query->value(Qt::ImCursorPosition).toInt(); + const QString &selection = query->value(Qt::ImCurrentSelection).toString(); + const int selLen = selection.length(); + if (selLen) { + m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt(); + m_extractedText.selectionEnd = m_extractedText.startOffset; + } + + return m_extractedText; +} + +QString QAndroidInputContext::getSelectedText(jint /*flags*/) +{ + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return QString(); + + return query->value(Qt::ImCurrentSelection).toString(); +} + +QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/) +{ + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return QString(); + + QString text = query->value(Qt::ImSurroundingText).toString(); + if (!text.length()) + return text; + + int cursorPos = query->value(Qt::ImCursorPosition).toInt(); + return text.mid(cursorPos, length); +} + +QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/) +{ + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return QString(); + + QString text = query->value(Qt::ImSurroundingText).toString(); + if (!text.length()) + return text; + + int cursorPos = query->value(Qt::ImCursorPosition).toInt(); + const int wordLeftPos = cursorPos - length; + return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos); +} + +jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition) +{ + if (newCursorPosition > 0) + newCursorPosition += text.length() - 1; + m_composingText = text; + QList attributes; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, + newCursorPosition, + 1, + QVariant())); + // Show compose text underlined + QTextCharFormat underlined; + underlined.setFontUnderline(true); + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, text.length(), + QVariant(underlined))); + + QInputMethodEvent event(m_composingText, attributes); + sendInputMethodEvent(&event); + + QSharedPointer query = focusObjectInputMethodQuery(); + if (!query.isNull()) { + int cursorPos = query->value(Qt::ImCursorPosition).toInt(); + int preeditLength = text.length(); + QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, cursorPos, cursorPos+preeditLength); + } + + return JNI_TRUE; +} + +jboolean QAndroidInputContext::setSelection(jint start, jint end) +{ + QList attributes; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, + start, + end - start, + QVariant())); + + QInputMethodEvent event(QString(), attributes); + sendInputMethodEvent(&event); + return JNI_TRUE; +} + +jboolean QAndroidInputContext::selectAll() +{ +#warning TODO + return JNI_FALSE; +} + +jboolean QAndroidInputContext::cut() +{ +#warning TODO + return JNI_FALSE; +} + +jboolean QAndroidInputContext::copy() +{ +#warning TODO + return JNI_FALSE; +} + +jboolean QAndroidInputContext::copyURL() +{ +#warning TODO + return JNI_FALSE; +} + +jboolean QAndroidInputContext::paste() +{ +#warning TODO + return JNI_FALSE; +} + +QSharedPointer QAndroidInputContext::focusObjectInputMethodQuery(Qt::InputMethodQueries queries) +{ +#warning TODO make qGuiApp->focusObject() thread safe !!! + QObject *focusObject = qGuiApp->focusObject(); + if (!focusObject) + return QSharedPointer(); + + QSharedPointer ret = QSharedPointer(new QInputMethodQueryEvent(queries)); + if (qGuiApp->thread()==QThread::currentThread()) { + QCoreApplication::sendEvent(focusObject, ret.data()); + } else { + QMetaObject::invokeMethod(this, + "sendEvent", + Qt::BlockingQueuedConnection, + Q_ARG(QObject*, focusObject), + Q_ARG(QInputMethodQueryEvent*, ret.data())); + } + + return ret; +} + +void QAndroidInputContext::sendInputMethodEvent(QInputMethodEvent *event) +{ +#warning TODO make qGuiApp->focusObject() thread safe !!! + QObject *focusObject = qGuiApp->focusObject(); + if (!focusObject) + return; + + if (qGuiApp->thread() == QThread::currentThread()) { + QCoreApplication::sendEvent(focusObject, event); + } else { + QMetaObject::invokeMethod(this, + "sendEvent", + Qt::BlockingQueuedConnection, + Q_ARG(QObject*, focusObject), + Q_ARG(QInputMethodEvent*, event)); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/src/qandroidinputcontext.h new file mode 100644 index 0000000000..e2b8107044 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidinputcontext.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDINPUTCONTEXT_H +#define ANDROIDINPUTCONTEXT_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QAndroidInputContext: public QPlatformInputContext +{ + Q_OBJECT + enum CapsMode + { + CAP_MODE_CHARACTERS = 0x00001000, + CAP_MODE_SENTENCES = 0x00004000, + CAP_MODE_WORDS = 0x00002000 + }; + +public: + struct ExtractedText + { + ExtractedText() { clear(); } + + void clear() + { + partialEndOffset = partialStartOffset = selectionEnd = selectionStart = startOffset = -1; + text.clear(); + } + + int partialEndOffset; + int partialStartOffset; + int selectionEnd; + int selectionStart; + int startOffset; + QString text; + }; + +public: + QAndroidInputContext(); + ~QAndroidInputContext(); + bool isValid() const { return true; } + + void reset(); + void commit(); + void update(Qt::InputMethodQueries queries); + void invokeAction(QInputMethod::Action action, int cursorPosition); + QRectF keyboardRect() const; + bool isAnimating() const; + void showInputPanel(); + void hideInputPanel(); + bool isInputPanelVisible() const; + + bool isComposing() const; + void clear(); + + //---------------// + jboolean commitText(const QString &text, jint newCursorPosition); + jboolean deleteSurroundingText(jint leftLength, jint rightLength); + jboolean finishComposingText(); + jint getCursorCapsMode(jint reqModes); + const ExtractedText &getExtractedText(jint hintMaxChars, jint hintMaxLines, jint flags); + QString getSelectedText(jint flags); + QString getTextAfterCursor(jint length, jint flags); + QString getTextBeforeCursor(jint length, jint flags); + jboolean setComposingText(const QString &text, jint newCursorPosition); + jboolean setSelection(jint start, jint end); + jboolean selectAll(); + jboolean cut(); + jboolean copy(); + jboolean copyURL(); + jboolean paste(); + +private: + QSharedPointer focusObjectInputMethodQuery(Qt::InputMethodQueries queries = Qt::ImQueryAll); + void sendInputMethodEvent(QInputMethodEvent *event); + +private slots: + virtual void sendEvent(QObject *receiver, QInputMethodEvent *event); + virtual void sendEvent(QObject *receiver, QInputMethodQueryEvent *event); + +private: + ExtractedText m_extractedText; + QString m_composingText; +}; + +QT_END_NAMESPACE + +#endif // ANDROIDINPUTCONTEXT_H diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp new file mode 100644 index 0000000000..bc48b4935b --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformclipboard.h" +#include "androidjniclipboard.h" +#ifndef QT_NO_CLIPBOARD +#include + +QT_BEGIN_NAMESPACE + +QAndroidPlatformClipboard::QAndroidPlatformClipboard() +{ + QtAndroidClipboard::setClipboardListener(this); +} + +QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode) +{ + if (QClipboard::Clipboard != mode || !QtAndroidClipboard::hasClipboardText()) + return 0; + + QMimeData *mimeData = new QMimeData(); + mimeData->setText(QtAndroidClipboard::clipboardText()); + return mimeData; +} + +void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) +{ + if (!data || !data->hasText() || QClipboard::Clipboard != mode) + return; + + QtAndroidClipboard::setClipboardText(data->text()); +} + +bool QAndroidPlatformClipboard::supportsMode(QClipboard::Mode mode) const +{ + return QClipboard::Clipboard == mode; +} + +QT_END_NAMESPACE + +#endif // QT_NO_CLIPBOARD diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.h b/src/plugins/platforms/android/src/qandroidplatformclipboard.h new file mode 100644 index 0000000000..644f326934 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformclipboard.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMCLIPBOARD_H +#define QANDROIDPLATFORMCLIPBOARD_H + +#include + +#ifndef QT_NO_CLIPBOARD +QT_BEGIN_NAMESPACE + +class QAndroidPlatformClipboard: public QPlatformClipboard +{ +public: + QAndroidPlatformClipboard(); + + virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); + virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); + virtual bool supportsMode(QClipboard::Mode mode) const; +}; + +QT_END_NAMESPACE +#endif // QT_NO_CLIPBOARD + +#endif // QANDROIDPLATFORMCLIPBOARD_H diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp new file mode 100644 index 0000000000..7f68b44ed8 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qandroidplatformfontdatabase.h" + +QString QAndroidPlatformFontDatabase::fontDir() const +{ + return QLatin1String("/system/fonts"); +} + +void QAndroidPlatformFontDatabase::populateFontDatabase() +{ + QString fontpath = fontDir(); + + if (!QFile::exists(fontpath)) { + qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?", + qPrintable(fontpath)); + } + + QDir dir(fontpath, QLatin1String("*.ttf")); + for (int i = 0; i < int(dir.count()); ++i) { + const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i])); + addTTFile(QByteArray(), file); + } +} + +QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &family, + QFont::Style style, + QFont::StyleHint styleHint, + QChar::Script script) const +{ + Q_UNUSED(family); + Q_UNUSED(style); + Q_UNUSED(script); + if (styleHint == QFont::Monospace) + return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";"); + + return QString(qgetenv("QT_ANDROID_FONTS")).split(";"); +} diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h new file mode 100644 index 0000000000..3cbfe95d36 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMFONTDATABASE_H +#define QANDROIDPLATFORMFONTDATABASE_H + +#include + +class QAndroidPlatformFontDatabase: public QBasicFontDatabase +{ +public: + QString fontDir() const; + void populateFontDatabase(); + QStringList fallbacksForFamily(const QString &family, + QFont::Style style, + QFont::StyleHint styleHint, + QChar::Script script) const; +}; + +#endif // QANDROIDPLATFORMFONTDATABASE_H diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp new file mode 100644 index 0000000000..1091416ccc --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -0,0 +1,283 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformintegration.h" +#include "qabstracteventdispatcher.h" +#include "androidjnimain.h" +#include +#include +#include +#include +#include "qandroidplatformservices.h" +#include "qandroidplatformfontdatabase.h" +#include "qandroidplatformclipboard.h" +#include + +#ifndef ANDROID_PLUGIN_OPENGL +# include "qandroidplatformscreen.h" +# include "qandroidplatformwindow.h" +# include +#else +# include "qeglfswindow.h" +# include "androidjnimenu.h" +# include "qandroidopenglcontext.h" +# include "qandroidopenglplatformwindow.h" +# include "qeglfshooks.h" +# include +#endif + +#include "qandroidplatformtheme.h" + +QT_BEGIN_NAMESPACE + +int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320; +int QAndroidPlatformIntegration::m_defaultGeometryHeight = 455; +int QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth = 50; +int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71; + +void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) +{ + if (resource=="JavaVM") + return QtAndroid::javaVM(); + if (resource == "QtActivity") + return QtAndroid::activity(); + + return 0; +} + +QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶mList) +#ifdef ANDROID_PLUGIN_OPENGL + : m_primaryWindow(0) +#endif +{ + Q_UNUSED(paramList); + +#ifndef ANDROID_PLUGIN_OPENGL + m_eventDispatcher = createUnixEventDispatcher(); +#endif + + m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface(); + +#ifndef ANDROID_PLUGIN_OPENGL + m_primaryScreen = new QAndroidPlatformScreen(); + screenAdded(m_primaryScreen); + m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight)); + m_primaryScreen->setGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight)); +#endif + + m_mainThread = QThread::currentThread(); + QtAndroid::setAndroidPlatformIntegration(this); + + m_androidFDB = new QAndroidPlatformFontDatabase(); + m_androidPlatformServices = new QAndroidPlatformServices(); + m_androidPlatformClipboard = new QAndroidPlatformClipboard(); +} + +bool QAndroidPlatformIntegration::hasCapability(Capability cap) const +{ + switch (cap) { + case ThreadedPixmaps: return true; + default: +#ifndef ANDROID_PLUGIN_OPENGL + return QPlatformIntegration::hasCapability(cap); +#else + return QEglFSIntegration::hasCapability(cap); +#endif + } +} + +#ifndef ANDROID_PLUGIN_OPENGL +QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QFbBackingStore(window); +} + +QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const +{ + return new QAndroidPlatformWindow(window); +} + +QAbstractEventDispatcher *QAndroidPlatformIntegration::guiThreadEventDispatcher() const +{ + return m_eventDispatcher; +} +#else // !ANDROID_PLUGIN_OPENGL +QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const +{ + if (m_primaryWindow != 0) { + qWarning("QAndroidPlatformIntegration::createPlatformWindow: Unsupported case: More than " + "one top-level window created."); + } + + m_primaryWindow = new QAndroidOpenGLPlatformWindow(window); + m_primaryWindow->requestActivateWindow(); + QtAndroidMenu::setActiveTopLevelWindow(window); + + return m_primaryWindow; +} + +void QAndroidPlatformIntegration::invalidateNativeSurface() +{ + if (m_primaryWindow != 0) + m_primaryWindow->invalidateSurface(); +} + +void QAndroidPlatformIntegration::surfaceChanged() +{ + if (m_primaryWindow != 0) + m_primaryWindow->resetSurface(); +} + +QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + return new QAndroidOpenGLContext(this, + QEglFSHooks::hooks()->surfaceFormatFor(context->format()), + context->shareHandle(), + display()); +} +#endif // ANDROID_PLUGIN_OPENGL + +QAndroidPlatformIntegration::~QAndroidPlatformIntegration() +{ + delete m_androidPlatformNativeInterface; + delete m_androidFDB; + QtAndroid::setAndroidPlatformIntegration(NULL); +} +QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const +{ + return m_androidFDB; +} + +#ifndef QT_NO_CLIPBOARD +QPlatformClipboard *QAndroidPlatformIntegration::clipboard() const +{ +static QAndroidPlatformClipboard *clipboard = 0; + if (!clipboard) + clipboard = new QAndroidPlatformClipboard; + + return clipboard; +} +#endif + +QPlatformInputContext *QAndroidPlatformIntegration::inputContext() const +{ + return &m_platformInputContext; +} + +QPlatformNativeInterface *QAndroidPlatformIntegration::nativeInterface() const +{ + return m_androidPlatformNativeInterface; +} + +QPlatformServices *QAndroidPlatformIntegration::services() const +{ + return m_androidPlatformServices; +} + +static const QLatin1String androidThemeName("android"); +QStringList QAndroidPlatformIntegration::themeNames() const +{ + return QStringList(QString(androidThemeName)); +} + +QPlatformTheme *QAndroidPlatformIntegration::createPlatformTheme(const QString &name) const +{ + if (androidThemeName == name) + return new QAndroidPlatformTheme; + + return 0; +} + +void QAndroidPlatformIntegration::setDefaultDisplayMetrics(int gw, int gh, int sw, int sh) +{ + m_defaultGeometryWidth = gw; + m_defaultGeometryHeight = gh; + m_defaultPhysicalSizeWidth = sw; + m_defaultPhysicalSizeHeight = sh; +} + +void QAndroidPlatformIntegration::setDefaultDesktopSize(int gw, int gh) +{ + m_defaultGeometryWidth = gw; + m_defaultGeometryHeight = gh; +} + + +#ifndef ANDROID_PLUGIN_OPENGL +void QAndroidPlatformIntegration::setDesktopSize(int width, int height) +{ + if (m_primaryScreen) + QMetaObject::invokeMethod(m_primaryScreen, "setGeometry", Qt::AutoConnection, Q_ARG(QRect, QRect(0,0,width, height))); +} + +void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height) +{ + if (m_primaryScreen) + QMetaObject::invokeMethod(m_primaryScreen, "setPhysicalSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height))); +} +#else +void QAndroidPlatformIntegration::setDesktopSize(int width, int height) +{ + m_defaultGeometryWidth = width; + m_defaultGeometryHeight = height; +} + +void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height) +{ + m_defaultPhysicalSizeWidth = width; + m_defaultPhysicalSizeHeight = height; +} + +#endif + +void QAndroidPlatformIntegration::pauseApp() +{ + if (QAbstractEventDispatcher::instance(m_mainThread)) + QAbstractEventDispatcher::instance(m_mainThread)->interrupt(); +} + +void QAndroidPlatformIntegration::resumeApp() +{ + if (QAbstractEventDispatcher::instance(m_mainThread)) + QAbstractEventDispatcher::instance(m_mainThread)->wakeUp(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h new file mode 100644 index 0000000000..7dde277d25 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMINTERATION_H +#define QANDROIDPLATFORMINTERATION_H + +#include +#include +#include +#include + +#include +#include "qandroidinputcontext.h" + +#ifndef ANDROID_PLUGIN_OPENGL +# include "qandroidplatformscreen.h" +#else +# include "qeglfsintegration.h" +#endif + +QT_BEGIN_NAMESPACE + +class QDesktopWidget; +class QAndroidPlatformServices; + +#ifdef ANDROID_PLUGIN_OPENGL +class QAndroidOpenGLPlatformWindow; +#endif + +class QAndroidPlatformNativeInterface: public QPlatformNativeInterface +{ +public: + void *nativeResourceForIntegration(const QByteArray &resource); +}; + +class QAndroidPlatformIntegration +#ifndef ANDROID_PLUGIN_OPENGL + : public QPlatformIntegration +#else + : public QEglFSIntegration +#endif +{ + friend class QAndroidPlatformScreen; + +public: + QAndroidPlatformIntegration(const QStringList ¶mList); + ~QAndroidPlatformIntegration(); + + bool hasCapability(QPlatformIntegration::Capability cap) const; + +#ifndef ANDROID_PLUGIN_OPENGL + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QAndroidPlatformScreen *screen() { return m_primaryScreen; } +#else + QPlatformWindow *createPlatformWindow(QWindow *window) const; + void invalidateNativeSurface(); + void surfaceChanged(); + QAndroidOpenGLPlatformWindow *primaryWindow() const { return m_primaryWindow; } + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; +#endif + + virtual void setDesktopSize(int width, int height); + virtual void setDisplayMetrics(int width, int height); + bool isVirtualDesktop() { return true; } + + QPlatformFontDatabase *fontDatabase() const; + +#ifndef QT_NO_CLIPBOARD + QPlatformClipboard *clipboard() const; +#endif + + QPlatformInputContext *inputContext() const; + QPlatformNativeInterface *nativeInterface() const; + QPlatformServices *services() const; + + QStringList themeNames() const; + QPlatformTheme *createPlatformTheme(const QString &name) const; + + void pauseApp(); + void resumeApp(); + static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh); + static void setDefaultDesktopSize(int gw, int gh); + + static QSize defaultDesktopSize() + { + return QSize(m_defaultGeometryWidth, m_defaultGeometryHeight); + } + +private: + + friend class QEglFSAndroidHooks; +#ifndef ANDROID_PLUGIN_OPENGL + QAbstractEventDispatcher *m_eventDispatcher; + QAndroidPlatformScreen *m_primaryScreen; +#else + mutable QAndroidOpenGLPlatformWindow *m_primaryWindow; +#endif + + QThread *m_mainThread; + + static int m_defaultGeometryWidth; + static int m_defaultGeometryHeight; + static int m_defaultPhysicalSizeWidth; + static int m_defaultPhysicalSizeHeight; + + QPlatformFontDatabase *m_androidFDB; + QImage *m_FbScreenImage; + QPainter *m_compositePainter; + QAndroidPlatformNativeInterface *m_androidPlatformNativeInterface; + QAndroidPlatformServices *m_androidPlatformServices; + QPlatformClipboard *m_androidPlatformClipboard; + + mutable QAndroidInputContext m_platformInputContext; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp new file mode 100644 index 0000000000..36247e86f9 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformmenu.h" +#include "qandroidplatformmenuitem.h" +#include "androidjnimenu.h" + +QAndroidPlatformMenu::QAndroidPlatformMenu() +{ + m_tag = reinterpret_cast(this); // QMenu will overwrite this later, but we need a unique ID for QtQuick + m_enabled = true; + m_isVisible = true; +} + +QAndroidPlatformMenu::~QAndroidPlatformMenu() +{ + QtAndroidMenu::androidPlatformMenuDestroyed(this); +} + +void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) +{ + QMutexLocker lock(&m_menuItemsMutex); + m_menuItems.insert(qFind(m_menuItems.begin(), + m_menuItems.end(), + static_cast(before)), + static_cast(menuItem)); +} + +void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) +{ + QMutexLocker lock(&m_menuItemsMutex); + m_menuItems.erase(qFind(m_menuItems.begin(), + m_menuItems.end(), + static_cast(menuItem))); +} + +void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) +{ + PlatformMenuItemsType::iterator it; + for (it = m_menuItems.begin(); it != m_menuItems.end(); ++it) { + if ((*it)->tag() == menuItem->tag()) + break; + } + + if (it != m_menuItems.end()) + QtAndroidMenu::syncMenu(this); +} + +void QAndroidPlatformMenu::syncSeparatorsCollapsible(bool enable) +{ + Q_UNUSED(enable) +} + +void QAndroidPlatformMenu::setTag(quintptr tag) +{ + m_tag = tag; +} + +quintptr QAndroidPlatformMenu::tag() const +{ + return m_tag; +} + +void QAndroidPlatformMenu::setText(const QString &text) +{ + m_text = text; +} + +QString QAndroidPlatformMenu::text() const +{ + return m_text; +} + +void QAndroidPlatformMenu::setIcon(const QIcon &icon) +{ + m_icon = icon; +} + +QIcon QAndroidPlatformMenu::icon() const +{ + return m_icon; +} + +void QAndroidPlatformMenu::setEnabled(bool enabled) +{ + m_enabled = enabled; +} + +bool QAndroidPlatformMenu::isEnabled() const +{ + return m_enabled; +} + +void QAndroidPlatformMenu::setVisible(bool visible) +{ + m_isVisible = visible; +} + +bool QAndroidPlatformMenu::isVisible() const +{ + return m_isVisible; +} + +QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const +{ + if (position < m_menuItems.size()) + return m_menuItems[position]; + return 0; +} + +QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const +{ + foreach (QPlatformMenuItem *menuItem, m_menuItems) { + if (menuItem->tag() == tag) + return menuItem; + } + + return 0; +} + +QAndroidPlatformMenu::PlatformMenuItemsType QAndroidPlatformMenu::menuItems() const +{ + return m_menuItems; +} + +QMutex *QAndroidPlatformMenu::menuItemsMutex() +{ + return &m_menuItemsMutex; +} diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.h b/src/plugins/platforms/android/src/qandroidplatformmenu.h new file mode 100644 index 0000000000..20236cb636 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformmenu.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMMENU_H +#define QANDROIDPLATFORMMENU_H + +#include +#include +#include + +class QAndroidPlatformMenuItem; +class QAndroidPlatformMenu: public QPlatformMenu +{ +public: + typedef QVector PlatformMenuItemsType; + +public: + QAndroidPlatformMenu(); + ~QAndroidPlatformMenu(); + + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before); + void removeMenuItem(QPlatformMenuItem *menuItem); + void syncMenuItem(QPlatformMenuItem *menuItem); + void syncSeparatorsCollapsible(bool enable); + + void setTag(quintptr tag); + quintptr tag() const; + void setText(const QString &text); + QString text() const; + void setIcon(const QIcon &icon); + QIcon icon() const; + void setEnabled(bool enabled); + bool isEnabled() const; + void setVisible(bool visible); + bool isVisible() const; + + QPlatformMenuItem *menuItemAt(int position) const; + QPlatformMenuItem *menuItemForTag(quintptr tag) const; + + PlatformMenuItemsType menuItems() const; + QMutex *menuItemsMutex(); + +private: + PlatformMenuItemsType m_menuItems; + quintptr m_tag; + QString m_text; + QIcon m_icon; + bool m_enabled; + bool m_isVisible; + QMutex m_menuItemsMutex; +}; + +#endif // QANDROIDPLATFORMMENU_H diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp new file mode 100644 index 0000000000..ef1ac61356 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformmenubar.h" +#include "qandroidplatformmenu.h" +#include "androidjnimenu.h" + + +QAndroidPlatformMenuBar::QAndroidPlatformMenuBar() +{ + m_parentWindow = 0; + QtAndroidMenu::addMenuBar(this); +} + +QAndroidPlatformMenuBar::~QAndroidPlatformMenuBar() +{ + QtAndroidMenu::removeMenuBar(this); +} + +void QAndroidPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before) +{ + QMutexLocker lock(&m_menusListMutex); + m_menus.insert(qFind(m_menus.begin(), + m_menus.end(), + static_cast(before)), + static_cast(menu)); +} + +void QAndroidPlatformMenuBar::removeMenu(QPlatformMenu *menu) +{ + QMutexLocker lock(&m_menusListMutex); + m_menus.erase(qFind(m_menus.begin(), + m_menus.end(), + static_cast(menu))); +} + +void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu) +{ + QtAndroidMenu::syncMenu(static_cast(menu)); +} + +void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow) +{ + m_parentWindow = newParentWindow; + QtAndroidMenu::setMenuBar(this, newParentWindow); +} + +QPlatformMenu *QAndroidPlatformMenuBar::menuForTag(quintptr tag) const +{ + foreach (QPlatformMenu *menu, m_menus) { + if (menu->tag() == tag) + return menu; + } + + return 0; +} + +QWindow *QAndroidPlatformMenuBar::parentWindow() const +{ + return m_parentWindow; +} + +QAndroidPlatformMenuBar::PlatformMenusType QAndroidPlatformMenuBar::menus() const +{ + return m_menus; +} + +QMutex *QAndroidPlatformMenuBar::menusListMutex() +{ + return &m_menusListMutex; +} diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.h b/src/plugins/platforms/android/src/qandroidplatformmenubar.h new file mode 100644 index 0000000000..56915335c2 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMMENUBAR_H +#define QANDROIDPLATFORMMENUBAR_H + +#include +#include +#include + +class QAndroidPlatformMenu; +class QAndroidPlatformMenuBar: public QPlatformMenuBar +{ +public: + typedef QVector PlatformMenusType; +public: + QAndroidPlatformMenuBar(); + ~QAndroidPlatformMenuBar(); + + void insertMenu(QPlatformMenu *menu, QPlatformMenu *before); + void removeMenu(QPlatformMenu *menu); + void syncMenu(QPlatformMenu *menu); + void handleReparent(QWindow *newParentWindow); + QPlatformMenu *menuForTag(quintptr tag) const; + + QWindow *parentWindow() const; + PlatformMenusType menus() const; + QMutex *menusListMutex(); + +private: + PlatformMenusType m_menus; + QWindow *m_parentWindow; + QMutex m_menusListMutex; +}; + +#endif // QANDROIDPLATFORMMENUBAR_H diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp b/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp new file mode 100644 index 0000000000..bd37834d2a --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformmenuitem.h" +#include "qandroidplatformmenu.h" + +QAndroidPlatformMenuItem::QAndroidPlatformMenuItem() +{ + m_tag = reinterpret_cast(this); // QMenu will overwrite this later, but we need a unique ID for QtQuick + m_menu = 0; + m_isVisible = true; + m_isSeparator = false; + m_role = NoRole; + m_isCheckable = false; + m_isChecked = false; + m_isEnabled = true; +} + +void QAndroidPlatformMenuItem::setTag(quintptr tag) +{ + m_tag = tag; +} + +quintptr QAndroidPlatformMenuItem::tag() const +{ + return m_tag; +} + +void QAndroidPlatformMenuItem::setText(const QString &text) +{ + m_text = text; + if (m_menu) + m_menu->setText(m_text); +} + +QString QAndroidPlatformMenuItem::text() const +{ + return m_text; +} + +void QAndroidPlatformMenuItem::setIcon(const QIcon &icon) +{ + m_icon = icon; + if (m_menu) + m_menu->setIcon(m_icon); +} + +QIcon QAndroidPlatformMenuItem::icon() const +{ + return m_icon; +} + +void QAndroidPlatformMenuItem::setMenu(QPlatformMenu *menu) +{ + m_menu = static_cast(menu); + if (!m_menu) + return; + + m_menu->setText(m_text); + m_menu->setIcon(m_icon); + m_menu->setVisible(m_isVisible); + m_menu->setEnabled(m_isEnabled); +} + +QAndroidPlatformMenu *QAndroidPlatformMenuItem::menu() const +{ + return m_menu; +} + +void QAndroidPlatformMenuItem::setVisible(bool isVisible) +{ + m_isVisible = isVisible; + if (m_menu) + m_menu->setVisible(m_isVisible); +} + +bool QAndroidPlatformMenuItem::isVisible() const +{ + return m_isVisible; +} + +void QAndroidPlatformMenuItem::setIsSeparator(bool isSeparator) +{ + m_isSeparator = isSeparator; +} + +bool QAndroidPlatformMenuItem::isSeparator() const +{ + return m_isSeparator; +} + +void QAndroidPlatformMenuItem::setFont(const QFont &font) +{ + Q_UNUSED(font) +} + +void QAndroidPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role) +{ + m_role = role; +} + +QPlatformMenuItem::MenuRole QAndroidPlatformMenuItem::role() const +{ + return m_role; +} + +void QAndroidPlatformMenuItem::setCheckable(bool checkable) +{ + m_isCheckable = checkable; +} + +bool QAndroidPlatformMenuItem::isCheckable() const +{ + return m_isCheckable; +} + +void QAndroidPlatformMenuItem::setChecked(bool isChecked) +{ + m_isChecked = isChecked; +} + +bool QAndroidPlatformMenuItem::isChecked() const +{ + return m_isChecked; +} + +void QAndroidPlatformMenuItem::setShortcut(const QKeySequence &shortcut) +{ + Q_UNUSED(shortcut) +} + +void QAndroidPlatformMenuItem::setEnabled(bool enabled) +{ + m_isEnabled = enabled; + if (m_menu) + m_menu->setEnabled(m_isEnabled); +} + +bool QAndroidPlatformMenuItem::isEnabled() const +{ + return m_isEnabled; +} diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.h b/src/plugins/platforms/android/src/qandroidplatformmenuitem.h new file mode 100644 index 0000000000..5861e8e195 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformmenuitem.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMMENUITEM_H +#define QANDROIDPLATFORMMENUITEM_H +#include + +class QAndroidPlatformMenu; + +class QAndroidPlatformMenuItem: public QPlatformMenuItem +{ +public: + QAndroidPlatformMenuItem(); + void setTag(quintptr tag); + quintptr tag() const; + + void setText(const QString &text); + QString text() const; + + void setIcon(const QIcon &icon); + QIcon icon() const; + + void setMenu(QPlatformMenu *menu); + QAndroidPlatformMenu *menu() const; + + void setVisible(bool isVisible); + bool isVisible() const; + + void setIsSeparator(bool isSeparator); + bool isSeparator() const; + + void setFont(const QFont &font); + + void setRole(MenuRole role); + MenuRole role() const; + + void setCheckable(bool checkable); + bool isCheckable() const; + + void setChecked(bool isChecked); + bool isChecked() const; + + void setShortcut(const QKeySequence &shortcut); + + void setEnabled(bool enabled); + bool isEnabled() const; + +private: + quintptr m_tag; + QString m_text; + QIcon m_icon; + QAndroidPlatformMenu *m_menu; + bool m_isVisible; + bool m_isSeparator; + MenuRole m_role; + bool m_isCheckable; + bool m_isChecked; + bool m_isEnabled; +}; + +#endif // QANDROIDPLATFORMMENUITEM_H diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.cpp b/src/plugins/platforms/android/src/qandroidplatformservices.cpp new file mode 100644 index 0000000000..841a9d4d51 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformservices.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformservices.h" +#include +#include +#include + +QAndroidPlatformServices::QAndroidPlatformServices() +{ + JNIEnv *env; + if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) { + qCritical() << "AttachCurrentThread failed"; + return; + } + + m_openURIMethodID = env->GetStaticMethodID(QtAndroid::applicationClass(), + "openURL", + "(Ljava/lang/String;)V"); +} + +bool QAndroidPlatformServices::openUrl(const QUrl &url) +{ + JNIEnv *env; + if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) { + qCritical() << "AttachCurrentThread failed"; + return false; + } + + jstring string = env->NewString(reinterpret_cast(url.toString().constData()), + url.toString().length()); + env->CallStaticVoidMethod(QtAndroid::applicationClass(), m_openURIMethodID, string); + env->DeleteLocalRef(string); + return true; +} + +bool QAndroidPlatformServices::openDocument(const QUrl &url) +{ + return openUrl(url); +} + +QByteArray QAndroidPlatformServices::desktopEnvironment() const +{ + return QByteArray("Android"); +} diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.h b/src/plugins/platforms/android/src/qandroidplatformservices.h new file mode 100644 index 0000000000..8368b19043 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformservices.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDPLATFORMDESKTOPSERVICE_H +#define ANDROIDPLATFORMDESKTOPSERVICE_H + +#include +#include "androidjnimain.h" +#include + +class QAndroidPlatformServices: public QPlatformServices +{ +public: + QAndroidPlatformServices(); + bool openUrl(const QUrl &url); + bool openDocument(const QUrl &url); + QByteArray desktopEnvironment() const; +private: + jmethodID m_openURIMethodID; + +}; + +#endif // ANDROIDPLATFORMDESKTOPSERVICE_H diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp new file mode 100644 index 0000000000..25f2ade11a --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformtheme.h" +#include "qandroidplatformmenubar.h" +#include "qandroidplatformmenu.h" +#include "qandroidplatformmenuitem.h" +#include +#include + +QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const +{ + return new QAndroidPlatformMenuBar; +} + +QPlatformMenu *QAndroidPlatformTheme::createPlatformMenu() const +{ + return new QAndroidPlatformMenu; +} + +QPlatformMenuItem *QAndroidPlatformTheme::createPlatformMenuItem() const +{ + return new QAndroidPlatformMenuItem; +} + +QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const +{ + switch (hint) { + case StyleNames: + if (qgetenv("QT_USE_ANDROID_NATIVE_STYLE").toInt() + && (!qgetenv("MINISTRO_ANDROID_STYLE_PATH").isEmpty() + || QFileInfo("/data/data/org.kde.necessitas.ministro/files/qt/style/style.json").exists())) { + return QStringList("android"); + } + return QStringList("fusion"); + break; + default: + return QPlatformTheme::themeHint(hint); + } +} diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.h b/src/plugins/platforms/android/src/qandroidplatformtheme.h new file mode 100644 index 0000000000..263878ee16 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformtheme.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMTHEME_H +#define QANDROIDPLATFORMTHEME_H + +#include + +class QAndroidPlatformTheme: public QPlatformTheme +{ +public: + virtual QPlatformMenuBar *createPlatformMenuBar() const; + virtual QPlatformMenu *createPlatformMenu() const; + virtual QPlatformMenuItem *createPlatformMenuItem() const; + virtual QVariant themeHint(ThemeHint hint) const; +}; + +#endif // QANDROIDPLATFORMTHEME_H diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp new file mode 100644 index 0000000000..2779d7cffd --- /dev/null +++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformscreen.h" +#include "qandroidplatformintegration.h" +#include "androidjnimain.h" +#include "androidjnimenu.h" + +QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen() +{ + mGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight); + mFormat = QImage::Format_RGB16; + mDepth = 16; + mPhysicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight); + mPhysicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth); + initializeCompositor(); +} + +void QAndroidPlatformScreen::topWindowChanged(QWindow *w) +{ + QtAndroidMenu::setActiveTopLevelWindow(w); +} + +QRegion QAndroidPlatformScreen::doRedraw() +{ + QRegion touched; + touched = QFbScreen::doRedraw(); + if (touched.isEmpty()) + return touched; + + QtAndroid::flushImage(mGeometry.topLeft(), *mScreenImage, touched.boundingRect()); + return touched; +} diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h new file mode 100644 index 0000000000..df08e43af4 --- /dev/null +++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMSCREEN_H +#define QANDROIDPLATFORMSCREEN_H + +#include + +class QAndroidPlatformScreen: public QFbScreen +{ + Q_OBJECT +public: + QAndroidPlatformScreen(); + void topWindowChanged(QWindow *w); + +public slots: + QRegion doRedraw(); + +}; + +#endif diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp new file mode 100644 index 0000000000..94a69c10c7 --- /dev/null +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformwindow.h" + +QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window) +{ +} + +void QAndroidPlatformWindow::setGeometry(const QRect &rect) +{ + QFbWindow::setGeometry(rect); +} + +void QAndroidPlatformWindow::propagateSizeHints() +{ + //shut up warning from default implementation +} diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h new file mode 100644 index 0000000000..3ee815fd69 --- /dev/null +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2012 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDPLATFORMWINDOW_H +#define ANDROIDPLATFORMWINDOW_H +#include +#include + +class QAndroidPlatformWindow: public QObject, public QFbWindow +{ + Q_OBJECT +public: + explicit QAndroidPlatformWindow(QWindow *window); + + void propagateSizeHints(); + +public slots: + void setGeometry(const QRect &rect); + +}; + +#endif // ANDROIDPLATFORMWINDOW_H diff --git a/src/plugins/platforms/android/src/raster/raster.pri b/src/plugins/platforms/android/src/raster/raster.pri new file mode 100644 index 0000000000..86e5aa235f --- /dev/null +++ b/src/plugins/platforms/android/src/raster/raster.pri @@ -0,0 +1,7 @@ +INCLUDEPATH += $$PWD + +SOURCES += $$PWD/qandroidplatformscreen.cpp \ + $$PWD/qandroidplatformwindow.cpp + +HEADERS += $$PWD/qandroidplatformscreen.h \ + $$PWD/qandroidplatformwindow.h diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri new file mode 100644 index 0000000000..9bf36b2337 --- /dev/null +++ b/src/plugins/platforms/android/src/src.pri @@ -0,0 +1,47 @@ +load(qt_plugin) + +QT += core-private gui-private widgets-private platformsupport-private + +CONFIG += qpa/genericunixfontdatabase + +OTHER_FILES += $$PWD/android.json + +INCLUDEPATH += $$PWD +INCLUDEPATH += $$PWD/../../../../3rdparty/android/src + +SOURCES += $$PWD/androidplatformplugin.cpp \ + $$PWD/androidjnimain.cpp \ + $$PWD/androidjniinput.cpp \ + $$PWD/androidjnimenu.cpp \ + $$PWD/androidjniclipboard.cpp \ + $$PWD/qandroidplatformintegration.cpp \ + $$PWD/qandroidplatformservices.cpp \ + $$PWD/qandroidassetsfileenginehandler.cpp \ + $$PWD/qandroidinputcontext.cpp \ + $$PWD/qandroidplatformfontdatabase.cpp \ + $$PWD/qandroidplatformclipboard.cpp \ + $$PWD/qandroidplatformtheme.cpp \ + $$PWD/qandroidplatformmenubar.cpp \ + $$PWD/qandroidplatformmenu.cpp \ + $$PWD/qandroidplatformmenuitem.cpp + + +HEADERS += $$PWD/qandroidplatformintegration.h \ + $$PWD/androidjnimain.h \ + $$PWD/androidjniinput.h \ + $$PWD/androidjnimenu.h \ + $$PWD/androidjniclipboard.h \ + $$PWD/qandroidplatformservices.h \ + $$PWD/qandroidassetsfileenginehandler.h \ + $$PWD/qandroidinputcontext.h \ + $$PWD/qandroidplatformfontdatabase.h \ + $$PWD/qandroidplatformclipboard.h \ + $$PWD/qandroidplatformtheme.h \ + $$PWD/qandroidplatformmenubar.h \ + $$PWD/qandroidplatformmenu.h \ + $$PWD/qandroidplatformmenuitem.h + + +#Non-standard install directory, QTBUG-29859 +DESTDIR = $$DESTDIR/android +target.path = $${target.path}/android diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 0fc4c44629..8cebe16775 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -53,7 +53,7 @@ #include #include -#if !defined(QT_NO_EVDEV) +#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) #include #include #include @@ -77,7 +77,7 @@ QEglFSIntegration::QEglFSIntegration() { QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); -#if !defined(QT_NO_EVDEV) +#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); new QEvdevTouchScreenHandlerThread(QString() /* spec */, this); diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index a60a3626fa..92664826ab 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -1,5 +1,7 @@ TEMPLATE = subdirs +android:!android-no-sdk: SUBDIRS += android + SUBDIRS += minimal offscreen contains(QT_CONFIG, xcb) { -- cgit v1.2.3 From f4933eba546be71c97a36cfeed2b6d8d187a16c3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 4 Mar 2013 09:52:37 +0100 Subject: Windows: Take custom margins into account for size constraints. Fix a warning unearthed by the task's code example. The minimum size of the window would be too big since it did not take the negative custom top margin into account. Task-number: QTBUG-29904 Change-Id: I8b71a39f0724bdd1b9359676ce1d86ef5384d685 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 15 ++++++++------- src/plugins/platforms/windows/qwindowswindow.h | 3 ++- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index d565420f4f..ed814336f0 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -575,9 +575,10 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe #define QWINDOWSIZE_MAX ((1<<24)-1) -QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w) : +QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w, const QMargins &cm) : minimumSize(w->minimumSize()), - maximumSize(w->maximumSize()) + maximumSize(w->maximumSize()), + customMargins(cm) { } @@ -650,8 +651,8 @@ void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXI << " in " << *mmi; const QMargins margins = QWindowsGeometryHint::frame(style, exStyle); - const int frameWidth = margins.left() + margins.right(); - const int frameHeight = margins.top() + margins.bottom(); + const int frameWidth = margins.left() + margins.right() + customMargins.left() + customMargins.right(); + const int frameHeight = margins.top() + margins.bottom() + customMargins.top() + customMargins.bottom(); if (minimumSize.width() > 0) mmi->ptMinTrackSize.x = minimumSize.width() + frameWidth; if (minimumSize.height() > 0) @@ -702,7 +703,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QRect &geometry, const QMargins &cm, DWORD style_, DWORD exStyle_) : - geometryHint(w), style(style_), exStyle(exStyle_), + geometryHint(w, cm), style(style_), exStyle(exStyle_), requestedGeometry(geometry), obtainedGeometry(geometry), margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm), frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT), @@ -1095,7 +1096,7 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) const QSize newSize = rect.size(); // Check on hint. if (newSize != oldSize) { - const QWindowsGeometryHint hint(window()); + const QWindowsGeometryHint hint(window(), m_data.customMargins); if (!hint.validSize(newSize)) { qWarning("%s: Attempt to set a size (%dx%d) violating the constraints" "(%dx%d - %dx%d) on window '%s'.", __FUNCTION__, @@ -1683,7 +1684,7 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { - const QWindowsGeometryHint hint(window()); + const QWindowsGeometryHint hint(window(), m_data.customMargins); hint.applyToMinMaxInfo(m_data.hwnd, mmi); if (QWindowsContext::verboseWindows) qDebug() << __FUNCTION__ << window() << *mmi; diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 8fe5cbe17b..87397f1c1d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -67,7 +67,7 @@ class QWindowsEGLStaticContext; struct QWindowsGeometryHint { QWindowsGeometryHint() {} - explicit QWindowsGeometryHint(const QWindow *w); + explicit QWindowsGeometryHint(const QWindow *w, const QMargins &customMargins); static QMargins frame(DWORD style, DWORD exStyle); static bool handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result); #ifndef Q_OS_WINCE //MinMax maybe define struct if not available @@ -85,6 +85,7 @@ struct QWindowsGeometryHint QSize minimumSize; QSize maximumSize; + QMargins customMargins; }; struct QWindowCreationContext -- cgit v1.2.3 From 9100a68221b2317a1858976583cd840978e3a98f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 4 Mar 2013 09:37:41 +0100 Subject: Windows: Print size constraints in geometry warning. Change-Id: I0f8f82e975bfe7e9b00c48741b2a0317fac5f839 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ed814336f0..cecbd81214 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1114,14 +1114,19 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) if (m_data.geometry != rect) { qWarning("%s: Unable to set geometry %dx%d+%d+%d on '%s'." " Resulting geometry: %dx%d+%d+%d " - "(frame: %d, %d, %d, %d).", + "(frame: %d, %d, %d, %d, custom margin: %d, %d, %d, %d" + ", minimum size: %dx%d, maximum size: %dx%d).", __FUNCTION__, rect.width(), rect.height(), rect.x(), rect.y(), qPrintable(window()->objectName()), m_data.geometry.width(), m_data.geometry.height(), m_data.geometry.x(), m_data.geometry.y(), m_data.frame.left(), m_data.frame.top(), - m_data.frame.right(), m_data.frame.bottom()); + m_data.frame.right(), m_data.frame.bottom(), + m_data.customMargins.left(), m_data.customMargins.top(), + m_data.customMargins.right(), m_data.customMargins.bottom(), + window()->minimumWidth(), window()->minimumHeight(), + window()->maximumWidth(), window()->maximumHeight()); } } else { QPlatformWindow::setGeometry(rect); -- cgit v1.2.3 From d28073d9eb0f35bae534470970e693a94463c549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 2 Mar 2013 15:46:37 +0100 Subject: Distinguish between 'mac' and 'macx' qmake scopes The former applies both on Mac OS X and iOS, but 'macx' is specific to Mac OS X. ios.conf and macx.conf now share most of their settings in the common mac.conf. We set the default QMAKE_MAC_SDK before loading mac.conf, so that any overrides in the device config will apply afterwards. This means configure's mkspec parsing will be able to read the QMAKE_MAC_SDK. Change-Id: I0c7e26a6a0103e19b23ef152aa9e4ab461cee632 Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard Moe Gustavsen --- src/plugins/bearer/bearer.pro | 4 ++-- src/plugins/platforminputcontexts/platforminputcontexts.pro | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index 0375500306..42f039b19b 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -9,7 +9,7 @@ linux*:qtHaveModule(dbus) { win32:SUBDIRS += generic blackberry:SUBDIRS += blackberry win32:!wince*:SUBDIRS += nativewifi -macx:contains(QT_CONFIG, corewlan):SUBDIRS += corewlan -macx:SUBDIRS += generic +mac:contains(QT_CONFIG, corewlan):SUBDIRS += corewlan +mac:SUBDIRS += generic isEmpty(SUBDIRS):SUBDIRS = generic diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro index c8449e7e44..7b3c6e9c36 100644 --- a/src/plugins/platforminputcontexts/platforminputcontexts.pro +++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs qtHaveModule(dbus) { -!macx:!win32:SUBDIRS += ibus maliit +!mac:!win32:SUBDIRS += ibus maliit } -- cgit v1.2.3 From b5bdd31de41cb5e6d6abedce79864fc01d8d4984 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Wed, 12 Dec 2012 17:18:28 +0100 Subject: Implement XEmbed protocol Add a static QWindow::fromWinId(WId id) constructor which can be used to create a QWindow object representing windows created by other processes. Then, QWindow::setParent() can be used to embed a window into a foreign window socket and QWindow::setTransientParent() to stick the current window on top of a foreign window. The changes in the QtWidgets module ensure that the focus chain (TAB navigation) correctly works when a QtWidgets-based window is embedded into another application. As far as the platform implementation is concerned, this commit only implements the embedding functionality in the XCB plugin. So, this is roughly equivalent to the Qt4 QX11EmbedWidget functionality. Change-Id: Iff8f7b9ee974d33fb30f36056f7838b433a413c7 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qxcbconnection.cpp | 4 +- src/plugins/platforms/xcb/qxcbconnection.h | 2 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 260 +++++++++++++++++++++++++- src/plugins/platforms/xcb/qxcbwindow.h | 9 + 5 files changed, 264 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 2467eb6e7a..1504bd99d2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1066,7 +1066,7 @@ void QXcbConnection::processXcbEvents() while (it != m_peekFuncs.end()) { // These callbacks return true if the event is what they were // waiting for, remove them from the list in that case. - if ((*it)(event)) + if ((*it)(this, event)) it = m_peekFuncs.erase(it); else ++it; @@ -1086,7 +1086,7 @@ void QXcbConnection::processXcbEvents() // Indicate with a null event that the event the callbacks are waiting for // is not in the queue currently. Q_FOREACH (PeekFunc f, m_peekFuncs) - f(0); + f(this, 0); m_peekFuncs.clear(); xcb_flush(xcb_connection()); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index b499f75b78..f69a8a9f35 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -364,7 +364,7 @@ public: template inline xcb_generic_event_t *checkEvent(T &checker); - typedef bool (*PeekFunc)(xcb_generic_event_t *); + typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *); void addPeekFunc(PeekFunc f); inline xcb_timestamp_t time() const { return m_time; } diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 0a02ea02af..f0cabea43d 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -228,6 +228,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const case ThreadedOpenGL: return m_connections.at(0)->supportsThreadedRendering(); case WindowMasks: return true; case MultipleWindows: return true; + case ForeignWindows: return true; default: return QPlatformIntegration::hasCapability(cap); } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index abd2f7a147..27cd163c36 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -122,6 +122,36 @@ enum { QT_BEGIN_NAMESPACE +#undef FocusIn + +enum QX11EmbedFocusInDetail { + XEMBED_FOCUS_CURRENT = 0, + XEMBED_FOCUS_FIRST = 1, + XEMBED_FOCUS_LAST = 2 +}; + +enum QX11EmbedInfoFlags { + XEMBED_MAPPED = (1 << 0), +}; + +enum QX11EmbedMessageType { + XEMBED_EMBEDDED_NOTIFY = 0, + XEMBED_WINDOW_ACTIVATE = 1, + XEMBED_WINDOW_DEACTIVATE = 2, + XEMBED_REQUEST_FOCUS = 3, + XEMBED_FOCUS_IN = 4, + XEMBED_FOCUS_OUT = 5, + XEMBED_FOCUS_NEXT = 6, + XEMBED_FOCUS_PREV = 7, + XEMBED_MODALITY_ON = 10, + XEMBED_MODALITY_OFF = 11, + XEMBED_REGISTER_ACCELERATOR = 12, + XEMBED_UNREGISTER_ACCELERATOR = 13, + XEMBED_ACTIVATE_ACCELERATOR = 14 +}; + +static unsigned int XEMBED_VERSION = 0; + // Returns true if we should set WM_TRANSIENT_FOR on \a w static inline bool isTransient(const QWindow *w) { @@ -157,6 +187,7 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_mapped(false) , m_transparent(false) , m_deferredActivation(false) + , m_embedded(false) , m_netWmUserTimeWindow(XCB_NONE) , m_dirtyFrameMargins(false) #if defined(XCB_USE_EGL) @@ -168,7 +199,10 @@ QXcbWindow::QXcbWindow(QWindow *window) setConnection(m_screen->connection()); - create(); + if (window->type() != Qt::ForeignWindow) + create(); + else + m_window = window->winId(); } void QXcbWindow::create() @@ -235,8 +269,10 @@ void QXcbWindow::create() } xcb_window_t xcb_parent_id = m_screen->root(); - if (parent()) + if (parent()) { xcb_parent_id = static_cast(parent())->xcb_window(); + m_embedded = parent()->window()->type() == Qt::ForeignWindow; + } m_format = window()->requestedFormat(); @@ -368,6 +404,14 @@ void QXcbWindow::create() atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32, 1, &leader)); + /* Add XEMBED info; this operation doesn't initiate the embedding. */ + long data[] = { XEMBED_VERSION, XEMBED_MAPPED }; + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + atom(QXcbAtom::_XEMBED_INFO), + atom(QXcbAtom::_XEMBED_INFO), + 32, 2, (void *)data)); + + #ifdef XCB_USE_XINPUT2_MAEMO if (connection()->isUsingXInput2Maemo()) { XIEventMask xieventmask; @@ -410,7 +454,8 @@ void QXcbWindow::create() QXcbWindow::~QXcbWindow() { - destroy(); + if (window()->type() != Qt::ForeignWindow) + destroy(); } void QXcbWindow::destroy() @@ -574,9 +619,10 @@ void QXcbWindow::show() propagateSizeHints(); // update WM_TRANSIENT_FOR - if (isTransient(window())) { + const QWindow *tp = window()->transientParent(); + if (isTransient(window()) || tp != 0) { xcb_window_t transientXcbParent = 0; - if (const QWindow *tp = window()->transientParent()) + if (tp) transientXcbParent = static_cast(tp->handle())->winId(); // Default to client leader if there is no transient parent, else modal dialogs can // be hidden by their parents. @@ -1140,7 +1186,15 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) { QPoint topLeft = geometry().topLeft(); - xcb_window_t xcb_parent_id = parent ? static_cast(parent)->xcb_window() : m_screen->root(); + xcb_window_t xcb_parent_id; + if (parent) { + const QXcbWindow *qXcbParent = static_cast(parent); + xcb_parent_id = qXcbParent->xcb_window(); + m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow; + } else { + xcb_parent_id = m_screen->root(); + m_embedded = false; + } Q_XCB_CALL(xcb_reparent_window(xcb_connection(), xcb_window(), xcb_parent_id, topLeft.x(), topLeft.y())); } @@ -1271,6 +1325,13 @@ void QXcbWindow::propagateSizeHints() void QXcbWindow::requestActivateWindow() { + /* Never activate embedded windows; doing that would prevent the container + * to re-gain the keyboard focus later. */ + if (m_embedded) { + QPlatformWindow::requestActivateWindow(); + return; + } + if (!m_mapped) { m_deferredActivation = true; return; @@ -1434,7 +1495,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even } else if (event->type == atom(QXcbAtom::XdndDrop)) { connection()->drag()->handleDrop(window(), event); #endif - } else if (event->type == atom(QXcbAtom::_XEMBED)) { // QSystemTrayIcon + } else if (event->type == atom(QXcbAtom::_XEMBED)) { + handleXEmbedMessage(event); } else { qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type); } @@ -1476,6 +1538,53 @@ bool QXcbWindow::isExposed() const return m_mapped; } +bool QXcbWindow::isEmbedded(const QPlatformWindow *parentWindow) const +{ + if (!m_embedded) + return false; + + return parentWindow ? (parentWindow == parent()) : true; +} + +QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const +{ + if (!m_embedded) + return pos; + + QPoint ret; + xcb_translate_coordinates_cookie_t cookie = + xcb_translate_coordinates(xcb_connection(), xcb_window(), m_screen->root(), + pos.x(), pos.y()); + xcb_translate_coordinates_reply_t *reply = + xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); + if (reply) { + ret.setX(reply->dst_x); + ret.setY(reply->dst_y); + free(reply); + } + + return ret; +} + +QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const +{ + if (!m_embedded) + return pos; + QPoint ret; + xcb_translate_coordinates_cookie_t cookie = + xcb_translate_coordinates(xcb_connection(), m_screen->root(), xcb_window(), + pos.x(), pos.y()); + xcb_translate_coordinates_reply_t *reply = + xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL); + if (reply) { + ret.setX(reply->dst_x); + ret.setY(reply->dst_y); + free(reply); + } + + return ret; +} + void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event) { if (event->window == m_window) { @@ -1506,6 +1615,15 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) updateNetWmUserTime(event->time); + if (m_embedded) { + if (window() != QGuiApplication::focusWindow()) { + const QXcbWindow *container = static_cast(parent()); + Q_ASSERT(container != 0); + + sendXEmbedMessage(container->xcb_window(), XEMBED_REQUEST_FOCUS); + } + } + QPoint local(event->event_x, event->event_y); QPoint global(event->root_x, event->root_y); @@ -1661,6 +1779,25 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev QWindowSystemInterface::handleWindowStateChanged(window(), newState); m_lastWindowStateEvent = newState; } + return; + } + + const xcb_atom_t xEmbedInfoAtom = atom(QXcbAtom::_XEMBED_INFO); + if (event->atom == xEmbedInfoAtom) { + const xcb_get_property_cookie_t get_cookie = + xcb_get_property(xcb_connection(), 0, m_window, xEmbedInfoAtom, + XCB_ATOM_ANY, 0, 3); + + xcb_get_property_reply_t *reply = + xcb_get_property_reply(xcb_connection(), get_cookie, NULL); + if (reply && reply->length >= 2) { + const long *data = (const long *)xcb_get_property_value(reply); + if (data[1] & XEMBED_MAPPED) + Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); + else + Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window)); + } + free(reply); } } @@ -1672,7 +1809,7 @@ void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) QWindowSystemInterface::handleWindowActivated(w); } -static bool focusInPeeker(xcb_generic_event_t *event) +static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) { if (!event) { // FocusIn event is not in the queue, proceed with FocusOut normally. @@ -1680,7 +1817,18 @@ static bool focusInPeeker(xcb_generic_event_t *event) return true; } uint response_type = event->response_type & ~0x80; - return response_type == XCB_FOCUS_IN; + if (response_type == XCB_FOCUS_IN) + return true; + + /* We are also interested in XEMBED_FOCUS_IN events */ + if (response_type == XCB_CLIENT_MESSAGE) { + xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; + if (cme->type == connection->atom(QXcbAtom::_XEMBED) + && cme->data.data32[1] == XEMBED_FOCUS_IN) + return true; + } + + return false; } void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) @@ -1744,6 +1892,35 @@ void QXcbWindow::setCursor(xcb_cursor_t cursor) xcb_flush(xcb_connection()); } +void QXcbWindow::windowEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::FocusIn: + if (m_embedded && !event->spontaneous()) { + QFocusEvent *focusEvent = static_cast(event); + switch (focusEvent->reason()) { + case Qt::TabFocusReason: + case Qt::BacktabFocusReason: + { + const QXcbWindow *container = + static_cast(parent()); + sendXEmbedMessage(container->xcb_window(), + focusEvent->reason() == Qt::TabFocusReason ? + XEMBED_FOCUS_NEXT : XEMBED_FOCUS_PREV); + event->accept(); + } + break; + default: + break; + } + } + break; + default: + break; + } + QPlatformWindow::windowEvent(event); +} + bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) { const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); @@ -1772,6 +1949,71 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) return true; } +// Sends an XEmbed message. +void QXcbWindow::sendXEmbedMessage(xcb_window_t window, long message, + long detail, long data1, long data2) +{ + xcb_client_message_event_t event; + + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = window; + event.type = atom(QXcbAtom::_XEMBED); + event.data.data32[0] = connection()->time(); + event.data.data32[1] = message; + event.data.data32[2] = detail; + event.data.data32[3] = data1; + event.data.data32[4] = data2; + Q_XCB_CALL(xcb_send_event(xcb_connection(), false, window, + XCB_EVENT_MASK_NO_EVENT, (const char *)&event)); +} + +static bool activeWindowChangeQueued(const QWindow *window) +{ + /* Check from window system event queue if the next queued activation + * targets a window other than @window. + */ + QWindowSystemInterfacePrivate::ActivatedWindowEvent *systemEvent = + static_cast + (QWindowSystemInterfacePrivate::peekWindowSystemEvent(QWindowSystemInterfacePrivate::ActivatedWindow)); + return systemEvent && systemEvent->activated != window; +} + +void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event) +{ + connection()->setTime(event->data.data32[0]); + switch (event->data.data32[1]) { + case XEMBED_WINDOW_ACTIVATE: + case XEMBED_WINDOW_DEACTIVATE: + case XEMBED_EMBEDDED_NOTIFY: + break; + case XEMBED_FOCUS_IN: + Qt::FocusReason reason; + switch (event->data.data32[2]) { + case XEMBED_FOCUS_FIRST: + reason = Qt::TabFocusReason; + break; + case XEMBED_FOCUS_LAST: + reason = Qt::BacktabFocusReason; + break; + case XEMBED_FOCUS_CURRENT: + default: + reason = Qt::OtherFocusReason; + break; + } + connection()->setFocusWindow(static_cast(window()->handle())); + QWindowSystemInterface::handleWindowActivated(window(), reason); + break; + case XEMBED_FOCUS_OUT: + if (window() == QGuiApplication::focusWindow() + && !activeWindowChangeQueued(window())) { + connection()->setFocusWindow(0); + QWindowSystemInterface::handleWindowActivated(0); + } + break; + } +} + #if !defined(QT_NO_SHAPE) static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 3b5404684f..1810a58c7b 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -87,6 +87,9 @@ public: void setParent(const QPlatformWindow *window); bool isExposed() const; + bool isEmbedded(const QPlatformWindow *parentWindow) const; + QPoint mapToGlobal(const QPoint &pos) const; + QPoint mapFromGlobal(const QPoint &pos) const; void setWindowTitle(const QString &title); void setWindowIcon(const QIcon &icon); @@ -107,6 +110,8 @@ public: QSurfaceFormat format() const; + void windowEvent(QEvent *event); + bool startSystemResize(const QPoint &pos, Qt::Corner corner); void setOpacity(qreal level); @@ -158,6 +163,9 @@ private: void updateDoesNotAcceptFocus(bool doesNotAcceptFocus); QRect windowToWmGeometry(QRect r) const; + void sendXEmbedMessage(xcb_window_t window, long message, + long detail = 0, long data1 = 0, long data2 = 0); + void handleXEmbedMessage(const xcb_client_message_event_t *event); void create(); void destroy(); @@ -184,6 +192,7 @@ private: bool m_deferredActivation; bool m_deferredExpose; bool m_configureNotifyPending; + bool m_embedded; xcb_window_t m_netWmUserTimeWindow; QSurfaceFormat m_format; -- cgit v1.2.3 From 5f948eb62ddb9f429f46ade08f32072212cda493 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 5 Mar 2013 16:52:08 +0100 Subject: qtbase: Fix duplicate symbol errors in static build on Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is some code duplication between QMacStyle anf the Cocoa QPA plugin regarding painting and bridging with Cocoa. Task-number: QTBUG-29725 Change-Id: I347407a9bca47b6fccd77fb924688bd35135d96b Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 7 +++---- src/plugins/platforms/cocoa/qpaintengine_mac.mm | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 29a8c49511..3f00893465 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -466,10 +466,9 @@ QString qt_mac_removeMnemonics(const QString &original) return returnText; } - -CGColorSpaceRef m_genericColorSpace = 0; -QHash m_displayColorSpaceHash; -bool m_postRoutineRegistered = false; +static CGColorSpaceRef m_genericColorSpace = 0; +static QHash m_displayColorSpaceHash; +static bool m_postRoutineRegistered = false; CGColorSpaceRef qt_mac_genericColorSpace() { diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 56ab732a32..301beb11c1 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE QCoreGraphicsPaintEngine utility functions *****************************************************************************/ -void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) +static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) { CGAffineTransform old_xform = CGAffineTransformIdentity; if (orig_xform) { //setup xforms -- cgit v1.2.3 From 638d9d3831357f80800a2fae4925f71648907f30 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 6 Mar 2013 11:54:08 +0100 Subject: Fix multi-touch input on Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The touch events were collected but then thrown away because of a missing port of he handleTouchEvent() function call. Task-number: QTBUG-29126 Change-Id: I02f7380945be04a36da14a89f2f3ff9429b17cbc Reviewed-by: Samuel Rødal --- .../platforms/android/src/androidjniinput.cpp | 21 +++++++++++++++++++-- .../platforms/android/src/androidjnimain.cpp | 6 ++++++ src/plugins/platforms/android/src/androidjnimain.h | 1 + .../android/src/qandroidplatformintegration.cpp | 4 +++- .../android/src/qandroidplatformintegration.h | 6 ++++++ 5 files changed, 35 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index 6a3dd1f349..da6156a330 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -41,6 +41,7 @@ #include "androidjniinput.h" #include "androidjnimain.h" +#include "qandroidplatformintegration.h" #include #include @@ -219,6 +220,9 @@ namespace QtAndroidInput static void touchEnd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint action) { + if (m_touchPoints.isEmpty()) + return; + QEvent::Type eventType = QEvent::None; switch (action) { case 0: @@ -232,8 +236,21 @@ namespace QtAndroidInput break; } - // FIXME - // QWindowSystemInterface::handleTouchEvent(0, 0, eventType, QTouchEvent::TouchScreen, m_touchPoints); + QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration(); + QTouchDevice *touchDevice = platformIntegration->touchDevice(); + if (touchDevice == 0) { + touchDevice = new QTouchDevice; + touchDevice->setType(QTouchDevice::TouchScreen); + touchDevice->setCapabilities(QTouchDevice::Position + | QTouchDevice::Area + | QTouchDevice::Pressure + | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(touchDevice); + platformIntegration->setTouchDevice(touchDevice); + } + + QWindow *window = QtAndroid::topLevelWindowAt(m_touchPoints.at(0).area.center().toPoint()); + QWindowSystemInterface::handleTouchEvent(window, touchDevice, m_touchPoints); } static int mapAndroidKey(int key) diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 2a4c48df3c..f8f077908c 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -266,6 +266,12 @@ namespace QtAndroid m_surfaceMutex.unlock(); } + QAndroidPlatformIntegration *androidPlatformIntegration() + { + QMutexLocker locker(&m_surfaceMutex); + return m_androidPlatformIntegration; + } + void setFullScreen(QWidget *widget) { AttachedJNIEnv env; diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h index 36699f15b8..618bd87cdb 100644 --- a/src/plugins/platforms/android/src/androidjnimain.h +++ b/src/plugins/platforms/android/src/androidjnimain.h @@ -65,6 +65,7 @@ class QWindow; namespace QtAndroid { + QAndroidPlatformIntegration *androidPlatformIntegration(); void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration); void setQtThread(QThread *thread); diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 1091416ccc..cbd0f26835 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -84,8 +84,9 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA } QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶mList) + : m_touchDevice(0) #ifdef ANDROID_PLUGIN_OPENGL - : m_primaryWindow(0) + , m_primaryWindow(0) #endif { Q_UNUSED(paramList); @@ -179,6 +180,7 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration() { delete m_androidPlatformNativeInterface; delete m_androidFDB; + delete m_touchDevice; QtAndroid::setAndroidPlatformIntegration(NULL); } QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h index 7dde277d25..3f8cc5a809 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -126,9 +126,15 @@ public: return QSize(m_defaultGeometryWidth, m_defaultGeometryHeight); } + QTouchDevice *touchDevice() const { return m_touchDevice; } + void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; } + private: friend class QEglFSAndroidHooks; + + QTouchDevice *m_touchDevice; + #ifndef ANDROID_PLUGIN_OPENGL QAbstractEventDispatcher *m_eventDispatcher; QAndroidPlatformScreen *m_primaryScreen; -- cgit v1.2.3 From da672eba998eb909b6ea264c71f75b4d611101e0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 8 Mar 2013 14:06:32 +0100 Subject: Windows: Use arrow cursor for toplevels with no cursor set. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes unsetting the cursor in Qt Quick Controls. Task-number: QTBUG-28879 Change-Id: I049beafaa723f6e782df872f14c09b7f927e70ac Reviewed-by: Jan Arve Sæther Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2d0f537477..2da0af8abb 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1705,6 +1705,16 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const } #endif // !Q_OS_WINCE +// Return the default cursor (Arrow) from QWindowsCursor's cache. +static inline QWindowsWindowCursor defaultCursor(const QWindow *w) +{ + if (QScreen *screen = w->screen()) + if (const QPlatformScreen *platformScreen = screen->handle()) + if (QPlatformCursor *cursor = platformScreen->cursor()) + return static_cast(cursor)->standardWindowCursor(Qt::ArrowCursor); + return QWindowsWindowCursor(Qt::ArrowCursor); +} + /*! \brief Applies to cursor property set on the window to the global cursor. @@ -1714,9 +1724,12 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const void QWindowsWindow::applyCursor() { #ifndef QT_NO_CURSOR - if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor. - if (const QWindow *p = window()->parent()) + if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel. + if (const QWindow *p = window()->parent()) { QWindowsWindow::baseWindowOf(p)->applyCursor(); + } else { + SetCursor(defaultCursor(window()).handle()); + } } else { SetCursor(m_cursor.handle()); } -- cgit v1.2.3 From 39a902c0081f442141353c466ada09d62036c04e Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sat, 29 Dec 2012 17:08:12 +0100 Subject: Add support for setting/getting the paper name on the QPrinter This adds support for specifying a paper name which will be set on the printer if it is available for the driver. Change-Id: Id7fd0c8cf68745db3d7a8de7e2ac98d3e2ba9b79 Reviewed-by: Pierre Rossi --- src/plugins/platforms/cocoa/qprintengine_mac.mm | 38 +++++++++++++++++ src/plugins/platforms/cocoa/qprintengine_mac_p.h | 1 + src/plugins/printsupport/cups/qcupsprintengine.cpp | 47 +++++++++++++++++++++- src/plugins/printsupport/cups/qcupsprintengine_p.h | 1 + 4 files changed, 85 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 4570a663f6..4748005f1a 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -180,6 +180,38 @@ QPrinter::PaperSize QMacPrintEnginePrivate::paperSize() const return QPlatformPrinterSupport::convertQSizeFToPaperSize(sizef); } +void QMacPrintEnginePrivate::setPaperName(const QString &name) +{ + Q_Q(QMacPrintEngine); + PMPrinter printer; + + if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) { + CFArrayRef array; + if (PMPrinterGetPaperList(printer, &array) != noErr) { + PMRelease(printer); + return; + } + int count = CFArrayGetCount(array); + for (int i = 0; i < count; ++i) { + PMPaper paper = static_cast(const_cast(CFArrayGetValueAtIndex(array, i))); + QCFString paperName; + if (PMPaperCreateLocalizedName(paper, printer, &paperName) == noErr) { + if (QString(paperName) == name) { + PMPageFormat tmp; + PMCreatePageFormatWithPMPaper(&tmp, paper); + PMCopyPageFormat(tmp, format()); + q->setProperty(QPrintEngine::PPK_Orientation, orient); + if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) { + // Don't know, warn for the moment. + qWarning("QMacPrintEngine, problem setting paper name"); + } + } + } + } + PMRelease(printer); + } +} + QList QMacPrintEnginePrivate::supportedResolutions() const { Q_ASSERT_X(printInfo, "QMacPrinterEngine::supportedResolutions", @@ -601,6 +633,9 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va case PPK_PaperSize: d->setPaperSize(QPrinter::PaperSize(value.toInt())); break; + case PPK_PaperName: + d->setPaperName(value.toString()); + break; case PPK_PrinterName: { bool printerNameSet = false; OSStatus status = noErr; @@ -739,6 +774,9 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const case PPK_PaperSize: ret = d->paperSize(); break; + case PPK_PaperName: + ret = QCFString::toQString([d->printInfo localizedPaperName]); + break; case PPK_PaperRect: { QRect r; PMRect macrect; diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index e122cc5822..fd1b60a9ad 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -142,6 +142,7 @@ public: bool newPage_helper(); void setPaperSize(QPrinter::PaperSize ps); QPrinter::PaperSize paperSize() const; + void setPaperName(const QString &name); QList supportedResolutions() const; inline bool isPrintSessionInitialized() const { diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index 21895e9d28..1c86420cb2 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -103,7 +103,9 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v d->cupsOptions = value.toStringList(); break; case PPK_CupsStringPageSize: + case PPK_PaperName: d->cupsStringPageSize = value.toString(); + d->setPaperName(); break; case PPK_PrinterName: // prevent setting the defaults again for the same printer @@ -140,6 +142,7 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const ret = d->cupsOptions; break; case PPK_CupsStringPageSize: + case PPK_PaperName: ret = d->cupsStringPageSize; break; default: @@ -284,6 +287,7 @@ void QCupsPrintEnginePrivate::setPaperSize() QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(printerPaperSize)); if (cups.currentPPD()) { + cupsStringPageSize = QLatin1String("Custom"); const ppd_option_t* pageSizes = cups.pageSizes(); for (int i = 0; i < pageSizes->num_choices; ++i) { QByteArray cupsPageSize = pageSizes->choices[i].choice; @@ -293,7 +297,7 @@ void QCupsPrintEnginePrivate::setPaperSize() if (qAbs(size.width - tmpCupsPaperRect.width()) < 5 && qAbs(size.height - tmpCupsPaperRect.height()) < 5) { cupsPaperRect = tmpCupsPaperRect; cupsPageRect = tmpCupsPageRect; - + cupsStringPageSize = pageSizes->choices[i].text; leftMargin = cupsPageRect.x() - cupsPaperRect.x(); topMargin = cupsPageRect.y() - cupsPaperRect.y(); rightMargin = cupsPaperRect.right() - cupsPageRect.right(); @@ -307,6 +311,43 @@ void QCupsPrintEnginePrivate::setPaperSize() } } +void QCupsPrintEnginePrivate::setPaperName() +{ + if (QCUPSSupport::isAvailable()) { + QCUPSSupport cups; + if (cups.currentPPD()) { + const ppd_option_t* pageSizes = cups.pageSizes(); + bool foundPaperName = false; + for (int i = 0; i < pageSizes->num_choices; ++i) { + if (cupsStringPageSize == pageSizes->choices[i].text) { + foundPaperName = true; + QByteArray cupsPageSize = pageSizes->choices[i].choice; + cupsPaperRect = cups.paperRect(cupsPageSize); + cupsPageRect = cups.pageRect(cupsPageSize); + leftMargin = cupsPageRect.x() - cupsPaperRect.x(); + topMargin = cupsPageRect.y() - cupsPaperRect.y(); + rightMargin = cupsPaperRect.right() - cupsPageRect.right(); + bottomMargin = cupsPaperRect.bottom() - cupsPageRect.bottom(); + printerPaperSize = QPrinter::Custom; + customPaperSize = cupsPaperRect.size(); + for (int ps = 0; ps < QPrinter::NPageSize; ++ps) { + QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps)); + if (qAbs(size.width - cupsPaperRect.width()) < 5 && qAbs(size.height - cupsPaperRect.height()) < 5) { + printerPaperSize = static_cast(ps); + customPaperSize = QSize(); + break; + } + } + updatePaperSize(); + break; + } + } + if (!foundPaperName) + cupsStringPageSize = QString(); + } + } +} + void QCupsPrintEnginePrivate::setCupsDefaults() { if (QCUPSSupport::isAvailable()) { @@ -348,8 +389,10 @@ void QCupsPrintEnginePrivate::setCupsDefaults() const ppd_option_t* pageSizes = cups.pageSizes(); QByteArray cupsPageSize; for (int i = 0; i < pageSizes->num_choices; ++i) { - if (static_cast(pageSizes->choices[i].marked) == 1) + if (static_cast(pageSizes->choices[i].marked) == 1) { cupsPageSize = pageSizes->choices[i].choice; + cupsStringPageSize = pageSizes->choices[i].text; + } } cupsOptions = cups.options(); diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index 31ee6bb256..db947a0232 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -97,6 +97,7 @@ public: void updatePaperSize(); void setPaperSize(); + void setPaperName(); void setCupsDefaults(); private: -- cgit v1.2.3 From 381566445e89c4d945ca40d1fbc12c728e0186b5 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 8 Mar 2013 14:00:27 +0100 Subject: Reset the X error handler after initializing GTK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that we were setting the error handler to a dummy one in qxcbconnection.cpp, but GTK then overrides it to an handler that calls exit(1) on errors. This causes problems as we are relying on the glXCreateContextAttribsARB call to fail when creating an OpenGL context, so we need to reset the handler after GTK initialization. Change-Id: I9bc3eb2480abfd3740884cb0000b9180d2cf37a5 Reviewed-by: J-P Nurmi Reviewed-by: Samuel Rødal --- src/plugins/platformthemes/gtk2/qgtk2theme.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp index b26ab94b83..f069d9f97c 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp @@ -46,6 +46,8 @@ #undef signals #include +#include + QT_BEGIN_NAMESPACE const char *QGtk2Theme::name = "gtk2"; @@ -62,7 +64,13 @@ static QString gtkSetting(const gchar *propertyName) QGtk2Theme::QGtk2Theme() { + // gtk_init will reset the Xlib error handler, and that causes + // Qt applications to quit on X errors. Therefore, we need to manually restore it. + int (*oldErrorHandler)(Display *, XErrorEvent *) = XSetErrorHandler(NULL); + gtk_init(0, 0); + + XSetErrorHandler(oldErrorHandler); } QVariant QGtk2Theme::themeHint(QPlatformTheme::ThemeHint hint) const -- cgit v1.2.3 From a410273fabb294b46b04f7ccee38bab668413061 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Tue, 12 Mar 2013 09:24:16 +0100 Subject: Fix wrong initial position If the widget is larger than the screen, its title bar top left corner will be shown inside the screen. Task-number: QTBUG-30142 Change-Id: Id93773874be3616b3ef4b9bee6e1bb751c541d7b Reviewed-by: Caroline Chao Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 21 ++++++++++++++++++++- src/plugins/platforms/windows/qwindowswindow.cpp | 5 +++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 3f00893465..5ec2cea362 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -47,6 +47,7 @@ #include #include #include +#include #ifndef QT_NO_WIDGETS #include @@ -584,10 +585,28 @@ QString qt_mac_applicationName() return appName; } +/* + Mac window coordinates are in the first quadrant: 0, 0 is at the lower-left + corner of the primary screen. This function converts the given rect to an + NSRect for the window geometry, flipping from 4th quadrant to 1st quadrant + and simultaneously ensuring that as much of the window as possible will be + onscreen. If the rect is too tall for the screen, the OS will reduce the + window's height anyway; but by moving the window upwards we can have more + of it onscreen. But the application can still control the y coordinate + in case it really wants the window to be positioned partially offscreen. +*/ NSRect qt_mac_flipRect(const QRect &rect, QWindow *window) { QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window); - int flippedY = onScreen->geometry().height() - rect.y() - rect.height(); + int flippedY = onScreen->geometry().height() - (rect.y() + rect.height()); + + // In case of automatic positioning, try to put as much of the window onscreen as possible. + if (window->isTopLevel() && qt_window_private(const_cast(window))->positionAutomatic && flippedY < 0) + flippedY = onScreen->geometry().height() - onScreen->availableGeometry().height() - onScreen->availableGeometry().y(); +#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG + qDebug() << Q_FUNC_INFO << rect << "flippedY" << flippedY << + "screen" << onScreen->geometry() << "available" << onScreen->availableGeometry(); +#endif return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2da0af8abb..6cbe3e8cf7 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -487,6 +487,11 @@ QWindowsWindow::WindowData const QWindowCreationContextPtr context(new QWindowCreationContext(w, rect, data.customMargins, style, exStyle)); QWindowsContext::instance()->setWindowCreationContext(context); + if (context->frameX < 0) + context->frameX = 0; + if (context->frameY < 0) + context->frameY = 0; + if (QWindowsContext::verboseWindows) qDebug().nospace() << "CreateWindowEx: " << w << *this -- cgit v1.2.3 From 06a65b053e9b8697c0140219fdc3c28495426e77 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 7 Mar 2013 15:21:07 +0200 Subject: Get rid of qt_determine_writing_systems_from_truetype_bits() Move this code to QPlatformFontDatabase and get rid of all dups of it. Change-Id: Idea6c84819039bf3b345b1305305951ade8d1ac4 Reviewed-by: Lars Knoll --- .../platforms/windows/qwindowsfontdatabase.cpp | 126 +-------------------- .../platforms/windows/qwindowsfontdatabase_ft.cpp | 2 +- 2 files changed, 2 insertions(+), 126 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 6fdb10288a..2fa691347d 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -606,130 +606,6 @@ QDebug operator<<(QDebug d, const QFontDef &def) return d; } -/* From QFontDatabase.cpp, qt_determine_writing_systems_from_truetype_bits(). - * Fixme: Make public? */ - -// see the Unicode subset bitfields in the MSDN docs -static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { - // Any, - { 127, 127 }, - // Latin, - { 0, 127 }, - // Greek, - { 7, 127 }, - // Cyrillic, - { 9, 127 }, - // Armenian, - { 10, 127 }, - // Hebrew, - { 11, 127 }, - // Arabic, - { 13, 127 }, - // Syriac, - { 71, 127 }, - //Thaana, - { 72, 127 }, - //Devanagari, - { 15, 127 }, - //Bengali, - { 16, 127 }, - //Gurmukhi, - { 17, 127 }, - //Gujarati, - { 18, 127 }, - //Oriya, - { 19, 127 }, - //Tamil, - { 20, 127 }, - //Telugu, - { 21, 127 }, - //Kannada, - { 22, 127 }, - //Malayalam, - { 23, 127 }, - //Sinhala, - { 73, 127 }, - //Thai, - { 24, 127 }, - //Lao, - { 25, 127 }, - //Tibetan, - { 70, 127 }, - //Myanmar, - { 74, 127 }, - // Georgian, - { 26, 127 }, - // Khmer, - { 80, 127 }, - // SimplifiedChinese, - { 126, 127 }, - // TraditionalChinese, - { 126, 127 }, - // Japanese, - { 126, 127 }, - // Korean, - { 56, 127 }, - // Vietnamese, - { 0, 127 }, // same as latin1 - // Other, - { 126, 127 }, - // Ogham, - { 78, 127 }, - // Runic, - { 79, 127 }, - // Nko, - { 14, 127 }, -}; - -enum -{ - SimplifiedChineseCsbBit = 18, - TraditionalChineseCsbBit = 20, - JapaneseCsbBit = 17, - KoreanCsbBit = 21 -}; - -static inline void writingSystemsFromTrueTypeBits(quint32 unicodeRange[4], - quint32 codePageRange[2], - QSupportedWritingSystems *ws) -{ - bool hasScript = false; - for(int i = 0; i < QFontDatabase::WritingSystemsCount; i++) { - int bit = requiredUnicodeBits[i][0]; - int index = bit/32; - int flag = 1 << (bit&31); - if (bit != 126 && unicodeRange[index] & flag) { - bit = requiredUnicodeBits[i][1]; - index = bit/32; - - flag = 1 << (bit&31); - if (bit == 127 || unicodeRange[index] & flag) { - ws->setSupported(QFontDatabase::WritingSystem(i), true); - hasScript = true; - } - } - } - if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) { - ws->setSupported(QFontDatabase::SimplifiedChinese, true); - hasScript = true; - } - if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) { - ws->setSupported(QFontDatabase::TraditionalChinese, true); - hasScript = true; - } - if(codePageRange[0] & (1 << JapaneseCsbBit)) { - ws->setSupported(QFontDatabase::Japanese, true); - hasScript = true; - //qDebug("font %s supports Japanese", familyName.latin1()); - } - if(codePageRange[0] & (1 << KoreanCsbBit)) { - ws->setSupported(QFontDatabase::Korean, true); - hasScript = true; - } - if (!hasScript) - ws->setSupported(QFontDatabase::Symbol, true); -} - // convert 0 ~ 1000 integer to QFont::Weight static inline QFont::Weight weightFromInteger(long weight) { @@ -1019,7 +895,7 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, unicodeRange[3] = 0xffffffff; } #endif - writingSystemsFromTrueTypeBits(unicodeRange, codePageRange, &writingSystems); + writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange); // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains // the symbol for Baht, and Windows thus reports that it supports the Thai script. // Since it's the default UI font on this platform, most widgets will be unable to diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index c2ddb912f1..99b8d215f2 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -175,7 +175,7 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, quint32 codePageRange[2] = { signature->fsCsb[0], signature->fsCsb[1] }; - writingSystems = QBasicFontDatabase::determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange); // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains // the symbol for Baht, and Windows thus reports that it supports the Thai script. // Since it's the default UI font on this platform, most widgets will be unable to -- cgit v1.2.3 From bf3adbcdf5e1a54093febc30e02c4dac09376c7e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 21 Feb 2013 15:30:11 +0100 Subject: XCB: support creation of OpenGL ES profiles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GLX_EXT_create_context_es2_profile extension allows us to create OpenGL ES profiles even under a desktop OpenGL implementation. Therefore, if a OpenGL ES renderable type is requested, and we have that extension, we can fullfill the request. We also strenghten the renderable types that the XCB plugin supports (default, OpenGL, OpenGL ES). Change-Id: I94ecbbaa910ab4c6d71185a69640e79594cb7bdc Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qglxintegration.cpp | 124 ++++++++++++++++---------- 1 file changed, 78 insertions(+), 46 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 5efac6ce12..516b35dac8 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -71,6 +71,10 @@ typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXC #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #endif +#ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#endif + #ifndef GLX_CONTEXT_PROFILE_MASK_ARB #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 #endif @@ -123,33 +127,34 @@ static void updateFormatFromContext(QSurfaceFormat &format) } format.setProfile(QSurfaceFormat::NoProfile); + format.setOption(QSurfaceFormat::FormatOptions()); - const int version = (major << 8) + minor; - if (version < 0x0300) { - format.setProfile(QSurfaceFormat::NoProfile); - format.setOption(QSurfaceFormat::DeprecatedFunctions); - return; - } - - // Version 3.0 onwards - check if it includes deprecated functionality or is - // a debug context - GLint value = 0; - glGetIntegerv(GL_CONTEXT_FLAGS, &value); - if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)) - format.setOption(QSurfaceFormat::DeprecatedFunctions); - if (value & GL_CONTEXT_FLAG_DEBUG_BIT) - format.setOption(QSurfaceFormat::DebugContext); - if (version < 0x0302) - return; - - // Version 3.2 and newer have a profile - value = 0; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); + if (format.renderableType() == QSurfaceFormat::OpenGL) { + if (format.version() < qMakePair(3, 0)) { + format.setOption(QSurfaceFormat::DeprecatedFunctions); + return; + } - if (value & GL_CONTEXT_CORE_PROFILE_BIT) - format.setProfile(QSurfaceFormat::CoreProfile); - else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) - format.setProfile(QSurfaceFormat::CompatibilityProfile); + // Version 3.0 onwards - check if it includes deprecated functionality or is + // a debug context + GLint value = 0; + glGetIntegerv(GL_CONTEXT_FLAGS, &value); + if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)) + format.setOption(QSurfaceFormat::DeprecatedFunctions); + if (value & GL_CONTEXT_FLAG_DEBUG_BIT) + format.setOption(QSurfaceFormat::DebugContext); + if (format.version() < qMakePair(3, 2)) + return; + + // Version 3.2 and newer have a profile + value = 0; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); + + if (value & GL_CONTEXT_CORE_PROFILE_BIT) + format.setProfile(QSurfaceFormat::CoreProfile); + else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + format.setProfile(QSurfaceFormat::CompatibilityProfile); + } } QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share) @@ -162,7 +167,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat { if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType) m_format.setRenderableType(QSurfaceFormat::OpenGL); - if (m_format.renderableType() != QSurfaceFormat::OpenGL) + if (m_format.renderableType() != QSurfaceFormat::OpenGL && m_format.renderableType() != QSurfaceFormat::OpenGLES) return; if (share) @@ -181,17 +186,31 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile"); // Use glXCreateContextAttribsARB if available - if (glxExt.contains("GLX_ARB_create_context") && glXCreateContextAttribsARB != 0) { + // Also, GL ES context creation requires GLX_EXT_create_context_es2_profile + if (glxExt.contains("GLX_ARB_create_context") && glXCreateContextAttribsARB != 0 + && (m_format.renderableType() != QSurfaceFormat::OpenGLES || (supportsProfiles && glxExt.contains("GLX_EXT_create_context_es2_profile")))) { // Try to create an OpenGL context for each known OpenGL version in descending // order from the requested version. const int requestedVersion = format.majorVersion() * 10 + qMin(format.minorVersion(), 9); QVector glVersions; - if (requestedVersion > 43) - glVersions << requestedVersion; + if (m_format.renderableType() == QSurfaceFormat::OpenGL) { + if (requestedVersion > 43) + glVersions << requestedVersion; + + // Don't bother with versions below 2.0 + glVersions << 43 << 42 << 41 << 40 << 33 << 32 << 31 << 30 << 21 << 20; + } else if (m_format.renderableType() == QSurfaceFormat::OpenGLES) { + if (requestedVersion > 30) + glVersions << requestedVersion; + + // Don't bother with versions below ES 2.0 + glVersions << 30 << 20; + // ES does not support any format option + m_format.setOption(QSurfaceFormat::FormatOptions()); + } - // Don't bother with versions below 2.0 - glVersions << 43 << 42 << 41 << 40 << 33 << 32 << 31 << 30 << 21 << 20; + Q_ASSERT(glVersions.count() > 0); for (int i = 0; !m_context && i < glVersions.count(); i++) { const int version = glVersions[i]; @@ -205,25 +224,30 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat contextAttributes << GLX_CONTEXT_MAJOR_VERSION_ARB << majorVersion << GLX_CONTEXT_MINOR_VERSION_ARB << minorVersion; - // If asking for OpenGL 3.2 or newer we should also specify a profile - if (version >= 32 && supportsProfiles) { - if (m_format.profile() == QSurfaceFormat::CoreProfile) - contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - else - contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - int flags = 0; + if (m_format.renderableType() == QSurfaceFormat::OpenGL) { + // If asking for OpenGL 3.2 or newer we should also specify a profile + if (version >= 32 && supportsProfiles) { + if (m_format.profile() == QSurfaceFormat::CoreProfile) + contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + else + contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } - if (m_format.testOption(QSurfaceFormat::DebugContext)) - flags |= GLX_CONTEXT_DEBUG_BIT_ARB; + int flags = 0; - // A forward-compatible context may be requested for 3.0 and later - if (version >= 30 && !m_format.testOption(QSurfaceFormat::DeprecatedFunctions)) - flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + if (m_format.testOption(QSurfaceFormat::DebugContext)) + flags |= GLX_CONTEXT_DEBUG_BIT_ARB; - if (flags != 0) - contextAttributes << GLX_CONTEXT_FLAGS_ARB << flags; + // A forward-compatible context may be requested for 3.0 and later + if (version >= 30 && !m_format.testOption(QSurfaceFormat::DeprecatedFunctions)) + flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (flags != 0) + contextAttributes << GLX_CONTEXT_FLAGS_ARB << flags; + } else if (m_format.renderableType() == QSurfaceFormat::OpenGLES) { + contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + } contextAttributes << None; @@ -239,6 +263,10 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat // Could not create a context using glXCreateContextAttribsARB, falling back to glXCreateNewContext. if (!m_context) { + // requesting an OpenGL ES context requires glXCreateContextAttribsARB, so bail out + if (m_format.renderableType() == QSurfaceFormat::OpenGLES) + return; + m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, m_shareContext, true); if (!m_context && m_shareContext) { // re-try without a shared glx context @@ -255,6 +283,10 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat // Create a temporary window so that we can make the new context current window = createDummyWindow(screen, config); } else { + // requesting an OpenGL ES context requires glXCreateContextAttribsARB, so bail out + if (m_format.renderableType() == QSurfaceFormat::OpenGLES) + return; + // Note that m_format gets updated with the used surface format visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(screen), screen->screenNumber(), &m_format); if (!visualInfo) -- cgit v1.2.3 From ef7c25e8486a092ead3c02e0346cc0d765d6a22f Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Thu, 7 Mar 2013 11:38:36 -0300 Subject: QNX: Fix build error This error was caused by a merge Change-Id: I937ab6ac905ba3a729669060285df6d0c3d5be2f Reviewed-by: Thomas McGuire Reviewed-by: Tobias Koenig Reviewed-by: Wolfgang Bremer --- src/plugins/platforms/qnx/qqnxscreen.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 3e79ca7f1d..f9efbde40c 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -503,11 +503,6 @@ QPlatformCursor * QQnxScreen::cursor() const return m_cursor; } -QPlatformCursor * QQnxScreen::cursor() const -{ - return m_cursor; -} - void QQnxScreen::keyboardHeightChanged(int height) { if (height == m_keyboardHeight) -- cgit v1.2.3 From 0194fa135b1d84a8c8d70ed8a0ff46eef0289fb7 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sun, 10 Mar 2013 10:55:27 +0200 Subject: Hide Harfbuzz from the outer world Don't export, don't generate private headers, don't mention HB in API. Change-Id: I048ebd178bf4afaf9fda710a00933b95274cf910 Reviewed-by: Josh Faust Reviewed-by: Lars Knoll --- src/plugins/platforms/windows/windows.pro | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index ff162e2d41..3aa9caaa0f 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -102,12 +102,8 @@ contains(QT_CONFIG, opengles2) { } } -# Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h. -DEFINES *= QT_COMPILES_IN_HARFBUZZ - contains(QT_CONFIG, freetype) { DEFINES *= QT_NO_FONTCONFIG - DEFINES *= QT_COMPILES_IN_HARFBUZZ QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype HEADERS += \ -- cgit v1.2.3 From bad1918cb438874e31dee05536e300c3470c7b23 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 13 Mar 2013 10:19:21 +0100 Subject: Fix build with Windows SDKs pre 7.0. Check whether the IShellLibrary interface exists. Task-number: QTBUG-29447 Change-Id: I93fc54a1e6d5c090f7c1768c756571ba57a7b2d2 Reviewed-by: Andreas Holzammer Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 14bc26f770..0530707479 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1004,7 +1004,7 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, QF qErrnoWarning("%s: SetOptions() failed", __FUNCTION__); } -#ifndef Q_OS_WINCE +#if !defined(Q_OS_WINCE) && defined(__IShellLibrary_INTERFACE_DEFINED__) // Windows SDK 7 // Helper for "Libraries": collections of folders appearing from Windows 7 // on, visible in the file dialogs. @@ -1057,7 +1057,7 @@ QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *i return result; } -#else // !Q_OS_WINCE +#else // !Q_OS_WINCE && __IShellLibrary_INTERFACE_DEFINED__ QStringList QWindowsNativeFileDialogBase::libraryItemPaths(IShellItem *) { @@ -1069,7 +1069,7 @@ QString QWindowsNativeFileDialogBase::libraryDefaultSaveFolder(IShellItem *) return QString(); } -#endif // Q_OS_WINCE +#endif // Q_OS_WINCE || !__IShellLibrary_INTERFACE_DEFINED__ QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item) { -- cgit v1.2.3 From d1d0df8fb6a3461d37455f87445d9bcef62a0f93 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 12 Mar 2013 15:35:37 +0100 Subject: Make qaccessible2.h internal. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should have been done right from the start, instead we only made the documentation internal. Also remove the classes from the BIC data. Change-Id: I238a7a7cc5d26980b23931c78e7e5a4477d46920 Reviewed-by: Oswald Buddenhagen Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/complexwidgets.h | 4 ++-- src/plugins/accessible/widgets/itemviews.cpp | 2 +- src/plugins/accessible/widgets/itemviews.h | 4 ++-- src/plugins/accessible/widgets/qaccessiblemenu.h | 2 +- src/plugins/accessible/widgets/qaccessiblewidgets.h | 4 ++-- src/plugins/accessible/widgets/rangecontrols.h | 4 ++-- src/plugins/accessible/widgets/simplewidgets.h | 4 ++-- src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 2 +- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 2 +- src/plugins/platforms/cocoa/qnsviewaccessibility.mm | 2 +- src/plugins/platforms/windows/accessible/iaccessible2.cpp | 2 +- src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp | 2 +- src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h index 1dc4d99ea8..32f67c9c69 100644 --- a/src/plugins/accessible/widgets/complexwidgets.h +++ b/src/plugins/accessible/widgets/complexwidgets.h @@ -43,9 +43,9 @@ #define COMPLEXWIDGETS_H #include -#include +#include #include -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 092278f7fb..93f962da57 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #ifndef QT_NO_ACCESSIBILITY diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index baf7fd8587..bba698bda2 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -44,8 +44,8 @@ #include "QtCore/qpointer.h" #include -#include -#include +#include +#include #include #include diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h index 0241cebab6..74d118a09e 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ b/src/plugins/accessible/widgets/qaccessiblemenu.h @@ -42,7 +42,7 @@ #ifndef QACCESSIBLEMENU_H #define QACCESSIBLEMENU_H -#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index 683893f477..35ef3ce905 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -42,8 +42,8 @@ #ifndef QACCESSIBLEWIDGETS_H #define QACCESSIBLEWIDGETS_H -#include -#include +#include +#include #ifndef QT_NO_ACCESSIBILITY diff --git a/src/plugins/accessible/widgets/rangecontrols.h b/src/plugins/accessible/widgets/rangecontrols.h index ef6f3fa226..a5bc11e1c8 100644 --- a/src/plugins/accessible/widgets/rangecontrols.h +++ b/src/plugins/accessible/widgets/rangecontrols.h @@ -42,8 +42,8 @@ #ifndef RANGECONTROLS_H #define RANGECONTROLS_H -#include -#include +#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index ae1a041dab..4701634ca0 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -43,8 +43,8 @@ #define SIMPLEWIDGETS_H #include -#include -#include +#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 070f23f028..adeb423cf9 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -41,7 +41,7 @@ #include "qcocoaaccessibility.h" #include "qcocoaaccessibilityelement.h" #include -#include +#include #include #ifndef QT_NO_COCOA_ACCESSIBILITY diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index f5f37c5b00..df496a413b 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -43,7 +43,7 @@ #include "qcocoahelpers.h" #include -#include "QAccessibleActionInterface" +#include #import diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index 8ee39bf767..e05ffbe343 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -46,7 +46,7 @@ #include "qcocoaaccessibility.h" #include "qcocoaaccessibilityelement.h" -#include "QAccessibleActionInterface" +#include #include #import diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 164bd6eed9..fb08daa38e 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -44,7 +44,7 @@ #include "iaccessible2.h" #include "qwindowsaccessibility.h" -#include +#include #include #include #include diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 8830d3023a..752b9e7c20 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -51,7 +51,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index c23902014c..bb5d5d13a7 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3 From 94d1d8486154a1df81545cdda2fe4a2ddcb001e1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 7 Mar 2013 18:07:14 +0100 Subject: GTK+ platform theme: cleanup coding style Change-Id: I5db283d7ed42346d9c2b90acbc342336b450aa97 Reviewed-by: Gabriel de Dietrich --- src/plugins/platformthemes/gtk2/main.cpp | 2 +- .../platformthemes/gtk2/qgtk2dialoghelpers.cpp | 12 +++---- .../platformthemes/gtk2/qgtk2dialoghelpers.h | 42 +++++++++++----------- src/plugins/platformthemes/gtk2/qgtk2theme.h | 6 ++-- 4 files changed, 31 insertions(+), 31 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/main.cpp b/src/plugins/platformthemes/gtk2/main.cpp index 0c3fe46e29..13e7d57b13 100644 --- a/src/plugins/platformthemes/gtk2/main.cpp +++ b/src/plugins/platformthemes/gtk2/main.cpp @@ -56,7 +56,7 @@ public: QPlatformTheme *QGtk2ThemePlugin::create(const QString &key, const QStringList ¶ms) { Q_UNUSED(params); - if (!key.compare(QStringLiteral("gtk2"), Qt::CaseInsensitive)) + if (!key.compare(QLatin1String(QGtk2Theme::name), Qt::CaseInsensitive)) return new QGtk2Theme; return 0; diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp index 2a8815654f..25d45eb81d 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp @@ -65,7 +65,7 @@ public: QGtk2Dialog(GtkWidget *gtkWidget); ~QGtk2Dialog(); - GtkDialog* gtkDialog() const; + GtkDialog *gtkDialog() const; void exec(); bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); @@ -93,7 +93,7 @@ QGtk2Dialog::~QGtk2Dialog() gtk_widget_destroy(gtkWidget); } -GtkDialog* QGtk2Dialog::gtkDialog() const +GtkDialog *QGtk2Dialog::gtkDialog() const { return GTK_DIALOG(gtkWidget); } @@ -217,7 +217,7 @@ void QGtk2ColorDialogHelper::onColorChanged(QGtk2ColorDialogHelper *dialog) void QGtk2ColorDialogHelper::applyOptions() { - GtkDialog* gtkDialog = d->gtkDialog(); + GtkDialog *gtkDialog = d->gtkDialog(); gtk_window_set_title(GTK_WINDOW(gtkDialog), options()->windowTitle().toUtf8()); GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog)); @@ -449,7 +449,7 @@ void QGtk2FileDialogHelper::applyOptions() } } -void QGtk2FileDialogHelper::setNameFilters(const QStringList& filters) +void QGtk2FileDialogHelper::setNameFilters(const QStringList &filters) { GtkDialog *gtkDialog = d->gtkDialog(); foreach (GtkFileFilter *filter, _filters) @@ -501,7 +501,7 @@ void QGtk2FontDialogHelper::hide() d->hide(); } -static QString qt_fontToString(const QFont& font) +static QString qt_fontToString(const QFont &font) { PangoFontDescription *desc = pango_font_description_new(); pango_font_description_set_size(desc, font.pointSizeF() * PANGO_SCALE); @@ -537,7 +537,7 @@ static QString qt_fontToString(const QFont& font) static QFont qt_fontFromString(const QString &name) { QFont font; - PangoFontDescription* desc = pango_font_description_from_string(name.toUtf8()); + PangoFontDescription *desc = pango_font_description_from_string(name.toUtf8()); font.setPointSizeF(static_cast(pango_font_description_get_size(desc)) / PANGO_SCALE); QString family = QString::fromUtf8(pango_font_description_get_family(desc)); diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h index 08af59b2a4..c2d12625f5 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h @@ -60,12 +60,12 @@ public: QGtk2ColorDialogHelper(); ~QGtk2ColorDialogHelper(); - virtual bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); - virtual void exec(); - virtual void hide(); + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + void exec(); + void hide(); - virtual void setCurrentColor(const QColor &color); - virtual QColor currentColor() const; + void setCurrentColor(const QColor &color); + QColor currentColor() const; private Q_SLOTS: void onAccepted(); @@ -85,18 +85,18 @@ public: QGtk2FileDialogHelper(); ~QGtk2FileDialogHelper(); - virtual bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); - virtual void exec(); - virtual void hide(); + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + void exec(); + void hide(); - virtual bool defaultNameFilterDisables() const; - virtual void setDirectory(const QString &directory); - virtual QString directory() const; - virtual void selectFile(const QString &filename); - virtual QStringList selectedFiles() const; - virtual void setFilter(); - virtual void selectNameFilter(const QString &filter); - virtual QString selectedNameFilter() const; + bool defaultNameFilterDisables() const; + void setDirectory(const QString &directory); + QString directory() const; + void selectFile(const QString &filename); + QStringList selectedFiles() const; + void setFilter(); + void selectNameFilter(const QString &filter); + QString selectedNameFilter() const; private Q_SLOTS: void onAccepted(); @@ -122,12 +122,12 @@ public: QGtk2FontDialogHelper(); ~QGtk2FontDialogHelper(); - virtual bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); - virtual void exec(); - virtual void hide(); + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); + void exec(); + void hide(); - virtual void setCurrentFont(const QFont &font); - virtual QFont currentFont() const; + void setCurrentFont(const QFont &font); + QFont currentFont() const; private Q_SLOTS: void onAccepted(); diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.h b/src/plugins/platformthemes/gtk2/qgtk2theme.h index a351b5b738..a0bd34ed9f 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.h +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.h @@ -51,10 +51,10 @@ class QGtk2Theme : public QGnomeTheme public: QGtk2Theme(); - virtual QVariant themeHint(ThemeHint hint) const; + QVariant themeHint(ThemeHint hint) const; - virtual bool usePlatformNativeDialog(DialogType type) const; - virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + bool usePlatformNativeDialog(DialogType type) const; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; static const char *name; }; -- cgit v1.2.3 From a8e933a74ce44283182b1dea1ec5a73afe6e85a8 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 14 Mar 2013 06:56:28 +0200 Subject: Fix build on MinGW, Win<7 /* broken by 26149d057a464ddafcc9694cfa94525c01a45231 */ Change-Id: I63f4d70e2a6fc1f8f1b302d188cf34d1abb0699c Reviewed-by: Friedemann Kleint Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 0530707479..5cc5230832 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1059,12 +1059,12 @@ QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *i #else // !Q_OS_WINCE && __IShellLibrary_INTERFACE_DEFINED__ -QStringList QWindowsNativeFileDialogBase::libraryItemPaths(IShellItem *) +QStringList QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *) { return QStringList(); } -QString QWindowsNativeFileDialogBase::libraryDefaultSaveFolder(IShellItem *) +QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *) { return QString(); } -- cgit v1.2.3 From 1a60bfdcd1260aad8e8daeb117d4526970aa8228 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Thu, 7 Mar 2013 16:29:11 +0200 Subject: XCB: don't map hidden windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This bug was introduced by the XEMBED implementation (carried over from Qt4, but there it applied to QX11EmbedWidget only): the _XEMBED_INFO property is used to inform the *embedder* whether the embedded window should be mapped when embedded. Task-number: QTBUG-30084 Change-Id: I8d1c467874bdee3300a1b18b8174b2d62f498713 Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbwindow.cpp | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 27cd163c36..20d312216a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1781,24 +1781,6 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev } return; } - - const xcb_atom_t xEmbedInfoAtom = atom(QXcbAtom::_XEMBED_INFO); - if (event->atom == xEmbedInfoAtom) { - const xcb_get_property_cookie_t get_cookie = - xcb_get_property(xcb_connection(), 0, m_window, xEmbedInfoAtom, - XCB_ATOM_ANY, 0, 3); - - xcb_get_property_reply_t *reply = - xcb_get_property_reply(xcb_connection(), get_cookie, NULL); - if (reply && reply->length >= 2) { - const long *data = (const long *)xcb_get_property_value(reply); - if (data[1] & XEMBED_MAPPED) - Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); - else - Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window)); - } - free(reply); - } } void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) -- cgit v1.2.3 From b11317a64339f5a4bcffc8234ecaf15c7fb416f2 Mon Sep 17 00:00:00 2001 From: Axel Waggershauser Date: Fri, 15 Mar 2013 00:42:15 +0100 Subject: Whitespace cleanup: remove trailing whitespace Remove all trailing whitespace from the following list of files: *.cpp *.h *.conf *.qdoc *.pro *.pri *.mm *.rc *.pl *.qps *.xpm *.txt *README excluding 3rdparty, test-data and auto generated code. Note A): the only non 3rdparty c++-files that still have trailing whitespace after this change are: * src/corelib/codecs/cp949codetbl_p.h * src/corelib/codecs/qjpunicode.cpp * src/corelib/codecs/qbig5codec.cpp * src/corelib/xml/qxmlstream_p.h * src/tools/qdoc/qmlparser/qqmljsgrammar.cpp * src/tools/uic/ui4.cpp * tests/auto/other/qtokenautomaton/tokenizers/* * tests/benchmarks/corelib/tools/qstring/data.cpp * util/lexgen/tokenizer.cpp Note B): in about 30 files some overlapping 'leading tab' and 'TAB character in non-leading whitespace' issues have been fixed to make the sanity bot happy. Plus some general ws-fixes here and there as asked for during review. Change-Id: Ia713113c34d82442d6ce4d93d8b1cf545075d11d Reviewed-by: Oswald Buddenhagen --- src/plugins/bearer/connman/qconnmanengine.cpp | 2 +- .../bearer/connman/qconnmanservice_linux.cpp | 4 +- .../bearer/connman/qconnmanservice_linux_p.h | 2 +- .../bearer/networkmanager/qnetworkmanagerservice.h | 84 +++++++++++----------- src/plugins/bearer/qnetworksession_impl.h | 2 +- src/plugins/imageformats/ico/qicohandler.cpp | 2 +- src/plugins/imageformats/ico/qicohandler.h | 6 +- .../platforms/cocoa/qcocoaeventdispatcher.mm | 36 +++++----- src/plugins/platforms/xcb/qxcbcursor.cpp | 2 +- 9 files changed, 70 insertions(+), 70 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 589b0e2c24..e85949afb6 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -574,7 +574,7 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath) QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ptr->id, ptr); foundConfigurations.append(cpPriv); - configInterfaces[cpPriv->id] = serv->getInterface(); + configInterfaces[cpPriv->id] = serv->getInterface(); locker.unlock(); emit configurationAdded(ptr); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 56ae2b6e3c..e78a597433 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -405,7 +405,7 @@ QVariant QConnmanProfileInterface::getProperty(const QString &property) QVariantMap map = getProperties(); if (map.contains(property)) { var = map.value(property); - } + } return var; } @@ -493,7 +493,7 @@ QVariant QConnmanServiceInterface::getProperty(const QString &property) QVariantMap map = getProperties(); if (map.contains(property)) { var = map.value(property); - } + } return var; } diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index d1524ca753..a437c6609c 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -134,7 +134,7 @@ public: QString requestSession(const QString &bearerName); void releaseSession(); - + // properties QString getState(); QStringList getAvailableTechnologies(); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 7038dde3d9..7febe27ad2 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -139,26 +139,26 @@ class QNetworkManagerInterfacePrivate; class QNetworkManagerInterface : public QObject { Q_OBJECT - + public: - + QNetworkManagerInterface(QObject *parent = 0); ~QNetworkManagerInterface(); - + QList getDevices() const; void activateConnection(const QString &serviceName, QDBusObjectPath connection, QDBusObjectPath device, QDBusObjectPath specificObject); void deactivateConnection(QDBusObjectPath connectionPath) const; - + QDBusObjectPath path() const; QDBusInterface *connectionInterface() const; - + bool wirelessEnabled() const; bool wirelessHardwareEnabled() const; QList activeConnections() const; quint32 state(); bool setConnections(); bool isValid(); - + Q_SIGNALS: void deviceAdded(QDBusObjectPath); void deviceRemoved(QDBusObjectPath); @@ -176,9 +176,9 @@ class QNetworkManagerInterfaceAccessPointPrivate; class QNetworkManagerInterfaceAccessPoint : public QObject { Q_OBJECT - + public: - + enum DeviceState { Unknown = 0, Unmanaged, @@ -191,14 +191,14 @@ public: Activated, Failed }; - + enum ApFlag { ApNone = 0x0, Privacy = 0x1 }; - + Q_DECLARE_FLAGS(ApFlags, ApFlag); - + enum ApSecurityFlag { ApSecurityNone = 0x0, PairWep40 = 0x1, @@ -212,9 +212,9 @@ public: KeyPsk = 0x100, Key8021x = 0x200 }; - + Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag); - + explicit QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0); ~QNetworkManagerInterfaceAccessPoint(); @@ -231,7 +231,7 @@ public: quint32 strength() const; bool setConnections(); bool isValid(); - + Q_SIGNALS: void propertiesChanged(QMap ); void propertiesChanged( const QString &, QMap); @@ -245,23 +245,23 @@ class QNetworkManagerInterfaceDevicePrivate; class QNetworkManagerInterfaceDevice : public QObject { Q_OBJECT - + public: - + explicit QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = 0); ~QNetworkManagerInterfaceDevice(); - + QString udi() const; QString networkInterface() const; QDBusInterface *connectionInterface() const; quint32 ip4Address() const; quint32 state() const; quint32 deviceType() const; - + QDBusObjectPath ip4config() const; bool setConnections(); bool isValid(); - + Q_SIGNALS: void stateChanged(const QString &, quint32); @@ -274,20 +274,20 @@ class QNetworkManagerInterfaceDeviceWiredPrivate; class QNetworkManagerInterfaceDeviceWired : public QObject { Q_OBJECT - + public: - + explicit QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, QObject *parent = 0); ~QNetworkManagerInterfaceDeviceWired(); - + QDBusInterface *connectionInterface() const; QString hwAddress() const; quint32 speed() const; bool carrier() const; bool setConnections(); bool isValid(); - + Q_SIGNALS: void propertiesChanged( const QString &, QMap); private: @@ -299,9 +299,9 @@ class QNetworkManagerInterfaceDeviceWirelessPrivate; class QNetworkManagerInterfaceDeviceWireless : public QObject { Q_OBJECT - + public: - + enum DeviceCapability { None = 0x0, Wep40 = 0x1, @@ -311,11 +311,11 @@ public: Wpa = 0x10, Rsn = 0x20 }; - + explicit QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, QObject *parent = 0); ~QNetworkManagerInterfaceDeviceWireless(); - + QDBusObjectPath path() const; QList getAccessPoints(); QDBusInterface *connectionInterface() const; @@ -327,7 +327,7 @@ public: quint32 wirelessCapabilities() const; bool setConnections(); bool isValid(); - + Q_SIGNALS: void propertiesChanged( const QString &, QMap); void accessPointAdded(const QString &,QDBusObjectPath); @@ -341,12 +341,12 @@ class QNetworkManagerSettingsPrivate; class QNetworkManagerSettings : public QObject { Q_OBJECT - + public: - + explicit QNetworkManagerSettings(const QString &settingsService, QObject *parent = 0); ~QNetworkManagerSettings(); - + QDBusInterface *connectionInterface() const; QList listConnections(); bool setConnections(); @@ -362,12 +362,12 @@ class QNetworkManagerSettingsConnectionPrivate; class QNetworkManagerSettingsConnection : public QObject { Q_OBJECT - + public: - + QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent = 0); ~QNetworkManagerSettingsConnection(); - + QDBusInterface *connectionInterface() const; QNmSettingsMap getSettings(); bool setConnections(); @@ -382,7 +382,7 @@ public: bool isValid(); Q_SIGNALS: - + void updated(const QNmSettingsMap &settings); void removed(const QString &path); @@ -395,18 +395,18 @@ class QNetworkManagerConnectionActivePrivate; class QNetworkManagerConnectionActive : public QObject { Q_OBJECT - + public: - + enum ActiveConnectionState { Unknown = 0, Activating = 1, Activated = 2 }; - + explicit QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = 0); ~ QNetworkManagerConnectionActive(); - + QDBusInterface *connectionInterface() const; QString serviceName() const; QDBusObjectPath connection() const; @@ -417,7 +417,7 @@ public: bool setConnections(); bool isValid(); - + Q_SIGNALS: void propertiesChanged(QList); void propertiesChanged( const QString &, QMap); @@ -430,7 +430,7 @@ class QNetworkManagerIp4ConfigPrivate; class QNetworkManagerIp4Config : public QObject { Q_OBJECT - + public: explicit QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0); ~QNetworkManagerIp4Config(); @@ -439,7 +439,7 @@ public: bool isValid(); private: - QNetworkManagerIp4ConfigPrivate *d; + QNetworkManagerIp4ConfigPrivate *d; }; QT_END_NAMESPACE diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index 12893108dc..23828c885c 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -77,7 +77,7 @@ public: //called by QNetworkSession constructor and ensures //that the state is immediately updated (w/o actually opening - //a session). Also this function should take care of + //a session). Also this function should take care of //notification hooks to discover future state changes. void syncStateWithInterface(); diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index b1ef823068..a45c3875bc 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -/*! +/*! \class QtIcoHandler \since 4.4 \brief The QtIcoHandler class provides support for the ICO image format. diff --git a/src/plugins/imageformats/ico/qicohandler.h b/src/plugins/imageformats/ico/qicohandler.h index c0439b9d11..65c0f5cf59 100644 --- a/src/plugins/imageformats/ico/qicohandler.h +++ b/src/plugins/imageformats/ico/qicohandler.h @@ -57,13 +57,13 @@ public: bool write(const QImage &image); QByteArray name() const; - + int imageCount() const; bool jumpToImage(int imageNumber); bool jumpToNextImage(); - + static bool canRead(QIODevice *device); - + bool supportsOption(ImageOption option) const; QVariant option(ImageOption option) const; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index ed4f8cd1fb..5c487b0bdd 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -299,27 +299,27 @@ bool QCocoaEventDispatcher::hasPendingEvents() static bool IsMouseOrKeyEvent( NSEvent* event ) { bool result = false; - + switch( [event type] ) { - case NSLeftMouseDown: - case NSLeftMouseUp: - case NSRightMouseDown: - case NSRightMouseUp: + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSRightMouseDown: + case NSRightMouseUp: case NSMouseMoved: // ?? - case NSLeftMouseDragged: + case NSLeftMouseDragged: case NSRightMouseDragged: - case NSMouseEntered: - case NSMouseExited: - case NSKeyDown: - case NSKeyUp: + case NSMouseEntered: + case NSMouseExited: + case NSKeyDown: + case NSKeyUp: case NSFlagsChanged: // key modifiers changed? case NSCursorUpdate: // ?? - case NSScrollWheel: - case NSTabletPoint: - case NSTabletProximity: - case NSOtherMouseDown: - case NSOtherMouseUp: + case NSScrollWheel: + case NSTabletPoint: + case NSTabletProximity: + case NSOtherMouseDown: + case NSOtherMouseUp: case NSOtherMouseDragged: #ifndef QT_NO_GESTURES case NSEventTypeGesture: // touch events @@ -639,7 +639,7 @@ static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal) Q_UNUSED(worksWhenModal) // For NSPanels (but not NSWindows, sadly), we can set the flag - // worksWhenModal, so that they are active even when they are not modal. + // worksWhenModal, so that they are active even when they are not modal. /* ### not ported QList dialogs = window->findChildren(); @@ -680,7 +680,7 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() // this to actually end the sessions for real (rather than at the // point they were marked as stopped), is that ending a session // when no other session runs below it on the stack will make cocoa - // drop some events on the floor. + // drop some events on the floor. QCocoaAutoReleasePool pool; int stackSize = cocoaModalSessionStack.size(); @@ -859,7 +859,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() if (currentExecIsNSAppRun) { // The event dispatcher has been interrupted. But since // [NSApplication run] is running the event loop, we - // delayed stopping it until now (to let cocoa process + // delayed stopping it until now (to let cocoa process // pending cocoa events first). if (currentModalSessionCached) temporarilyStopAllModalSessions(); diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 1b11ef7f95..ff40c6a9ab 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -306,7 +306,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) else // No X11 cursor control when there is no widget under the cursor return; - + xcb_cursor_t c = XCB_CURSOR_NONE; if (cursor) { if (cursor->shape() == Qt::BitmapCursor) { -- cgit v1.2.3 From 2fa3d365ac60aba43ad09e5239ec61d740c8704d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 Mar 2013 15:25:04 +0100 Subject: Windows: Fix class name generation for Qt Quick Controls. New combinations of settings need to be handled (for example, GL + drop shadows for menus). Generate the class name depending on style settings. Introduce new dynamic property for drop shadows. Change-Id: I438f7bdd87f09d3c99076ebf825a12d862948ec1 Reviewed-by: Joerg Bornemann Reviewed-by: Jens Bache-Wiig Reviewed-by: Oliver Wolff Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/windows/qwindowscontext.cpp | 81 +++++++++++------------ 1 file changed, 39 insertions(+), 42 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index f824666a54..7e6b55dead 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -368,56 +368,53 @@ void QWindowsContext::setKeyGrabber(QWindow *w) } // Window class registering code (from qapplication_win.cpp) -// If 0 is passed as the widget pointer, register a window class -// for QWidget as default. This is used in QGLTemporaryContext -// during GL initialization, where we don't want to use temporary -// QWidgets or QGLWidgets, neither do we want to have separate code -// to register window classes. QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL) { - const Qt::WindowFlags flags = w ? w->flags() : (Qt::WindowFlags)0; + Q_ASSERT(w); + const Qt::WindowFlags flags = w->flags(); const Qt::WindowFlags type = flags & Qt::WindowType_Mask; - - uint style = 0; - bool icon = false; - QString cname = QStringLiteral("Qt5"); - if (w && isGL) { - cname += QStringLiteral("QGLWindow"); - style = CS_DBLCLKS|CS_OWNDC; - icon = true; - } else if (w && (flags & Qt::MSWindowsOwnDC)) { - cname += QStringLiteral("QWindowOwnDC"); - style = CS_DBLCLKS|CS_OWNDC; - icon = true; - } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) { - style = CS_DBLCLKS; - if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) { - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) { - style |= CS_DROPSHADOW; - } - cname += QStringLiteral("QToolTip"); - } else { - cname += QStringLiteral("QTool"); - } - style |= CS_SAVEBITS; - icon = false; - } else if (w && (type == Qt::Popup)) { - cname += QStringLiteral("QPopup"); - style = CS_DBLCLKS|CS_SAVEBITS; - if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP - && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based))) - style |= CS_DROPSHADOW; + // Determine style and icon. + uint style = CS_DBLCLKS; + bool icon = true; + if (isGL || (flags & Qt::MSWindowsOwnDC)) + style |= CS_OWNDC; + if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) + && (type == Qt::Popup || w->property("_q_windowsDropShadow").toBool())) { + style |= CS_DROPSHADOW; + } + if (type == Qt::Tool || type == Qt::ToolTip || type == Qt::Popup) { + style |= CS_SAVEBITS; // Save/restore background icon = false; - } else { - cname += QStringLiteral("QWindow"); - style = CS_DBLCLKS; - icon = true; } + // Create a unique name for the flag combination + QString cname = QStringLiteral("Qt5QWindow"); + switch (type) { + case Qt::Tool: + cname += QStringLiteral("Tool"); + break; + case Qt::ToolTip: + cname += QStringLiteral("ToolTip"); + break; + case Qt::Popup: + cname += QStringLiteral("Popup"); + break; + default: + break; + } + if (isGL) + cname += QStringLiteral("GL"); + if (style & CS_DROPSHADOW) + cname += QStringLiteral("DropShadow"); + if (style & CS_SAVEBITS) + cname += QStringLiteral("SaveBits"); + if (style & CS_OWNDC) + cname += QStringLiteral("OwnDC"); + if (icon) + cname += QStringLiteral("Icon"); HBRUSH brush = 0; - if (w && !isGL) + if (!isGL) brush = GetSysColorBrush(COLOR_WINDOW); return registerWindowClass(cname, qWindowsWndProc, style, brush, icon); } -- cgit v1.2.3 From d1b4857d1718ef50dba64c8700253fed5d187ab2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 10 Mar 2013 13:34:52 -0700 Subject: Make sure that we #include qconfig.h before testing for features. This is mandatory in public headers (qiodevice.h, qopengl*, etc.), but it's a good idea even in private headers, in case someone includes that header first somewhere. In particular, all platformsupport API is private. Change-Id: If287baa5d9ed14e93c1666efa0e6332c4c1cd9a4 Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h | 1 + src/plugins/platforms/cocoa/qcocoasystemtrayicon.h | 2 ++ src/plugins/platforms/cocoa/qprintengine_mac_p.h | 2 ++ src/plugins/platforms/qnx/qqnxclipboard.h | 2 ++ src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h | 2 ++ 5 files changed, 9 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h index 7ebe7a4e9d..3b1fbe042d 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h @@ -41,6 +41,7 @@ #ifndef QCOCOAACCESIBILITYELEMENT_H #define QCOCOAACCESIBILITYELEMENT_H +#include #import #import diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h index 89ab51cf05..61a6ba3e2f 100755 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h @@ -43,6 +43,8 @@ #ifndef QCOCOASYSTEMTRAYICON_P_H #define QCOCOASYSTEMTRAYICON_P_H +#include + #ifndef QT_NO_SYSTEMTRAYICON #include "QtCore/qstring.h" diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index fd1b60a9ad..28183118d8 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -53,6 +53,8 @@ // We mean it. // +#include + #ifndef QT_NO_PRINTER #include diff --git a/src/plugins/platforms/qnx/qqnxclipboard.h b/src/plugins/platforms/qnx/qqnxclipboard.h index 0b75393efd..e069355adc 100644 --- a/src/plugins/platforms/qnx/qqnxclipboard.h +++ b/src/plugins/platforms/qnx/qqnxclipboard.h @@ -42,6 +42,8 @@ #ifndef QQNXCLIPBOARD_H #define QQNXCLIPBOARD_H +#include + #ifndef QT_NO_CLIPBOARD #include diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index 35ed6f3891..106087f757 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -42,6 +42,8 @@ #ifndef QWINDOWSFONTENGINEDIRECTWRITE_H #define QWINDOWSFONTENGINEDIRECTWRITE_H +#include + #ifndef QT_NO_DIRECTWRITE #include -- cgit v1.2.3 From f8624b188b648defb82f65772ccc38286d1b8586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 18 Mar 2013 14:30:28 +0100 Subject: iOS: Use didFinishLaunchingWithOptions to support iOS < 6.0 UIApplicationDelegate's willFinishLaunchingWithOptions message was introduced in 6.0. For now we don't need to distinguish the two, so no need to use willFinishLaunchingWithOptions on iOS >= 6.0. Change-Id: Ic6c2c9d2901def5a5500b186ed57fbe8b8c556d1 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 10c83f4b18..916224f936 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -53,7 +53,7 @@ extern int qt_main(int argc, char *argv[]); @implementation QIOSMainWrapperApplicationDelegate -- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; @@ -70,7 +70,7 @@ extern int qt_main(int argc, char *argv[]); selector:@selector(runUserMain) userInfo:nil repeats:NO]; if ([QIOSApplicationDelegate instancesRespondToSelector:_cmd]) - return [super application:application willFinishLaunchingWithOptions:launchOptions]; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; else return YES; } -- cgit v1.2.3 From 79e729e111dd799ddbe281aaddfbc0e1ec0e7bc0 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 13 Mar 2013 15:28:39 +0100 Subject: OSX: obey the Qt::WindowTransparentForInput flag Ignoring the mouse means you don't get window enter/exit events for that window either. Task-number: QTBUG-30122 Change-Id: I979be9f72f7d225d7b960fc5db4c3956d2749982 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 500eea6f4b..5eab036661 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -418,6 +418,8 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) NSInteger level = this->windowLevel(flags); [m_nsWindow setStyleMask:styleMask]; [m_nsWindow setLevel:level]; + [m_nsWindow setIgnoresMouseEvents:((flags & Qt::ToolTip) == Qt::ToolTip) ? YES : NO]; + // TODO deal with WindowTransparentForInput; setIgnoresMouseEvents is too extreme, you can't click the titlebar setWindowShadow(flags); } -- cgit v1.2.3 From bd8630763c407f723533e4f29f24647d96a79288 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 18 Mar 2013 15:03:06 +0100 Subject: OSX: a window which has WindowDoesNotAcceptFocus isn't first responder Change-Id: If02ce190d93fcae18f1e1b41bc73c83b3226d4e7 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 8f88387966..18714ddbae 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -397,6 +397,8 @@ static QTouchDevice *touchDevice = 0; - (BOOL)acceptsFirstResponder { + if (m_window->flags() & Qt::WindowDoesNotAcceptFocus) + return NO; if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip) return NO; return YES; -- cgit v1.2.3 From 1148da5aa82e07ccab4b5d4fa2bb7a16f6361515 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 18 Mar 2013 20:23:17 +0100 Subject: Fix crash when trying to access accessible parent in dtor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I36a065facc0ea80b3a155eaf646613cbd86fdfac Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/itemviews.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 93f962da57..cb34116f32 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -501,7 +501,7 @@ QRect QAccessibleTable::rect() const QAccessibleInterface *QAccessibleTable::parent() const { - if (view()->parent()) { + if (view() && view()->parent()) { if (qstrcmp("QComboBoxPrivateContainer", view()->parent()->metaObject()->className()) == 0) { return QAccessible::queryAccessibleInterface(view()->parent()->parent()); } -- cgit v1.2.3 From 67faba073dd0ded7de96430cdc7f7e1da7966880 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Wed, 13 Mar 2013 15:55:34 -0300 Subject: BlackBerry: implement QWidget::showMinimized() Add window minimization capability on the plugin. Change-Id: I4539d29b8ebbef935213edde634f0a85b6a21766 Reviewed-by: Kevin Krammer Reviewed-by: Sean Harmer --- src/plugins/platforms/qnx/qqnxbpseventfilter.cpp | 2 +- src/plugins/platforms/qnx/qqnxwindow.cpp | 38 ++++++++++++++++++++++-- src/plugins/platforms/qnx/qqnxwindow.h | 1 + 3 files changed, 38 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp index 542833473d..765853e392 100644 --- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp +++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp @@ -87,7 +87,7 @@ void QQnxBpsEventFilter::installOnEventDispatcher(QAbstractEventDispatcher *disp { qBpsEventFilterDebug() << Q_FUNC_INFO << "dispatcher=" << dispatcher; - if (navigator_request_events(0) != BPS_SUCCESS) + if (navigator_request_events(NAVIGATOR_EXTENDED_DATA) != BPS_SUCCESS) qWarning("QQNX: failed to register for navigator events"); dispatcher->installNativeEventFilter(this); diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index cabbd405e5..51435a1e55 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -53,6 +53,11 @@ #include +#ifdef Q_OS_BLACKBERRY +#include +#include +#endif + #ifdef QQNXWINDOW_DEBUG #define qWindowDebug qDebug #else @@ -624,12 +629,20 @@ void QQnxWindow::setWindowState(Qt::WindowState state) switch (state) { - // WindowMinimized is not supported - navigator does not have an API to minimize a window // WindowActive is not an accepted parameter according to the docs - case Qt::WindowMinimized: case Qt::WindowActive: return; + case Qt::WindowMinimized: + minimize(); + + if (m_unmaximizedGeometry.isValid()) + setGeometry(m_unmaximizedGeometry); + else + setGeometry(m_screen->geometry()); + + break; + case Qt::WindowMaximized: case Qt::WindowFullScreen: m_unmaximizedGeometry = geometry(); @@ -689,6 +702,27 @@ void QQnxWindow::blitFrom(QQnxWindow *sourceWindow, const QPoint &sourceOffset, blitHelper(sourceBuffer, targetBuffer, sourceOffset, QPoint(0, 0), targetRegion, true); } +void QQnxWindow::minimize() +{ +#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET) + qWindowDebug() << Q_FUNC_INFO; + + pps_encoder_t encoder; + + pps_encoder_initialize(&encoder, false); + pps_encoder_add_string(&encoder, "msg", "minimizeWindow"); + + if (navigator_raw_write(pps_encoder_buffer(&encoder), + pps_encoder_length(&encoder)) != BPS_SUCCESS) { + qWindowDebug() << Q_FUNC_INFO << "navigator_raw_write failed:" << strerror(errno); + } + + pps_encoder_cleanup(&encoder); +#else + qWarning("Qt::WindowMinimized is not supported by this OS version"); +#endif +} + void QQnxWindow::updateZorder(int &topZorder) { errno = 0; diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index 90226bb9a4..ad136227e3 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -116,6 +116,7 @@ public: QQnxWindow *findWindow(screen_window_t windowHandle); void blitFrom(QQnxWindow *sourceWindow, const QPoint &sourceOffset, const QRegion &targetRegion); + void minimize(); private: QRect setGeometryHelper(const QRect &rect); -- cgit v1.2.3 From 36cb3f3f655a9090c82de609010cbfb88651a0f3 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 15 Mar 2013 01:28:40 +0200 Subject: Fix the font engines leaking 1. when there were some engines with ref > 1 in the cache, prior to calling QFontDatabase::{add,remove}ApplicationFont()/removeAllApplicationFonts() (QFontCache::clear() has never decreased engine's cache_count); 2. when the QFontEngineData's engine is not in cache i.e. the Box or Test font engine (~QFontEngineData() didn't free engines it keeps). Instead of using the font engine's (external) "cache_count" counter, QFontCache now references a given font engine every time it is inserted to the cache and dereferences exactly that number of times in clear(). Change-Id: I87677ebd24c1f4a81a53526f2e726e596b043c61 Reviewed-by: Lars Knoll --- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 2fa691347d..c59b0edf78 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1097,11 +1097,11 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal if (request.family != fontEngine->fontDef.family) { qWarning("%s: Failed to load font. Got fallback instead: %s", __FUNCTION__, qPrintable(fontEngine->fontDef.family)); - if (fontEngine->cache_count == 0 && fontEngine->ref.load() == 0) + if (fontEngine->ref.load() == 0) delete fontEngine; fontEngine = 0; } else { - Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref.load() == 0); + Q_ASSERT(fontEngine->ref.load() == 0); // Override the generated font name static_cast(fontEngine)->setUniqueFamilyName(uniqueFamilyName); -- cgit v1.2.3