Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Added support for multitouch on Android.
Browse files Browse the repository at this point in the history
Fixes Bugzilla #1294.

Thanks to Gabriel Jacobo for the patch!
  • Loading branch information
icculus committed Oct 13, 2011
1 parent 4e72541 commit 8730cc6
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 24 deletions.
41 changes: 30 additions & 11 deletions android-project/src/org/libsdl/app/SDLActivity.java
Expand Up @@ -93,7 +93,8 @@ void sendCommand(int command, Object data) {
public static native void onNativeResize(int x, int y, int format);
public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode);
public static native void onNativeTouch(int action, float x,
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
float y, float p);
public static native void onNativeAccel(float x, float y, float z);
public static native void nativeRunAudioThread();
Expand Down Expand Up @@ -459,16 +460,34 @@ else if (event.getAction() == KeyEvent.ACTION_UP) {

// Touch events
public boolean onTouch(View v, MotionEvent event) {

int action = event.getAction();
float x = event.getX();
float y = event.getY();
float p = event.getPressure();

// TODO: Anything else we need to pass?
SDLActivity.onNativeTouch(action, x, y, p);
return true;
}
{
final int touchDevId = event.getDeviceId();
final int pointerCount = event.getPointerCount();
// touchId, pointerId, action, x, y, pressure
int actionPointerIndex = event.getActionIndex();
int pointerFingerId = event.getPointerId(actionPointerIndex);
int action = event.getActionMasked();

float x = event.getX(actionPointerIndex);
float y = event.getY(actionPointerIndex);
float p = event.getPressure(actionPointerIndex);

if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
// TODO send motion to every pointer if its position has
// changed since prev event.
for (int i = 0; i < pointerCount; i++) {
pointerFingerId = event.getPointerId(i);
x = event.getX(i);
y = event.getY(i);
p = event.getPressure(i);
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
}
} else {
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
}
}
return true;
}

// Sensor events
public void enableSensor(int sensortype, boolean enabled) {
Expand Down
3 changes: 2 additions & 1 deletion src/core/android/SDL_android.cpp
Expand Up @@ -123,9 +123,10 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(
// Touch
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(
JNIEnv* env, jclass jcls,
jint touch_device_id_in, jint pointer_finger_id_in,
jint action, jfloat x, jfloat y, jfloat p)
{
Android_OnTouch(action, x, y, p);
Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p);
}

// Accelerometer
Expand Down
51 changes: 40 additions & 11 deletions src/video/android/SDL_androidtouch.c
Expand Up @@ -24,6 +24,7 @@

#include "SDL_events.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"

#include "SDL_androidtouch.h"

Expand All @@ -33,27 +34,55 @@
#define ACTION_MOVE 2
#define ACTION_CANCEL 3
#define ACTION_OUTSIDE 4
// The following two are deprecated but it seems they are still emitted (instead the corresponding ACTION_UP/DOWN) as of Android 3.2
#define ACTION_POINTER_1_DOWN 5
#define ACTION_POINTER_1_UP 6

void Android_OnTouch(int action, float x, float y, float p)
void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
{
SDL_TouchID touchDeviceId = 0;
SDL_FingerID fingerId = 0;

if (!Android_Window) {
return;
}

touchDeviceId = (SDL_TouchID)touch_device_id_in;
if (!SDL_GetTouch(touchDeviceId)) {
SDL_Touch touch;
memset( &touch, 0, sizeof(touch) );
touch.id = touchDeviceId;
touch.x_min = 0.0f;
touch.x_max = (float)Android_ScreenWidth;
touch.native_xres = touch.x_max - touch.x_min;
touch.y_min = 0.0f;
touch.y_max = (float)Android_ScreenHeight;
touch.native_yres = touch.y_max - touch.y_min;
touch.pressure_min = 0.0f;
touch.pressure_max = 1.0f;
touch.native_pressureres = touch.pressure_max - touch.pressure_min;
if (SDL_AddTouch(&touch, "") < 0) {
SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
}
}

if ((action != ACTION_CANCEL) && (action != ACTION_OUTSIDE)) {
SDL_SetMouseFocus(Android_Window);
SDL_SendMouseMotion(Android_Window, 0, (int)x, (int)y);
switch(action) {

fingerId = (SDL_FingerID)pointer_finger_id_in;
switch (action) {
case ACTION_DOWN:
SDL_SendMouseButton(Android_Window, SDL_PRESSED, SDL_BUTTON_LEFT);
case ACTION_POINTER_1_DOWN:
SDL_SendFingerDown(touchDeviceId, fingerId, SDL_TRUE, x, y, p);
break;
case ACTION_MOVE:
SDL_SendTouchMotion(touchDeviceId, fingerId, SDL_FALSE, x, y, p);
break;
case ACTION_UP:
SDL_SendMouseButton(Android_Window, SDL_RELEASED, SDL_BUTTON_LEFT);
case ACTION_POINTER_1_UP:
SDL_SendFingerDown(touchDeviceId, fingerId, SDL_FALSE, x, y, p);
break;
}
} else {
SDL_SetMouseFocus(NULL);
}
default:
break;
}
}

/* vi: set ts=4 sw=4 expandtab: */
2 changes: 1 addition & 1 deletion src/video/android/SDL_androidtouch.h
Expand Up @@ -22,6 +22,6 @@

#include "SDL_androidvideo.h"

extern void Android_OnTouch(int action, float x, float y, float p);
extern void Android_OnTouch( int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p);

/* vi: set ts=4 sw=4 expandtab: */

0 comments on commit 8730cc6

Please sign in to comment.