summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java1
-rw-r--r--src/corelib/doc/snippets/file/file.cpp2
-rw-r--r--src/corelib/global/qcompilerdetection.h3
-rw-r--r--src/gui/text/qfontdatabase.cpp10
-rw-r--r--src/gui/text/qfontdatabase.h2
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl_android.cpp126
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.cpp68
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.h3
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp1
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp21
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h9
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp151
-rw-r--r--src/xml/doc/qtxml.qdocconf2
-rw-r--r--tests/auto/gui/text/qfont/tst_qfont.cpp10
-rw-r--r--tests/auto/gui/text/qfontdatabase/qfontdatabase.pro5
-rw-r--r--tests/auto/gui/text/qfontdatabase/testdata.qrc5
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp24
21 files changed, 204 insertions, 252 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index 591cd27844..79e30f0552 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -453,6 +453,7 @@ public class QtActivityDelegate
m_environmentVariables = loaderParams.getString(ENVIRONMENT_VARIABLES_KEY);
String additionalEnvironmentVariables = "QT_ANDROID_FONTS_MONOSPACE=Droid Sans Mono;Droid Sans;Droid Sans Fallback"
+ + "\tQT_ANDROID_FONTS_SERIF=Droid Serif"
+ "\tNECESSITAS_API_LEVEL=" + necessitasApiLevel
+ "\tHOME=" + m_activity.getFilesDir().getAbsolutePath()
+ "\tTMPDIR=" + m_activity.getFilesDir().getAbsolutePath();
diff --git a/src/corelib/doc/snippets/file/file.cpp b/src/corelib/doc/snippets/file/file.cpp
index 0b15360736..5776701283 100644
--- a/src/corelib/doc/snippets/file/file.cpp
+++ b/src/corelib/doc/snippets/file/file.cpp
@@ -90,7 +90,7 @@ static void writeTextStream_snippet()
//! [2]
}
-static void writeTextStream_snippet()
+static void writeDataStream_snippet()
{
QFile file("out.dat");
if (!file.open(QIODevice::WriteOnly))
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 0f9a821e40..24c5bfa741 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -530,7 +530,8 @@
# define Q_COMPILER_NOEXCEPT
# endif
# if __INTEL_COMPILER >= 1400
-# define Q_COMPILER_CONSTEXPR
+// causes issues with QArrayData and QtPrivate::RefCount - Intel issue ID 6000056211, bug DPD200534796
+//# define Q_COMPILER_CONSTEXPR
# define Q_COMPILER_DELEGATING_CONSTRUCTORS
# define Q_COMPILER_EXPLICIT_CONVERSIONS
# define Q_COMPILER_EXPLICIT_OVERRIDES
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 06438103ad..86a0bf1066 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -596,7 +596,7 @@ struct QtFontDesc
static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
- QtFontDesc *desc, const QList<int> &blacklisted);
+ QtFontDesc *desc, const QList<int> &blacklisted, bool fallback);
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi)
{
@@ -1079,7 +1079,7 @@ static bool matchFamilyName(const QString &familyName, QtFontFamily *f)
*/
static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
- QtFontDesc *desc, const QList<int> &blacklistedFamilies)
+ QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool fallback = false)
{
Q_UNUSED(force_encoding_id);
int result = -1;
@@ -1132,7 +1132,7 @@ static int match(int script, const QFontDef &request,
load(test.family->name, script);
// Check if family is supported in the script we want
- if (script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported))
+ if (!fallback && script != QChar::Script_Common && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported))
continue;
// as we know the script is supported, we can be sure
@@ -2450,7 +2450,7 @@ bool QFontDatabase::supportsThreadedFontRendering()
*/
QFontEngine *
QFontDatabase::findFont(int script, const QFontPrivate *fp,
- const QFontDef &request, bool multi)
+ const QFontDef &request, bool multi, bool fallback)
{
QMutexLocker locker(fontDatabaseMutex());
@@ -2478,7 +2478,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
QtFontDesc desc;
QList<int> blackListed;
- int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed);
+ int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed, fallback);
if (index >= 0) {
engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
if (!engine)
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 5be24dc3fe..245d1cf81b 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -160,7 +160,7 @@ private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
static QString resolveFontFamilyAlias(const QString &family);
- static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false);
+ static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false, bool fallback = false);
static void load(const QFontPrivate *d, int script);
friend struct QFontDef;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 3ce4ae67ae..5f801c3bf4 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -2045,7 +2045,7 @@ void QFontEngineMultiBasicImpl::loadEngine(int at)
request.family = fallbackFamilies.at(at-1);
engines[at] = QFontDatabase::findFont(script,
/*fontprivate = */0,
- request, /*multi = */false);
+ request, /*multi = */false, true);
Q_ASSERT(engines[at]);
engines[at]->ref.ref();
engines[at]->fontDef = request;
diff --git a/src/network/ssl/qsslsocket_openssl_android.cpp b/src/network/ssl/qsslsocket_openssl_android.cpp
index c7cf03d86d..8cff542e47 100644
--- a/src/network/ssl/qsslsocket_openssl_android.cpp
+++ b/src/network/ssl/qsslsocket_openssl_android.cpp
@@ -55,126 +55,32 @@
****************************************************************************/
#include "qsslsocket_openssl_p.h"
-
-
-
-#include <jni.h>
-#include <android/log.h>
-
-static JavaVM *javaVM = 0;
-static jclass appClass;
-
-static jmethodID getSslCertificatesMethodID;
-
-struct AttachedJNIEnv
-{
- AttachedJNIEnv()
- {
- attached = false;
- if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
- if (javaVM->AttachCurrentThread(&jniEnv, NULL) < 0) {
- __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
- jniEnv = 0;
- return;
- }
- attached = true;
- }
- }
-
- ~AttachedJNIEnv()
- {
- if (attached)
- javaVM->DetachCurrentThread();
- }
- bool attached;
- JNIEnv *jniEnv;
-};
-
-static const char logTag[] = "Qt";
-static const char classErrorMsg[] = "Can't find class \"%s\"";
-static const char methodErrorMsg[] = "Can't find method \"%s%s\"";
-
-
-#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
-clazz = env->FindClass(CLASS_NAME); \
-if (!clazz) { \
- __android_log_print(ANDROID_LOG_FATAL, logTag, classErrorMsg, CLASS_NAME); \
- return JNI_FALSE; \
-}
-
-#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
-VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
-if (!VAR) { \
- __android_log_print(ANDROID_LOG_FATAL, logTag, methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
- return JNI_FALSE; \
-}
-
-static bool registerNatives(JNIEnv *env)
-{
- jclass clazz;
- FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative");
- appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
-
-#if 0 //we don't call C++ functions from Java at this time
- if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
- __android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives failed");
- return JNI_FALSE;
- }
-#endif
-
- GET_AND_CHECK_STATIC_METHOD(getSslCertificatesMethodID, appClass, "getSSLCertificates", "()[[B");
-
- return true;
-}
-
-Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
-{
- typedef union {
- JNIEnv *nativeEnvironment;
- void *venv;
- } UnionJNIEnvToVoid;
-
- __android_log_print(ANDROID_LOG_INFO, logTag, "Network start");
- UnionJNIEnvToVoid uenv;
- uenv.venv = NULL;
- javaVM = 0;
-
- if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
- __android_log_print(ANDROID_LOG_FATAL, logTag, "GetEnv failed");
- return -1;
- }
- JNIEnv *env = uenv.nativeEnvironment;
- if (!registerNatives(env)) {
- __android_log_print(ANDROID_LOG_FATAL, logTag, "registerNatives failed");
- return -1;
- }
-
- javaVM = vm;
- return JNI_VERSION_1_4;
-}
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
{
QList<QByteArray> certificateData;
- AttachedJNIEnv env;
- if (env.jniEnv) {
- jobjectArray jcertificates =
- static_cast<jobjectArray>(env.jniEnv->CallStaticObjectMethod(appClass, getSslCertificatesMethodID));
- jint nCertificates = env.jniEnv->GetArrayLength(jcertificates);
+ QJNIObjectPrivate certificates = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
+ "getSSLCertificates",
+ "()[[B");
+ if (!certificates.isValid())
+ return certificateData;
- for (int i = 0; i < nCertificates; ++i) {
- jbyteArray jCert = static_cast<jbyteArray>(env.jniEnv->GetObjectArrayElement(jcertificates, i));
+ QJNIEnvironmentPrivate env;
+ jobjectArray jcertificates = static_cast<jobjectArray>(certificates.object());
+ const jint nCertificates = env->GetArrayLength(jcertificates);
- const uint sz = env.jniEnv->GetArrayLength(jCert);
- jbyte *buffer = env.jniEnv->GetByteArrayElements(jCert, 0);
- certificateData.append(QByteArray(reinterpret_cast<char*>(buffer), sz));
+ for (int i = 0; i < nCertificates; ++i) {
+ jbyteArray jCert = static_cast<jbyteArray>(env->GetObjectArrayElement(jcertificates, i));
+ const uint sz = env->GetArrayLength(jCert);
+ jbyte *buffer = env->GetByteArrayElements(jCert, 0);
+ certificateData.append(QByteArray(reinterpret_cast<char*>(buffer), sz));
- env.jniEnv->ReleaseByteArrayElements(jCert, buffer, JNI_ABORT); // don't copy back the elements
- env.jniEnv->DeleteLocalRef(jCert);
- }
+ env->ReleaseByteArrayElements(jCert, buffer, JNI_ABORT); // don't copy back the elements
+ env->DeleteLocalRef(jCert);
}
return certificateData;
diff --git a/src/plugins/platforms/android/androidjniclipboard.cpp b/src/plugins/platforms/android/androidjniclipboard.cpp
index 87bb08910d..712a384a36 100644
--- a/src/plugins/platforms/android/androidjniclipboard.cpp
+++ b/src/plugins/platforms/android/androidjniclipboard.cpp
@@ -41,83 +41,39 @@
#include "androidjniclipboard.h"
#include "androidjnimain.h"
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
using namespace QtAndroid;
namespace QtAndroidClipboard
{
- // Clipboard support
- static jmethodID m_registerClipboardManagerMethodID = 0;
- static jmethodID m_setClipboardTextMethodID = 0;
- static jmethodID m_hasClipboardTextMethodID = 0;
- static jmethodID m_getClipboardTextMethodID = 0;
- // Clipboard support
-
void setClipboardListener(QAndroidPlatformClipboard *listener)
{
Q_UNUSED(listener);
-
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_registerClipboardManagerMethodID);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "registerClipboardManager");
}
void setClipboardText(const QString &text)
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- jstring jtext = env.jniEnv->NewString(reinterpret_cast<const jchar *>(text.data()),
- text.length());
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_setClipboardTextMethodID, jtext);
- env.jniEnv->DeleteLocalRef(jtext);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
+ "setClipboardText",
+ "(Ljava/lang/String;)V",
+ QJNIObjectPrivate::fromString(text).object());
}
bool hasClipboardText()
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return false;
-
- return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_hasClipboardTextMethodID);
+ return QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(),
+ "hasClipboardText");
}
QString clipboardText()
{
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return QString();
-
- jstring text = reinterpret_cast<jstring>(env.jniEnv->CallStaticObjectMethod(applicationClass(),
- m_getClipboardTextMethodID));
- const jchar *jstr = env.jniEnv->GetStringChars(text, 0);
- QString str(reinterpret_cast<const QChar *>(jstr), env.jniEnv->GetStringLength(text));
- env.jniEnv->ReleaseStringChars(text, jstr);
- return str;
- }
-
-
-#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
- VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
- if (!VAR) { \
- __android_log_print(ANDROID_LOG_FATAL, qtTagText(), methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
- return false; \
- }
-
- bool registerNatives(JNIEnv *env)
- {
- jclass appClass = QtAndroid::applicationClass();
-
- GET_AND_CHECK_STATIC_METHOD(m_registerClipboardManagerMethodID, appClass, "registerClipboardManager", "()V");
- GET_AND_CHECK_STATIC_METHOD(m_setClipboardTextMethodID, appClass, "setClipboardText", "(Ljava/lang/String;)V");
- GET_AND_CHECK_STATIC_METHOD(m_hasClipboardTextMethodID, appClass, "hasClipboardText", "()Z");
- GET_AND_CHECK_STATIC_METHOD(m_getClipboardTextMethodID, appClass, "getClipboardText", "()Ljava/lang/String;");
-
- return true;
+ QJNIObjectPrivate text = QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
+ "getClipboardText",
+ "()Ljava/lang/String;");
+ return text.toString();
}
}
diff --git a/src/plugins/platforms/android/androidjniclipboard.h b/src/plugins/platforms/android/androidjniclipboard.h
index 764ef908df..bd833226af 100644
--- a/src/plugins/platforms/android/androidjniclipboard.h
+++ b/src/plugins/platforms/android/androidjniclipboard.h
@@ -42,7 +42,6 @@
#ifndef ANDROIDJNICLIPBOARD_H
#define ANDROIDJNICLIPBOARD_H
-#include <jni.h>
#include <QString>
QT_BEGIN_NAMESPACE
@@ -56,8 +55,6 @@ namespace QtAndroidClipboard
bool hasClipboardText();
QString clipboardText();
// Clipboard support
-
- bool registerNatives(JNIEnv *env);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index d82487ae9b..3e3e169df9 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -773,7 +773,6 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
JNIEnv *env = uenv.nativeEnvironment;
if (!registerNatives(env)
|| !QtAndroidInput::registerNatives(env)
- || !QtAndroidClipboard::registerNatives(env)
|| !QtAndroidMenu::registerNatives(env)
|| !QtAndroidAccessibility::registerNatives(env)
|| !QtAndroidDialogHelpers::registerNatives(env)) {
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index fd14f812a0..682a49f6d6 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
@@ -86,6 +86,8 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami
if (styleHint == QFont::Monospace || styleHint == QFont::Courier)
return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";") + m_fallbacks[script];
+ else if (styleHint == QFont::Serif)
+ return QString(qgetenv("QT_ANDROID_FONTS_SERIF")).split(";") + m_fallbacks[script];
return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script];
}
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 3a3ea71562..f27bea8863 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -72,9 +72,8 @@ bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud()
if (!set) {
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
needsWorkaround =
- qstrcmp(rendererString, "Mali-400 MP") == 0
- || qstrcmp(rendererString, "Adreno (TM) 200") == 0
- || qstrcmp(rendererString, "Adreno (TM) 205") == 0
+ qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450
+ || qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205
|| qstrcmp(rendererString, "GC1000 core") == 0;
set = true;
}
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 02fe29e576..9c21abe39b 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
@@ -43,30 +43,21 @@
#include <QUrl>
#include <QDir>
#include <QDebug>
+#include <QtCore/private/qjni_p.h>
QT_BEGIN_NAMESPACE
QAndroidPlatformServices::QAndroidPlatformServices()
{
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- m_openURIMethodID = env.jniEnv->GetStaticMethodID(QtAndroid::applicationClass(),
- "openURL",
- "(Ljava/lang/String;)V");
}
bool QAndroidPlatformServices::openUrl(const QUrl &url)
{
- QtAndroid::AttachedJNIEnv env;
- if (!env.jniEnv)
- return false;
-
- jstring string = env.jniEnv->NewString(reinterpret_cast<const jchar *>(url.toString().constData()),
- url.toString().length());
- env.jniEnv->CallStaticVoidMethod(QtAndroid::applicationClass(), m_openURIMethodID, string);
- env.jniEnv->DeleteLocalRef(string);
+ QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
+ QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(),
+ "openURL",
+ "(Ljava/lang/String;)V",
+ urlString.object());
return true;
}
diff --git a/src/plugins/platforms/android/qandroidplatformservices.h b/src/plugins/platforms/android/qandroidplatformservices.h
index 08d7773ca4..dd6872b2e9 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.h
+++ b/src/plugins/platforms/android/qandroidplatformservices.h
@@ -44,7 +44,6 @@
#include <qpa/qplatformservices.h>
#include "androidjnimain.h"
-#include <jni.h>
QT_BEGIN_NAMESPACE
@@ -55,9 +54,6 @@ public:
bool openUrl(const QUrl &url);
bool openDocument(const QUrl &url);
QByteArray desktopEnvironment() const;
-private:
- jmethodID m_openURIMethodID;
-
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 15fdf50a1e..82ad027a50 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -508,22 +508,25 @@ private:
int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
#ifndef QT_NO_TABLETEVENT
struct TabletData {
- TabletData() : deviceId(0), down(false), serialId(0), inProximity(false) { }
+ TabletData() : deviceId(0), pointerType(QTabletEvent::UnknownPointer),
+ tool(QTabletEvent::Stylus), down(false), serialId(0), inProximity(false) { }
int deviceId;
QTabletEvent::PointerType pointerType;
+ QTabletEvent::TabletDevice tool;
bool down;
qint64 serialId;
bool inProximity;
struct ValuatorClassInfo {
- ValuatorClassInfo() : minVal(0), maxVal(0) { }
+ ValuatorClassInfo() : minVal(0.), maxVal(0.), curVal(0.) { }
double minVal;
double maxVal;
+ double curVal;
int number;
};
QHash<int, ValuatorClassInfo> valuatorInfo;
};
bool xi2HandleTabletEvent(void *event, TabletData *tabletData);
- void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
+ void xi2ReportTabletEvent(TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
#endif
struct ScrollingDevice {
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index cf809b37e5..e21db89a20 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -685,6 +685,39 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
#endif // XCB_USE_XINPUT21
}
+static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) {
+ // keep in sync with wacom_intuos_inout() in Linux kernel driver wacom_wac.c
+ switch (toolId) {
+ case 0xd12:
+ case 0x912:
+ case 0x112:
+ case 0x913: /* Intuos3 Airbrush */
+ case 0x91b: /* Intuos3 Airbrush Eraser */
+ case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
+ case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
+ case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
+ case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
+ return QTabletEvent::Airbrush;
+ case 0x007: /* Mouse 4D and 2D */
+ case 0x09c:
+ case 0x094:
+ return QTabletEvent::FourDMouse;
+ case 0x017: /* Intuos3 2D Mouse */
+ case 0x806: /* Intuos4 Mouse */
+ case 0x096: /* Lens cursor */
+ case 0x097: /* Intuos3 Lens cursor */
+ case 0x006: /* Intuos4 Lens cursor */
+ return QTabletEvent::Puck;
+ case 0x885: /* Intuos3 Art Pen (Marker Pen) */
+ case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
+ case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
+ return QTabletEvent::RotationStylus;
+ case 0:
+ return QTabletEvent::NoDevice;
+ }
+ return QTabletEvent::Stylus; // Safe default assumption if nonzero
+}
+
#ifndef QT_NO_TABLETEVENT
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
@@ -713,9 +746,19 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
xi2ReportTabletEvent(*tabletData, xiEvent);
break;
case XI_PropertyEvent: {
+ // This is the wacom driver's way of reporting tool proximity.
+ // The evdev driver doesn't do it this way.
xXIPropertyEvent *ev = reinterpret_cast<xXIPropertyEvent *>(event);
if (ev->what == XIPropertyModified) {
if (ev->property == atom(QXcbAtom::WacomSerialIDs)) {
+ enum WacomSerialIndex {
+ _WACSER_USB_ID = 0,
+ _WACSER_LAST_TOOL_SERIAL,
+ _WACSER_LAST_TOOL_ID,
+ _WACSER_TOOL_SERIAL,
+ _WACSER_TOOL_ID,
+ _WACSER_COUNT
+ };
Atom propType;
int propFormat;
unsigned long numItems, bytesAfter;
@@ -723,27 +766,44 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
if (XIGetProperty(xDisplay, tabletData->deviceId, ev->property, 0, 100,
0, AnyPropertyType, &propType, &propFormat,
&numItems, &bytesAfter, &data) == Success) {
- if (propType == atom(QXcbAtom::INTEGER) && propFormat == 32) {
- int *ptr = reinterpret_cast<int *>(data);
- for (unsigned long i = 0; i < numItems; ++i)
- tabletData->serialId |= qint64(ptr[i]) << (i * 32);
+ if (propType == atom(QXcbAtom::INTEGER) && propFormat == 32 && numItems == _WACSER_COUNT) {
+ quint32 *ptr = reinterpret_cast<quint32 *>(data);
+ quint32 tool = ptr[_WACSER_TOOL_ID];
+ // Workaround for http://sourceforge.net/p/linuxwacom/bugs/246/
+ // e.g. on Thinkpad Helix, tool ID will be 0 and serial will be 1
+ if (!tool && ptr[_WACSER_TOOL_SERIAL])
+ tool = ptr[_WACSER_TOOL_SERIAL];
+
+ // The property change event informs us which tool is in proximity or which one left proximity.
+ if (tool) {
+ tabletData->inProximity = true;
+ tabletData->tool = toolIdToTabletDevice(tool);
+ tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_TOOL_SERIAL]);
+ QWindowSystemInterface::handleTabletEnterProximityEvent(tabletData->tool,
+ tabletData->pointerType,
+ tabletData->serialId);
+ } else {
+ tabletData->inProximity = false;
+ tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_ID]);
+ // Workaround for http://sourceforge.net/p/linuxwacom/bugs/246/
+ // e.g. on Thinkpad Helix, tool ID will be 0 and serial will be 1
+ if (!tabletData->tool)
+ tabletData->tool = toolIdToTabletDevice(ptr[_WACSER_LAST_TOOL_SERIAL]);
+ tabletData->serialId = qint64(ptr[_WACSER_USB_ID]) << 32 | qint64(ptr[_WACSER_LAST_TOOL_SERIAL]);
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(tabletData->tool,
+ tabletData->pointerType,
+ tabletData->serialId);
+ }
+ if (Q_UNLIKELY(debug_xinput)) {
+ // TODO maybe have a hash of tabletData->deviceId to device data so we can
+ // look up the tablet name here, and distinguish multiple tablets
+ qDebug("XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d",
+ ev->deviceid, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID],
+ ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool);
+ }
}
XFree(data);
}
- // With recent-enough X drivers this property change event seems to come always
- // when entering and leaving proximity. Due to the lack of other options hook up
- // the enter/leave events to it.
- if (tabletData->inProximity) {
- tabletData->inProximity = false;
- QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus,
- tabletData->pointerType,
- tabletData->serialId);
- } else {
- tabletData->inProximity = true;
- QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus,
- tabletData->pointerType,
- tabletData->serialId);
- }
}
}
break;
@@ -755,7 +815,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
return handled;
}
-void QXcbConnection::xi2ReportTabletEvent(const TabletData &tabletData, void *event)
+void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event)
{
xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
QXcbWindow *xcbWindow = platformWindowFromId(ev->event);
@@ -765,45 +825,52 @@ void QXcbConnection::xi2ReportTabletEvent(const TabletData &tabletData, void *ev
const double scale = 65536.0;
QPointF local(ev->event_x / scale, ev->event_y / scale);
QPointF global(ev->root_x / scale, ev->root_y / scale);
- double pressure = 0, rotation = 0;
+ double pressure = 0, rotation = 0, tangentialPressure = 0;
int xTilt = 0, yTilt = 0;
- for (QHash<int, TabletData::ValuatorClassInfo>::const_iterator it = tabletData.valuatorInfo.constBegin(),
- ite = tabletData.valuatorInfo.constEnd(); it != ite; ++it) {
+ for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData.valuatorInfo.begin(),
+ ite = tabletData.valuatorInfo.end(); it != ite; ++it) {
int valuator = it.key();
- const TabletData::ValuatorClassInfo &classInfo(it.value());
- double value;
- if (xi2GetValuatorValueIfSet(event, classInfo.number, &value)) {
- double normalizedValue = (value - classInfo.minVal) / double(classInfo.maxVal - classInfo.minVal);
- switch (valuator) {
- case QXcbAtom::AbsPressure:
- pressure = normalizedValue;
- break;
- case QXcbAtom::AbsTiltX:
- xTilt = value;
+ TabletData::ValuatorClassInfo &classInfo(it.value());
+ xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal);
+ double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal);
+ switch (valuator) {
+ case QXcbAtom::AbsPressure:
+ pressure = normalizedValue;
+ break;
+ case QXcbAtom::AbsTiltX:
+ xTilt = classInfo.curVal;
+ break;
+ case QXcbAtom::AbsTiltY:
+ yTilt = classInfo.curVal;
+ break;
+ case QXcbAtom::AbsWheel:
+ switch (tabletData.tool) {
+ case QTabletEvent::Airbrush:
+ tangentialPressure = normalizedValue * 2.0 - 1.0; // Convert 0..1 range to -1..+1 range
break;
- case QXcbAtom::AbsTiltY:
- yTilt = value;
+ case QTabletEvent::RotationStylus:
+ rotation = normalizedValue * 360.0 - 180.0; // Convert 0..1 range to -180..+180 degrees
break;
- case QXcbAtom::AbsWheel:
- rotation = value / 64.0;
- break;
- default:
+ default: // Other types of styli do not use this valuator
break;
}
+ break;
+ default:
+ break;
}
}
if (Q_UNLIKELY(debug_xinput))
- qDebug("XI2 tablet event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f pressure %4.2lf tilt %d, %d rotation %6.2lf",
- ev->type, ev->sequenceNumber, ev->detail,
+ qDebug("XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f pressure %4.2lf tilt %d, %d rotation %6.2lf",
+ ev->deviceid, tabletData.tool, ev->type, ev->sequenceNumber, ev->detail,
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
pressure, xTilt, yTilt, rotation);
QWindowSystemInterface::handleTabletEvent(window, tabletData.down, local, global,
- QTabletEvent::Stylus, tabletData.pointerType,
- pressure, xTilt, yTilt, 0,
+ tabletData.tool, tabletData.pointerType,
+ pressure, xTilt, yTilt, tangentialPressure,
rotation, 0, tabletData.serialId);
}
#endif // QT_NO_TABLETEVENT
diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf
index ab10818522..8ca421ff4e 100644
--- a/src/xml/doc/qtxml.qdocconf
+++ b/src/xml/doc/qtxml.qdocconf
@@ -26,7 +26,7 @@ qhp.QtXml.subprojects.classes.sortPages = true
tagfile = ../../../doc/qtxml/qtxml.tags
-depends += qtcore qtnetwork qtdoc
+depends += qtcore qtnetwork qtdoc qtwidgets
headerdirs += ..
diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp
index 6f75a1f8bb..57cf3a1fb6 100644
--- a/tests/auto/gui/text/qfont/tst_qfont.cpp
+++ b/tests/auto/gui/text/qfont/tst_qfont.cpp
@@ -710,11 +710,11 @@ void tst_QFont::defaultFamily_data()
QTest::addColumn<QFont::StyleHint>("styleHint");
QTest::addColumn<QStringList>("acceptableFamilies");
- QTest::newRow("serif") << QFont::Serif << (QStringList() << "Times New Roman" << "Times" << getPlatformGenericFont("serif"));
- QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << getPlatformGenericFont("monospace"));
- QTest::newRow("cursive") << QFont::Cursive << (QStringList() << "Comic Sans MS" << "Apple Chancery" << getPlatformGenericFont("cursive"));
- QTest::newRow("fantasy") << QFont::Fantasy << (QStringList() << "Impact" << "Zapfino" << getPlatformGenericFont("fantasy"));
- QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << getPlatformGenericFont("sans-serif"));
+ QTest::newRow("serif") << QFont::Serif << (QStringList() << "Times New Roman" << "Times" << "Droid Serif" << getPlatformGenericFont("serif"));
+ QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << "Droid Sans Mono" << getPlatformGenericFont("monospace"));
+ QTest::newRow("cursive") << QFont::Cursive << (QStringList() << "Comic Sans MS" << "Apple Chancery" << "Roboto" << "Droid Sans" << getPlatformGenericFont("cursive"));
+ QTest::newRow("fantasy") << QFont::Fantasy << (QStringList() << "Impact" << "Zapfino" << "Roboto" << "Droid Sans" << getPlatformGenericFont("fantasy"));
+ QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << "Roboto" << "Droid Sans" << getPlatformGenericFont("sans-serif"));
}
void tst_QFont::defaultFamily()
diff --git a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro
index 6975c4088b..831ed1f572 100644
--- a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro
+++ b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro
@@ -9,3 +9,8 @@ wince* {
additionalFiles.path = .
DEPLOYMENT += additionalFiles
}
+
+android {
+ RESOURCES += testdata.qrc
+}
+
diff --git a/tests/auto/gui/text/qfontdatabase/testdata.qrc b/tests/auto/gui/text/qfontdatabase/testdata.qrc
new file mode 100644
index 0000000000..8a8670bf17
--- /dev/null
+++ b/tests/auto/gui/text/qfontdatabase/testdata.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>LED_REAL.TTF</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index 28db0ba291..2ae12ec246 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -44,6 +44,8 @@
#include <qfontdatabase.h>
#include <qfontinfo.h>
#include <qfontmetrics.h>
+#include <qtextlayout.h>
+#include <private/qrawfont_p.h>
#include <qpa/qplatformfontdatabase.h>
class tst_QFontDatabase : public QObject
@@ -77,6 +79,7 @@ private slots:
void addAppFont();
void aliases();
+ void fallbackFonts();
private:
const QString m_testFont;
@@ -285,5 +288,26 @@ void tst_QFontDatabase::aliases()
QVERIFY(db.hasFamily(alias));
}
+void tst_QFontDatabase::fallbackFonts()
+{
+ QTextLayout layout;
+ QString s;
+ s.append(QChar(0x31));
+ s.append(QChar(0x05D0));
+ layout.setText(s);
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> runs = layout.glyphRuns(0, 1);
+ foreach (QGlyphRun run, runs) {
+ QRawFont rawFont = run.rawFont();
+ QVERIFY(rawFont.isValid());
+
+ QCOMPARE(run.glyphIndexes().size(), 1);
+ QVERIFY(run.glyphIndexes().at(0) != 0);
+ }
+}
+
QTEST_MAIN(tst_QFontDatabase)
#include "tst_qfontdatabase.moc"