Proper mouse/stylus support in Gingerbread and ICS

This commit is contained in:
pelya
2012-06-13 19:35:29 +03:00
parent 77a16225aa
commit dd67bba742
5 changed files with 172 additions and 72 deletions

View File

@@ -2603,7 +2603,6 @@ class Settings
int leftClickTimeout, int rightClickTimeout,
int relativeMovement, int relativeMovementSpeed,
int relativeMovementAccel, int showMouseCursor);
public static native void nativeSetExternalMouseDetected();
private static native void nativeSetJoystickUsed();
private static native void nativeSetMultitouchUsed();
private static native void nativeSetTouchscreenKeyboardUsed();

View File

@@ -89,7 +89,10 @@ class Mouse
abstract class DifferentTouchInput
{
public static boolean ExternalMouseDetected = true;
public abstract void process(final MotionEvent event);
public abstract void processGenericEvent(final MotionEvent event);
public static boolean ExternalMouseDetected = false;
public static DifferentTouchInput getInstance()
{
@@ -105,7 +108,9 @@ abstract class DifferentTouchInput
multiTouchAvailable2 = true;
}
try {
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD )
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH && IcsTouchInput.Holder.sInstance != null )
return IcsTouchInput.Holder.sInstance;
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD && XperiaPlayTouchpadTouchInput.Holder.sInstance != null )
return XperiaPlayTouchpadTouchInput.Holder.sInstance;
if (multiTouchAvailable1 && multiTouchAvailable2)
return MultiTouchInput.Holder.sInstance;
@@ -122,8 +127,6 @@ abstract class DifferentTouchInput
}
}
}
public abstract void process(final MotionEvent event);
public abstract void processGenericEvent(final MotionEvent event);
private static class SingleTouchInput extends DifferentTouchInput
{
private static class Holder
@@ -145,14 +148,13 @@ abstract class DifferentTouchInput
if( event.getAction() == MotionEvent.ACTION_MOVE )
action = Mouse.SDL_FINGER_MOVE;
if ( action >= 0 )
DemoGLSurfaceView.nativeMouse( (int)event.getX(), (int)event.getY(), action, 0,
DemoGLSurfaceView.nativeMotionEvent( (int)event.getX(), (int)event.getY(), action, 0,
(int)(event.getPressure() * 1000.0),
(int)(event.getSize() * 1000.0) );
}
}
private static class MultiTouchInput extends DifferentTouchInput
{
public static final int TOUCH_EVENTS_MAX = 16; // Max multitouch pointers
private class touchEvent
@@ -196,7 +198,7 @@ abstract class DifferentTouchInput
if( touchEvents[i].down )
{
touchEvents[i].down = false;
DemoGLSurfaceView.nativeMouse( touchEvents[i].x, touchEvents[i].y, action, i, touchEvents[i].pressure, touchEvents[i].size );
DemoGLSurfaceView.nativeMotionEvent( touchEvents[i].x, touchEvents[i].y, action, i, touchEvents[i].pressure, touchEvents[i].size );
}
}
}
@@ -213,7 +215,7 @@ abstract class DifferentTouchInput
touchEvents[id].y = (int)event.getY(i);
touchEvents[id].pressure = (int)(event.getPressure(i) * 1000.0);
touchEvents[id].size = (int)(event.getSize(i) * 1000.0);
DemoGLSurfaceView.nativeMouse( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
DemoGLSurfaceView.nativeMotionEvent( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
}
}
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE ||
@@ -247,7 +249,7 @@ abstract class DifferentTouchInput
{
action = Mouse.SDL_FINGER_UP;
touchEvents[id].down = false;
DemoGLSurfaceView.nativeMouse( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
DemoGLSurfaceView.nativeMotionEvent( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
}
}
else
@@ -270,20 +272,12 @@ abstract class DifferentTouchInput
touchEvents[id].y = (int)event.getY(ii);
touchEvents[id].pressure = (int)(event.getPressure(ii) * 1000.0);
touchEvents[id].size = (int)(event.getSize(ii) * 1000.0);
DemoGLSurfaceView.nativeMouse( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
DemoGLSurfaceView.nativeMotionEvent( touchEvents[id].x, touchEvents[id].y, action, id, touchEvents[id].pressure, touchEvents[id].size );
}
}
}
if( (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_HOVER_MOVE ) // Support bluetooth/USB mouse - available since Android 3.1
{
/*
if( !ExternalMouseDetected )
{
ExternalMouseDetected = true;
Settings.nativeSetExternalMouseDetected();
Toast.makeText(MainActivity.instance, R.string.hardware_mouse_detected, Toast.LENGTH_SHORT).show();
}
*/
// TODO: it is possible that multiple pointers return that event, but we're handling only pointer #0
if( touchEvents[0].down )
action = Mouse.SDL_FINGER_UP;
@@ -294,7 +288,7 @@ abstract class DifferentTouchInput
touchEvents[0].y = (int)event.getY();
touchEvents[0].pressure = 0;
touchEvents[0].size = 0;
DemoGLSurfaceView.nativeMouse( touchEvents[0].x, touchEvents[0].y, action, 0, touchEvents[0].pressure, touchEvents[0].size );
DemoGLSurfaceView.nativeMotionEvent( touchEvents[0].x, touchEvents[0].y, action, 0, touchEvents[0].pressure, touchEvents[0].size );
}
}
}
@@ -343,19 +337,20 @@ abstract class DifferentTouchInput
minRange = Math.min( Math.abs(ymax - ymin), Math.abs(xmax - xmin) );
}
}
public void process(final MotionEvent event)
{
boolean hwMouseEvent = ( event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == InputDevice.SOURCE_STYLUS );
if( ExternalMouseDetected != hwMouseEvent )
{
ExternalMouseDetected = hwMouseEvent;
DemoGLSurfaceView.nativeHardwareMouseDetected(hwMouseEvent ? 1 : 0);
}
super.process(event);
}
public void processGenericEvent(final MotionEvent event)
{
if( event.getSource() != InputDevice.SOURCE_TOUCHPAD )
{
/*
if( !ExternalMouseDetected &&
( event.getSource() == InputDevice.SOURCE_MOUSE || event.getSource() == InputDevice.SOURCE_STYLUS ) )
{
ExternalMouseDetected = true;
Settings.nativeSetExternalMouseDetected();
Toast.makeText(MainActivity.instance, R.string.hardware_mouse_detected, Toast.LENGTH_SHORT).show();
}
*/
process(event);
return;
}
@@ -385,6 +380,24 @@ abstract class DifferentTouchInput
DemoGLSurfaceView.nativeTouchpad( x, 65535-y, down, multitouch ); // Y axis is inverted, as you may have guessed
}
}
private static class IcsTouchInput extends XperiaPlayTouchpadTouchInput
{
private static class Holder
{
private static final IcsTouchInput sInstance = new IcsTouchInput();
}
private int buttonState = 0;
public void process(final MotionEvent event)
{
if( event.getButtonState() != buttonState )
{
buttonState = event.getButtonState();
//System.out.println("IcsTouchInput: button state " + buttonState);
DemoGLSurfaceView.nativeMouseButtonsPressed(buttonState);
}
super.process(event);
}
}
}
@@ -436,7 +449,6 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
MainActivity.LoadApplicationLibrary(context);
Settings.Apply(context);
DifferentTouchInput.ExternalMouseDetected = false;
accelerometer = new AccelerometerReader(context);
// Tweak video thread priority, if user selected big audio buffer
if(Globals.AudioBufferConfig >= 2)
@@ -676,10 +688,12 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL {
MainActivity mParent;
DifferentTouchInput touchInput = null;
public static native void nativeMouse( int x, int y, int action, int pointerId, int pressure, int radius );
public static native void nativeMotionEvent( int x, int y, int action, int pointerId, int pressure, int radius );
public static native int nativeKey( int keyCode, int down );
public static native void nativeTouchpad( int x, int y, int down, int multitouch );
public static native void initJavaCallbacks();
public static native void nativeHardwareMouseDetected( int detected );
public static native void nativeMouseButtonsPressed( int buttons );
}

View File

@@ -19,16 +19,16 @@ AppUsesMouse=y
AppNeedsTwoButtonMouse=y
ShowMouseCursor=n
ForceRelativeMouseMode=n
AppNeedsArrowKeys=y
AppNeedsArrowKeys=n
AppNeedsTextInput=y
AppUsesJoystick=y
AppUsesJoystick=n
AppHandlesJoystickSensitivity=n
AppUsesMultitouch=y
NonBlockingSwapBuffers=n
RedefinedKeys="SPACE RETURN NO_REMAP NO_REMAP SPACE ESCAPE"
AppTouchscreenKeyboardKeysAmount=0
AppTouchscreenKeyboardKeysAmountAutoFire=0
RedefinedKeysScreenKb="1 2 3 4 5 6 1 2 3 4"
RedefinedKeysScreenKb="0 1 2 3 4 5 6 7 8 9"
StartupMenuButtonTimeout=3000
HiddenMenuOptions='OptionalDownloadConfig'
FirstStartMenuOptions=''

View File

@@ -615,11 +615,12 @@ int main(int argc, char* argv[])
val1 = misaligned_mem_access(val0, 1);
val2 = misaligned_mem_access(val0, 2);
val3 = misaligned_mem_access(val0, 3);
/*
print_num_hex(screen, font_hex, 0, 40, val0);
print_num_hex(screen, font_hex, 0, 60, val1);
print_num_hex(screen, font_hex, 0, 80, val2);
print_num_hex(screen, font_hex, 0, 100, val3);
*/
print_num(screen, font, screen->w-37, screen->h-12, fps);
++fps_count;
@@ -643,10 +644,12 @@ int main(int argc, char* argv[])
if( b )
{
color = 0;
if( b & SDL_BUTTON_LEFT )
color |= 0xff00;
if( b & SDL_BUTTON_RIGHT )
color |= 0xff0000;
if( b & SDL_BUTTON_LMASK )
color |= 0xf000;
if( b & SDL_BUTTON_RMASK )
color |= 0x1f0;
if( b & SDL_BUTTON_MMASK )
color |= 0x1f;
}
r.x = mx;
r.y = my;

View File

@@ -83,40 +83,45 @@ SDL_Joystick *SDL_ANDROID_CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1] = {NULL};
static int TrackballDampening = 0; // in milliseconds
static Uint32 lastTrackballAction = 0;
enum { TOUCH_PTR_UP = 0, TOUCH_PTR_MOUSE = 1, TOUCH_PTR_SCREENKB = 2 };
int touchPointers[MAX_MULTITOUCH_POINTERS] = {0};
int firstMousePointerId = -1;
static int touchPointers[MAX_MULTITOUCH_POINTERS] = {0};
static int firstMousePointerId = -1;
enum { MAX_MULTITOUCH_GESTURES = 4 };
int multitouchGestureKeycode[MAX_MULTITOUCH_GESTURES] = {
static int multitouchGestureKeycode[MAX_MULTITOUCH_GESTURES] = {
SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_6)),
SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_7)),
SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_8)),
SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_9))
};
int multitouchGestureKeyPressed[MAX_MULTITOUCH_GESTURES] = { 0, 0, 0, 0 };
int multitouchGestureSensitivity = 0;
int multitouchGestureDist = -1;
int multitouchGestureAngle = 0;
int multitouchGestureX = -1;
int multitouchGestureY = -1;
static int multitouchGestureKeyPressed[MAX_MULTITOUCH_GESTURES] = { 0, 0, 0, 0 };
static int multitouchGestureSensitivity = 0;
static int multitouchGestureDist = -1;
static int multitouchGestureAngle = 0;
static int multitouchGestureX = -1;
static int multitouchGestureY = -1;
int SDL_ANDROID_TouchscreenCalibrationWidth = 480;
int SDL_ANDROID_TouchscreenCalibrationHeight = 320;
int SDL_ANDROID_TouchscreenCalibrationX = 0;
int SDL_ANDROID_TouchscreenCalibrationY = 0;
int leftClickTimeout = 0;
int rightClickTimeout = 0;
int mouseInitialX = -1;
int mouseInitialY = -1;
unsigned int mouseInitialTime = 0;
volatile int deferredMouseTap = 0;
int relativeMovement = 0;
int relativeMovementSpeed = 2;
int relativeMovementAccel = 0;
int relativeMovementX = 0;
int relativeMovementY = 0;
unsigned int relativeMovementTime = 0;
int oldMouseX = 0;
int oldMouseY = 0;
int oldMouseButtons = 0;
static int leftClickTimeout = 0;
static int rightClickTimeout = 0;
static int mouseInitialX = -1;
static int mouseInitialY = -1;
static unsigned int mouseInitialTime = 0;
static volatile int deferredMouseTap = 0;
static int relativeMovement = 0;
static int relativeMovementSpeed = 2;
static int relativeMovementAccel = 0;
static int relativeMovementX = 0;
static int relativeMovementY = 0;
static unsigned int relativeMovementTime = 0;
static int oldMouseX = 0;
static int oldMouseY = 0;
static int oldMouseButtons = 0;
static int hardwareMouseDetected = 0;
enum { MOUSE_HW_BUTTON_LEFT = 1, MOUSE_HW_BUTTON_RIGHT = 2, MOUSE_HW_BUTTON_MIDDLE = 4, MOUSE_HW_BUTTON_BACK = 8, MOUSE_HW_BUTTON_FORWARD = 16, MOUSE_HW_BUTTON_MAX = MOUSE_HW_BUTTON_FORWARD };
static int hardwareMouseButtonsPressed = 0;
static int hardwareMouseButtonsPressedOld = 0;
static int UnicodeToUtf8(int src, char * dest)
{
@@ -265,7 +270,7 @@ void UpdateScreenUnderFingerRect(int x, int y)
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, jint x, jint y, jint action, jint pointerId, jint force, jint radius )
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject thiz, jint x, jint y, jint action, jint pointerId, jint force, jint radius )
{
// TODO: this method is damn huge
int i;
@@ -351,7 +356,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, j
}
}
}
else
else if( !hardwareMouseDetected )
{
if( firstMousePointerId != pointerId )
{
@@ -438,6 +443,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, j
#endif
// The old, bad, deprecated, but still used multitouch API
/*
if( action == MOUSE_DOWN )
SDL_ANDROID_MainThreadPushJoystickButton(pointerId+1, 0, SDL_PRESSED);
SDL_ANDROID_MainThreadPushJoystickAxis(pointerId+1, 0, x);
@@ -446,6 +452,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, j
SDL_ANDROID_MainThreadPushJoystickAxis(pointerId+1, 3, radius);
if( action == MOUSE_UP )
SDL_ANDROID_MainThreadPushJoystickButton(pointerId+1, 0, SDL_RELEASED);
*/
// The new, good, clean multitouch API, which is using only the first joystick, and sending both X and Y coords simultaneously in one event
if( action == MOUSE_DOWN )
SDL_ANDROID_MainThreadPushJoystickButton(0, pointerId, SDL_PRESSED);
@@ -465,7 +472,46 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, j
if( !isMouseUsed )
return;
if( pointerId == firstMousePointerId )
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Mouse buttons %d pointerId %d firstMousePointerId %d", hardwareMouseButtonsPressed, pointerId, firstMousePointerId);
if( pointerId == firstMousePointerId && (hardwareMouseButtonsPressedOld != hardwareMouseButtonsPressed || hardwareMouseButtonsPressed != 0) )
{
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
for( i = 1; i <= MOUSE_HW_BUTTON_MAX; i *= 2 )
{
int btn = SDL_BUTTON_LEFT;
switch(i)
{
case MOUSE_HW_BUTTON_LEFT:
btn = SDL_BUTTON_LEFT;
break;
case MOUSE_HW_BUTTON_RIGHT:
btn = SDL_BUTTON_RIGHT;
break;
case MOUSE_HW_BUTTON_MIDDLE:
btn = SDL_BUTTON_MIDDLE;
break;
case MOUSE_HW_BUTTON_BACK:
btn = SDL_BUTTON_WHEELUP;
break;
case MOUSE_HW_BUTTON_FORWARD:
btn = SDL_BUTTON_WHEELDOWN;
break;
}
if( (hardwareMouseButtonsPressed & i) && !(hardwareMouseButtonsPressedOld & i) )
{
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Mouse button DOWN: %d", btn);
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, btn );
}
else
if( !(hardwareMouseButtonsPressed & i) && (hardwareMouseButtonsPressedOld & i) )
{
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Mouse button UP : %d", btn);
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, btn );
}
}
hardwareMouseButtonsPressedOld = hardwareMouseButtonsPressed;
}
else if( pointerId == firstMousePointerId )
{
if( relativeMovement )
{
@@ -919,16 +965,54 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
}
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(Settings_nativeSetExternalMouseDetected) (JNIEnv* env, jobject thiz)
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected)
{
if( !isMouseUsed )
return;
leftClickMethod = LEFT_CLICK_NORMAL;
SDL_ANDROID_ShowScreenUnderFinger = 0;
leftClickTimeout = 0;
relativeMovement = 0;
SDL_ANDROID_ShowMouseCursor = 0;
static struct {
int leftClickMethod;
int ShowScreenUnderFinger;
int leftClickTimeout;
int relativeMovement;
int ShowMouseCursor;
} cfg = { 0 };
if( hardwareMouseDetected != detected )
{
hardwareMouseDetected = detected;
if(detected)
{
cfg.leftClickMethod = leftClickMethod;
cfg.ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger;
cfg.leftClickTimeout = leftClickTimeout;
cfg.relativeMovement = relativeMovement;
cfg.ShowMouseCursor = SDL_ANDROID_ShowMouseCursor;
leftClickMethod = LEFT_CLICK_NORMAL;
SDL_ANDROID_ShowScreenUnderFinger = 0;
leftClickTimeout = 0;
relativeMovement = 0;
SDL_ANDROID_ShowMouseCursor = 0;
}
else
{
leftClickMethod = cfg.leftClickMethod;
SDL_ANDROID_ShowScreenUnderFinger = cfg.ShowScreenUnderFinger;
leftClickTimeout = cfg.leftClickTimeout;
relativeMovement = cfg.relativeMovement;
SDL_ANDROID_ShowMouseCursor = cfg.ShowMouseCursor;
}
}
}
JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseButtonsPressed) (JNIEnv* env, jobject thiz, int buttons)
{
if( !isMouseUsed )
return;
hardwareMouseButtonsPressed = buttons;
}
JNIEXPORT void JNICALL