Merge remote-tracking branch 'origin/5.3' into dev
Conflicts: src/gui/text/qfontengine_qpf2.cpp Change-Id: Ib04f92c41d0edd55d3aef8fb1708d917fba0f2a8
This commit is contained in:
commit
7c495cfea9
@ -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();
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
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::AbsTiltX:
|
||||
xTilt = value;
|
||||
case QTabletEvent::RotationStylus:
|
||||
rotation = normalizedValue * 360.0 - 180.0; // Convert 0..1 range to -180..+180 degrees
|
||||
break;
|
||||
case QXcbAtom::AbsTiltY:
|
||||
yTilt = value;
|
||||
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
|
||||
|
@ -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 += ..
|
||||
|
||||
|
@ -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()
|
||||
|
@ -9,3 +9,8 @@ wince* {
|
||||
additionalFiles.path = .
|
||||
DEPLOYMENT += additionalFiles
|
||||
}
|
||||
|
||||
android {
|
||||
RESOURCES += testdata.qrc
|
||||
}
|
||||
|
||||
|
5
tests/auto/gui/text/qfontdatabase/testdata.qrc
Normal file
5
tests/auto/gui/text/qfontdatabase/testdata.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>LED_REAL.TTF</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user