summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp21
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp20
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamimetypes.mm129
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp8
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp88
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h7
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm2
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp25
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp62
13 files changed, 253 insertions, 119 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index a38741cc91..fa7e259460 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -170,7 +170,7 @@ if (!clazz) { \
jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
if (!method) { \
__android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
- return; \
+ return false; \
} \
env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \
}
@@ -190,12 +190,12 @@ if (!clazz) { \
return jdesc;
}
- static void populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
+ static bool populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node)
{
QAccessibleInterface *iface = interfaceFromId(objectId);
if (!iface || !iface->isValid()) {
__android_log_print(ANDROID_LOG_WARN, m_qtTag, "Accessibility: populateNode for Invalid ID");
- return;
+ return false;
}
QAccessible::State state = iface->state();
@@ -215,11 +215,10 @@ if (!clazz) { \
}
CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
- //CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable)
- CALL_METHOD(node, "setFocusable", "(Z)V", true)
- //CALL_METHOD(node, "setFocused", "(Z)V", state.focused)
- CALL_METHOD(node, "setCheckable", "(Z)V", state.checkable)
- CALL_METHOD(node, "setChecked", "(Z)V", state.checked)
+ CALL_METHOD(node, "setFocusable", "(Z)V", (bool)state.focusable)
+ CALL_METHOD(node, "setFocused", "(Z)V", (bool)state.focused)
+ CALL_METHOD(node, "setCheckable", "(Z)V", (bool)state.checkable)
+ CALL_METHOD(node, "setChecked", "(Z)V", (bool)state.checked)
CALL_METHOD(node, "setVisibleToUser", "(Z)V", !state.invisible)
if (iface->actionInterface()) {
@@ -227,7 +226,7 @@ if (!clazz) { \
bool clickable = actions.contains(QAccessibleActionInterface::pressAction());
bool toggle = actions.contains(QAccessibleActionInterface::toggleAction());
if (clickable || toggle) {
- CALL_METHOD(node, "setClickable", "(Z)V", clickable)
+ CALL_METHOD(node, "setClickable", "(Z)V", (bool)clickable)
CALL_METHOD(node, "addAction", "(I)V", 16) // ACTION_CLICK defined in AccessibilityNodeInfo
}
}
@@ -235,6 +234,8 @@ if (!clazz) { \
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
//CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc)
+
+ return true;
}
static JNINativeMethod methods[] = {
@@ -244,7 +245,7 @@ if (!clazz) { \
{"descriptionForAccessibleObject", "(I)Ljava/lang/String;", (jstring)descriptionForAccessibleObject},
{"screenRect", "(I)Landroid/graphics/Rect;", (jobject)screenRect},
{"hitTest", "(FF)I", (void*)hitTest},
- {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)V", (void*)populateNode},
+ {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)Z", (void*)populateNode},
{"clickAction", "(I)Z", (void*)clickAction},
};
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 2998762cc3..7ca4db710b 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -463,17 +463,19 @@ static void *startMainMethod(void */*data*/)
static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString)
{
m_mainLibraryHnd = NULL;
- const char *nativeString = env->GetStringUTFChars(environmentString, 0);
- QByteArray string = nativeString;
- env->ReleaseStringUTFChars(environmentString, nativeString);
- m_applicationParams=string.split('\t');
- foreach (string, m_applicationParams) {
- if (!string.isEmpty() && putenv(string.constData()))
- qWarning() << "Can't set environment" << string;
+ { // Set env. vars
+ const char *nativeString = env->GetStringUTFChars(environmentString, 0);
+ const QList<QByteArray> envVars = QByteArray(nativeString).split('\t');
+ env->ReleaseStringUTFChars(environmentString, nativeString);
+ foreach (const QByteArray &envVar, envVars) {
+ const QList<QByteArray> envVarPair = envVar.split('=');
+ if (envVarPair.size() == 2 && ::setenv(envVarPair[0], envVarPair[1], 1) != 0)
+ qWarning() << "Can't set environment" << envVarPair;
+ }
}
- nativeString = env->GetStringUTFChars(paramsString, 0);
- string = nativeString;
+ const char *nativeString = env->GetStringUTFChars(paramsString, 0);
+ QByteArray string = nativeString;
env->ReleaseStringUTFChars(paramsString, nativeString);
m_applicationParams=string.split('\t');
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 7423e6c55a..935caed467 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
@@ -82,7 +82,7 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami
Q_UNUSED(family);
Q_UNUSED(style);
- if (styleHint == QFont::Monospace)
+ if (styleHint == QFont::Monospace || styleHint == QFont::Courier)
return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";") + m_fallbacks[script];
return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script];
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 9e748bff72..32692edde4 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -119,7 +119,7 @@ QCocoaMenuItem::~QCocoaMenuItem()
void QCocoaMenuItem::setText(const QString &text)
{
- m_text = qt_mac_removeAmpersandEscapes(text);
+ m_text = text;
}
void QCocoaMenuItem::setIcon(const QIcon &icon)
diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
index 8151d31449..421d934fa7 100644
--- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm
+++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
@@ -45,6 +45,67 @@
QT_BEGIN_NAMESPACE
+class QMacPasteboardMimeTraditionalMacPlainText : public QMacInternalPasteboardMime {
+public:
+ QMacPasteboardMimeTraditionalMacPlainText() : 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 QMacPasteboardMimeTraditionalMacPlainText::convertorName()
+{
+ return QLatin1String("PlainText (traditional-mac-plain-text)");
+}
+
+QString QMacPasteboardMimeTraditionalMacPlainText::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/plain"))
+ return QLatin1String("com.apple.traditional-mac-plain-text");
+ return QString();
+}
+
+QString QMacPasteboardMimeTraditionalMacPlainText::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("com.apple.traditional-mac-plain-text"))
+ return QLatin1String("text/plain");
+ return QString();
+}
+
+bool QMacPasteboardMimeTraditionalMacPlainText::canConvert(const QString &mime, QString flav)
+{
+ return flavorFor(mime) == flav;
+}
+
+QVariant QMacPasteboardMimeTraditionalMacPlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
+{
+ if (data.count() > 1)
+ qWarning("QMacPasteboardMimeTraditionalMacPlainText: Cannot handle multiple member data");
+ const QByteArray &firstData = data.first();
+ QVariant ret;
+ if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) {
+ return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault,
+ reinterpret_cast<const UInt8 *>(firstData.constData()),
+ firstData.size(), CFStringGetSystemEncoding(), false));
+ } else {
+ qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
+ }
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimeTraditionalMacPlainText::convertFromMime(const QString &, QVariant data, QString flavor)
+{
+ QList<QByteArray> ret;
+ QString string = data.toString();
+ if (flavor == QLatin1String("com.apple.traditional-mac-plain-text"))
+ ret.append(string.toLatin1());
+ return ret;
+}
+
class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime {
public:
QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { }
@@ -136,76 +197,10 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q
return ret;
}
-// This handler is special: It supports converting public.rtf top text/html,
-// but not the other way around.
-class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime {
-public:
- QMacPasteboardMimeRtfText() : 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 QMacPasteboardMimeRtfText::convertorName()
-{
- return QLatin1String("Rtf");
-}
-
-QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime)
-{
- if (mime == QLatin1String("text/html"))
- return QLatin1String("public.rtf");
- return QString();
-}
-
-QString QMacPasteboardMimeRtfText::mimeFor(QString flav)
-{
- if (flav == QLatin1String("public.rtf"))
- return QLatin1String("text/html");
- return QString();
-}
-
-bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav)
-{
- return flavorFor(mime) == flav;
-}
-
-QVariant QMacPasteboardMimeRtfText::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");
-
- // Convert Rtf to Html.
- NSAttributedString *string = [[NSAttributedString alloc] initWithRTF:data.at(0).toNSData() documentAttributes:NULL];
- NSError *error;
- NSRange range = NSMakeRange(0,[string length]);
- NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
- NSData *htmldata = [string dataFromRange:range documentAttributes:dict error:&error];
- [string release];
- return QByteArray::fromNSData(htmldata);
-}
-
-QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor)
-{
- Q_UNUSED(mime);
- Q_UNUSED(data);
- Q_UNUSED(flavor);
-
- qWarning("QMacPasteboardMimeRtfText: Conversion from Html to Rtf is not supported");
- QList<QByteArray> ret;
- return ret;
-}
-
void QCocoaMimeTypes::initializeMimeTypes()
{
+ new QMacPasteboardMimeTraditionalMacPlainText;
new QMacPasteboardMimeTiff;
- new QMacPasteboardMimeRtfText;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 60152b56b2..651fedb26e 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1620,6 +1620,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
if (!m_drawContentBorderGradient) {
[window setStyleMask:[window styleMask] & ~NSTexturedBackgroundWindowMask];
+ [[[window contentView] superview] setNeedsDisplay:YES];
return;
}
@@ -1650,6 +1651,8 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
[window setContentBorderThickness:effectiveBottomContentBorderThickness forEdge:NSMinYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
+
+ [[[window contentView] superview] setNeedsDisplay:YES];
}
void QCocoaWindow::updateNSToolbar()
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index 9833d50e6c..0e38f9b12a 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -80,12 +80,12 @@ private:
{}
public:
- // 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update
+ // 6.2.9200.16492 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update
enum {
D2DMinVersionPart1 = 6,
D2DMinVersionPart2 = 2,
D2DMinVersionPart3 = 9200,
- D2DMinVersionPart4 = 16765
+ D2DMinVersionPart4 = 16492
};
static Direct2DVersion systemVersion() {
@@ -93,8 +93,8 @@ public:
TCHAR filename[bufSize];
UINT i = GetSystemDirectory(filename, bufSize);
- if (i > 0 && i < MAX_PATH) {
- if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) {
+ if (i > 0 && i < bufSize) {
+ if (_tcscat_s(filename, bufSize, __TEXT("\\d2d1.dll")) == 0) {
DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (versionInfoSize) {
QVector<BYTE> info(versionInfoSize);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index ca2dcf908d..a838950c9e 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -592,9 +592,13 @@ public:
props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ
props.dashOffset = newPen.dashOffset();
- props.transformType = qIsNull(newPen.widthF()) ? D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE
- : newPen.isCosmetic() ? D2D1_STROKE_TRANSFORM_TYPE_FIXED
- : D2D1_STROKE_TRANSFORM_TYPE_NORMAL;
+
+ if (newPen.widthF() == 0)
+ props.transformType = D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE;
+ else if (qt_pen_is_cosmetic(newPen, q->state()->renderHints))
+ props.transformType = D2D1_STROKE_TRANSFORM_TYPE_FIXED;
+ else
+ props.transformType = D2D1_STROKE_TRANSFORM_TYPE_NORMAL;
switch (newPen.style()) {
case Qt::SolidLine:
@@ -930,6 +934,33 @@ void QWindowsDirect2DPaintEngine::setState(QPainterState *s)
transformChanged();
}
+void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ if (!geometry) {
+ qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
+ return;
+ }
+
+ const QBrush &brush = state()->brush;
+ if (qbrush_style(brush) != Qt::NoBrush) {
+ if (emulationRequired(BrushEmulation))
+ rasterFill(path, brush);
+ else
+ fill(geometry.Get(), brush);
+ }
+
+ const QPen &pen = state()->pen;
+ if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) {
+ if (emulationRequired(PenEmulation))
+ QPaintEngineEx::stroke(path, pen);
+ else
+ stroke(geometry.Get(), pen);
+ }
+}
+
void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
{
Q_D(QWindowsDirect2DPaintEngine);
@@ -939,7 +970,6 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
return;
ensureBrush(brush);
-
if (emulationRequired(BrushEmulation)) {
rasterFill(path, brush);
return;
@@ -957,6 +987,56 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get());
}
+void QWindowsDirect2DPaintEngine::fill(ID2D1Geometry *geometry, const QBrush &brush)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugFillTag);
+
+ ensureBrush(brush);
+ if (!d->brush.brush)
+ return;
+
+ d->dc()->FillGeometry(geometry, d->brush.brush.Get());
+}
+
+void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugFillTag);
+
+ if (path.isEmpty())
+ return;
+
+ ensurePen(pen);
+ if (emulationRequired(PenEmulation)) {
+ QPaintEngineEx::stroke(path, pen);
+ return;
+ }
+
+ if (!d->pen.brush)
+ return;
+
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ if (!geometry) {
+ qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
+ return;
+ }
+
+ d->dc()->DrawGeometry(geometry.Get(), d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+}
+
+void QWindowsDirect2DPaintEngine::stroke(ID2D1Geometry *geometry, const QPen &pen)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugFillTag);
+
+ ensurePen(pen);
+ if (!d->pen.brush)
+ return;
+
+ d->dc()->DrawGeometry(geometry, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+}
+
void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
{
Q_D(QWindowsDirect2DPaintEngine);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
index fb9b7acec3..c91a951ebe 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -68,7 +68,14 @@ public:
void setState(QPainterState *s) Q_DECL_OVERRIDE;
+ void draw(const QVectorPath &path) Q_DECL_OVERRIDE;
+
void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
+ void fill(ID2D1Geometry *geometry, const QBrush &brush);
+
+ void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE;
+ void stroke(ID2D1Geometry *geometry, const QPen &pen);
+
void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
void clipEnabledChanged() Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
index 3f6c6d1256..79e3897013 100644
--- a/src/plugins/platforms/ios/quiview_textinput.mm
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -253,7 +253,7 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
- (UITextRange *)selectedTextRange {
int cursorPos = [self imValue:Qt::ImCursorPosition].toInt();
int anchorPos = [self imValue:Qt::ImAnchorPosition].toInt();
- return [QUITextRange rangeWithNSRange:NSMakeRange(cursorPos, (anchorPos - cursorPos))];
+ return [QUITextRange rangeWithNSRange:NSMakeRange(qMin(cursorPos, anchorPos), qAbs(anchorPos - cursorPos))];
}
- (NSString *)textInRange:(UITextRange *)range
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 63615dd4bf..322bae10aa 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -741,6 +741,27 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn,
HWND_MESSAGE, NULL, (HINSTANCE)GetModuleHandle(0), NULL);
}
+#ifndef Q_OS_WINCE
+// Re-engineered from the inline function _com_error::ErrorMessage().
+// We cannot use it directly since it uses swprintf_s(), which is not
+// present in the MSVCRT.DLL found on Windows XP (QTBUG-35617).
+static inline QString errorMessageFromComError(const _com_error &comError)
+{
+ TCHAR *message = Q_NULLPTR;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, comError.Error(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
+ message, 0, NULL);
+ if (message) {
+ const QString result = QString::fromWCharArray(message).trimmed();
+ LocalFree((HLOCAL)message);
+ return result;
+ }
+ if (const WORD wCode = comError.WCode())
+ return QStringLiteral("IDispatch error #") + QString::number(wCode);
+ return QStringLiteral("Unknown error 0x0") + QString::number(comError.Error(), 16);
+}
+#endif // !Q_OS_WINCE
+
/*!
\brief Common COM error strings.
*/
@@ -807,7 +828,7 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr)
#ifndef Q_OS_WINCE
_com_error error(hr);
result += QByteArrayLiteral(" (");
- result += QString::fromWCharArray(error.ErrorMessage()).toLocal8Bit();
+ result += errorMessageFromComError(error);
result += ')';
#endif // !Q_OS_WINCE
return result;
@@ -876,7 +897,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
// TODO: Release/regrab mouse if a popup has mouse grab.
return false;
case QtWindows::DestroyEvent:
- if (!platformWindow->testFlag(QWindowsWindow::WithinDestroy)) {
+ if (platformWindow && !platformWindow->testFlag(QWindowsWindow::WithinDestroy)) {
qWarning() << "External WM_DESTROY received for " << platformWindow->window()
<< ", parent: " << platformWindow->window()->parent()
<< ", transient parent: " << platformWindow->window()->transientParent();
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 52825ebc6d..f081bbd307 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -165,6 +165,9 @@ namespace {
Q_ASSERT(tagName.size() == 4);
quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData()));
+ if (m_fontData.size() < sizeof(OffsetSubTable) + sizeof(TableDirectory))
+ return 0;
+
OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index efa1691780..eb7b220c43 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -148,15 +148,17 @@ void QXcbConnection::initializeXInput2()
}
case XIButtonClass: {
XIButtonClassInfo *bci = reinterpret_cast<XIButtonClassInfo *>(devices[i].classes[c]);
- for (int i=0; i < bci->num_buttons; ++i) {
- const int buttonAtom = qatom(bci->labels[i]);
- if (buttonAtom == QXcbAtom::ButtonWheelUp
- || buttonAtom == QXcbAtom::ButtonWheelDown) {
+ if (bci->num_buttons >= 5) {
+ Atom label4 = bci->labels[3];
+ Atom label5 = bci->labels[4];
+ if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp) && (!label5 || qatom(label5) == QXcbAtom::ButtonWheelDown))
scrollingDevice.legacyOrientations |= Qt::Vertical;
- } else if (buttonAtom == QXcbAtom::ButtonHorizWheelLeft
- || buttonAtom == QXcbAtom::ButtonHorizWheelRight) {
+ }
+ if (bci->num_buttons >= 7) {
+ Atom label6 = bci->labels[5];
+ Atom label7 = bci->labels[6];
+ if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight))
scrollingDevice.legacyOrientations |= Qt::Horizontal;
- }
}
break;
}
@@ -246,6 +248,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
}
#endif // XCB_USE_XINPUT22
+ QSet<int> tabletDevices;
#ifndef QT_NO_TABLETEVENT
// For each tablet, select some additional event types.
// Press, motion, etc. events must never be selected for _all_ devices
@@ -253,15 +256,19 @@ void QXcbConnection::xi2Select(xcb_window_t window)
// similar handlers useless and we have no intention to infect
// all the pure xcb code with Xlib-based XI2.
if (!m_tabletData.isEmpty()) {
+ unsigned int tabletBitMask = bitMask;
+ unsigned char *xiTabletBitMask = reinterpret_cast<unsigned char *>(&tabletBitMask);
QVector<XIEventMask> xiEventMask(m_tabletData.count());
- bitMask |= XI_ButtonPressMask;
- bitMask |= XI_ButtonReleaseMask;
- bitMask |= XI_MotionMask;
- bitMask |= XI_PropertyEventMask;
+ tabletBitMask |= XI_ButtonPressMask;
+ tabletBitMask |= XI_ButtonReleaseMask;
+ tabletBitMask |= XI_MotionMask;
+ tabletBitMask |= XI_PropertyEventMask;
for (int i = 0; i < m_tabletData.count(); ++i) {
- xiEventMask[i].deviceid = m_tabletData.at(i).deviceId;
- xiEventMask[i].mask_len = sizeof(bitMask);
- xiEventMask[i].mask = xiBitMask;
+ int deviceId = m_tabletData.at(i).deviceId;
+ tabletDevices.insert(deviceId);
+ xiEventMask[i].deviceid = deviceId;
+ xiEventMask[i].mask_len = sizeof(tabletBitMask);
+ xiEventMask[i].mask = xiTabletBitMask;
}
XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count());
}
@@ -271,17 +278,30 @@ void QXcbConnection::xi2Select(xcb_window_t window)
// Enable each scroll device
if (!m_scrollingDevices.isEmpty()) {
QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
- bitMask = XI_MotionMask;
+ unsigned int scrollBitMask = 0;
+ unsigned char *xiScrollBitMask = reinterpret_cast<unsigned char *>(&scrollBitMask);
+ scrollBitMask = XI_MotionMask;
+ scrollBitMask |= XI_ButtonReleaseMask;
+ bitMask |= XI_MotionMask;
bitMask |= XI_ButtonReleaseMask;
int i=0;
Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
+ if (tabletDevices.contains(scrollingDevice.deviceId))
+ continue; // All necessary events are already captured.
xiEventMask[i].deviceid = scrollingDevice.deviceId;
- xiEventMask[i].mask_len = sizeof(bitMask);
- xiEventMask[i].mask = xiBitMask;
+ if (m_touchDevices.contains(scrollingDevice.deviceId)) {
+ xiEventMask[i].mask_len = sizeof(bitMask);
+ xiEventMask[i].mask = xiBitMask;
+ } else {
+ xiEventMask[i].mask_len = sizeof(scrollBitMask);
+ xiEventMask[i].mask = xiScrollBitMask;
+ }
i++;
}
- XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size());
+ XISelectEvents(xDisplay, window, xiEventMask.data(), i);
}
+#else
+ Q_UNUSED(xiBitMask);
#endif
}
@@ -655,13 +675,15 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
if (reinterpret_cast<xXIDeviceEvent *>(event)->detail == 1) { // ignore the physical buttons on the stylus
tabletData->down = true;
xi2ReportTabletEvent(*tabletData, xiEvent);
- }
+ } else
+ handled = false;
break;
case XI_ButtonRelease: // stylus up
if (reinterpret_cast<xXIDeviceEvent *>(event)->detail == 1) {
tabletData->down = false;
xi2ReportTabletEvent(*tabletData, xiEvent);
- }
+ } else
+ handled = false;
break;
case XI_Motion:
// Report TabletMove only when the stylus is touching the tablet.