summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp10
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp1
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp55
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm16
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm4
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp42
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h9
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp135
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp110
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp38
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h5
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp92
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h7
-rw-r--r--src/plugins/platforms/ios/qiosapplicationstate.mm1
-rw-r--r--src/plugins/platforms/ios/qioswindow.h1
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm68
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp5
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp23
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp21
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h5
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp1
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/xcb-static/xcb-static.pro5
-rw-r--r--src/plugins/printsupport/printsupport.pro2
31 files changed, 511 insertions, 169 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index b987c49c9c..a38741cc91 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -50,7 +50,7 @@
#include "qdebug.h"
-static const char m_qtTag[] = "QtA11y";
+static const char m_qtTag[] = "Qt A11Y";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
@@ -184,8 +184,6 @@ if (!clazz) { \
desc = iface->text(QAccessible::Name);
if (desc.isEmpty())
desc = iface->text(QAccessible::Description);
-
- desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
}
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
@@ -216,12 +214,6 @@ if (!clazz) { \
}
}
- if ((iface->role() != QAccessible::NoRole) &&
- (iface->role() != QAccessible::Client) &&
- (iface->role() != QAccessible::Pane)) {
- desc += QChar(' ') + QString::fromUtf8(qAccessibleRoleString(iface->role()));
- }
-
CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
//CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable)
CALL_METHOD(node, "setFocusable", "(Z)V", true)
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index ff1a40bfc5..2998762cc3 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -769,7 +769,6 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|| !QtAndroidInput::registerNatives(env)
|| !QtAndroidClipboard::registerNatives(env)
|| !QtAndroidMenu::registerNatives(env)
- || !QtAndroidAccessibility::registerNatives(env)
|| !QtAndroidDialogHelpers::registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index e255a49ac7..c2e5f83639 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -591,19 +591,37 @@ jboolean QAndroidInputContext::endBatchEdit()
return JNI_TRUE;
}
-jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/)
+/*
+ Android docs say: If composing, replace compose text with \a text.
+ Otherwise insert \a text at current cursor position.
+
+ The cursor should then be moved to newCursorPosition. If > 0, this is
+ relative to the end of the text - 1; if <= 0, this is relative to the start
+ of the text. updateSelection() needs to be called.
+*/
+jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (query.isNull())
- return JNI_FALSE;
+ QInputMethodEvent event;
+ event.setCommitString(text);
+ sendInputMethodEvent(&event);
+ clear();
+ // Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1
+ if (newCursorPosition != 1) {
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (!query.isNull()) {
+ QList<QInputMethodEvent::Attribute> attributes;
+ const int localPos = query->value(Qt::ImCursorPosition).toInt();
+ const int newLocalPos = newCursorPosition > 0
+ ? localPos + newCursorPosition - 1
+ : localPos - text.length() + newCursorPosition;
+ //move the cursor
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
+ newLocalPos, 0, QVariant()));
+ }
+ }
- const int cursorPos = getAbsoluteCursorPosition(query);
- m_composingText = text;
- m_composingTextStart = cursorPos;
- m_composingCursor = cursorPos + text.length();
- finishComposingText();
- //### move cursor to newCursorPosition and call updateCursorPosition()
+ updateCursorPosition();
return JNI_TRUE;
}
@@ -624,9 +642,24 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right
return JNI_TRUE;
}
+// Android docs say the cursor must not move
jboolean QAndroidInputContext::finishComposingText()
{
- QInputMethodEvent event;
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return JNI_FALSE;
+
+ if (m_composingText.isEmpty())
+ return JNI_TRUE; // not composing
+
+ const int blockPos = getBlockPosition(query);
+ const int localCursorPos = m_composingCursor - blockPos;
+
+ // Moving Qt's cursor to where the preedit cursor used to be
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, localCursorPos, 0, QVariant()));
+
+ QInputMethodEvent event(QString(), attributes);
event.setCommitString(m_composingText);
sendInputMethodEvent(&event);
clear();
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index dc22da0983..a18f721e04 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -92,16 +92,20 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
QFont newFont;
if (cocoaFont) {
int pSize = qRound([cocoaFont pointSize]);
- CTFontDescriptorRef font = CTFontCopyFontDescriptor((CTFontRef)cocoaFont);
- // QCoreTextFontDatabase::populateFontDatabase() is using localized names
- QString family = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL));
- QString style = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL));
+ QString family(QCFString::toQString([cocoaFont familyName]));
+ QString typeface(QCFString::toQString([cocoaFont fontName]));
+
+ int hyphenPos = typeface.indexOf(QLatin1Char('-'));
+ if (hyphenPos != -1) {
+ typeface.remove(0, hyphenPos + 1);
+ } else {
+ typeface = QLatin1String("Normal");
+ }
- newFont = QFontDatabase().font(family, style, pSize);
+ newFont = QFontDatabase().font(family, typeface, pSize);
newFont.setUnderline(resolveFont.underline());
newFont.setStrikeOut(resolveFont.strikeOut());
- CFRelease(font);
}
return newFont;
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 44bc3b8f69..a89979a8ea 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -234,6 +234,10 @@ QCocoaMenu::QCocoaMenu() :
QCocoaMenu::~QCocoaMenu()
{
+ foreach (QCocoaMenuItem *item, m_menuItems) {
+ if (COCOA_MENU_ANCESTOR(item) == this)
+ SET_COCOA_MENU_ANCESTOR(item, 0);
+ }
QCocoaAutoReleasePool pool;
[m_nativeItem setSubmenu:nil];
[m_nativeMenu release];
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 99d26034bf..9e748bff72 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -106,6 +106,8 @@ QCocoaMenuItem::QCocoaMenuItem() :
QCocoaMenuItem::~QCocoaMenuItem()
{
+ if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this)
+ SET_COCOA_MENU_ANCESTOR(m_menu, 0);
if (m_merged) {
[m_native setHidden:YES];
} else {
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
index 57d5c800e0..7322025df6 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -463,7 +463,11 @@ bool QCocoaPrintDevice::openPpdFile()
ppdClose(m_ppd);
m_ppd = 0;
CFURLRef ppdURL = NULL;
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+ char ppdPath[PATH_MAX];
+#else
char ppdPath[MAXPATHLEN];
+#endif
if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr
&& ppdURL != NULL
&& CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath))) {
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
index 439d31fb56..03997f2737 100644
--- a/src/plugins/platforms/direct2d/direct2d.pro
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -9,7 +9,7 @@ QT *= core-private
QT *= gui-private
QT *= platformsupport-private
-LIBS *= -ld2d1 -ld3d11 -ldwrite
+LIBS *= -ld2d1 -ld3d11 -ldwrite -lVersion
include(../windows/windows.pri)
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
index e4ce81bd24..be013f027b 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -66,6 +66,16 @@ static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p)
return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle());
}
+static inline QWindowsDirect2DBitmap *bitmap(QPixmap *p)
+{
+ return platformPixmap(p)->bitmap();
+}
+
+static inline QWindowsDirect2DWindow *nativeWindow(QWindow *window)
+{
+ return static_cast<QWindowsDirect2DWindow *>(window->handle());
+}
+
QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window)
: QPlatformBackingStore(window)
{
@@ -77,36 +87,40 @@ QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore()
void QWindowsDirect2DBackingStore::beginPaint(const QRegion &)
{
- platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->begin();
+ bitmap(nativeWindow(window())->pixmap())->deviceContext()->begin();
}
void QWindowsDirect2DBackingStore::endPaint()
{
- platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->end();
+ bitmap(nativeWindow(window())->pixmap())->deviceContext()->end();
}
QPaintDevice *QWindowsDirect2DBackingStore::paintDevice()
{
- return m_pixmap.data();
+ return nativeWindow(window())->pixmap();
}
-void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+void QWindowsDirect2DBackingStore::flush(QWindow *targetWindow, const QRegion &region, const QPoint &offset)
{
- QPlatformWindow *pw = window->handle();
- if (pw && m_pixmap)
- static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset);
+ if (targetWindow != window()) {
+ QSharedPointer<QWindowsDirect2DBitmap> copy(nativeWindow(window())->copyBackBuffer());
+ nativeWindow(targetWindow)->flush(copy.data(), region, offset);
+ }
+
+ nativeWindow(targetWindow)->present();
}
void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion &region)
{
- Q_UNUSED(region);
+ QPixmap old = nativeWindow(window())->pixmap()->copy();
- QScopedPointer<QPixmap> oldPixmap(m_pixmap.take());
- m_pixmap.reset(new QPixmap(size.width(), size.height()));
+ nativeWindow(window())->resizeSwapChain(size);
+ QPixmap *newPixmap = nativeWindow(window())->pixmap();
- if (oldPixmap) {
- foreach (const QRect &rect, region.rects())
- platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect);
+ if (!old.isNull()) {
+ foreach (const QRect &rect, region.rects()) {
+ platformPixmap(newPixmap)->copy(old.handle(), rect);
+ }
}
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
index fc6802aaa2..71e9437274 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -50,6 +50,8 @@
QT_BEGIN_NAMESPACE
+class QWindowsDirect2DWindow;
+
class QWindowsDirect2DBackingStore : public QPlatformBackingStore
{
Q_DISABLE_COPY(QWindowsDirect2DBackingStore)
@@ -62,11 +64,8 @@ public:
void endPaint();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void flush(QWindow *targetWindow, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
-
-private:
- QScopedPointer<QPixmap> m_pixmap;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
index 58002fb0dd..80688a1da7 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -99,7 +99,7 @@ public:
return false;
}
- hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
+ hr = dxgiDevice->GetAdapter(&dxgiAdapter);
if (FAILED(hr)) {
qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
return false;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index 1a26d7029e..44fc7aa927 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -48,7 +48,8 @@
#include "qwindowscontext.h"
-#include <QtCore/QDebug>
+#include <qplatformdefs.h>
+#include <QtCore/QCoreApplication>
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
@@ -61,8 +62,140 @@ public:
QWindowsDirect2DContext m_d2dContext;
};
+class Direct2DVersion
+{
+private:
+ Direct2DVersion()
+ : partOne(0)
+ , partTwo(0)
+ , partThree(0)
+ , partFour(0)
+ {}
+
+ Direct2DVersion(int one, int two, int three, int four)
+ : partOne(one)
+ , partTwo(two)
+ , partThree(three)
+ , partFour(four)
+ {}
+
+public:
+ // 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update
+ enum {
+ D2DMinVersionPart1 = 6,
+ D2DMinVersionPart2 = 2,
+ D2DMinVersionPart3 = 9200,
+ D2DMinVersionPart4 = 16765
+ };
+
+ static Direct2DVersion systemVersion() {
+ static const int bufSize = 512;
+ TCHAR filename[bufSize];
+
+ UINT i = GetSystemDirectory(filename, bufSize);
+ if (i > 0 && i < MAX_PATH) {
+ if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) {
+ DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
+ if (versionInfoSize) {
+ QVector<BYTE> info(versionInfoSize);
+ if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) {
+ UINT size;
+ DWORD *fi;
+
+ if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) {
+ VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi;
+ return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS),
+ LOWORD(verInfo->dwFileVersionMS),
+ HIWORD(verInfo->dwFileVersionLS),
+ LOWORD(verInfo->dwFileVersionLS));
+ }
+ }
+ }
+ }
+ }
+
+ return Direct2DVersion();
+ }
+
+ static Direct2DVersion minimumVersion() {
+ return Direct2DVersion(D2DMinVersionPart1,
+ D2DMinVersionPart2,
+ D2DMinVersionPart3,
+ D2DMinVersionPart4);
+ }
+
+ bool isValid() const {
+ return partOne || partTwo || partThree || partFour;
+ }
+
+ bool operator<(const Direct2DVersion &other) {
+ int c = cmp(partOne, other.partOne);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ c = cmp(partTwo, other.partTwo);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ c = cmp(partThree, other.partThree);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ c = cmp(partFour, other.partFour);
+ if (c > 0)
+ return false;
+ if (c < 0)
+ return true;
+
+ return false;
+ }
+
+ static Q_DECL_CONSTEXPR int cmp(int a, int b) {
+ return a - b;
+ }
+
+ int partOne, partTwo, partThree, partFour;
+};
+
QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
{
+ Direct2DVersion systemVersion = Direct2DVersion::systemVersion();
+
+ if (systemVersion.isValid() && systemVersion < Direct2DVersion::minimumVersion()) {
+ QString msg = QCoreApplication::translate("QWindowsDirect2DIntegration",
+ "Qt cannot load the direct2d platform plugin because " \
+ "the Direct2D version on this system is too old. The " \
+ "minimum system requirement for this platform plugin " \
+ "is Windows 7 SP1 with Platform Update.\n\n" \
+ "The minimum Direct2D version required is %1.%2.%3.%4. " \
+ "The Direct2D version on this system is %5.%6.%7.%8.");
+
+ msg = msg.arg(Direct2DVersion::D2DMinVersionPart1)
+ .arg(Direct2DVersion::D2DMinVersionPart2)
+ .arg(Direct2DVersion::D2DMinVersionPart3)
+ .arg(Direct2DVersion::D2DMinVersionPart4)
+ .arg(systemVersion.partOne)
+ .arg(systemVersion.partTwo)
+ .arg(systemVersion.partThree)
+ .arg(systemVersion.partFour);
+
+ QString caption = QCoreApplication::translate("QWindowsDirect2DIntegration",
+ "Cannot load direct2d platform plugin");
+
+ MessageBoxW(NULL,
+ msg.toStdWString().c_str(),
+ caption.toStdWString().c_str(),
+ MB_OK | MB_ICONERROR);
+
+ return Q_NULLPTR;
+ }
+
QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
if (!integration->init()) {
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index 58c30b6eeb..6e8d9b0baf 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -58,7 +58,6 @@
#include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qstatictext_p.h>
-#include <wrl.h>
using Microsoft::WRL::ComPtr;
QT_BEGIN_NAMESPACE
@@ -346,6 +345,8 @@ public:
QPointF currentBrushOrigin;
+ QHash< QFont, ComPtr<IDWriteFontFace> > fontCache;
+
struct {
bool emulate;
QPen qpen;
@@ -1291,44 +1292,6 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
}
}
-static ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe)
-{
- ComPtr<IDWriteFontFace> fontFace;
-
- switch (fe->type()) {
- case QFontEngine::Win:
- {
- QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
- QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
-
- HGDIOBJ oldfont = wfe->selectDesignFont();
- HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
- DeleteObject(SelectObject(wfed->hdc, oldfont));
- if (FAILED(hr))
- qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
-
- }
- break;
-
-#ifndef QT_NO_DIRECTWRITE
-
- case QFontEngine::DirectWrite:
- {
- QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
- fontFace = wfedw->directWriteFontFace();
- }
- break;
-
-#endif // QT_NO_DIRECTWRITE
-
- default:
- qWarning("%s: Unknown font engine!", __FUNCTION__);
- break;
- }
-
- return fontFace;
-}
-
void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticTextItem)
{
Q_D(QWindowsDirect2DPaintEngine);
@@ -1340,24 +1303,22 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText
ensurePen();
// If we can't support the current configuration with Direct2D, fall back to slow path
- // Most common cases are perspective transform and gradient brush as pen
- if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ if (emulationRequired(PenEmulation)) {
QPaintEngineEx::drawStaticTextItem(staticTextItem);
return;
}
- ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->fontEngine());
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->font, staticTextItem->fontEngine());
if (!fontFace) {
qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
QPaintEngineEx::drawStaticTextItem(staticTextItem);
return;
}
- QVector<UINT16> glyphIndices(staticTextItem->numGlyphs);
- QVector<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
- QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
+ QVarLengthArray<UINT16> glyphIndices(staticTextItem->numGlyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
- // XXX Are we generating a lot of cache misses here?
for (int i = 0; i < staticTextItem->numGlyphs; i++) {
glyphIndices[i] = UINT16(staticTextItem->glyphs[i]); // Imperfect conversion here
@@ -1390,24 +1351,22 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
ensurePen();
// If we can't support the current configuration with Direct2D, fall back to slow path
- // Most common cases are perspective transform and gradient brush as pen
- if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ if (emulationRequired(PenEmulation)) {
QPaintEngine::drawTextItem(p, textItem);
return;
}
- ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(ti.fontEngine);
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(*ti.f, ti.fontEngine);
if (!fontFace) {
qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
QPaintEngine::drawTextItem(p, textItem);
return;
}
- QVector<UINT16> glyphIndices(ti.glyphs.numGlyphs);
- QVector<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
- QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
+ QVarLengthArray<UINT16> glyphIndices(ti.glyphs.numGlyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
- // XXX Are we generating a lot of cache misses here?
for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
@@ -1618,4 +1577,49 @@ void QWindowsDirect2DPaintEngine::adjustForAliasing(QPointF *point)
(*point) += adjustment;
}
+Microsoft::WRL::ComPtr<IDWriteFontFace> QWindowsDirect2DPaintEngine::fontFaceFromFontEngine(const QFont &font, QFontEngine *fe)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ ComPtr<IDWriteFontFace> fontFace = d->fontCache.value(font);
+ if (fontFace)
+ return fontFace;
+
+ switch (fe->type()) {
+ case QFontEngine::Win:
+ {
+ QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
+ QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
+
+ HGDIOBJ oldfont = wfe->selectDesignFont();
+ HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
+ DeleteObject(SelectObject(wfed->hdc, oldfont));
+ if (FAILED(hr))
+ qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
+
+ }
+ break;
+
+#ifndef QT_NO_DIRECTWRITE
+
+ case QFontEngine::DirectWrite:
+ {
+ QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
+ fontFace = wfedw->directWriteFontFace();
+ }
+ break;
+
+#endif // QT_NO_DIRECTWRITE
+
+ default:
+ qWarning("%s: Unknown font engine!", __FUNCTION__);
+ break;
+ }
+
+ if (fontFace)
+ d->fontCache.insert(font, fontFace);
+
+ return fontFace;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
index badd7a7688..fb9b7acec3 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -47,6 +47,7 @@
#include <d2d1_1.h>
#include <dwrite_1.h>
+#include <wrl.h>
QT_BEGIN_NAMESPACE
@@ -114,6 +115,8 @@ private:
bool antiAliasingEnabled() const;
void adjustForAliasing(QRectF *rect);
void adjustForAliasing(QPointF *point);
+
+ Microsoft::WRL::ComPtr<IDWriteFontFace> fontFaceFromFontEngine(const QFont &font, QFontEngine *fe);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
index 072c4b3c0e..d9f7c595ca 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -56,12 +56,27 @@ class QWindowsDirect2DPlatformPixmapPrivate
{
public:
QWindowsDirect2DPlatformPixmapPrivate()
- : bitmap(new QWindowsDirect2DBitmap)
- , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap))
+ : owns_bitmap(true)
+ , bitmap(new QWindowsDirect2DBitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
, devicePixelRatio(1.0)
{}
- QScopedPointer<QWindowsDirect2DBitmap> bitmap;
+ QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap)
+ : owns_bitmap(false)
+ , bitmap(bitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
+ , devicePixelRatio(1.0)
+ {}
+
+ ~QWindowsDirect2DPlatformPixmapPrivate()
+ {
+ if (owns_bitmap)
+ delete bitmap;
+ }
+
+ bool owns_bitmap;
+ QWindowsDirect2DBitmap *bitmap;
QScopedPointer<QWindowsDirect2DPaintDevice> device;
qreal devicePixelRatio;
};
@@ -75,6 +90,19 @@ QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelTy
setSerialNumber(qt_d2dpixmap_serno++);
}
+QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixelType pixelType,
+ QWindowsDirect2DBitmap *bitmap)
+ : QPlatformPixmap(pixelType, Direct2DClass)
+ , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate(bitmap))
+{
+ setSerialNumber(qt_d2dpixmap_serno++);
+
+ is_null = false;
+ w = bitmap->size().width();
+ h = bitmap->size().height();
+ this->d = 32;
+}
+
QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap()
{
@@ -173,7 +201,7 @@ void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const
{
Q_D(const QWindowsDirect2DPlatformPixmap);
- return d->bitmap.data();
+ return d->bitmap;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
index e6684ea423..1936ef0622 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -55,6 +55,9 @@ class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap
Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap)
public:
QWindowsDirect2DPlatformPixmap(PixelType pixelType);
+
+ // We do NOT take ownership of the bitmap through this constructor!
+ QWindowsDirect2DPlatformPixmap(PixelType pixelType, QWindowsDirect2DBitmap *bitmap);
~QWindowsDirect2DPlatformPixmap();
virtual void resize(int width, int height);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
index 50d0cb81f5..15ec0c3526 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -43,6 +43,7 @@
#include "qwindowsdirect2dwindow.h"
#include "qwindowsdirect2ddevicecontext.h"
#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dplatformpixmap.h"
#include <d3d11.h>
#include <d2d1_1.h>
@@ -87,6 +88,13 @@ QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
{
}
+QPixmap *QWindowsDirect2DWindow::pixmap()
+{
+ setupBitmap();
+
+ return m_pixmap.data();
+}
+
void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset)
{
DXGI_SWAP_CHAIN_DESC1 desc;
@@ -102,32 +110,38 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion
if (!m_bitmap)
return;
- m_bitmap->deviceContext()->begin();
-
- ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
- if (!m_needsFullFlush) {
- QRegion clipped = region;
- clipped &= QRect(0, 0, desc.Width, desc.Height);
-
- foreach (const QRect &rect, clipped.rects()) {
- QRectF rectF(rect);
+ if (bitmap != m_bitmap.data()) {
+ m_bitmap->deviceContext()->begin();
+
+ ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
+ if (!m_needsFullFlush) {
+ QRegion clipped = region;
+ clipped &= QRect(0, 0, desc.Width, desc.Height);
+
+ foreach (const QRect &rect, clipped.rects()) {
+ QRectF rectF(rect);
+ dc->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(rectF),
+ 1.0,
+ D2D1_INTERPOLATION_MODE_LINEAR,
+ to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ }
+ } else {
+ QRectF rectF(0, 0, desc.Width, desc.Height);
dc->DrawBitmap(bitmap->bitmap(),
to_d2d_rect_f(rectF),
1.0,
D2D1_INTERPOLATION_MODE_LINEAR,
to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ m_needsFullFlush = false;
}
- } else {
- QRectF rectF(0, 0, desc.Width, desc.Height);
- dc->DrawBitmap(bitmap->bitmap(),
- to_d2d_rect_f(rectF),
- 1.0,
- D2D1_INTERPOLATION_MODE_LINEAR,
- to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
- m_needsFullFlush = false;
+
+ m_bitmap->deviceContext()->end();
}
+}
- m_bitmap->deviceContext()->end();
+void QWindowsDirect2DWindow::present()
+{
m_swapChain->Present(0, 0);
}
@@ -136,6 +150,7 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
if (!m_swapChain)
return;
+ m_pixmap.reset();
m_bitmap.reset();
m_deviceContext->SetTarget(Q_NULLPTR);
@@ -149,6 +164,43 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
m_needsFullFlush = true;
}
+QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const
+{
+ const QSharedPointer<QWindowsDirect2DBitmap> null_result;
+
+ if (!m_bitmap)
+ return null_result;
+
+ D2D1_PIXEL_FORMAT format = m_bitmap->bitmap()->GetPixelFormat();
+ D2D1_SIZE_U size = m_bitmap->bitmap()->GetPixelSize();
+
+ FLOAT dpiX, dpiY;
+ m_bitmap->bitmap()->GetDpi(&dpiX, &dpiY);
+
+ D2D1_BITMAP_PROPERTIES1 properties = {
+ format, // D2D1_PIXEL_FORMAT pixelFormat;
+ dpiX, // FLOAT dpiX;
+ dpiY, // FLOAT dpiY;
+ D2D1_BITMAP_OPTIONS_TARGET, // D2D1_BITMAP_OPTIONS bitmapOptions;
+ Q_NULLPTR // _Field_size_opt_(1) ID2D1ColorContext *colorContext;
+ };
+ ComPtr<ID2D1Bitmap1> copy;
+ HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, &copy);
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr);
+ return null_result;
+ }
+
+ hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr);
+ return null_result;
+ }
+
+ return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), Q_NULLPTR));
+}
+
void QWindowsDirect2DWindow::setupBitmap()
{
if (m_bitmap)
@@ -175,6 +227,10 @@ void QWindowsDirect2DWindow::setupBitmap()
}
m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get()));
+
+ QWindowsDirect2DPlatformPixmap *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType,
+ m_bitmap.data());
+ m_pixmap.reset(new QPixmap(pp));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
index 7996904639..47c790da5d 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
@@ -56,16 +56,21 @@ public:
QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data);
~QWindowsDirect2DWindow();
+ QPixmap *pixmap();
void flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset);
+ void present();
+ void resizeSwapChain(const QSize &size);
+
+ QSharedPointer<QWindowsDirect2DBitmap> copyBackBuffer() const;
private:
- void resizeSwapChain(const QSize &size);
void setupBitmap();
private:
Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
+ QScopedPointer<QPixmap> m_pixmap;
bool m_needsFullFlush;
};
diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm
index 8d77e608e5..afa3ecb21f 100644
--- a/src/plugins/platforms/ios/qiosapplicationstate.mm
+++ b/src/plugins/platforms/ios/qiosapplicationstate.mm
@@ -150,6 +150,7 @@
break;
}
QWindowSystemInterface::handleApplicationStateChanged(state);
+ QWindowSystemInterface::flushWindowSystemEvents();
}
@end
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index fc99543aa6..6b6892e6e4 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -88,6 +88,7 @@ public:
WId winId() const { return WId(m_view); };
private:
+ void applicationStateChanged(Qt::ApplicationState state);
void applyGeometry(const QRect &rect);
QUIView *m_view;
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 7d5c507972..6f5c96cfc1 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -192,12 +192,25 @@
- (void)displayLayer:(CALayer *)layer
{
- QSize bounds = fromCGRect(layer.bounds).toRect().size();
+ Q_UNUSED(layer);
+ Q_ASSERT(layer == self.layer);
- Q_ASSERT(m_qioswindow->geometry().size() == bounds);
- Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());
+ [self sendUpdatedExposeEvent];
+}
+
+- (void)sendUpdatedExposeEvent
+{
+ QRegion region;
+
+ if (m_qioswindow->isExposed()) {
+ QSize bounds = fromCGRect(self.layer.bounds).toRect().size();
+
+ Q_ASSERT(m_qioswindow->geometry().size() == bounds);
+ Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());
+
+ region = QRect(QPoint(), bounds);
+ }
- QRegion region = self.hidden ? QRegion() : QRect(QPoint(), bounds);
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
QWindowSystemInterface::flushWindowSystemEvents();
}
@@ -279,19 +292,33 @@
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
- if (!touches && m_activeTouches.isEmpty())
+ if (m_activeTouches.isEmpty())
return;
- if (!touches) {
- m_activeTouches.clear();
- } else {
- for (UITouch *touch in touches)
- m_activeTouches.remove(touch);
-
- Q_ASSERT_X(m_activeTouches.isEmpty(), Q_FUNC_INFO,
- "Subset of active touches cancelled by UIKit");
- }
-
+ // When four-finger swiping, we get a touchesCancelled callback
+ // which includes all four touch points. The swipe gesture is
+ // then active until all four touches have been released, and
+ // we start getting touchesBegan events again.
+
+ // When five-finger pinching, we also get a touchesCancelled
+ // callback with all five touch points, but the pinch gesture
+ // ends when the second to last finger is released from the
+ // screen. The last finger will not emit any more touch
+ // events, _but_, will contribute to starting another pinch
+ // gesture. That second pinch gesture will _not_ trigger a
+ // touchesCancelled event when starting, but as each finger
+ // is released, and we may get touchesMoved events for the
+ // remaining fingers. [event allTouches] also contains one
+ // less touch point than it should, so this behavior is
+ // likely a bug in the iOS system gesture recognizer, but we
+ // have to take it into account when maintaining the Qt state.
+ // We do this by assuming that there are no cases where a
+ // sub-set of the active touch events are intentionally cancelled.
+
+ if (touches && (static_cast<NSInteger>([touches count]) != m_activeTouches.count()))
+ qWarning("Subset of active touches cancelled by UIKit");
+
+ m_activeTouches.clear();
m_nextTouchId = 0;
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
@@ -334,6 +361,8 @@ QIOSWindow::QIOSWindow(QWindow *window)
, m_view([[QUIView alloc] initWithQIOSWindow:this])
, m_windowLevel(0)
{
+ connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged);
+
setParent(QPlatformWindow::parent());
// Resolve default window geometry in case it was not set before creating the
@@ -471,7 +500,8 @@ void QIOSWindow::applyGeometry(const QRect &rect)
bool QIOSWindow::isExposed() const
{
- return window()->isVisible() && !window()->geometry().isEmpty();
+ return qApp->applicationState() > Qt::ApplicationHidden
+ && window()->isVisible() && !window()->geometry().isEmpty();
}
void QIOSWindow::setWindowState(Qt::WindowState state)
@@ -593,6 +623,12 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio
[[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO];
}
+void QIOSWindow::applicationStateChanged(Qt::ApplicationState)
+{
+ if (window()->isExposed() != isExposed())
+ [m_view sendUpdatedExposeEvent];
+}
+
qreal QIOSWindow::devicePixelRatio() const
{
return m_view.contentScaleFactor;
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
index 1e08c6f301..8e669fe7d5 100644
--- a/src/plugins/platforms/kms/qkmsdevice.cpp
+++ b/src/plugins/platforms/kms/qkmsdevice.cpp
@@ -85,8 +85,7 @@ QKmsDevice::~QKmsDevice()
void QKmsDevice::createScreens()
{
- drmModeRes *resources = 0;
- resources = drmModeGetResources(m_fd);
+ drmModeRes *resources = drmModeGetResources(m_fd);
if (!resources)
qFatal("drmModeGetResources failed");
@@ -95,7 +94,7 @@ void QKmsDevice::createScreens()
drmModeConnector *connector = 0;
connector = drmModeGetConnector(m_fd, resources->connectors[i]);
if (connector && connector->connection == DRM_MODE_CONNECTED) {
- m_integration->addScreen(new QKmsScreen(this, connector->connector_id));
+ m_integration->addScreen(new QKmsScreen(this, resources, connector));
}
drmModeFreeConnector(connector);
}
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
index ad1a45b459..a930aa6545 100644
--- a/src/plugins/platforms/kms/qkmsscreen.cpp
+++ b/src/plugins/platforms/kms/qkmsscreen.cpp
@@ -63,18 +63,18 @@ static drmModeModeInfo builtin_1024x768 = {
"1024x768"
};
-QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId)
+QKmsScreen::QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector)
: m_device(device),
m_current_bo(0),
m_next_bo(0),
- m_connectorId(connectorId),
+ m_connectorId(connector->connector_id),
m_depth(32),
m_format(QImage::Format_Invalid),
m_eglWindowSurface(EGL_NO_SURFACE),
m_modeSet(false)
{
m_cursor = new QKmsCursor(this);
- initializeScreenMode();
+ initializeScreenMode(resources, connector);
}
QKmsScreen::~QKmsScreen()
@@ -114,14 +114,9 @@ QPlatformCursor *QKmsScreen::cursor() const
return m_cursor;
}
-void QKmsScreen::initializeScreenMode()
+void QKmsScreen::initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector)
{
//Determine optimal mode for screen
- drmModeRes *resources = drmModeGetResources(m_device->fd());
- if (!resources)
- qFatal("drmModeGetResources failed");
-
- drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
drmModeModeInfo *mode = 0;
for (int i = 0; i < connector->count_modes; ++i) {
if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
@@ -129,8 +124,12 @@ void QKmsScreen::initializeScreenMode()
break;
}
}
- if (!mode)
- mode = &builtin_1024x768;
+ if (!mode) {
+ if (connector->count_modes > 0)
+ mode = &connector->modes[0];
+ else
+ mode = &builtin_1024x768;
+ }
drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
if (encoder == 0)
@@ -162,8 +161,6 @@ void QKmsScreen::initializeScreenMode()
qDebug() << "created gbm surface" << m_gbmSurface << m_mode.hdisplay << m_mode.vdisplay;
//Cleanup
drmModeFreeEncoder(encoder);
- drmModeFreeConnector(connector);
- drmModeFreeResources(resources);
}
QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format)
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
index 5ae5a1062b..1fa8dbb763 100644
--- a/src/plugins/platforms/kms/qkmsscreen.h
+++ b/src/plugins/platforms/kms/qkmsscreen.h
@@ -68,7 +68,7 @@ class QKmsContext;
class QKmsScreen : public QPlatformScreen
{
public:
- QKmsScreen(QKmsDevice *device, int connectorId);
+ QKmsScreen(QKmsDevice *device, const drmModeRes *resources, const drmModeConnector *connector);
~QKmsScreen();
QRect geometry() const;
@@ -94,7 +94,7 @@ public:
private:
void performPageFlip();
- void initializeScreenMode();
+ void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector);
QKmsDevice *m_device;
gbm_bo *m_current_bo;
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 1abf447709..34a9c1df5f 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -145,9 +145,8 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
<< " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
- QImage::Format format = QWindowsNativeImage::systemFormat();
- if (format == QImage::Format_RGB32 && window()->format().hasAlpha())
- format = QImage::Format_ARGB32_Premultiplied;
+ const QImage::Format format = window()->format().hasAlpha() ?
+ QImage::Format_ARGB32_Premultiplied : QWindowsNativeImage::systemFormat();
QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 29c43fc7a5..6f97c8584b 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -169,6 +169,20 @@ bool QWindowsFontEngine::hasCMapTable() const
return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR;
}
+bool QWindowsFontEngine::hasGlyfTable() const
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ return GetFontData(hdc, MAKE_TAG('g', 'l', 'y', 'f'), 0, 0, 0) != GDI_ERROR;
+}
+
+bool QWindowsFontEngine::hasEbdtTable() const
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ return GetFontData(hdc, MAKE_TAG('E', 'B', 'D', 'T'), 0, 0, 0) != GDI_ERROR;
+}
+
void QWindowsFontEngine::getCMap()
{
ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable();
@@ -308,6 +322,8 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont));
userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf)));
setUserData(userData);
+
+ hasUnreliableOutline = hasGlyfTable() && hasEbdtTable();
}
QWindowsFontEngine::~QWindowsFontEngine()
@@ -662,6 +678,11 @@ void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qre
}
#endif // Q_CC_MINGW
+bool QWindowsFontEngine::hasUnreliableGlyphOutline() const
+{
+ return hasUnreliableOutline;
+}
+
qreal QWindowsFontEngine::minLeftBearing() const
{
if (lbearing == SHRT_MIN)
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 7a0803830c..0ddf778fa0 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -122,6 +122,8 @@ public:
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
+ bool hasUnreliableGlyphOutline() const Q_DECL_OVERRIDE;
+
int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
void getCMap();
@@ -136,6 +138,8 @@ private:
QImage::Format mask_format);
bool hasCFFTable() const;
bool hasCMapTable() const;
+ bool hasGlyfTable() const;
+ bool hasEbdtTable() const;
const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
@@ -146,6 +150,7 @@ private:
uint stockFont : 1;
uint ttf : 1;
uint hasOutline : 1;
+ uint hasUnreliableOutline : 1;
uint cffTable : 1;
TEXTMETRIC tm;
int lw;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 583441f396..773220660a 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -496,6 +496,7 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
// Set initial orientation
onOrientationChanged(0);
+ setOrientationUpdateMask(m_nativeOrientation);
m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
&m_tokens[QEvent::OrientationChange]);
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index 30d5c911e7..7304930b8b 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -419,7 +419,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
return;
}
m_format = QSurfaceFormat();
- m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL
+ m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL
? QSurfaceFormat::OpenGL : QSurfaceFormat::OpenGLES);
updateFormatFromContext(m_format);
if (vinfo)
diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
index 19852b74b1..dfdcb2e83a 100644
--- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
+++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
@@ -3,9 +3,8 @@
# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image,
# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb
#
-TEMPLATE = lib
-TARGET = xcb-static
-CONFIG += staticlib
+CONFIG += static
+load(qt_helper_lib)
XCB_DIR = ../../../../3rdparty/xcb
diff --git a/src/plugins/printsupport/printsupport.pro b/src/plugins/printsupport/printsupport.pro
index 93f3d65bc5..ed201f0744 100644
--- a/src/plugins/printsupport/printsupport.pro
+++ b/src/plugins/printsupport/printsupport.pro
@@ -1,5 +1,5 @@
TEMPLATE = subdirs
-mac: SUBDIRS += cocoa
+osx: SUBDIRS += cocoa
win32: SUBDIRS += windows
unix:!mac:contains(QT_CONFIG, cups): SUBDIRS += cups