diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-07-14 10:35:51 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-07-14 10:35:51 +0200 |
commit | 7c495cfea96e13dbd8b4f9bfa2fc8ee5d015597f (patch) | |
tree | e64c56e73d11c1f0640b280a60c556e0aec557a4 /src/plugins | |
parent | 607462019a1da6241d3f4b6bf6356b7dc0a413d0 (diff) | |
parent | b61ee210e67e5575bc96489908b9c46f7b74ec7a (diff) |
Merge remote-tracking branch 'origin/5.3' into dev
Conflicts:
src/gui/text/qfontengine_qpf2.cpp
Change-Id: Ib04f92c41d0edd55d3aef8fb1708d917fba0f2a8
Diffstat (limited to 'src/plugins')
9 files changed, 137 insertions, 127 deletions
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 |