Skip to content

Commit

Permalink
Added detection of touch devices before first touch events happen on …
Browse files Browse the repository at this point in the history
…Android.

On Android available touch devices are now added with video initialization (like
the keyboard). This fixes SDL_GetNumTouchDevices() returning 0 before any touch
events happened although there is a touch screen available. The adding of touch
devices after a touch event was received is still active to allow connecting
devices later (if this is possible) and to provide a fallback if the new init
did not work somehow. For the implementation JNI was used and API level 9 is
required. There seems to be nothing in the Android NDK's input header (input.h)
to implement everything on C side without communication with Java side.
  • Loading branch information
philippwiesemann committed Oct 5, 2013
1 parent 36b7591 commit 0db36f5
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 0 deletions.
20 changes: 20 additions & 0 deletions android-project/src/org/libsdl/app/SDLActivity.java
@@ -1,5 +1,7 @@
package org.libsdl.app;

import java.util.Arrays;

import android.app.*;
import android.content.*;
import android.view.*;
Expand Down Expand Up @@ -386,6 +388,24 @@ public static void audioQuit() {
mAudioTrack = null;
}
}

// Input

/**
* @return an array which may be empty but is never null.
*/
public static int[] inputGetInputDeviceIds(int sources) {
int[] ids = InputDevice.getDeviceIds();
int[] filtered = new int[ids.length];
int used = 0;
for (int i = 0; i < ids.length; ++i) {
InputDevice device = InputDevice.getDevice(ids[i]);
if ((device != null) && ((device.getSources() & sources) != 0)) {
filtered[used++] = device.getId();
}
}
return Arrays.copyOf(filtered, used);
}
}

/**
Expand Down
26 changes: 26 additions & 0 deletions src/core/android/SDL_android.c
Expand Up @@ -1186,6 +1186,32 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
return 0;
}

/* returns number of found touch devices as return value and ids in parameter ids */
int Android_JNI_GetTouchDeviceIds(int **ids) {
JNIEnv *env = Android_JNI_GetEnv();
jint sources = 4098; /* == InputDevice.SOURCE_TOUCHSCREEN */
jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "inputGetInputDeviceIds", "(I)[I");
jintArray array = (jintArray) (*env)->CallStaticObjectMethod(env, mActivityClass, mid, sources);
int number = 0;
*ids = NULL;
if (array) {
number = (int) (*env)->GetArrayLength(env, array);
if (0 < number) {
jint* elements = (*env)->GetIntArrayElements(env, array, NULL);
if (elements) {
int i;
*ids = SDL_malloc(number * sizeof (*ids[0]));
for (i = 0; i < number; ++i) { /* not assuming sizeof (jint) == sizeof (int) */
*ids[i] = elements[i];
}
(*env)->ReleaseIntArrayElements(env, array, elements, JNI_ABORT);
}
}
(*env)->DeleteLocalRef(env, array);
}
return number;
}

/* sends message to be handled on the UI event dispatch thread */
int Android_JNI_SendMessage(int command, int param)
{
Expand Down
3 changes: 3 additions & 0 deletions src/core/android/SDL_android.h
Expand Up @@ -65,6 +65,9 @@ SDL_bool Android_JNI_HasClipboardText();
/* Power support */
int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent);

/* Touch support */
int Android_JNI_GetTouchDeviceIds(int **ids);

/* Threads */
#include <jni.h>
JNIEnv *Android_JNI_GetEnv(void);
Expand Down
14 changes: 14 additions & 0 deletions src/video/android/SDL_androidtouch.c
Expand Up @@ -31,6 +31,7 @@

#include "SDL_androidtouch.h"

#include "../../core/android/SDL_android.h"

#define ACTION_DOWN 0
#define ACTION_UP 1
Expand All @@ -53,6 +54,19 @@ static void Android_GetWindowCoordinates(float x, float y,
*window_y = (int)(y * window_h);
}

void Android_InitTouch(void)
{
int i;
int* ids;
int number = Android_JNI_GetTouchDeviceIds(&ids);
if (0 < number) {
for (i = 0; i < number; ++i) {
SDL_AddTouch((SDL_TouchID) ids[i], ""); /* no error handling */
}
SDL_free(ids);
}
}

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;
Expand Down
1 change: 1 addition & 0 deletions src/video/android/SDL_androidtouch.h
Expand Up @@ -22,6 +22,7 @@

#include "SDL_androidvideo.h"

extern void Android_InitTouch(void);
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: */
3 changes: 3 additions & 0 deletions src/video/android/SDL_androidvideo.c
Expand Up @@ -36,6 +36,7 @@
#include "SDL_androidclipboard.h"
#include "SDL_androidevents.h"
#include "SDL_androidkeyboard.h"
#include "SDL_androidtouch.h"
#include "SDL_androidwindow.h"

#define ANDROID_VID_DRIVER_NAME "Android"
Expand Down Expand Up @@ -165,6 +166,8 @@ Android_VideoInit(_THIS)

Android_InitKeyboard();

Android_InitTouch();

/* We're done! */
return 0;
}
Expand Down

0 comments on commit 0db36f5

Please sign in to comment.