diff options
Diffstat (limited to 'src/plugins/platforms')
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. |