diff options
Diffstat (limited to 'src/plugins')
70 files changed, 1163 insertions, 1402 deletions
diff --git a/src/plugins/generic/tslib/qtslib.cpp b/src/plugins/generic/tslib/qtslib.cpp index 9905d9cc9e..0dcf5bc6ca 100644 --- a/src/plugins/generic/tslib/qtslib.cpp +++ b/src/plugins/generic/tslib/qtslib.cpp @@ -110,12 +110,17 @@ static bool get_sample(struct tsdev *dev, struct ts_sample *sample, bool rawMode void QTsLibMouseHandler::readMouseData() { ts_sample sample; - while (get_sample(m_dev, &sample, m_rawMode)) { + while (get_sample(m_dev, &sample, m_rawMode)) { bool pressed = sample.pressure; int x = sample.x; int y = sample.y; + // work around missing coordinates on mouse release + if (sample.pressure == 0 && sample.x == 0 && sample.y == 0) { + x = m_x; + y = m_y; + } if (!m_rawMode) { //filtering: ignore movements of 2 pixels or less @@ -123,12 +128,6 @@ void QTsLibMouseHandler::readMouseData() int dy = y - m_y; if (dx*dx <= 4 && dy*dy <= 4 && pressed == m_pressed) continue; - } else { - // work around missing coordinates on mouse release in raw mode - if (sample.pressure == 0 && sample.x == 0 && sample.y == 0) { - x = m_x; - y = m_y; - } } QPoint pos(x, y); diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro index c206e99e57..546a0a2af7 100644 --- a/src/plugins/platforminputcontexts/compose/compose.pro +++ b/src/plugins/platforminputcontexts/compose/compose.pro @@ -8,7 +8,7 @@ QT += gui-private LIBS += $$QMAKE_LIBS_XKBCOMMON QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON -DEFINES += COMPOSE_X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"' +DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"' SOURCES += $$PWD/main.cpp \ $$PWD/qcomposeplatforminputcontext.cpp \ diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index e2810c8448..ca61b0e495 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -73,13 +73,19 @@ TableGenerator::TableGenerator() : m_state(NoErrors), void TableGenerator::initPossibleLocations() { - // To add an extra system path use the QTCOMPOSE environment variable - if (qEnvironmentVariableIsSet("QTCOMPOSE")) { - m_possibleLocations.append(QString(qgetenv("QTCOMPOSE"))); - } - - m_possibleLocations.append(QStringLiteral(COMPOSE_X11_PREFIX "/share/X11/locale")); - m_possibleLocations.append(QStringLiteral(COMPOSE_X11_PREFIX "/lib/X11/locale")); + // Compose files come as a part of Xlib library. Xlib doesn't provide + // a mechanism how to retrieve the location of these files reliably, since it was + // never meant for external software to parse compose tables directly. Best we + // can do is to hardcode search paths. To add an extra system path use + // the QTCOMPOSE environment variable + if (qEnvironmentVariableIsSet("QTCOMPOSE")) + m_possibleLocations.append(QString::fromLocal8Bit(qgetenv("QTCOMPOSE"))); + m_possibleLocations.append(QStringLiteral("/usr/share/X11/locale")); + m_possibleLocations.append(QStringLiteral("/usr/local/share/X11/locale")); + m_possibleLocations.append(QStringLiteral("/usr/lib/X11/locale")); + m_possibleLocations.append(QStringLiteral("/usr/local/lib/X11/locale")); + m_possibleLocations.append(QStringLiteral(X11_PREFIX "/share/X11/locale")); + m_possibleLocations.append(QStringLiteral(X11_PREFIX "/lib/X11/locale")); } void TableGenerator::findComposeFile() diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp index 1df7ce3179..b85b1157a8 100644 --- a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp +++ b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp @@ -51,7 +51,10 @@ QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window) : QPlatformBackingStore(window) { Q_ASSERT(window->handle()); - (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this); + if (window->surfaceType() == QSurface::RasterSurface) + (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this); + else + qWarning("QAndroidPlatformBackingStore does not support GL windows."); } QPaintDevice *QAndroidPlatformBackingStore::paintDevice() diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp index bc48b4935b..0b5e96fa36 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp +++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp @@ -42,7 +42,6 @@ #include "qandroidplatformclipboard.h" #include "androidjniclipboard.h" #ifndef QT_NO_CLIPBOARD -#include <QMimeData> QT_BEGIN_NAMESPACE @@ -56,9 +55,8 @@ QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode) if (QClipboard::Clipboard != mode || !QtAndroidClipboard::hasClipboardText()) return 0; - QMimeData *mimeData = new QMimeData(); - mimeData->setText(QtAndroidClipboard::clipboardText()); - return mimeData; + m_mimeData.setText(QtAndroidClipboard::clipboardText()); + return &m_mimeData; } void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.h b/src/plugins/platforms/android/qandroidplatformclipboard.h index 644f326934..f67355c358 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.h +++ b/src/plugins/platforms/android/qandroidplatformclipboard.h @@ -43,6 +43,7 @@ #define QANDROIDPLATFORMCLIPBOARD_H #include <qpa/qplatformclipboard.h> +#include <QMimeData> #ifndef QT_NO_CLIPBOARD QT_BEGIN_NAMESPACE @@ -55,6 +56,9 @@ public: 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; + +private: + QMimeData m_mimeData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp index 59ca69c004..a0b3ae066c 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) - :QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API) + :QEGLPlatformContext(format, share, display) { } diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index 039b19f861..94e58eaeb6 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -47,6 +47,7 @@ #include <QVariant> #include <QFileInfo> #include <QCoreApplication> +#include <private/qguiapplication_p.h> #include <qandroidplatformintegration.h> QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface) @@ -179,7 +180,30 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const return QStringList("android"); } return QStringList("fusion"); - break; + + case MouseDoubleClickDistance: + { + int minimumDistance = qgetenv("QT_ANDROID_MINIMUM_MOUSE_DOUBLE_CLICK_DISTANCE").toInt(); + int ret = minimumDistance; + + QAndroidPlatformIntegration *platformIntegration + = static_cast<QAndroidPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QAndroidPlatformScreen *platformScreen = platformIntegration->screen(); + if (platformScreen != 0) { + QScreen *screen = platformScreen->screen(); + qreal dotsPerInch = screen->physicalDotsPerInch(); + + // Allow 15% of an inch between clicks when double clicking + int distance = qRound(dotsPerInch * 0.15); + if (distance > minimumDistance) + ret = distance; + } + + if (ret > 0) + return ret; + + // fall through + } default: return QPlatformTheme::themeHint(hint); } diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index a2fd8c0613..d8cd32255c 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -33,13 +33,13 @@ OBJECTIVE_SOURCES += main.mm \ qcocoaclipboard.mm \ qcocoadrag.mm \ qmacclipboard.mm \ - qmacmime.mm \ qcocoasystemsettings.mm \ qcocoainputcontext.mm \ qcocoaservices.mm \ qcocoasystemtrayicon.mm \ qcocoaintrospection.mm \ qcocoakeymapper.mm \ + qcocoamimetypes.mm SOURCES += messages.cpp @@ -70,14 +70,14 @@ HEADERS += qcocoaintegration.h \ qcocoaclipboard.h \ qcocoadrag.h \ qmacclipboard.h \ - qmacmime.h \ qcocoasystemsettings.h \ qcocoainputcontext.h \ qcocoaservices.h \ qcocoasystemtrayicon.h \ qcocoaintrospection.h \ qcocoakeymapper.h \ - messages.h + messages.h \ + qcocoamimetypes.h RESOURCES += qcocoaresources.qrc diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm index a49ff902a5..f6c424d4fd 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qcocoaclipboard.h" -#include "qmacmime.h" #include "qmacclipboard.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 5d7f53ee5d..2c8d391d2b 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qcocoadrag.h" -#include "qmacmime.h" #include "qmacclipboard.h" #include "qcocoahelpers.h" diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 29eed73535..91b631bff9 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -681,7 +681,7 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() { // Go through the list of modal sessions, and end those // that no longer has a window assosiated; no window means - // the the session has logically ended. The reason we wait like + // the session has logically ended. The reason we wait like // 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 diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index dff7c9bd50..1892a5b6bf 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -52,7 +52,7 @@ #include "qcocoafiledialoghelper.h" #include "qcocoatheme.h" #include "qcocoainputcontext.h" -#include "qmacmime.h" +#include "qcocoamimetypes.h" #include "qcocoaaccessibility.h" #include <qpa/qplatformaccessibility.h> @@ -274,6 +274,7 @@ QCocoaIntegration::QCocoaIntegration() updateScreens(); QMacInternalPasteboardMime::initializeMimeTypes(); + QCocoaMimeTypes::initializeMimeTypes(); } QCocoaIntegration::~QCocoaIntegration() diff --git a/src/plugins/platforms/cocoa/qmacmime.h b/src/plugins/platforms/cocoa/qcocoamimetypes.h index 0802987fab..7b55e38525 100644 --- a/src/plugins/platforms/cocoa/qmacmime.h +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.h @@ -39,51 +39,19 @@ ** ****************************************************************************/ -#ifndef QMACMIME_H -#define QMACMIME_H +#ifndef QCOCOAMIMETYPES_H +#define QCOCOAMIMETYPES_H -#include <QtCore> - -#include <CoreFoundation/CoreFoundation.h> +#include <QtCore/QtCore> QT_BEGIN_NAMESPACE -// Duplicate of QMacPasteboardMime in QtMacExtras. Keep in sync! -class QMacInternalPasteboardMime { - char type; +class QCocoaMimeTypes +{ public: - enum QMacPasteboardMimeType { MIME_DND=0x01, - MIME_CLIP=0x02, - MIME_QT_CONVERTOR=0x04, - MIME_QT3_CONVERTOR=0x08, - MIME_ALL=MIME_DND|MIME_CLIP - }; - explicit QMacInternalPasteboardMime(char); - virtual ~QMacInternalPasteboardMime(); - static void initializeMimeTypes(); - static void destroyMimeTypes(); - - static QList<QMacInternalPasteboardMime*> all(uchar); - static QMacInternalPasteboardMime *convertor(uchar, const QString &mime, QString flav); - static QString flavorToMime(uchar, QString flav); - - virtual QString convertorName() = 0; - - virtual bool canConvert(const QString &mime, QString flav) = 0; - virtual QString mimeFor(QString flav) = 0; - virtual QString flavorFor(const QString &mime) = 0; - virtual QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav) = 0; - virtual QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav) = 0; - virtual int count(QMimeData *mimeData); }; -void qt_mac_addToGlobalMimeList(QMacInternalPasteboardMime *macMime); -void qt_mac_removeFromGlobalMimeList(QMacInternalPasteboardMime *macMime); -void qt_mac_registerDraggedTypes(const QStringList &types); -const QStringList& qt_mac_enabledDraggedTypes(); - QT_END_NAMESPACE #endif - diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm new file mode 100644 index 0000000000..05d4c19112 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** 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 "qcocoamimetypes.h" +#include <QtPlatformSupport/private/qmacmime_p.h> +#include "qcocoahelpers.h" + +QT_BEGIN_NAMESPACE + +class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); + QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeTiff::convertorName() +{ + return QLatin1String("Tiff"); +} + +QString QMacPasteboardMimeTiff::flavorFor(const QString &mime) +{ + if (mime.startsWith(QLatin1String("application/x-qt-image"))) + return QLatin1String("public.tiff"); + return QString(); +} + +QString QMacPasteboardMimeTiff::mimeFor(QString flav) +{ + if (flav == QLatin1String("public.tiff")) + return QLatin1String("application/x-qt-image"); + return QString(); +} + +bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav) +{ + return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image"); +} + +QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) +{ + if (data.count() > 1) + qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data"); + QVariant ret; + if (!canConvert(mime, flav)) + return ret; + const QByteArray &a = data.first(); + QCFType<CGImageRef> image; + QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0, + reinterpret_cast<const UInt8 *>(a.constData()), + a.size(), kCFAllocatorNull); + QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0); + image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0); + if (image != 0) + ret = QVariant(qt_mac_toQImage(image)); + return ret; +} + +QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav) +{ + QList<QByteArray> ret; + if (!canConvert(mime, flav)) + return ret; + + QImage img = qvariant_cast<QImage>(variant); + QCFType<CGImageRef> cgimage = qt_mac_toCGImage(img); + + QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0); + QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0); + if (imageDestination != 0) { + CFTypeRef keys[2]; + QCFType<CFTypeRef> values[2]; + QCFType<CFDictionaryRef> options; + keys[0] = kCGImagePropertyPixelWidth; + keys[1] = kCGImagePropertyPixelHeight; + int width = img.width(); + int height = img.height(); + values[0] = CFNumberCreate(0, kCFNumberIntType, &width); + values[1] = CFNumberCreate(0, kCFNumberIntType, &height); + options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys), + reinterpret_cast<const void **>(values), 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CGImageDestinationAddImage(imageDestination, cgimage, options); + CGImageDestinationFinalize(imageDestination); + } + QByteArray ar(CFDataGetLength(data), 0); + CFDataGetBytes(data, + CFRangeMake(0, ar.size()), + reinterpret_cast<UInt8 *>(ar.data())); + ret.append(ar); + return ret; +} + +void QCocoaMimeTypes::initializeMimeTypes() +{ + new QMacPasteboardMimeTiff; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index f4776342de..5e57200ebc 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -44,7 +44,6 @@ #include "qcocoawindow.h" #include "qcocoamenu.h" #include "qcocoamenubar.h" -#include "qmacmime.h" #include "qcocoahelpers.h" #include "qcocoaapplication.h" #include "qcocoaintegration.h" diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 748280af6a..67cac41383 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -52,27 +52,61 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) -@interface QNSWindow : NSWindow +@class QNSWindowHelper; + +@protocol QNSWindowProtocol + +@property (nonatomic, readonly) QNSWindowHelper *helper; + +- (void)superSendEvent:(NSEvent *)theEvent; +- (void)closeAndRelease; + +@end + +typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow; + +@interface QNSWindowHelper : NSObject { - @public QCocoaWindow *m_cocoaPlatformWindow; + QCocoaNSWindow *_window; + QCocoaWindow *_platformWindow; + BOOL _grabbingMouse; + BOOL _releaseOnMouseUp; } + +@property (nonatomic, readonly) QCocoaNSWindow *window; +@property (nonatomic, readonly) QCocoaWindow *platformWindow; +@property (nonatomic) BOOL grabbingMouse; +@property (nonatomic) BOOL releaseOnMouseUp; + +- (id)initWithNSWindow:(QCocoaNSWindow *)window platformWindow:(QCocoaWindow *)platformWindow; +- (void)handleWindowEvent:(NSEvent *)theEvent; + +@end + +@interface QNSWindow : NSWindow<QNSWindowProtocol> +{ + QNSWindowHelper *_helper; +} + +@property (nonatomic, readonly) QNSWindowHelper *helper; + - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle qPlatformWindow:(QCocoaWindow *)qpw; -- (void)clearPlatformWindow; @end -@interface QNSPanel : NSPanel +@interface QNSPanel : NSPanel<QNSWindowProtocol> { - @public QCocoaWindow *m_cocoaPlatformWindow; + QNSWindowHelper *_helper; } +@property (nonatomic, readonly) QNSWindowHelper *helper; + - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle qPlatformWindow:(QCocoaWindow *)qpw; -- (void)clearPlatformWindow; @end @class QNSWindowDelegate; @@ -183,9 +217,8 @@ public: QWindow *childWindowAt(QPoint windowPoint); protected: void recreateWindow(const QPlatformWindow *parentWindow); - NSWindow *createNSWindow(); - void setNSWindow(NSWindow *window); - void clearNSWindow(NSWindow *window); + QCocoaNSWindow *createNSWindow(); + void setNSWindow(QCocoaNSWindow *window); bool shouldUseNSPanel(); @@ -202,7 +235,7 @@ public: // for QNSView NSView *m_contentView; QNSView *m_qtView; - NSWindow *m_nsWindow; + QCocoaNSWindow *m_nsWindow; QCocoaWindow *m_forwardWindow; // TODO merge to one variable if possible @@ -213,7 +246,6 @@ public: // for QNSView bool m_isNSWindowChild; // this window is a non-top level QWindow with a NSWindow. QList<QCocoaWindow *> m_childWindows; - QNSWindowDelegate *m_nsWindowDelegate; Qt::WindowFlags m_windowFlags; Qt::WindowState m_synchedWindowState; Qt::WindowModality m_windowModality; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index bf41270d12..f1f88a13dd 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -81,15 +81,10 @@ static bool isMouseEvent(NSEvent *ev) } @interface NSWindow (CocoaWindowCategory) -- (void) clearPlatformWindow; - (NSRect) legacyConvertRectFromScreen:(NSRect) rect; @end @implementation NSWindow (CocoaWindowCategory) -- (void) clearPlatformWindow -{ -} - - (NSRect) legacyConvertRectFromScreen:(NSRect) rect { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 @@ -103,8 +98,100 @@ static bool isMouseEvent(NSEvent *ev) } @end + +@implementation QNSWindowHelper + +@synthesize window = _window; +@synthesize platformWindow = _platformWindow; +@synthesize grabbingMouse = _grabbingMouse; +@synthesize releaseOnMouseUp = _releaseOnMouseUp; + +- (id)initWithNSWindow:(QCocoaNSWindow *)window platformWindow:(QCocoaWindow *)platformWindow +{ + self = [super init]; + if (self) { + _window = window; + _platformWindow = platformWindow; + + _window.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:_platformWindow]; + + // Prevent Cocoa from releasing the window on close. Qt + // handles the close event asynchronously and we want to + // make sure that m_nsWindow stays valid until the + // QCocoaWindow is deleted by Qt. + [_window setReleasedWhenClosed:NO]; + } + + return self; +} + +- (void)handleWindowEvent:(NSEvent *)theEvent +{ + QCocoaWindow *pw = self.platformWindow; + if (pw && pw->m_forwardWindow) { + if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) { + QNSView *forwardView = pw->m_qtView; + if (theEvent.type == NSLeftMouseUp) { + [forwardView mouseUp:theEvent]; + pw->m_forwardWindow = 0; + } else { + [forwardView mouseDragged:theEvent]; + } + } + + if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) { + pw->m_forwardWindow = 0; + } + } + + if (theEvent.type == NSLeftMouseDown) { + self.grabbingMouse = YES; + } else if (theEvent.type == NSLeftMouseUp) { + self.grabbingMouse = NO; + if (self.releaseOnMouseUp) { + [self detachFromPlatformWindow]; + [self.window release]; + return; + } + } + + [self.window superSendEvent:theEvent]; + + if (!self.window.delegate) + return; // Already detached, pending NSAppKitDefined event + + if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { + NSPoint loc = [theEvent locationInWindow]; + NSRect windowFrame = [self.window legacyConvertRectFromScreen:[self.window frame]]; + NSRect contentFrame = [[self.window contentView] frame]; + if (NSMouseInRect(loc, windowFrame, NO) && + !NSMouseInRect(loc, contentFrame, NO)) + { + QNSView *contentView = (QNSView *)pw->contentView(); + [contentView handleFrameStrutMouseEvent: theEvent]; + } + } +} + +- (void)detachFromPlatformWindow +{ + [self.window.delegate release]; + self.window.delegate = nil; +} + +- (void)dealloc +{ + _window = nil; + _platformWindow = 0; + [super dealloc]; +} + +@end + @implementation QNSWindow +@synthesize helper = _helper; + - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle qPlatformWindow:(QCocoaWindow *)qpw @@ -116,7 +203,7 @@ static bool isMouseEvent(NSEvent *ev) // set up before the window is shown and needs a proper window) if (self) { - m_cocoaPlatformWindow = qpw; + _helper = [[QNSWindowHelper alloc] initWithNSWindow:self platformWindow:qpw]; } return self; } @@ -125,7 +212,8 @@ static bool isMouseEvent(NSEvent *ev) { // Prevent child NSWindows from becoming the key window in // order keep the active apperance of the top-level window. - if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->m_isNSWindowChild) + QCocoaWindow *pw = self.helper.platformWindow; + if (!pw || pw->m_isNSWindowChild) return NO; // The default implementation returns NO for title-bar less windows, @@ -140,8 +228,8 @@ static bool isMouseEvent(NSEvent *ev) // Windows with a transient parent (such as combobox popup windows) // cannot become the main window: - if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->m_isNSWindowChild - || m_cocoaPlatformWindow->window()->transientParent()) + QCocoaWindow *pw = self.helper.platformWindow; + if (!pw || pw->m_isNSWindowChild || pw->window()->transientParent()) canBecomeMain = NO; return canBecomeMain; @@ -149,51 +237,39 @@ static bool isMouseEvent(NSEvent *ev) - (void) sendEvent: (NSEvent*) theEvent { - if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->m_forwardWindow) { - if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) { - QNSView *forwardView = m_cocoaPlatformWindow->m_qtView; - if (theEvent.type == NSLeftMouseUp) { - [forwardView mouseUp:theEvent]; - m_cocoaPlatformWindow->m_forwardWindow = 0; - } else { - [forwardView mouseDragged:theEvent]; - } - - return; - } - - if (theEvent.type == NSLeftMouseDown) { - m_cocoaPlatformWindow->m_forwardWindow = 0; - } - } + [self.helper handleWindowEvent:theEvent]; +} - [super sendEvent: theEvent]; +- (void)superSendEvent:(NSEvent *)theEvent +{ + [super sendEvent:theEvent]; +} - if (!m_cocoaPlatformWindow) - return; +- (void)closeAndRelease +{ + [self close]; - if (m_cocoaPlatformWindow->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { - NSPoint loc = [theEvent locationInWindow]; - NSRect windowFrame = [self legacyConvertRectFromScreen:[self frame]]; - NSRect contentFrame = [[self contentView] frame]; - if (NSMouseInRect(loc, windowFrame, NO) && - !NSMouseInRect(loc, contentFrame, NO)) - { - QNSView *contentView = (QNSView *) m_cocoaPlatformWindow->contentView(); - [contentView handleFrameStrutMouseEvent: theEvent]; - } + if (self.helper.grabbingMouse) { + self.helper.releaseOnMouseUp = YES; + } else { + [self.helper detachFromPlatformWindow]; + [self release]; } } -- (void)clearPlatformWindow +- (void)dealloc { - m_cocoaPlatformWindow = 0; + [_helper release]; + _helper = nil; + [super dealloc]; } @end @implementation QNSPanel +@synthesize helper = _helper; + - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle qPlatformWindow:(QCocoaWindow *)qpw @@ -205,47 +281,47 @@ static bool isMouseEvent(NSEvent *ev) // set up before the window is shown and needs a proper window) if (self) { - m_cocoaPlatformWindow = qpw; + _helper = [[QNSWindowHelper alloc] initWithNSWindow:self platformWindow:qpw]; } return self; } - (BOOL)canBecomeKeyWindow { - if (!m_cocoaPlatformWindow) + QCocoaWindow *pw = self.helper.platformWindow; + if (!pw) return NO; // Only tool or dialog windows should become key: - if (m_cocoaPlatformWindow - && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || - m_cocoaPlatformWindow->window()->type() == Qt::Dialog)) + Qt::WindowType type = pw->window()->type(); + if (type == Qt::Tool || type == Qt::Dialog) return YES; + return NO; } - (void) sendEvent: (NSEvent*) theEvent { - [super sendEvent: theEvent]; + [self.helper handleWindowEvent:theEvent]; +} - if (!m_cocoaPlatformWindow) - return; +- (void)superSendEvent:(NSEvent *)theEvent +{ + [super sendEvent:theEvent]; +} - if (m_cocoaPlatformWindow->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { - NSPoint loc = [theEvent locationInWindow]; - NSRect windowFrame = [self legacyConvertRectFromScreen:[self frame]]; - NSRect contentFrame = [[self contentView] frame]; - if (NSMouseInRect(loc, windowFrame, NO) && - !NSMouseInRect(loc, contentFrame, NO)) - { - QNSView *contentView = (QNSView *) m_cocoaPlatformWindow->contentView(); - [contentView handleFrameStrutMouseEvent: theEvent]; - } - } +- (void)closeAndRelease +{ + [self.helper detachFromPlatformWindow]; + [self close]; + [self release]; } -- (void)clearPlatformWindow +- (void)dealloc { - m_cocoaPlatformWindow = 0; + [_helper release]; + _helper = nil; + [super dealloc]; } @end @@ -262,7 +338,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_contentViewIsToBeEmbedded(false) , m_parentCocoaWindow(0) , m_isNSWindowChild(false) - , m_nsWindowDelegate(0) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) , m_windowUnderMouse(false) @@ -328,7 +403,8 @@ QCocoaWindow::~QCocoaWindow() #endif QCocoaAutoReleasePool pool; - clearNSWindow(m_nsWindow); + [m_nsWindow setContentView:nil]; + [m_nsWindow.helper detachFromPlatformWindow]; if (m_isNSWindowChild) { if (m_parentCocoaWindow) m_parentCocoaWindow->removeChildWindow(this); @@ -346,7 +422,6 @@ QCocoaWindow::~QCocoaWindow() [m_contentView release]; [m_nsWindow release]; - [m_nsWindowDelegate release]; [m_windowCursor release]; } @@ -1090,12 +1165,10 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) // Remove current window (if any) if ((m_nsWindow && !needsNSWindow) || (usesNSPanel != shouldUseNSPanel())) { - clearNSWindow(m_nsWindow); - [m_nsWindow close]; - [m_nsWindow release]; + [m_nsWindow closeAndRelease]; + if (wasNSWindowChild && oldParentCocoaWindow) + oldParentCocoaWindow->removeChildWindow(this); m_nsWindow = 0; - [m_nsWindowDelegate release]; - m_nsWindowDelegate = 0; } if (needsNSWindow) { @@ -1203,7 +1276,7 @@ bool QCocoaWindow::shouldUseNSPanel() ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog); } -NSWindow * QCocoaWindow::createNSWindow() +QCocoaNSWindow * QCocoaWindow::createNSWindow() { QCocoaAutoReleasePool pool; @@ -1219,7 +1292,7 @@ NSWindow * QCocoaWindow::createNSWindow() } else { styleMask = windowStyleMask(flags); } - NSWindow *createdWindow = 0; + QCocoaNSWindow *createdWindow = 0; // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen) // and dialogs @@ -1270,17 +1343,8 @@ NSWindow * QCocoaWindow::createNSWindow() return createdWindow; } -void QCocoaWindow::setNSWindow(NSWindow *window) +void QCocoaWindow::setNSWindow(QCocoaNSWindow *window) { - m_nsWindowDelegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this]; - [window setDelegate:m_nsWindowDelegate]; - - // Prevent Cocoa from releasing the window on close. Qt - // handles the close event asynchronously and we want to - // make sure that m_nsWindow stays valid until the - // QCocoaWindow is deleted by Qt. - [window setReleasedWhenClosed : NO]; - if (window.contentView != m_contentView) { [m_contentView setPostsFrameChangedNotifications: NO]; [window setContentView:m_contentView]; @@ -1288,17 +1352,6 @@ void QCocoaWindow::setNSWindow(NSWindow *window) } } -void QCocoaWindow::clearNSWindow(NSWindow *window) -{ - [window setContentView:nil]; - [window setDelegate:nil]; - [window clearPlatformWindow]; - - if (m_isNSWindowChild) { - m_parentCocoaWindow->removeChildWindow(this); - } -} - void QCocoaWindow::removeChildWindow(QCocoaWindow *child) { m_childWindows.removeOne(child); diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h index d8e588e36b..ddaa61a84d 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.h +++ b/src/plugins/platforms/cocoa/qmacclipboard.h @@ -43,7 +43,7 @@ #define QMACCLIPBOARD_H #include <QtGui> -#include "qmacmime.h" +#include <QtPlatformSupport/private/qmacmime_p.h> #undef slots diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 9ccf41fbf4..9368b65866 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -51,7 +51,6 @@ #include <stdlib.h> #include <string.h> #include "qcocoahelpers.h" -#include "qmacmime.h" #include "qcocoaautoreleasepool.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qmacmime.mm b/src/plugins/platforms/cocoa/qmacmime.mm deleted file mode 100644 index 4274e178f7..0000000000 --- a/src/plugins/platforms/cocoa/qmacmime.mm +++ /dev/null @@ -1,965 +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 "qmacmime.h" -#include "qcocoahelpers.h" -#include "qmacclipboard.h" - -#include "qdebug.h" -#include "qpixmap.h" -#include "qimagewriter.h" -#include "qimagereader.h" -#include "qdatastream.h" -#include "qbuffer.h" -#include "qdatetime.h" -#include "qguiapplication.h" -#include "qtextcodec.h" -#include "qregexp.h" -#include "qurl.h" -#include "qmap.h" - -#include <Cocoa/Cocoa.h> - -QT_BEGIN_NAMESPACE - -extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0); // qpaintengine_mac.cpp - -typedef QList<QMacInternalPasteboardMime*> MimeList; -Q_GLOBAL_STATIC(MimeList, globalMimeList) -Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList) - -void qt_mac_addToGlobalMimeList(QMacInternalPasteboardMime *macMime) -{ - // globalMimeList is in decreasing priority order. Recently added - // converters take prioity over previously added converters: prepend - // to the list. - globalMimeList()->prepend(macMime); -} - -void qt_mac_removeFromGlobalMimeList(QMacInternalPasteboardMime *macMime) -{ - if (!QGuiApplication::closingDown()) - globalMimeList()->removeAll(macMime); -} - -/*! - \fn void qRegisterDraggedTypes(const QStringList &types) - \relates QMacPasteboardMime - - Registers the given \a types as custom pasteboard types. - - This function should be called to enable the Drag and Drop events - for custom pasteboard types on Cocoa implementations. This is required - in addition to a QMacPasteboardMime subclass implementation. By default - drag and drop is enabled for all standard pasteboard types. - - \sa QMacPasteboardMime -*/ -void qt_mac_registerDraggedTypes(const QStringList &types) -{ - (*globalDraggedTypesList()) += types; -} - -const QStringList& qt_mac_enabledDraggedTypes() -{ - return (*globalDraggedTypesList()); -} - -/***************************************************************************** - QDnD debug facilities - *****************************************************************************/ -//#define DEBUG_MIME_MAPS - -//functions -extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp -extern void qt_mac_from_pascal_string(QString, Str255, TextEncoding encoding=0, int len=-1); //qglobal.cpp - -ScrapFlavorType qt_mac_mime_type = 'CUTE'; -CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker"); - -/*! - \class QMacPasteboardMime - \brief The QMacPasteboardMime class converts between a MIME type and a - \l{http://developer.apple.com/macosx/uniformtypeidentifiers.html}{Uniform - Type Identifier (UTI)} format. - \since 4.2 - - \ingroup draganddrop - \inmodule QtWidgets - - Qt's drag and drop and clipboard facilities use the MIME - standard. On X11, this maps trivially to the Xdnd protocol. On - Mac, although some applications use MIME to describe clipboard - contents, it is more common to use Apple's UTI format. - - QMacPasteboardMime's role is to bridge the gap between MIME and UTI; - By subclasses this class, one can extend Qt's drag and drop - and clipboard handling to convert to and from unsupported, or proprietary, UTI formats. - - A subclass of QMacPasteboardMime will automatically be registered, and active, upon instantiation. - - Qt has predefined support for the following UTIs: - \list - \i public.utf8-plain-text - converts to "text/plain" - \i public.utf16-plain-text - converts to "text/plain" - \i public.html - converts to "text/html" - \i public.url - converts to "text/uri-list" - \i public.file-url - converts to "text/uri-list" - \i public.tiff - converts to "application/x-qt-image" - \i public.vcard - converts to "text/plain" - \i com.apple.traditional-mac-plain-text - converts to "text/plain" - \i com.apple.pict - converts to "application/x-qt-image" - \endlist - - When working with MIME data, Qt will interate through all instances of QMacPasteboardMime to - find an instance that can convert to, or from, a specific MIME type. It will do this by calling - canConvert() on each instance, starting with (and choosing) the last created instance first. - The actual conversions will be done by using convertToMime() and convertFromMime(). - - \note The API uses the term "flavor" in some cases. This is for backwards - compatibility reasons, and should now be understood as UTIs. -*/ - -/*! \enum QMacPasteboardMime::QMacPasteboardMimeType - \internal -*/ - -/*! - Constructs a new conversion object of type \a t, adding it to the - globally accessed list of available convertors. -*/ -QMacInternalPasteboardMime::QMacInternalPasteboardMime(char t) : type(t) -{ - qt_mac_addToGlobalMimeList(this); -} - -/*! - Destroys a conversion object, removing it from the global - list of available convertors. -*/ -QMacInternalPasteboardMime::~QMacInternalPasteboardMime() -{ - qt_mac_removeFromGlobalMimeList(this); -} - -/*! - Returns the item count for the given \a mimeData -*/ -int QMacInternalPasteboardMime::count(QMimeData *mimeData) -{ - Q_UNUSED(mimeData); - return 1; -} - -class QMacPasteboardMimeAny : public QMacInternalPasteboardMime { -private: - -public: - QMacPasteboardMimeAny() : QMacInternalPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) { - } - ~QMacPasteboardMimeAny() { - } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeAny::convertorName() -{ - return QLatin1String("Any-Mime"); -} - -QString QMacPasteboardMimeAny::flavorFor(const QString &mime) -{ - // do not handle the mime type name in the drag pasteboard - if (mime == QLatin1String("application/x-qt-mime-type-name")) - return QString(); - QString ret = QLatin1String("com.trolltech.anymime.") + mime; - return ret.replace(QLatin1Char('/'), QLatin1String("--")); -} - -QString QMacPasteboardMimeAny::mimeFor(QString flav) -{ - const QString any_prefix = QLatin1String("com.trolltech.anymime."); - if (flav.size() > any_prefix.length() && flav.startsWith(any_prefix)) - return flav.mid(any_prefix.length()).replace(QLatin1String("--"), QLatin1String("/")); - return QString(); -} - -bool QMacPasteboardMimeAny::canConvert(const QString &mime, QString flav) -{ - return mimeFor(flav) == mime; -} - -QVariant QMacPasteboardMimeAny::convertToMime(const QString &mime, QList<QByteArray> data, QString) -{ - if (data.count() > 1) - qWarning("QMacPasteboardMimeAny: Cannot handle multiple member data"); - QVariant ret; - if (mime == QLatin1String("text/plain")) - ret = QString::fromUtf8(data.first()); - else - ret = data.first(); - return ret; -} - -QList<QByteArray> QMacPasteboardMimeAny::convertFromMime(const QString &mime, QVariant data, QString) -{ - QList<QByteArray> ret; - if (mime == QLatin1String("text/plain")) - ret.append(data.toString().toUtf8()); - else - ret.append(data.toByteArray()); - return ret; -} - -class QMacPasteboardMimeTypeName : public QMacInternalPasteboardMime { -private: - -public: - QMacPasteboardMimeTypeName() : QMacInternalPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) { - } - ~QMacPasteboardMimeTypeName() { - } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeTypeName::convertorName() -{ - return QLatin1String("Qt-Mime-Type"); -} - -QString QMacPasteboardMimeTypeName::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("application/x-qt-mime-type-name")) - return QLatin1String("com.trolltech.qt.MimeTypeName"); - return QString(); -} - -QString QMacPasteboardMimeTypeName::mimeFor(QString) -{ - return QString(); -} - -bool QMacPasteboardMimeTypeName::canConvert(const QString &, QString) -{ - return false; -} - -QVariant QMacPasteboardMimeTypeName::convertToMime(const QString &, QList<QByteArray>, QString) -{ - QVariant ret; - return ret; -} - -QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, QVariant, QString) -{ - QList<QByteArray> ret; - ret.append(QString("x-qt-mime-type-name").toUtf8()); - return ret; -} - -class QMacPasteboardMimePlainText : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimePlainText() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimePlainText::convertorName() -{ - return QLatin1String("PlainText"); -} - -QString QMacPasteboardMimePlainText::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("text/plain")) - return QLatin1String("com.apple.traditional-mac-plain-text"); - return QString(); -} - -QString QMacPasteboardMimePlainText::mimeFor(QString flav) -{ - if (flav == QLatin1String("com.apple.traditional-mac-plain-text")) - return QLatin1String("text/plain"); - return QString(); -} - -bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav) -{ - return flavorFor(mime) == flav; -} - -QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) -{ - if (data.count() > 1) - qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data"); - const QByteArray &firstData = data.first(); - QVariant ret; - if (flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text"))) { - QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast<const UInt8 *>(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false)); - ret = QString(str); - } else { - qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); - } - return ret; -} - -QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor) -{ - QList<QByteArray> ret; - QString string = data.toString(); - if (flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text"))) - ret.append(string.toLatin1()); - return ret; -} - -class QMacPasteboardMimeUnicodeText : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeUnicodeText() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeUnicodeText::convertorName() -{ - return QLatin1String("UnicodeText"); -} - -QString QMacPasteboardMimeUnicodeText::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("text/plain")) - return QLatin1String("public.utf16-plain-text"); - int i = mime.indexOf(QLatin1String("charset=")); - if (i >= 0) { - QString cs(mime.mid(i+8).toLower()); - i = cs.indexOf(QLatin1Char(';')); - if (i>=0) - cs = cs.left(i); - if (cs == QLatin1String("system")) - return QLatin1String("public.utf8-plain-text"); - else if (cs == QLatin1String("iso-10646-ucs-2") - || cs == QLatin1String("utf16")) - return QLatin1String("public.utf16-plain-text"); - } - return QString(); -} - -QString QMacPasteboardMimeUnicodeText::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.utf16-plain-text") || flav == QLatin1String("public.utf8-plain-text")) - return QLatin1String("text/plain"); - return QString(); -} - -bool QMacPasteboardMimeUnicodeText::canConvert(const QString &mime, QString flav) -{ - return flavorFor(mime) == flav; -} - -QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) -{ - if (data.count() > 1) - qWarning("QMacPasteboardMimeUnicodeText: Cannot handle multiple member data"); - const QByteArray &firstData = data.first(); - // I can only handle two types (system and unicode) so deal with them that way - QVariant ret; - if (flavor == QLatin1String("public.utf8-plain-text")) { - QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast<const UInt8 *>(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false)); - ret = QString(str); - } else if (flavor == QLatin1String("public.utf16-plain-text")) { - ret = QString(reinterpret_cast<const QChar *>(firstData.constData()), - firstData.size() / sizeof(QChar)); - } else { - qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); - } - return ret; -} - -QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &, QVariant data, QString flavor) -{ - QList<QByteArray> ret; - QString string = data.toString(); - if (flavor == QLatin1String("public.utf8-plain-text")) - ret.append(string.toUtf8()); - else if (flavor == QLatin1String("public.utf16-plain-text")) - ret.append(QByteArray((char*)string.utf16(), string.length()*2)); - return ret; -} - -class QMacPasteboardMimeHTMLText : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeHTMLText() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeHTMLText::convertorName() -{ - return QLatin1String("HTML"); -} - -QString QMacPasteboardMimeHTMLText::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("text/html")) - return QLatin1String("public.html"); - return QString(); -} - -QString QMacPasteboardMimeHTMLText::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.html")) - return QLatin1String("text/html"); - return QString(); -} - -bool QMacPasteboardMimeHTMLText::canConvert(const QString &mime, QString flav) -{ - return flavorFor(mime) == flav; -} - -QVariant QMacPasteboardMimeHTMLText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor) -{ - if (!canConvert(mimeType, flavor)) - return QVariant(); - if (data.count() > 1) - qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data"); - return data.first(); -} - -QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mime, QVariant data, QString flavor) -{ - QList<QByteArray> ret; - if (!canConvert(mime, flavor)) - return ret; - ret.append(data.toByteArray()); - return ret; -} - -class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeTiff::convertorName() -{ - return QLatin1String("Tiff"); -} - -QString QMacPasteboardMimeTiff::flavorFor(const QString &mime) -{ - if (mime.startsWith(QLatin1String("application/x-qt-image"))) - return QLatin1String("public.tiff"); - return QString(); -} - -QString QMacPasteboardMimeTiff::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.tiff")) - return QLatin1String("application/x-qt-image"); - return QString(); -} - -bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav) -{ - return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image"); -} - -QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) -{ - if (data.count() > 1) - qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data"); - QVariant ret; - if (!canConvert(mime, flav)) - return ret; - const QByteArray &a = data.first(); - QCFType<CGImageRef> image; - QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0, - reinterpret_cast<const UInt8 *>(a.constData()), - a.size(), kCFAllocatorNull); - QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0); - image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0); - if (image != 0) - ret = QVariant(qt_mac_toQImage(image)); - return ret; -} - -QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav) -{ - QList<QByteArray> ret; - if (!canConvert(mime, flav)) - return ret; - - QImage img = qvariant_cast<QImage>(variant); - QCFType<CGImageRef> cgimage = qt_mac_toCGImage(img); - - QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0); - QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0); - if (imageDestination != 0) { - CFTypeRef keys[2]; - QCFType<CFTypeRef> values[2]; - QCFType<CFDictionaryRef> options; - keys[0] = kCGImagePropertyPixelWidth; - keys[1] = kCGImagePropertyPixelHeight; - int width = img.width(); - int height = img.height(); - values[0] = CFNumberCreate(0, kCFNumberIntType, &width); - values[1] = CFNumberCreate(0, kCFNumberIntType, &height); - options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys), - reinterpret_cast<const void **>(values), 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CGImageDestinationAddImage(imageDestination, cgimage, options); - CGImageDestinationFinalize(imageDestination); - } - QByteArray ar(CFDataGetLength(data), 0); - CFDataGetBytes(data, - CFRangeMake(0, ar.size()), - reinterpret_cast<UInt8 *>(ar.data())); - ret.append(ar); - return ret; -} - - -class QMacPasteboardMimeFileUri : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeFileUri() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); - int count(QMimeData *mimeData); -}; - -QString QMacPasteboardMimeFileUri::convertorName() -{ - return QLatin1String("FileURL"); -} - -QString QMacPasteboardMimeFileUri::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("text/uri-list")) - return QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0)); - return QString(); -} - -QString QMacPasteboardMimeFileUri::mimeFor(QString flav) -{ - if (flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0))) - return QLatin1String("text/uri-list"); - return QString(); -} - -bool QMacPasteboardMimeFileUri::canConvert(const QString &mime, QString flav) -{ - return mime == QLatin1String("text/uri-list") - && flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0)); -} - -QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) -{ - if (!canConvert(mime, flav)) - return QVariant(); - QList<QVariant> ret; - for (int i = 0; i < data.size(); ++i) { - QUrl url = QUrl::fromEncoded(data.at(i)); - if (url.host().toLower() == QLatin1String("localhost")) - url.setHost(QString()); - url.setPath(url.path().normalized(QString::NormalizationForm_C)); - ret.append(url); - } - return QVariant(ret); -} - -QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime, QVariant data, QString flav) -{ - QList<QByteArray> ret; - if (!canConvert(mime, flav)) - return ret; - QList<QVariant> urls = data.toList(); - for (int i = 0; i < urls.size(); ++i) { - QUrl url = urls.at(i).toUrl(); - if (url.scheme().isEmpty()) - url.setScheme(QLatin1String("file")); - if (url.scheme().toLower() == QLatin1String("file")) { - if (url.host().isEmpty()) - url.setHost(QLatin1String("localhost")); - url.setPath(url.path().normalized(QString::NormalizationForm_D)); - } - ret.append(url.toEncoded()); - } - return ret; -} - -int QMacPasteboardMimeFileUri::count(QMimeData *mimeData) -{ - return mimeData->urls().count(); -} - -class QMacPasteboardMimeUrl : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeUrl() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeUrl::convertorName() -{ - return QLatin1String("URL"); -} - -QString QMacPasteboardMimeUrl::flavorFor(const QString &mime) -{ - if (mime.startsWith(QLatin1String("text/uri-list"))) - return QLatin1String("public.url"); - return QString(); -} - -QString QMacPasteboardMimeUrl::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.url")) - return QLatin1String("text/uri-list"); - return QString(); -} - -bool QMacPasteboardMimeUrl::canConvert(const QString &mime, QString flav) -{ - return flav == QLatin1String("public.url") - && mime == QLatin1String("text/uri-list"); -} - -QVariant QMacPasteboardMimeUrl::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) -{ - if (!canConvert(mime, flav)) - return QVariant(); - - QList<QVariant> ret; - for (int i=0; i<data.size(); ++i) { - QUrl url = QUrl::fromEncoded(data.at(i)); - if (url.host().toLower() == QLatin1String("localhost")) - url.setHost(QString()); - url.setPath(url.path().normalized(QString::NormalizationForm_C)); - ret.append(url); - } - return QVariant(ret); -} - -QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QVariant data, QString flav) -{ - QList<QByteArray> ret; - if (!canConvert(mime, flav)) - return ret; - - QList<QVariant> urls = data.toList(); - for (int i=0; i<urls.size(); ++i) { - QUrl url = urls.at(i).toUrl(); - if (url.scheme().isEmpty()) - url.setScheme(QLatin1String("file")); - if (url.scheme().toLower() == QLatin1String("file")) { - if (url.host().isEmpty()) - url.setHost(QLatin1String("localhost")); - url.setPath(url.path().normalized(QString::NormalizationForm_D)); - } - ret.append(url.toEncoded()); - } - return ret; -} - -class QMacPasteboardMimeVCard : public QMacInternalPasteboardMime -{ -public: - QMacPasteboardMimeVCard() : QMacInternalPasteboardMime(MIME_ALL){ } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeVCard::convertorName() -{ - return QString("VCard"); -} - -bool QMacPasteboardMimeVCard::canConvert(const QString &mime, QString flav) -{ - return mimeFor(flav) == mime; -} - -QString QMacPasteboardMimeVCard::flavorFor(const QString &mime) -{ - if (mime.startsWith(QLatin1String("text/plain"))) - return QLatin1String("public.vcard"); - return QString(); -} - -QString QMacPasteboardMimeVCard::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.vcard")) - return QLatin1String("text/plain"); - return QString(); -} - -QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByteArray> data, QString) -{ - QByteArray cards; - if (mime == QLatin1String("text/plain")) { - for (int i=0; i<data.size(); ++i) - cards += data[i]; - } - return QVariant(cards); -} - -QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, QVariant data, QString) -{ - QList<QByteArray> ret; - if (mime == QLatin1String("text/plain")) - ret.append(data.toString().toUtf8()); - return ret; -} - - -/*! - \internal - - This is an internal function. -*/ -void QMacInternalPasteboardMime::initializeMimeTypes() -{ - if (globalMimeList()->isEmpty()) { - // Create QMacPasteboardMimeAny first to put it at the end of globalMimeList - // with lowest priority. (the constructor prepends to the list) - new QMacPasteboardMimeAny; - - //standard types that we wrap - new QMacPasteboardMimeTiff; - new QMacPasteboardMimeUnicodeText; - new QMacPasteboardMimePlainText; - new QMacPasteboardMimeHTMLText; - new QMacPasteboardMimeFileUri; - new QMacPasteboardMimeUrl; - new QMacPasteboardMimeTypeName; - new QMacPasteboardMimeVCard; - } -} - -/*! - \internal -*/ -void QMacInternalPasteboardMime::destroyMimeTypes() -{ - MimeList *mimes = globalMimeList(); - while (!mimes->isEmpty()) - delete mimes->takeFirst(); -} - -/*! - Returns the most-recently created QMacPasteboardMime of type \a t that can convert - between the \a mime and \a flav formats. Returns 0 if no such convertor - exists. -*/ -QMacInternalPasteboardMime* -QMacInternalPasteboardMime::convertor(uchar t, const QString &mime, QString flav) -{ - MimeList *mimes = globalMimeList(); - for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) { -#ifdef DEBUG_MIME_MAPS - qDebug("QMacPasteboardMime::convertor: seeing if %s (%d) can convert %s to %d[%c%c%c%c] [%d]", - (*it)->convertorName().toLatin1().constData(), - (*it)->type & t, mime.toLatin1().constData(), - flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF, - (*it)->canConvert(mime,flav)); - for (int i = 0; i < (*it)->countFlavors(); ++i) { - int f = (*it)->flavor(i); - qDebug(" %d) %d[%c%c%c%c] [%s]", i, f, - (f >> 24) & 0xFF, (f >> 16) & 0xFF, (f >> 8) & 0xFF, (f) & 0xFF, - (*it)->convertorName().toLatin1().constData()); - } -#endif - if (((*it)->type & t) && (*it)->canConvert(mime, flav)) - return (*it); - } - return 0; -} -/*! - Returns a MIME type of type \a t for \a flav, or 0 if none exists. -*/ -QString QMacInternalPasteboardMime::flavorToMime(uchar t, QString flav) -{ - MimeList *mimes = globalMimeList(); - for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) { -#ifdef DEBUG_MIME_MAPS - qDebug("QMacMIme::flavorToMime: attempting %s (%d) for flavor %d[%c%c%c%c] [%s]", - (*it)->convertorName().toLatin1().constData(), - (*it)->type & t, flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF, - (*it)->mimeFor(flav).toLatin1().constData()); - -#endif - if ((*it)->type & t) { - QString mimeType = (*it)->mimeFor(flav); - if (!mimeType.isNull()) - return mimeType; - } - } - return QString(); -} - -/*! - Returns a list of all currently defined QMacPasteboardMime objects of type \a t. -*/ -QList<QMacInternalPasteboardMime*> QMacInternalPasteboardMime::all(uchar t) -{ - MimeList ret; - MimeList *mimes = globalMimeList(); - for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) { - if ((*it)->type & t) - ret.append((*it)); - } - return ret; -} - - -/*! - \fn QString QMacPasteboardMime::convertorName() - - Returns a name for the convertor. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn bool QMacPasteboardMime::canConvert(const QString &mime, QString flav) - - Returns \c true if the convertor can convert (both ways) between - \a mime and \a flav; otherwise returns \c false. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn QString QMacPasteboardMime::mimeFor(QString flav) - - Returns the MIME UTI used for Mac flavor \a flav, or 0 if this - convertor does not support \a flav. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn QString QMacPasteboardMime::flavorFor(const QString &mime) - - Returns the Mac UTI used for MIME type \a mime, or 0 if this - convertor does not support \a mime. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn QVariant QMacPasteboardMime::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) - - Returns \a data converted from Mac UTI \a flav to MIME type \a - mime. - - Note that Mac flavors must all be self-terminating. The input \a - data may contain trailing data. - - All subclasses must reimplement this pure virtual function. -*/ - -/*! - \fn QList<QByteArray> QMacPasteboardMime::convertFromMime(const QString &mime, QVariant data, QString flav) - - Returns \a data converted from MIME type \a mime - to Mac UTI \a flav. - - Note that Mac flavors must all be self-terminating. The return - value may contain trailing data. - - All subclasses must reimplement this pure virtual function. -*/ - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index fcca96a8a8..90d56bc3f3 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -49,7 +49,6 @@ #include "qcocoaautoreleasepool.h" #include "qmultitouch_mac_p.h" #include "qcocoadrag.h" -#include "qmacmime.h" #include <qpa/qplatformintegration.h> #include <qpa/qwindowsysteminterface.h> diff --git a/src/plugins/platforms/directfb/qdirectfb_egl.cpp b/src/plugins/platforms/directfb/qdirectfb_egl.cpp index c71f71c6a8..c738c3d027 100644 --- a/src/plugins/platforms/directfb/qdirectfb_egl.cpp +++ b/src/plugins/platforms/directfb/qdirectfb_egl.cpp @@ -223,8 +223,7 @@ QSurfaceFormat QDirectFbWindowEGL::format() const QDirectFbEGLContext::QDirectFbEGLContext(QDirectFbScreenEGL *screen, QOpenGLContext *context) - : QEGLPlatformContext(context->format(), context->shareHandle(), - screen->eglDisplay(), EGL_OPENGL_ES_API) + : QEGLPlatformContext(context->format(), context->shareHandle(), screen->eglDisplay()) , m_screen(screen) {} diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 86ceb0721b..9083abc562 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -52,10 +52,9 @@ QT_BEGIN_NAMESPACE -QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, - EGLDisplay display, EGLenum eglApi) +QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) : QEGLPlatformContext(QEglFSHooks::hooks()->surfaceFormatFor(format), share, display, - QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)), eglApi) + QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format))) { } diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h index 22a7c67e46..5d406f09f1 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.h +++ b/src/plugins/platforms/eglfs/qeglfscontext.h @@ -49,8 +49,7 @@ QT_BEGIN_NAMESPACE class QEglFSContext : public QEGLPlatformContext { public: - QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLenum eglApi = EGL_OPENGL_ES_API); + QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display); EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) Q_DECL_OVERRIDE; void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index f93a9d54bc..c8c31816a0 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -65,6 +65,10 @@ public: void raise() Q_DECL_OVERRIDE; void lower() Q_DECL_OVERRIDE; + void propagateSizeHints() Q_DECL_OVERRIDE { } + bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } + bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } + QSurfaceFormat format() const Q_DECL_OVERRIDE; EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE; EGLSurface surface() const; diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 175cc3f8bd..b7e074b95a 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -21,7 +21,8 @@ OBJECTIVE_SOURCES = \ qiosinputcontext.mm \ qiostheme.mm \ qiosglobal.mm \ - qiosservices.mm + qiosservices.mm \ + qiosclipboard.mm HEADERS = \ qiosintegration.h \ @@ -37,7 +38,8 @@ HEADERS = \ qiostheme.h \ qiosglobal.h \ qiosservices.h \ - quiview.h + quiview.h \ + qiosclipboard.h OTHER_FILES = \ quiview_textinput.mm diff --git a/src/plugins/platforms/ios/qiosclipboard.h b/src/plugins/platforms/ios/qiosclipboard.h new file mode 100644 index 0000000000..da4226a40d --- /dev/null +++ b/src/plugins/platforms/ios/qiosclipboard.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 QIOSCLIPBOARD_H +#define QIOSCLIPBOARD_H + +#import <UIKit/UIKit.h> + +#include <qpa/qplatformclipboard.h> + +@class QUIClipboard; + +QT_BEGIN_NAMESPACE + +class QIOSClipboard : public QPlatformClipboard +{ +public: + QIOSClipboard(); + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + void setMimeData(QMimeData *mimeData, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; + bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + +private: + QUIClipboard *m_clipboard; +}; + +QT_END_NAMESPACE + +#endif // QIOSCLIPBOARD_H diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm new file mode 100644 index 0000000000..0a7b34a216 --- /dev/null +++ b/src/plugins/platforms/ios/qiosclipboard.mm @@ -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 "qiosclipboard.h" + +#include <QtPlatformSupport/private/qmacmime_p.h> +#include <QtCore/QMimeData> +#include <QtGui/QGuiApplication> + +@interface UIPasteboard (QUIPasteboard) + + (UIPasteboard *)pasteboardWithQClipboardMode:(QClipboard::Mode)mode; +@end + +@implementation UIPasteboard (QUIPasteboard) ++ (UIPasteboard *)pasteboardWithQClipboardMode:(QClipboard::Mode)mode +{ + NSString *name = (mode == QClipboard::Clipboard) ? UIPasteboardNameGeneral : UIPasteboardNameFind; + return [UIPasteboard pasteboardWithName:name create:NO]; +} +@end + +// -------------------------------------------------------------------- + +@interface QUIClipboard : NSObject +{ +@public + QIOSClipboard *m_qiosClipboard; + NSInteger m_changeCountClipboard; + NSInteger m_changeCountFindBuffer; +} +@end + +@implementation QUIClipboard + +-(id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard +{ + self = [super init]; + if (self) { + m_qiosClipboard = qiosClipboard; + m_changeCountClipboard = [UIPasteboard pasteboardWithQClipboardMode:QClipboard::Clipboard].changeCount; + m_changeCountFindBuffer = [UIPasteboard pasteboardWithQClipboardMode:QClipboard::FindBuffer].changeCount; + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(updatePasteboardChanged:) + name:UIPasteboardChangedNotification object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(updatePasteboardChanged:) + name:UIPasteboardRemovedNotification object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(updatePasteboardChanged:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + } + return self; +} + +-(void)dealloc +{ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIPasteboardChangedNotification object:nil]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIPasteboardRemovedNotification object:nil]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIApplicationDidBecomeActiveNotification + object:nil]; + [super dealloc]; +} + +- (void)updatePasteboardChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + NSInteger changeCountClipboard = [UIPasteboard pasteboardWithQClipboardMode:QClipboard::Clipboard].changeCount; + NSInteger changeCountFindBuffer = [UIPasteboard pasteboardWithQClipboardMode:QClipboard::FindBuffer].changeCount; + + if (m_changeCountClipboard != changeCountClipboard) { + m_changeCountClipboard = changeCountClipboard; + m_qiosClipboard->emitChanged(QClipboard::Clipboard); + } + + if (m_changeCountFindBuffer != changeCountFindBuffer) { + m_changeCountFindBuffer = changeCountFindBuffer; + m_qiosClipboard->emitChanged(QClipboard::FindBuffer); + } +} + +@end + +// -------------------------------------------------------------------- + +QT_BEGIN_NAMESPACE + +class QIOSMimeData : public QMimeData { +public: + QIOSMimeData(QClipboard::Mode mode) : QMimeData(), m_mode(mode) { } + ~QIOSMimeData() { } + + QStringList formats() const Q_DECL_OVERRIDE; + QVariant retrieveData(const QString &mimeType, QVariant::Type type) const Q_DECL_OVERRIDE; + +private: + const QClipboard::Mode m_mode; +}; + +QStringList QIOSMimeData::formats() const +{ + QStringList foundMimeTypes; + UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:m_mode]; + NSArray *pasteboardTypes = [pb pasteboardTypes]; + + for (NSUInteger i = 0; i < [pasteboardTypes count]; ++i) { + QString uti = QString::fromNSString([pasteboardTypes objectAtIndex:i]); + QString mimeType = QMacInternalPasteboardMime::flavorToMime(QMacInternalPasteboardMime::MIME_ALL, uti); + if (!mimeType.isEmpty() && !foundMimeTypes.contains(mimeType)) + foundMimeTypes << mimeType; + } + + return foundMimeTypes; +} + +QVariant QIOSMimeData::retrieveData(const QString &mimeType, QVariant::Type) const +{ + UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:m_mode]; + NSArray *pasteboardTypes = [pb pasteboardTypes]; + + foreach (QMacInternalPasteboardMime *converter, + QMacInternalPasteboardMime::all(QMacInternalPasteboardMime::MIME_ALL)) { + if (!converter->canConvert(mimeType, converter->flavorFor(mimeType))) + continue; + + for (NSUInteger i = 0; i < [pasteboardTypes count]; ++i) { + NSString *availableUtiNSString = [pasteboardTypes objectAtIndex:i]; + QString availableUti = QString::fromNSString(availableUtiNSString); + if (!converter->canConvert(mimeType, availableUti)) + continue; + + NSData *nsData = [pb dataForPasteboardType:availableUtiNSString]; + QList<QByteArray> dataList; + dataList << QByteArray(reinterpret_cast<const char *>([nsData bytes]), [nsData length]); + return converter->convertToMime(mimeType, dataList, availableUti); + } + } + + return QVariant(); +} + +// -------------------------------------------------------------------- + +QIOSClipboard::QIOSClipboard() + : m_clipboard([[QUIClipboard alloc] initWithQIOSClipboard:this]) +{ +} + +QMimeData *QIOSClipboard::mimeData(QClipboard::Mode mode) +{ + Q_ASSERT(supportsMode(mode)); + return new QIOSMimeData(mode); +} + +void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) +{ + Q_ASSERT(supportsMode(mode)); + + UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:mode]; + NSMutableDictionary *pbItem = [NSMutableDictionary dictionaryWithCapacity:mimeData->formats().size()]; + + foreach (const QString &mimeType, mimeData->formats()) { + foreach (QMacInternalPasteboardMime *converter, + QMacInternalPasteboardMime::all(QMacInternalPasteboardMime::MIME_ALL)) { + QString uti = converter->flavorFor(mimeType); + if (uti.isEmpty() || !converter->canConvert(mimeType, uti)) + continue; + + QByteArray byteArray = converter->convertFromMime(mimeType, mimeData->data(mimeType), uti).first(); + NSData *nsData = [NSData dataWithBytes:byteArray.constData() length:byteArray.size()]; + [pbItem setValue:nsData forKey:uti.toNSString()]; + break; + } + } + + pb.items = [NSArray arrayWithObject:pbItem]; +} + +bool QIOSClipboard::supportsMode(QClipboard::Mode mode) const +{ + return (mode == QClipboard::Clipboard || mode == QClipboard::FindBuffer); +} + +bool QIOSClipboard::ownsMode(QClipboard::Mode mode) const +{ + Q_UNUSED(mode); + return false; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index d426028c46..4fe2cae15e 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -120,7 +120,7 @@ // For Qt applications we rotate the keyboard rect to align with the screen // orientation (which is the interface orientation of the root view controller). // For hybrid apps we follow native behavior, and return the rect unmodified: - CGRect keyboardFrame = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect keyboardFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; if (isQtApplication()) { UIView *view = m_viewController.view; return fromCGRect(CGRectOffset([view convertRect:keyboardFrame fromView:view.window], 0, -view.bounds.origin.y)); @@ -156,8 +156,8 @@ m_keyboardVisibleAndDocked = YES; m_keyboardEndRect = [self getKeyboardRect:notification]; if (!m_duration) { - m_duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; - m_curve = UIViewAnimationCurve([notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16); + m_duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + m_curve = UIViewAnimationCurve([[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16); } m_context->scrollToCursor(); } diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index fdecf70725..a28926ff99 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -66,6 +66,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QPlatformFontDatabase *fontDatabase() const; + QPlatformClipboard *clipboard() const; QPlatformInputContext *inputContext() const; QPlatformServices *services() const Q_DECL_OVERRIDE; @@ -74,8 +75,6 @@ public: QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; - QPlatformDrag *drag() const Q_DECL_OVERRIDE { return 0; } - QAbstractEventDispatcher *createEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; @@ -84,6 +83,7 @@ public: QTouchDevice *touchDevice(); private: QPlatformFontDatabase *m_fontDatabase; + QPlatformClipboard *m_clipboard; QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; QTouchDevice *m_touchDevice; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 660da6397f..7a40e349c9 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -46,11 +46,13 @@ #include "qiosbackingstore.h" #include "qiosscreen.h" #include "qioscontext.h" +#include "qiosclipboard.h" #include "qiosinputcontext.h" #include "qiostheme.h" #include "qiosservices.h" #include <QtPlatformSupport/private/qcoretextfontdatabase_p.h> +#include <QtPlatformSupport/private/qmacmime_p.h> #include <QDir> #include <QtDebug> @@ -59,6 +61,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) + , m_clipboard(new QIOSClipboard) , m_inputContext(new QIOSInputContext) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) , m_platformServices(new QIOSServices) @@ -81,6 +84,7 @@ QIOSIntegration::QIOSIntegration() m_touchDevice->setType(QTouchDevice::TouchScreen); m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); QWindowSystemInterface::registerTouchDevice(m_touchDevice); + QMacInternalPasteboardMime::initializeMimeTypes(); } QIOSIntegration::~QIOSIntegration() @@ -88,6 +92,10 @@ QIOSIntegration::~QIOSIntegration() delete m_fontDatabase; m_fontDatabase = 0; + delete m_clipboard; + m_clipboard = 0; + QMacInternalPasteboardMime::destroyMimeTypes(); + delete m_inputContext; m_inputContext = 0; @@ -149,6 +157,11 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformClipboard *QIOSIntegration::clipboard() const +{ + return m_clipboard; +} + QPlatformInputContext *QIOSIntegration::inputContext() const { return m_inputContext; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 5af84918d9..aca8d76041 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -148,7 +148,7 @@ static QSizeF determinePhysicalSize(const fb_var_screeninfo &vinfo, const QSize mmWidth = vinfo.width; mmHeight = vinfo.height; } else { - const int dpi = 72; + const int dpi = 100; mmWidth = qRound(res.width() * 25.4 / dpi); mmHeight = qRound(res.height() * 25.4 / dpi); } diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp index d26b20d364..578031807c 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp @@ -57,9 +57,8 @@ QT_BEGIN_NAMESPACE class QMinimalEglContext : public QEGLPlatformContext { public: - QMinimalEglContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLenum eglApi = EGL_OPENGL_ES_API) - : QEGLPlatformContext(format, share, display, eglApi) + QMinimalEglContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) + : QEGLPlatformContext(format, share, display) { } diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qblackberrytheme.cpp index 37c1079441..a0f334d909 100644 --- a/src/plugins/platforms/qnx/qqnxtheme.cpp +++ b/src/plugins/platforms/qnx/qblackberrytheme.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qqnxtheme.h" +#include "qblackberrytheme.h" #include "qqnxfiledialoghelper.h" #include "qqnxsystemsettings.h" @@ -47,16 +47,33 @@ QT_BEGIN_NAMESPACE -QQnxTheme::QQnxTheme(const QQnxIntegration *integration) : m_integration(integration) +QBlackberryTheme::QBlackberryTheme(const QQnxIntegration *integration) : m_integration(integration) { + // Set the dark theme as default palette + QColor color = QColor(211, 211, 211); + m_defaultPalette.setBrush(QPalette::ButtonText, color); + m_defaultPalette.setBrush(QPalette::WindowText, color); + m_defaultPalette.setBrush(QPalette::Text, color); + + color.setAlpha(179); + m_defaultPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, color); + m_defaultPalette.setBrush(QPalette::Disabled, QPalette::WindowText, color); + m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Text, color); + + m_defaultPalette.setColor(QPalette::Window, QColor(18, 18, 18)); + m_defaultPalette.setColor(QPalette::Base, QColor(18, 18, 18)); + m_defaultPalette.setColor(QPalette::AlternateBase, QColor(50, 50, 50)); + + m_defaultPalette.setBrush(QPalette::Highlight, QColor(0, 168, 223)); + m_defaultPalette.setBrush(QPalette::HighlightedText, QColor(250, 250,250)); } -QQnxTheme::~QQnxTheme() +QBlackberryTheme::~QBlackberryTheme() { qDeleteAll(m_fonts); } -bool QQnxTheme::usePlatformNativeDialog(DialogType type) const +bool QBlackberryTheme::usePlatformNativeDialog(DialogType type) const { if (type == QPlatformTheme::FileDialog) return true; @@ -71,7 +88,7 @@ bool QQnxTheme::usePlatformNativeDialog(DialogType type) const return false; } -QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) const +QPlatformDialogHelper *QBlackberryTheme::createPlatformDialogHelper(DialogType type) const { switch (type) { case QPlatformTheme::FileDialog: @@ -87,7 +104,7 @@ QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) co } } -const QFont *QQnxTheme::font(Font type) const +const QFont *QBlackberryTheme::font(Font type) const { QPlatformFontDatabase *fontDatabase = m_integration->fontDatabase(); @@ -96,4 +113,13 @@ const QFont *QQnxTheme::font(Font type) const return m_fonts.value(type, 0); } +const QPalette *QBlackberryTheme::palette(Palette type) const +{ + // Return the default palette + if (type == SystemPalette) + return &m_defaultPalette; + + return QPlatformTheme::palette(type); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxtheme.h b/src/plugins/platforms/qnx/qblackberrytheme.h index 17b2eab142..29fa0b8f61 100644 --- a/src/plugins/platforms/qnx/qqnxtheme.h +++ b/src/plugins/platforms/qnx/qblackberrytheme.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QQNXTHEME_H -#define QQNXTHEME_H +#ifndef QBLACKBERRYTHEME_H +#define QBLACKBERRYTHEME_H #include <qpa/qplatformtheme.h> @@ -49,15 +49,17 @@ #include <QtCore/qhash.h> #include <QtCore/qstring.h> +#include <QtGui/QPalette> + QT_BEGIN_NAMESPACE class QQnxIntegration; -class QQnxTheme : public QPlatformTheme +class QBlackberryTheme : public QPlatformTheme { public: - explicit QQnxTheme(const QQnxIntegration *); - ~QQnxTheme(); + explicit QBlackberryTheme(const QQnxIntegration *); + ~QBlackberryTheme(); static QString name() { return QStringLiteral("blackberry"); } @@ -66,11 +68,14 @@ public: const QFont *font(Font type = SystemFont) const; + const QPalette *palette(Palette type = SystemPalette) const; + private: mutable QHash<QPlatformTheme::Font, QFont*> m_fonts; const QQnxIntegration *m_integration; + QPalette m_defaultPalette; }; QT_END_NAMESPACE -#endif // QQNXTHEME_H +#endif // QBLACKBERRYTHEME_H diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 2399a91c12..04c6087cd1 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -91,14 +91,14 @@ CONFIG(blackberry) { qqnxeventdispatcher_blackberry.cpp \ qqnxbpseventfilter.cpp \ qqnxvirtualkeyboardbps.cpp \ - qqnxtheme.cpp \ + qblackberrytheme.cpp \ qqnxsystemsettings.cpp HEADERS += qqnxnavigatorbps.h \ qqnxeventdispatcher_blackberry.h \ qqnxbpseventfilter.h \ qqnxvirtualkeyboardbps.h \ - qqnxtheme.h \ + qblackberrytheme.h \ qqnxsystemsettings.h \ qqnxfiledialoghelper.h diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp index 56c804a5b4..830b110f2a 100644 --- a/src/plugins/platforms/qnx/qqnxfilepicker.cpp +++ b/src/plugins/platforms/qnx/qqnxfilepicker.cpp @@ -48,7 +48,9 @@ #include <QJsonObject> #include <QJsonArray> #include <QJsonParseError> +#include <QMimeDatabase> #include <QUrl> +#include <private/qppsobject_p.h> #include <bps/navigator.h> #include <bps/navigator_invoke.h> @@ -118,7 +120,7 @@ void QQnxFilePicker::open() } QVariantMap map; - map[QStringLiteral("Type")] = QStringLiteral("Other"); + map[QStringLiteral("Type")] = filePickerType(); map[QStringLiteral("Mode")] = modeToString(m_mode); map[QStringLiteral("Title")] = m_title; map[QStringLiteral("ViewMode")] = QStringLiteral("Default"); @@ -132,11 +134,16 @@ void QQnxFilePicker::open() if (!m_filters.isEmpty()) map[QStringLiteral("Filter")] = m_filters.join(";"); + QByteArray ppsData; +#if defined(Q_OS_BLACKBERRY_TABLET) QJsonDocument document; document.setObject(QJsonObject::fromVariantMap(map)); - const QByteArray jsonData = document.toJson(QJsonDocument::Compact); + ppsData = document.toJson(QJsonDocument::Compact); +#else + ppsData = QPpsObject::encode(map); +#endif - errorCode = navigator_invoke_invocation_set_data(m_invocationHandle, jsonData.constData(), jsonData.size()); + errorCode = navigator_invoke_invocation_set_data(m_invocationHandle, ppsData.constData(), ppsData.size()); if (errorCode != BPS_SUCCESS) { cleanup(); qWarning() << "QQnxFilePicker: unable to set data:" << strerror(errno); @@ -275,6 +282,39 @@ void QQnxFilePicker::handleFilePickerResponse(const char *data) cleanup(); } +QString QQnxFilePicker::filePickerType() const +{ + bool images = false; + bool video = false; + bool music = false; + QMimeDatabase mimeDb; + for (int i = 0; i < filters().count(); i++) { + QList<QMimeType> mimeTypes = mimeDb.mimeTypesForFileName(filters().at(i)); + if (mimeTypes.isEmpty()) + return QStringLiteral("Other"); + + if (mimeTypes.first().name().startsWith(QLatin1String("image"))) + images = true; + else if (mimeTypes.first().name().startsWith(QLatin1String("audio"))) + music = true; + else if (mimeTypes.first().name().startsWith(QLatin1String("video"))) + video = true; + else + return QStringLiteral("Other"); + } + + if (!video && !music) + return QStringLiteral("Picture"); + + if (!images && !music) + return QStringLiteral("Video"); + + if (!images && !video) + return QStringLiteral("Music"); + + return QStringLiteral("Other"); +} + QString QQnxFilePicker::modeToString(QQnxFilePicker::Mode mode) const { switch (mode) { diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.h b/src/plugins/platforms/qnx/qqnxfilepicker.h index 5bb8f0969f..e8272900b0 100644 --- a/src/plugins/platforms/qnx/qqnxfilepicker.h +++ b/src/plugins/platforms/qnx/qqnxfilepicker.h @@ -92,6 +92,7 @@ public Q_SLOTS: private: void cleanup(); void handleFilePickerResponse(const char *data); + QString filePickerType() const; QString modeToString(Mode mode) const; diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp index 3a365be408..23db7f09f3 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.cpp +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -124,15 +124,11 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) if (m_eglConfig == 0) qFatal("QQnxGLContext: failed to find EGL config"); - EGLContext shareContext = EGL_NO_CONTEXT; - if (m_glContext) { - QQnxGLContext *qshareContext = dynamic_cast<QQnxGLContext*>(m_glContext->shareHandle()); - if (qshareContext) { - shareContext = qshareContext->m_eglContext; - } - } + QQnxGLContext *glShareContext = static_cast<QQnxGLContext*>(m_glContext->shareHandle()); + m_eglShareContext = glShareContext ? glShareContext->m_eglContext : EGL_NO_CONTEXT; - m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs(format)); + m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, m_eglShareContext, + contextAttrs(format)); if (m_eglContext == EGL_NO_CONTEXT) { checkEGLError("eglCreateContext"); qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError()); @@ -271,6 +267,11 @@ QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName) return static_cast<QFunctionPointer>(eglGetProcAddress(procName.constData())); } +bool QQnxGLContext::isSharing() const +{ + return m_eglShareContext != EGL_NO_CONTEXT; +} + EGLDisplay QQnxGLContext::getEglDisplay() { return ms_eglDisplay; } diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h index af89586bd5..d12de7342b 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.h +++ b/src/plugins/platforms/qnx/qqnxglcontext.h @@ -72,6 +72,7 @@ public: QFunctionPointer getProcAddress(const QByteArray &procName); virtual QSurfaceFormat format() const { return m_windowFormat; } + bool isSharing() const; static EGLDisplay getEglDisplay(); EGLConfig getEglConfig() const { return m_eglConfig;} @@ -86,6 +87,7 @@ private: EGLConfig m_eglConfig; EGLContext m_eglContext; + EGLContext m_eglShareContext; EGLSurface m_currentEglSurface; static EGLint *contextAttrs(const QSurfaceFormat &format); diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index dd32116360..41ca2b5e18 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -63,7 +63,7 @@ #if defined(Q_OS_BLACKBERRY) #include "qqnxbpseventfilter.h" #include "qqnxnavigatorbps.h" -#include "qqnxtheme.h" +#include "qblackberrytheme.h" #include "qqnxvirtualkeyboardbps.h" #elif defined(QQNX_PPS) #include "qqnxnavigatorpps.h" @@ -462,15 +462,15 @@ QPlatformServices * QQnxIntegration::services() const #if defined(Q_OS_BLACKBERRY) QStringList QQnxIntegration::themeNames() const { - return QStringList(QQnxTheme::name()); + return QStringList(QBlackberryTheme::name()); } QPlatformTheme *QQnxIntegration::createPlatformTheme(const QString &name) const { qIntegrationDebug() << Q_FUNC_INFO << "name =" << name; - if (name == QQnxTheme::name()) - return new QQnxTheme(this); - return QPlatformIntegration::createPlatformTheme(name); + if (name == QBlackberryTheme::name()) + return new QBlackberryTheme(this); + return 0; } #endif diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index b89c103a06..a245a0c43a 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -109,7 +109,7 @@ void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QStri if (name == QStringLiteral("mmRendererWindowName")) { qnxWindow->setMMRendererWindowName(value.toString()); - } else if (name == QStringLiteral("windowGroup")) { + } else if (name == QStringLiteral("qnxWindowGroup")) { if (value.isNull()) qnxWindow->joinWindowGroup(QByteArray()); else if (value.canConvert<QByteArray>()) @@ -124,6 +124,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QQnxNativeInterfa return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::setHighlightColor); if (resource == "blackberryIMFCheckSpelling") return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::checkSpelling); +#else + Q_UNUSED(resource) #endif return 0; } diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index f2b57aec9a..9ae2d01ab4 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -73,6 +73,88 @@ QT_BEGIN_NAMESPACE +/*! + \class QQnxWindow + \brief The QQnxWindow is the base class of the various classes used as instances of + QPlatformWindow in the QNX QPA plugin. + + The standard properties and methods available in Qt are not a perfect match for the + features provided by the QNX screen service. While for the majority of applications + the default behavior suffices, some circumstances require greater control over the + interaction with screen. + + \section1 Window types + + The QNX QPA plugin can operate in two modes, with or without a root window. The + selection of mode is made via the \e rootwindow and \e no-rootwindow options to the + plugin. The default mode is rootwindow for BlackBerry builds and no-rootwindow for + non-BlackBerry builds. + + Windows with parents are always created as child windows, the difference in the modes + is in the treatment of parentless windows. In no-rootwindow mode, these windows are + created as application windows while in rootwindow mode, the first window on a screen + is created as an application window while subsequent windows are created as child + windows. The only exception to this is any window of type Qt::Desktop or Qt::CoverWindow; + these are created as application windows, but will never become the root window, + even if they are the first window created. + + It is also possible to create a parentless child window. These may be useful to + create windows that are parented by windows from other processes. To do this, you + attach a dynamic property \e qnxInitialWindowGroup to the QWindow though this must be done + prior to the platform window class (this class) being created which typically happens + when the window is made visible. When the window is created in QML, it is acceptable + to have the \e visible property hardcoded to true so long as the qnxInitialWindowGroup + is also set. + + \section1 Joining Window Groups + + Window groups may be joined in a number of ways, some are automatic based on + predefined rules though an application is also able to provide explicit control. + + A QWindow that has a parent will join its parent's window group. When rootwindow mode + is in effect, all but the first parentless window on a screen will be child windows + and join the window group of the first parentless window, the root window. + + If a QWindow has a valid dynamic property called \e qnxInitialWindowGroup at the time the + QQnxWindow is created, the window will be created as a child window and, if the + qnxInitialWindowGroup property is a non-empty string, an attempt will be made to join that + window group. This has an effect only when the QQnxWindow is created, subsequent + changes to this property are ignored. Setting the property to an empty string + provides a means to create 'top level' child windows without automatically joining + any group. Typically when this property is used \e qnxWindowId should be used as well + so that the process that owns the window group being joined has some means to + identify the window. + + At any point following the creation of the QQnxWindow object, an application can + change the window group it has joined. This is done by using the \e + setWindowProperty function of the native interface to set the \e qnxWindowGroup property + to the desired value, for example: + + \code + QQuickView *view = new QQuickView(parent); + view->create(); + QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", + group); + \endcode + + To leave the current window group, one passes a null value for the property value, + for example: + + \code + QQuickView *view = new QQuickView(parent); + view->create(); + QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", + QVariant()); + \endcode + + \section1 Window Id + + The screen window id string property can be set on a window by assigning the desired + value to a dynamic property \e qnxWindowId on the QWindow prior to the QQnxWindow having + been created. This is often wanted when one joins a window group belonging to a + different process. + +*/ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow) : QPlatformWindow(window), m_screenContext(context), @@ -88,12 +170,16 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle()); + // If a qnxInitialWindowGroup property is set on the window we'll take this as an + // indication that we want to create a child window and join that window group. + const QVariant windowGroup = window->property("qnxInitialWindowGroup"); + if (window->type() == Qt::CoverWindow || window->type() == Qt::Desktop) { // Cover windows have to be top level to be accessible to window delegate (i.e. navigator) // Desktop windows also need to be toplevel because they are not // supposed to be part of the window hierarchy tree m_isTopLevel = true; - } else if (parent() || (window->type() & Qt::Dialog) == Qt::Dialog) { + } else if (parent() || windowGroup.isValid()) { // If we have a parent we are a child window. Sometimes we have to be a child even if we // don't have a parent e.g. our parent might be in a different process. m_isTopLevel = false; @@ -117,6 +203,21 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW } createWindowGroup(); + + // If the window has a qnxWindowId property, set this as the string id property. This generally + // needs to be done prior to joining any group as it might be used by the owner of the + // group to identify the window. + const QVariant windowId = window->property("qnxWindowId"); + if (windowId.isValid() && windowId.canConvert<QByteArray>()) { + QByteArray id = windowId.toByteArray(); + Q_SCREEN_CHECKERROR(screen_set_window_property_cv(m_window, SCREEN_PROPERTY_ID_STRING, + id.size(), id), "Failed to set id"); + } + + // If a window group has been provided join it now. If it's an empty string that's OK too, + // it'll cause us not to join a group (the app will presumably join at some future time). + if (windowGroup.isValid() && windowGroup.canConvert<QByteArray>()) + joinWindowGroup(windowGroup.toByteArray()); } QQnxWindow::~QQnxWindow() diff --git a/src/plugins/platforms/windows/qwindows.qdocconf b/src/plugins/platforms/windows/qwindows.qdocconf deleted file mode 100644 index 1684773b87..0000000000 --- a/src/plugins/platforms/windows/qwindows.qdocconf +++ /dev/null @@ -1,25 +0,0 @@ -project = "Qt Windows Lighthouse Plugin" -description = "Documentation of the Qt Windows Lighthouse Plugin" - -language = Cpp - -headerdirs = . - -sourcedirs = . - -showinternal = true - -headers.fileextensions = "*.h" -sources.fileextensions = "*.cpp *.qdoc" - -qhp.projects = QtLighthouseWindows -qhp.QtLighthouseWindowsDev.file = qtlighthousewindows-dev.qhp -qhp.QtLighthouseWindowsDev.namespace = com.nokia.qt.developer.lighthouse -qhp.QtLighthouseWindowsDev.virtualFolder = doc -qhp.QtLighthouseWindowsDev.indexTitle = Qt Windows Lighthouse Plugin -qhp.QtLighthouseWindowsDev.indexRoot = - -# Doxygen compatibility commands - -macro.see = "\\sa" -macro.function = "\\fn" diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index f12c828d8a..1abf447709 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -203,4 +203,17 @@ HDC QWindowsBackingStore::getDC() const return 0; } +#ifndef QT_NO_OPENGL + +QImage QWindowsBackingStore::toImage() const +{ + if (m_image.isNull()) { + qCWarning(lcQpaBackingStore) <<__FUNCTION__ << "Image is null."; + return QImage(); + } + return m_image.data()->image(); +} + +#endif // !QT_NO_OPENGL + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h index b655aca835..758f6c941f 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.h +++ b/src/plugins/platforms/windows/qwindowsbackingstore.h @@ -67,6 +67,10 @@ public: HDC getDC() const; +#ifndef QT_NO_OPENGL + QImage toImage() const Q_DECL_OVERRIDE; +#endif + private: QScopedPointer<QWindowsNativeImage> m_image; }; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index c35af3623a..a74a7efb41 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -979,8 +979,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) case QtWindows::QueryEndSessionApplicationEvent: { QWindowsSessionManager *sessionManager = platformSessionManager(); - if (sessionManager->isActive()) // bogus message from windows + if (sessionManager->isActive()) { // bogus message from windows + *result = sessionManager->wasCanceled() ? 0 : 1; return true; + } sessionManager->setActive(true); sessionManager->blocksInteraction(); diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index e025d7e513..d5ca06bb3f 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -124,7 +124,7 @@ QWindowsEGLStaticContext::~QWindowsEGLStaticContext() QWindowsEGLContext::QWindowsEGLContext(const QWindowsEGLStaticContextPtr &staticContext, const QSurfaceFormat &format, QPlatformOpenGLContext *share) - : QEGLPlatformContext(format, share, staticContext->display(), EGL_OPENGL_ES_API) + : QEGLPlatformContext(format, share, staticContext->display()) , m_staticContext(staticContext) { } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 854444b254..8f9ddc2168 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1038,11 +1038,17 @@ QWindowsFontDatabase::~QWindowsFontDatabase() removeApplicationFonts(); } +QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) +{ + Q_UNUSED(script) + return new QWindowsMultiFontEngine(fontEngine, QStringList()); +} + QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) { - QFontEngine *fe = QWindowsFontDatabase::createEngine(QChar::Script_Common, fontDef, - 0, QWindowsContext::instance()->defaultDPI(), false, - QStringList(), sharedFontData()); + QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef, 0, + QWindowsContext::instance()->defaultDPI(), + false, sharedFontData()); qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle; return fe; } @@ -1087,12 +1093,12 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal QFontDef request; request.family = uniqueFamilyName; request.pixelSize = pixelSize; - request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; + request.styleStrategy = QFont::PreferMatch; request.hintingPreference = hintingPreference; - fontEngine = QWindowsFontDatabase::createEngine(QChar::Script_Common, request, 0, - QWindowsContext::instance()->defaultDPI(), false, QStringList(), - sharedFontData()); + fontEngine = QWindowsFontDatabase::createEngine(request, 0, + QWindowsContext::instance()->defaultDPI(), + false, sharedFontData()); if (fontEngine) { if (request.family != fontEngine->fontDef.family) { @@ -1623,9 +1629,8 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon } -QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &request, +QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, HDC fontHdc, int dpi, bool rawMode, - const QStringList &family_list, const QSharedPointer<QWindowsFontEngineData> &data) { LOGFONT lf; @@ -1769,17 +1774,6 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ directWriteFont->Release(); #endif - if ((script == QChar::Script_Common || script == QChar::Script_Han) - && !(request.styleStrategy & QFont::NoFontMerging)) { - const QStringList extraFonts = QWindowsFontDatabase::extraTryFontsForFamily(request.family); - if (extraFonts.size()) { - QStringList list = family_list; - list.append(extraFonts); - QFontEngine *mfe = new QWindowsMultiFontEngine(fe, list); - mfe->fontDef = fe->fontDef; - fe = mfe; - } - } return fe; } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h index 1e13fc2559..a2324544d2 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h @@ -78,6 +78,7 @@ public: ~QWindowsFontDatabase(); virtual void populateFontDatabase(); + virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script); virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; @@ -92,9 +93,8 @@ public: static QFont systemDefaultFont(); - static QFontEngine *createEngine(int script, const QFontDef &request, + static QFontEngine *createEngine(const QFontDef &request, HDC fontHdc, int dpi, bool rawMode, - const QStringList &family_list, const QSharedPointer<QWindowsFontEngineData> &data); static HFONT systemFont(); diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 86fcb666b0..c3774064e3 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -65,6 +65,7 @@ #include <QtCore/qmath.h> #include <QtCore/QThreadStorage> #include <QtCore/private/qsystemlibrary_p.h> +#include <QtCore/private/qstringiterator_p.h> #include <QtCore/QDebug> @@ -205,47 +206,37 @@ void QWindowsFontEngine::getCMap() } } -// ### Qt 5.1: replace with QStringIterator -inline unsigned int getChar(const QChar *str, int &i, const int len) -{ - uint uc = str[i].unicode(); - if (QChar::isHighSurrogate(uc) && i < len-1) { - uint low = str[i+1].unicode(); - if (QChar::isLowSurrogate(low)) { - uc = QChar::surrogateToUcs4(uc, low); - ++i; - } - } - return uc; -} - int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const { - int i = 0; int glyph_pos = 0; { #if defined(Q_OS_WINCE) { #else if (symbol) { - for (; i < numChars; ++i, ++glyph_pos) { - unsigned int uc = getChar(str, i, numChars); + QStringIterator it(str, str + numChars); + while (it.hasNext()) { + const uint uc = it.next(); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); if(!glyphs->glyphs[glyph_pos] && uc < 0x100) glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000); + ++glyph_pos; } } else if (ttf) { - for (; i < numChars; ++i, ++glyph_pos) { - unsigned int uc = getChar(str, i, numChars); + QStringIterator it(str, str + numChars); + while (it.hasNext()) { + const uint uc = it.next(); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); + ++glyph_pos; } } else { #endif wchar_t first = tm.tmFirstChar; wchar_t last = tm.tmLastChar; - for (; i < numChars; ++i, ++glyph_pos) { - uint uc = getChar(str, i, numChars); + QStringIterator it(str, str + numChars); + while (it.hasNext()) { + const uint uc = it.next(); if ( #ifdef Q_WS_WINCE tm.tmFirstChar > 60000 || @@ -254,6 +245,7 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa glyphs->glyphs[glyph_pos] = uc; else glyphs->glyphs[glyph_pos] = 0; + ++glyph_pos; } } } @@ -272,7 +264,8 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa QWindowsFontEngine::QWindowsFontEngine(const QString &name, HFONT _hfont, bool stockFontIn, LOGFONT lf, - const QSharedPointer<QWindowsFontEngineData> &fontEngineData) : + const QSharedPointer<QWindowsFontEngineData> &fontEngineData) + : QFontEngine(Win), m_fontEngineData(fontEngineData), _name(name), hfont(_hfont), @@ -340,6 +333,30 @@ QWindowsFontEngine::~QWindowsFontEngine() } } +glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const +{ + glyph_t glyph; + +#if !defined(Q_OS_WINCE) + if (symbol) { + glyph = getTrueTypeGlyphIndex(cmap, ucs4); + if (glyph == 0 && ucs4 < 0x100) + glyph = getTrueTypeGlyphIndex(cmap, ucs4 + 0xf000); + } else if (ttf) { + glyph = getTrueTypeGlyphIndex(cmap, ucs4); +#else + if (tm.tmFirstChar > 60000) { + glyph = ucs4; +#endif + } else if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) { + glyph = ucs4; + } else { + glyph = 0; + } + + return glyph; +} + HGDIOBJ QWindowsFontEngine::selectDesignFont() const { LOGFONT f = m_logfont; @@ -351,6 +368,7 @@ HGDIOBJ QWindowsFontEngine::selectDesignFont() const bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { + Q_ASSERT(glyphs->numGlyphs >= *nglyphs); if (*nglyphs < len) { *nglyphs = len; return false; @@ -746,46 +764,6 @@ qreal QWindowsFontEngine::minRightBearing() const #endif // Q_OS_WINCE } - -const char *QWindowsFontEngine::name() const -{ - return 0; -} - -bool QWindowsFontEngine::canRender(const QChar *string, int len) -{ - if (symbol) { - for (int i = 0; i < len; ++i) { - unsigned int uc = getChar(string, i, len); - if (getTrueTypeGlyphIndex(cmap, uc) == 0) { - if (uc < 0x100) { - if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0) - return false; - } else { - return false; - } - } - } - } else if (ttf) { - for (int i = 0; i < len; ++i) { - unsigned int uc = getChar(string, i, len); - if (getTrueTypeGlyphIndex(cmap, uc) == 0) - return false; - } - } else { - while(len--) { - if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode()) - return false; - } - } - return true; -} - -QFontEngine::Type QWindowsFontEngine::type() const -{ - return QFontEngine::Win; -} - static inline double qt_fixed_to_double(const FIXED &p) { return ((p.value << 16) + p.fract) / 65536.0; } @@ -1032,6 +1010,7 @@ bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) SelectObject(hdc, hfont); DWORD t = qbswap<quint32>(tag); *length = GetFontData(hdc, t, 0, buffer, *length); + Q_ASSERT(*length == GDI_ERROR || int(*length) > 0); return *length != GDI_ERROR; } @@ -1254,15 +1233,11 @@ QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const if (!uniqueFamilyName.isEmpty()) request.family = uniqueFamilyName; request.pixelSize = pixelSize; - // Disable font merging, as otherwise createEngine will return a multi-engine - // instance instead of the specific engine we wish to clone. - request.styleStrategy |= QFont::NoFontMerging; QFontEngine *fontEngine = - QWindowsFontDatabase::createEngine(QChar::Script_Common, request, 0, + QWindowsFontDatabase::createEngine(request, 0, QWindowsContext::instance()->defaultDPI(), - false, - QStringList(), m_fontEngineData); + false, m_fontEngineData); if (fontEngine) { fontEngine->fontDef.family = actualFontName; if (!uniqueFamilyName.isEmpty()) { @@ -1305,19 +1280,29 @@ void QWindowsFontEngine::initFontInfo(const QFontDef &request, */ QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks) - : QFontEngineMulti(fallbacks.size()+1), - fallbacks(fallbacks) + : QFontEngineMulti(fallbacks.size() + 1), + fallbackFamilies(fallbacks) { - qCDebug(lcQpaFonts) << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks; engines[0] = first; first->ref.ref(); fontDef = engines[0]->fontDef; cache_cost = first->cache_cost; } -QWindowsMultiFontEngine::~QWindowsMultiFontEngine() +void QWindowsMultiFontEngine::setFallbackFamiliesList(const QStringList &fallbacks) { - qCDebug(lcQpaFonts) << __FUNCTION__; + // Original FontEngine to restore after the fill. + QFontEngine *fe = engines[0]; + fallbackFamilies = fallbacks; + if (!fallbackFamilies.isEmpty()) { + engines.fill(0, fallbackFamilies.size() + 1); + engines[0] = fe; + } else { + // Turns out we lied about having any fallback at all. + fallbackFamilies << fe->fontDef.family; + engines[1] = fe; + fe->ref.ref(); + } } void QWindowsMultiFontEngine::loadEngine(int at) @@ -1344,7 +1329,7 @@ void QWindowsMultiFontEngine::loadEngine(int at) data = fe->fontEngineData(); } - const QString fam = fallbacks.at(at-1); + const QString fam = fallbackFamilies.at(at-1); memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded #ifndef QT_NO_DIRECTWRITE diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index e3fb3281a3..7d93484220 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -86,6 +86,7 @@ public: virtual int synthesized() const; virtual QFixed emSquareSize() const; + virtual glyph_t glyphIndex(uint ucs4) const; virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const; virtual void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const; @@ -109,12 +110,6 @@ public: virtual qreal minLeftBearing() const; virtual qreal minRightBearing() const; - virtual const char *name() const; - - bool canRender(const QChar *string, int len); - - Type type() const; - virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); } virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform); virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform); @@ -175,10 +170,11 @@ class QWindowsMultiFontEngine : public QFontEngineMulti { public: QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks); - virtual ~QWindowsMultiFontEngine(); + + void setFallbackFamiliesList(const QStringList &fallbacks); void loadEngine(int at); - QStringList fallbacks; + QStringList fallbackFamilies; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 1c5e4508ac..8f55e20536 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -53,6 +53,7 @@ #include <QtCore/QSettings> #include <QtCore/QtEndian> #include <QtCore/QVarLengthArray> +#include <private/qstringiterator_p.h> #include <dwrite.h> #include <d2d1.h> @@ -201,8 +202,8 @@ namespace { QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace, qreal pixelSize, const QSharedPointer<QWindowsFontEngineData> &d) - - : m_fontEngineData(d) + : QFontEngine(DirectWrite) + , m_fontEngineData(d) , m_directWriteFontFace(directWriteFontFace) , m_directWriteBitmapRenderTarget(0) , m_lineThickness(-1) @@ -282,8 +283,8 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui ret = true; if (buffer && *length >= tableSize) memcpy(buffer, tableData, tableSize); - else - *length = tableSize; + *length = tableSize; + Q_ASSERT(int(*length) > 0); } m_directWriteFontFace->ReleaseFontTable(tableContext); } else { @@ -301,23 +302,23 @@ QFixed QWindowsFontEngineDirectWrite::emSquareSize() const return QFontEngine::emSquareSize(); } -// ### Qt 5.1: replace with QStringIterator -inline unsigned int getChar(const QChar *str, int &i, const int len) +glyph_t QWindowsFontEngineDirectWrite::glyphIndex(uint ucs4) const { - uint uc = str[i].unicode(); - if (QChar::isHighSurrogate(uc) && i < len-1) { - uint low = str[i+1].unicode(); - if (QChar::isLowSurrogate(low)) { - uc = QChar::surrogateToUcs4(uc, low); - ++i; - } + UINT16 glyphIndex; + + HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(&ucs4, 1, &glyphIndex); + if (FAILED(hr)) { + qErrnoWarning("%s: glyphIndex failed", __FUNCTION__); + glyphIndex = 0; } - return uc; + + return glyphIndex; } bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { + Q_ASSERT(glyphs->numGlyphs >= *nglyphs); if (*nglyphs < len) { *nglyphs = len; return false; @@ -325,8 +326,9 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly QVarLengthArray<UINT32> codePoints(len); int actualLength = 0; - for (int i = 0; i < len; ++i) - codePoints[actualLength++] = getChar(str, i, len); + QStringIterator it(str, str + len); + while (it.hasNext()) + codePoints[actualLength++] = it.next(); QVarLengthArray<UINT16> glyphIndices(actualLength); HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength, @@ -628,39 +630,6 @@ QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t, : mask.convertToFormat(QImage::Format_RGB32); } -const char *QWindowsFontEngineDirectWrite::name() const -{ - return 0; -} - -bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len) -{ - QVarLengthArray<UINT32> codePoints(len); - int actualLength = 0; - for (int i=0; i<len; ++i, actualLength++) - codePoints[actualLength] = getChar(string, i, len); - - QVarLengthArray<UINT16> glyphIndices(actualLength); - HRESULT hr = m_directWriteFontFace->GetGlyphIndices(codePoints.data(), actualLength, - glyphIndices.data()); - if (FAILED(hr)) { - qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__); - return false; - } - - for (int i = 0; i < actualLength; ++i) { - if (glyphIndices.at(i) == 0) - return false; - } - - return true; -} - -QFontEngine::Type QWindowsFontEngineDirectWrite::type() const -{ - return QFontEngine::DirectWrite; -} - QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const { QFontEngine *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace, diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index 399bb5f5ad..2da014ddc3 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -74,6 +74,7 @@ public: bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; QFixed emSquareSize() const; + virtual glyph_t glyphIndex(uint ucs4) const; bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const; void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const; @@ -89,8 +90,6 @@ public: QFixed xHeight() const; qreal maxCharWidth() const; - const char *name() const; - bool supportsSubPixelPositions() const; QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition); @@ -98,9 +97,6 @@ public: QFontEngine *cloneWithSize(qreal pixelSize) const; - bool canRender(const QChar *string, int len); - Type type() const; - const QSharedPointer<QWindowsFontEngineData> &fontEngineData() const { return m_fontEngineData; } static QString fontNameSubstitute(const QString &familyName); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 9bfe4e6e26..c45c34ae4d 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -1050,7 +1050,7 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface) qCDebug(lcQpaGl) << __FUNCTION__ << this << m_windowContexts.size() << "contexts"; #endif // DEBUG_GL - Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface->surface()->supportsOpenGL()); // Do we already have a DC entry for that window? QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 3735865845..e0e8753e14 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -234,7 +234,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co return true; case ThreadedOpenGL: #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - return QOpenGLFunctions::isES() ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true; + return QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL + ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true; # else return true; # endif // QT_OPENGL_ES_2 @@ -245,6 +246,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co return true; case ForeignWindows: return true; + case RasterGLSurface: + return true; default: return QPlatformIntegration::hasCapability(cap); } @@ -296,7 +299,7 @@ QPlatformOpenGLContext { qCDebug(lcQpaGl) << __FUNCTION__ << context->format(); #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLFunctions::isES()){ + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) { if (d->m_staticEGLContext.isNull()) { QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create(); if (!staticContext) @@ -307,7 +310,7 @@ QPlatformOpenGLContext } #endif #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLFunctions::isES()) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { if (d->m_staticOpenGLContext.isNull()) d->m_staticOpenGLContext = QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create()); @@ -379,7 +382,7 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co switch (hint) { case QPlatformIntegration::CursorFlashTime: if (const unsigned timeMS = GetCaretBlinkTime()) - return QVariant(int(timeMS)); + return QVariant(int(timeMS) * 2); break; #ifdef SPI_GETKEYBOARDSPEED case KeyboardAutoRepeatRate: diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index fb1b63084f..7e15be1d19 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -69,13 +69,18 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle()); if (resource == "handle") return bw->handle(); - if (window->surfaceType() == QWindow::RasterSurface) { + switch (window->surfaceType()) { + case QWindow::RasterSurface: + case QWindow::RasterGLSurface: if (resource == "getDC") return bw->getDC(); if (resource == "releaseDC") { bw->releaseDC(); return 0; } + break; + case QWindow::OpenGLSurface: + break; } qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData()); return 0; @@ -120,7 +125,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour return 0; } #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLFunctions::isES()) { + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) { QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle()); if (resource == QByteArrayLiteral("eglDisplay")) return windowsEglContext->eglDisplay(); @@ -131,7 +136,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour } #endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLFunctions::isES()) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle()); if (resource == QByteArrayLiteral("renderingContext")) return windowsContext->renderingContext(); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 223ac9ac2d..274366d4fe 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -886,7 +886,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->surfaceType() == QWindow::OpenGLSurface) { setFlag(OpenGLSurface); #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLFunctions::isES()) + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) setFlag(OpenGL_ES2); #endif } diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 014378f896..3a1958a20e 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface) - : QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API), m_eglSurface(surface) + : QEGLPlatformContext(format, share, display), m_eglSurface(surface) { } diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 5bbf73a945..2e38f81499 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -63,6 +63,9 @@ #include <windows.ui.viewmanagement.h> #include <windows.graphics.display.h> #include <windows.foundation.h> +#ifdef Q_OS_WINPHONE +#include <windows.phone.ui.input.h> +#endif using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; @@ -75,6 +78,9 @@ using namespace ABI::Windows::UI::Input; using namespace ABI::Windows::UI::ViewManagement; using namespace ABI::Windows::Devices::Input; using namespace ABI::Windows::Graphics::Display; +#ifdef Q_OS_WINPHONE +using namespace ABI::Windows::Phone::UI::Input; +#endif typedef IEventHandler<IInspectable*> ResumeHandler; typedef IEventHandler<SuspendingEventArgs*> SuspendHandler; @@ -87,6 +93,9 @@ typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler; typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler; typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler; typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler; +#ifdef Q_OS_WINPHONE +typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler; +#endif QT_BEGIN_NAMESPACE @@ -465,6 +474,11 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window) m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]); m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]); m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]); +#ifdef Q_OS_WINPHONE + ComPtr<IHardwareButtonsStatics> hardwareButtons; + if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), &hardwareButtons))) + hardwareButtons->add_BackPressed(Callback<BackPressedHandler>(this, &QWinRTScreen::onBackButtonPressed).Get(), &m_tokens[QEvent::User]); +#endif // Q_OS_WINPHONE // Window event handlers m_coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &m_tokens[QEvent::WindowActivate]); @@ -984,6 +998,8 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChange boolean visible; args->get_Visible(&visible); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); + if (visible) + handleExpose(); return S_OK; } @@ -1000,4 +1016,27 @@ HRESULT QWinRTScreen::onOrientationChanged(IInspectable *) return S_OK; } +#ifdef Q_OS_WINPHONE +HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) +{ + QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier); + backPress.setAccepted(false); + + QObject *receiver = m_visibleWindows.isEmpty() + ? static_cast<QObject *>(QGuiApplication::instance()) + : static_cast<QObject *>(m_visibleWindows.first()); + + // If the event is ignored, the app will suspend + QGuiApplication::sendEvent(receiver, &backPress); + if (backPress.isAccepted()) { + args->put_Handled(true); + // If the app accepts the event, send the release for symmetry + QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); + QGuiApplication::sendEvent(receiver, &backRelease); + } + + return S_OK; +} +#endif // Q_OS_WINPHONE + QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 3131f879b5..c6511e9446 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -80,6 +80,15 @@ namespace ABI { struct IDisplayPropertiesStatics; } } +#ifdef Q_OS_WINPHONE + namespace Phone { + namespace UI { + namespace Input { + struct IBackPressedEventArgs; + } + } + } +#endif } } struct IInspectable; @@ -149,6 +158,10 @@ private: HRESULT onOrientationChanged(IInspectable *); +#ifdef Q_OS_WINPHONE + HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); +#endif + ABI::Windows::UI::Core::ICoreWindow *m_coreWindow; ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView; ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application; diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index ed2f685770..eaa4d05311 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -537,7 +537,7 @@ QGLXPbuffer::QGLXPbuffer(QOffscreenSurface *offscreenSurface) GLX_PBUFFER_HEIGHT, offscreenSurface->size().height(), GLX_LARGEST_PBUFFER, False, GLX_PRESERVED_CONTENTS, False, - GLX_NONE + None }; m_pbuffer = glXCreatePbuffer(DISPLAY_FROM_XCB(m_screen), config, attributes); diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/qxcbmain.cpp index f21ea03cf5..54c1629bf0 100644 --- a/src/plugins/platforms/xcb/main.cpp +++ b/src/plugins/platforms/xcb/qxcbmain.cpp @@ -62,4 +62,4 @@ QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QT_END_NAMESPACE -#include "main.moc" +#include "qxcbmain.moc" diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 7d69564c57..b45bd6a82e 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -80,7 +80,8 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("glxcontext"), QByteArrayLiteral("apptime"), QByteArrayLiteral("appusertime"), QByteArrayLiteral("hintstyle"), QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"), - QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen") + QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"), + QByteArrayLiteral("rootwindow") }; const QByteArray *end = names + sizeof(names) / sizeof(names[0]); const QByteArray *result = std::find(names, end, key); @@ -142,6 +143,9 @@ void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resour case X11Screen: result = x11Screen(); break; + case RootWindow: + result = rootWindow(); + break; default: break; } @@ -264,6 +268,15 @@ void *QXcbNativeInterface::x11Screen() return 0; } +void *QXcbNativeInterface::rootWindow() +{ + QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QXcbConnection *defaultConnection = integration->defaultConnection(); + if (defaultConnection) + return reinterpret_cast<void *>(defaultConnection->rootWindow()); + return 0; +} + void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time) { static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 9c4fa44d3b..fb1a46014c 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -70,7 +70,8 @@ public: StartupId, TrayWindow, GetTimestamp, - X11Screen + X11Screen, + RootWindow }; QXcbNativeInterface(); @@ -94,6 +95,7 @@ public: void *getTimestamp(const QXcbScreen *screen); void *startupId(); void *x11Screen(); + void *rootWindow(); static void setAppTime(QScreen *screen, xcb_timestamp_t time); static void setAppUserTime(QScreen *screen, xcb_timestamp_t time); static void *eglContextForContext(QOpenGLContext *context); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 29f71e6972..aabcb84a08 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -64,9 +64,7 @@ #include <xcb/xcb_icccm.h> #undef class #include <xcb/xfixes.h> -#ifndef QT_NO_SHAPE -# include <xcb/shape.h> -#endif // QT_NO_SHAPE +#include <xcb/shape.h> // xcb-icccm 3.8 support #ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS @@ -2077,8 +2075,6 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event) } } -#if !defined(QT_NO_SHAPE) - static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r) { xcb_rectangle_t result; @@ -2123,8 +2119,6 @@ void QXcbWindow::setMask(const QRegion ®ion) } } -#endif // !QT_NO_SHAPE - void QXcbWindow::setAlertState(bool enabled) { if (m_alertState == enabled) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 45d44b213f..a90ad7b5ed 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -114,10 +114,7 @@ public: bool startSystemResize(const QPoint &pos, Qt::Corner corner); void setOpacity(qreal level); - -#if !defined(QT_NO_SHAPE) void setMask(const QRegion ®ion); -#endif // !QT_NO_SHAPE void setAlertState(bool enabled); bool isAlertState() const { return m_alertState; } diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index 4727262f3f..bfbec91e3c 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -17,7 +17,7 @@ SOURCES = \ qxcbwindow.cpp \ qxcbbackingstore.cpp \ qxcbwmsupport.cpp \ - main.cpp \ + qxcbmain.cpp \ qxcbnativeinterface.cpp \ qxcbcursor.cpp \ qxcbimage.cpp \ @@ -121,8 +121,7 @@ contains(QT_CONFIG, xcb-qt) { INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr - !contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape + LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape contains(DEFINES, QT_NO_XKB) { LIBS += -lxcb-keysyms } else { diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro index 2fd5519053..19852b74b1 100644 --- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro +++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro @@ -1,6 +1,7 @@ # # Statically compile in code for -# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image, libxcb-keysyms, libxcb-icccm, libxcb-renderutil +# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image, +# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb # TEMPLATE = lib TARGET = xcb-static |