diff options
author | Jeff Brown <jeffbrown@google.com> | 2011-05-06 18:20:01 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2011-05-13 12:11:17 -0700 |
commit | fe9f8ab03a63b1037f07dd85799fbea80ec6adaa (patch) | |
tree | c0cfa91d0537321eeee0ede693fb414d8778a1a2 /core/jni/android_view_MotionEvent.cpp | |
parent | 1abf1c59f8b15d5b4b198063b884e268bd79fb32 (diff) | |
download | frameworks_base-fe9f8ab03a63b1037f07dd85799fbea80ec6adaa.zip frameworks_base-fe9f8ab03a63b1037f07dd85799fbea80ec6adaa.tar.gz frameworks_base-fe9f8ab03a63b1037f07dd85799fbea80ec6adaa.tar.bz2 |
Add initial API for stylus and mouse buttons.
Added the concept of pointer properties in a MotionEvent.
This is currently used to track the pointer tool type to enable
applications to distinguish finger touches from a stylus.
Button states are also reported to application as part of touch events.
There are no new actions for detecting changes in button states.
The application should instead query the button state from the
MotionEvent and take appropriate action as needed.
A good time to check the button state is on ACTION_DOWN.
As a side-effect, applications that do not support multiple buttons
will treat primary, secondary and tertiary buttons identically
for all touch events.
The back button on the mouse is mapped to KEYCODE_BACK
and the forward button is mapped to KEYCODE_FORWARD.
Added basic plumbing for the secondary mouse button to invoke
the context menu, particularly in lists.
Added clamp and split methods on MotionEvent to take care of
common filtering operations so we don't have them scattered
in multiple places across the framework.
Bug: 4260011
Change-Id: Ie992b4d4e00c8f2e76b961da0a902145b27f6d83
Diffstat (limited to 'core/jni/android_view_MotionEvent.cpp')
-rw-r--r-- | core/jni/android_view_MotionEvent.cpp | 150 |
1 files changed, 132 insertions, 18 deletions
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index 2ede7ec..fef06b2 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -55,6 +55,11 @@ static struct { jfieldID orientation; } gPointerCoordsClassInfo; +static struct { + jfieldID id; + jfieldID toolType; +} gPointerPropertiesClassInfo; + // ---------------------------------------------------------------------------- MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) { @@ -115,17 +120,17 @@ static bool validatePointerCount(JNIEnv* env, jint pointerCount) { return true; } -static bool validatePointerIdsArray(JNIEnv* env, jintArray pointerIdsArray, +static bool validatePointerPropertiesArray(JNIEnv* env, jobjectArray pointerPropertiesObjArray, size_t pointerCount) { - if (!pointerIdsArray) { + if (!pointerPropertiesObjArray) { jniThrowException(env, "java/lang/IllegalArgumentException", - "pointerIds array must not be null"); + "pointerProperties array must not be null"); return false; } - size_t length = size_t(env->GetArrayLength(pointerIdsArray)); + size_t length = size_t(env->GetArrayLength(pointerPropertiesObjArray)); if (length < pointerCount) { jniThrowException(env, "java/lang/IllegalArgumentException", - "pointerIds array must be large enough to hold all pointers"); + "pointerProperties array must be large enough to hold all pointers"); return false; } return true; @@ -174,6 +179,15 @@ static bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) { return true; } +static bool validatePointerProperties(JNIEnv* env, jobject pointerPropertiesObj) { + if (!pointerPropertiesObj) { + jniThrowException(env, "java/lang/IllegalArgumentException", + "pointerProperties must not be null"); + return false; + } + return true; +} + static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj, float xOffset, float yOffset, PointerCoords* outRawPointerCoords) { outRawPointerCoords->clear(); @@ -300,17 +314,36 @@ static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointer env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits); } +static void pointerPropertiesToNative(JNIEnv* env, jobject pointerPropertiesObj, + PointerProperties* outPointerProperties) { + outPointerProperties->clear(); + outPointerProperties->id = env->GetIntField(pointerPropertiesObj, + gPointerPropertiesClassInfo.id); + outPointerProperties->toolType = env->GetIntField(pointerPropertiesObj, + gPointerPropertiesClassInfo.toolType); +} + +static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* pointerProperties, + jobject outPointerPropertiesObj) { + env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.id, + pointerProperties->id); + env->SetIntField(outPointerPropertiesObj, gPointerPropertiesClassInfo.toolType, + pointerProperties->toolType); +} + // ---------------------------------------------------------------------------- static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz, jint nativePtr, - jint deviceId, jint source, jint action, jint flags, jint edgeFlags, jint metaState, + jint deviceId, jint source, jint action, jint flags, jint edgeFlags, + jint metaState, jint buttonState, jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision, jlong downTimeNanos, jlong eventTimeNanos, - jint pointerCount, jintArray pointerIdsArray, jobjectArray pointerCoordsObjArray) { + jint pointerCount, jobjectArray pointerPropertiesObjArray, + jobjectArray pointerCoordsObjArray) { if (!validatePointerCount(env, pointerCount) - || !validatePointerIdsArray(env, pointerIdsArray, pointerCount) + || !validatePointerPropertiesArray(env, pointerPropertiesObjArray, pointerCount) || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) { return 0; } @@ -320,29 +353,37 @@ static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz, event = new MotionEvent(); } + PointerProperties pointerProperties[pointerCount]; PointerCoords rawPointerCoords[pointerCount]; for (jint i = 0; i < pointerCount; i++) { + jobject pointerPropertiesObj = env->GetObjectArrayElement(pointerPropertiesObjArray, i); + if (!pointerPropertiesObj) { + goto Error; + } + pointerPropertiesToNative(env, pointerPropertiesObj, &pointerProperties[i]); + env->DeleteLocalRef(pointerPropertiesObj); + jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i); if (!pointerCoordsObj) { jniThrowNullPointerException(env, "pointerCoords"); - if (!nativePtr) { - delete event; - } - return 0; + goto Error; } pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]); env->DeleteLocalRef(pointerCoordsObj); } - int* pointerIds = static_cast<int*>(env->GetPrimitiveArrayCritical(pointerIdsArray, NULL)); - - event->initialize(deviceId, source, action, flags, edgeFlags, metaState, + event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision, - downTimeNanos, eventTimeNanos, pointerCount, pointerIds, rawPointerCoords); + downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords); - env->ReleasePrimitiveArrayCritical(pointerIdsArray, pointerIds, JNI_ABORT); return reinterpret_cast<jint>(event); + +Error: + if (!nativePtr) { + delete event; + } + return 0; } static jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz, @@ -454,12 +495,30 @@ static jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass claz return event->getMetaState(); } +static jint android_view_MotionEvent_nativeGetButtonState(JNIEnv* env, jclass clazz, + jint nativePtr) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + return event->getButtonState(); +} + static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz, jint nativePtr, jfloat deltaX, jfloat deltaY) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); return event->offsetLocation(deltaX, deltaY); } +static jfloat android_view_MotionEvent_nativeGetXOffset(JNIEnv* env, jclass clazz, + jint nativePtr) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + return event->getXOffset(); +} + +static jfloat android_view_MotionEvent_nativeGetYOffset(JNIEnv* env, jclass clazz, + jint nativePtr) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + return event->getYOffset(); +} + static jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz, jint nativePtr) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); @@ -478,6 +537,12 @@ static jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass return event->getDownTime(); } +static void android_view_MotionEvent_nativeSetDownTimeNanos(JNIEnv* env, jclass clazz, + jint nativePtr, jlong downTimeNanos) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + event->setDownTime(downTimeNanos); +} + static jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz, jint nativePtr) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); @@ -494,6 +559,16 @@ static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass claz return event->getPointerId(pointerIndex); } +static jint android_view_MotionEvent_nativeGetToolType(JNIEnv* env, jclass clazz, + jint nativePtr, jint pointerIndex) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + size_t pointerCount = event->getPointerCount(); + if (!validatePointerIndex(env, pointerIndex, pointerCount)) { + return -1; + } + return event->getToolType(pointerIndex); +} + static jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz, jint nativePtr, jint pointerId) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); @@ -581,6 +656,19 @@ static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass outPointerCoordsObj); } +static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz, + jint nativePtr, jint pointerIndex, jobject outPointerPropertiesObj) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + size_t pointerCount = event->getPointerCount(); + if (!validatePointerIndex(env, pointerIndex, pointerCount) + || !validatePointerProperties(env, outPointerPropertiesObj)) { + return; + } + + const PointerProperties* pointerProperties = event->getPointerProperties(pointerIndex); + pointerPropertiesFromNative(env, pointerProperties, outPointerPropertiesObj); +} + static void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz, jint nativePtr, jfloat scale) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); @@ -630,7 +718,8 @@ static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass cla static JNINativeMethod gMotionEventMethods[] = { /* name, signature, funcPtr */ { "nativeInitialize", - "(IIIIIIIFFFFJJI[I[Landroid/view/MotionEvent$PointerCoords;)I", + "(IIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;" + "[Landroid/view/MotionEvent$PointerCoords;)I", (void*)android_view_MotionEvent_nativeInitialize }, { "nativeCopy", "(IIZ)I", @@ -674,9 +763,18 @@ static JNINativeMethod gMotionEventMethods[] = { { "nativeGetMetaState", "(I)I", (void*)android_view_MotionEvent_nativeGetMetaState }, + { "nativeGetButtonState", + "(I)I", + (void*)android_view_MotionEvent_nativeGetButtonState }, { "nativeOffsetLocation", "(IFF)V", (void*)android_view_MotionEvent_nativeOffsetLocation }, + { "nativeGetXOffset", + "(I)F", + (void*)android_view_MotionEvent_nativeGetXOffset }, + { "nativeGetYOffset", + "(I)F", + (void*)android_view_MotionEvent_nativeGetYOffset }, { "nativeGetXPrecision", "(I)F", (void*)android_view_MotionEvent_nativeGetXPrecision }, @@ -686,12 +784,18 @@ static JNINativeMethod gMotionEventMethods[] = { { "nativeGetDownTimeNanos", "(I)J", (void*)android_view_MotionEvent_nativeGetDownTimeNanos }, + { "nativeSetDownTimeNanos", + "(IJ)V", + (void*)android_view_MotionEvent_nativeSetDownTimeNanos }, { "nativeGetPointerCount", "(I)I", (void*)android_view_MotionEvent_nativeGetPointerCount }, { "nativeGetPointerId", "(II)I", (void*)android_view_MotionEvent_nativeGetPointerId }, + { "nativeGetToolType", + "(II)I", + (void*)android_view_MotionEvent_nativeGetToolType }, { "nativeFindPointerIndex", "(II)I", (void*)android_view_MotionEvent_nativeFindPointerIndex }, @@ -710,6 +814,9 @@ static JNINativeMethod gMotionEventMethods[] = { { "nativeGetPointerCoords", "(IIILandroid/view/MotionEvent$PointerCoords;)V", (void*)android_view_MotionEvent_nativeGetPointerCoords }, + { "nativeGetPointerProperties", + "(IILandroid/view/MotionEvent$PointerProperties;)V", + (void*)android_view_MotionEvent_nativeGetPointerProperties }, { "nativeScale", "(IF)V", (void*)android_view_MotionEvent_nativeScale }, @@ -781,6 +888,13 @@ int register_android_view_MotionEvent(JNIEnv* env) { GET_FIELD_ID(gPointerCoordsClassInfo.orientation, clazz, "orientation", "F"); + FIND_CLASS(clazz, "android/view/MotionEvent$PointerProperties"); + + GET_FIELD_ID(gPointerPropertiesClassInfo.id, clazz, + "id", "I"); + GET_FIELD_ID(gPointerPropertiesClassInfo.toolType, clazz, + "toolType", "I"); + return 0; } |