1790 lines
54 KiB
C
1790 lines
54 KiB
C
/*
|
|
SDL - Simple DirectMedia Layer
|
|
Copyright (C) 1997-2009 Sam Lantinga
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
Sam Lantinga
|
|
slouken@libsdl.org
|
|
*/
|
|
#include <jni.h>
|
|
#include <android/log.h>
|
|
#include <sys/time.h>
|
|
#include <time.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
#include <string.h> // for memset()
|
|
|
|
#include "SDL_config.h"
|
|
|
|
#include "SDL_version.h"
|
|
#include "SDL_mutex.h"
|
|
#include "SDL_events.h"
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
#include "SDL_touch.h"
|
|
#include "../../events/SDL_touch_c.h"
|
|
#endif
|
|
|
|
#include "../SDL_sysvideo.h"
|
|
#include "SDL_androidvideo.h"
|
|
#include "SDL_androidinput.h"
|
|
#include "SDL_screenkeyboard.h"
|
|
#include "jniwrapperstuff.h"
|
|
#include "atan2i.h"
|
|
|
|
|
|
static SDLKey SDL_android_keymap[KEYCODE_LAST+1];
|
|
|
|
static inline SDL_scancode TranslateKey(int scancode)
|
|
{
|
|
if ( scancode >= SDL_arraysize(SDL_android_keymap) )
|
|
scancode = KEYCODE_UNKNOWN;
|
|
return SDL_android_keymap[scancode];
|
|
}
|
|
|
|
static int isTrackballUsed = 0;
|
|
static int isMouseUsed = 0;
|
|
|
|
enum { RIGHT_CLICK_NONE = 0, RIGHT_CLICK_WITH_MULTITOUCH = 1, RIGHT_CLICK_WITH_PRESSURE = 2, RIGHT_CLICK_WITH_KEY = 3, RIGHT_CLICK_WITH_TIMEOUT = 4 };
|
|
enum { LEFT_CLICK_NORMAL = 0, LEFT_CLICK_NEAR_CURSOR = 1, LEFT_CLICK_WITH_MULTITOUCH = 2, LEFT_CLICK_WITH_PRESSURE = 3,
|
|
LEFT_CLICK_WITH_KEY = 4, LEFT_CLICK_WITH_TIMEOUT = 5, LEFT_CLICK_WITH_TAP = 6, LEFT_CLICK_WITH_TAP_OR_TIMEOUT = 7 };
|
|
static int leftClickMethod = LEFT_CLICK_NORMAL;
|
|
static int rightClickMethod = RIGHT_CLICK_NONE;
|
|
static int leftClickKey = KEYCODE_DPAD_CENTER;
|
|
static int rightClickKey = KEYCODE_MENU;
|
|
int SDL_ANDROID_ShowScreenUnderFinger = 0;
|
|
SDL_Rect SDL_ANDROID_ShowScreenUnderFingerRect = {0, 0, 0, 0}, SDL_ANDROID_ShowScreenUnderFingerRectSrc = {0, 0, 0, 0};
|
|
static int moveMouseWithArrowKeys = 0;
|
|
static int clickMouseWithDpadCenter = 0;
|
|
static int moveMouseWithKbSpeed = 0;
|
|
static int moveMouseWithKbAccel = 0;
|
|
static int moveMouseWithKbX = -1, moveMouseWithKbY = -1;
|
|
static int moveMouseWithKbSpeedX = 0, moveMouseWithKbSpeedY = 0;
|
|
static int moveMouseWithKbAccelX = 0, moveMouseWithKbAccelY = 0;
|
|
static int moveMouseWithKbAccelUpdateNeeded = 0;
|
|
static int maxForce = 0;
|
|
static int maxRadius = 0;
|
|
int SDL_ANDROID_isJoystickUsed = 0;
|
|
static int isMultitouchUsed = 0;
|
|
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;
|
|
enum { MAX_MULTITOUCH_GESTURES = 4 };
|
|
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;
|
|
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;
|
|
int deferredMouseTap = 0;
|
|
int relativeMovement = 0;
|
|
int relativeMovementSpeed = 0;
|
|
int relativeMovementAccel = 0;
|
|
int relativeMovementX = 0;
|
|
int relativeMovementY = 0;
|
|
|
|
static inline int InsideRect(const SDL_Rect * r, int x, int y)
|
|
{
|
|
return ( x >= r->x && x <= r->x + r->w ) && ( y >= r->y && y <= r->y + r->h );
|
|
}
|
|
|
|
void UpdateScreenUnderFingerRect(int x, int y)
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
return;
|
|
/*
|
|
int screenX = 320, screenY = 240;
|
|
if( !SDL_ANDROID_ShowScreenUnderFinger )
|
|
return;
|
|
|
|
SDL_Window * window = SDL_GetFocusWindow();
|
|
if( window && window->renderer->window ) {
|
|
screenX = window->w;
|
|
screenY = window->h;
|
|
}
|
|
*/
|
|
#else
|
|
int screenX = SDL_ANDROID_sFakeWindowWidth, screenY = SDL_ANDROID_sFakeWindowHeight;
|
|
if( !SDL_ANDROID_ShowScreenUnderFinger )
|
|
return;
|
|
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 4;
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 4;
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2;
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 )
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 )
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w )
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h )
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h;
|
|
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.w = SDL_ANDROID_ShowScreenUnderFingerRectSrc.w * 3 / 2;
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.h = SDL_ANDROID_ShowScreenUnderFingerRectSrc.h * 3 / 2;
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.x = x + SDL_ANDROID_ShowScreenUnderFingerRect.w/10;
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.y = y - SDL_ANDROID_ShowScreenUnderFingerRect.h*11/10;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRect.x < 0 )
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.x = 0;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRect.y < 0 )
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.y = 0;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRect.x + SDL_ANDROID_ShowScreenUnderFingerRect.w >= screenX )
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w - 1;
|
|
if( SDL_ANDROID_ShowScreenUnderFingerRect.y + SDL_ANDROID_ShowScreenUnderFingerRect.h >= screenY )
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h - 1;
|
|
if( InsideRect(&SDL_ANDROID_ShowScreenUnderFingerRect, x, y) )
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.x = x - SDL_ANDROID_ShowScreenUnderFingerRect.w*11/10 - 1;
|
|
#endif
|
|
}
|
|
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, jint x, jint y, jint action, jint pointerId, jint force, jint radius )
|
|
{
|
|
int i;
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
|
|
SDL_Window * window = SDL_GetFocusWindow();
|
|
if( !window )
|
|
return;
|
|
|
|
#define SDL_ANDROID_sFakeWindowWidth window->w
|
|
#define SDL_ANDROID_sFakeWindowHeight window->h
|
|
|
|
#else
|
|
if( !SDL_CurrentVideoSurface )
|
|
return;
|
|
#endif
|
|
if(pointerId < 0)
|
|
pointerId = 0;
|
|
if(pointerId > MAX_MULTITOUCH_POINTERS)
|
|
pointerId = MAX_MULTITOUCH_POINTERS;
|
|
|
|
// The touch is passed either to on-screen keyboard or as mouse event for all duration of touch between down and up,
|
|
// even if the finger is not anymore above screen kb button it will not acr as mouse event, and if it's initially
|
|
// touches the screen outside of screen kb it won't trigger button keypress -
|
|
// I think it's more logical this way
|
|
if( SDL_ANDROID_isTouchscreenKeyboardUsed && ( action == MOUSE_DOWN || touchPointers[pointerId] == TOUCH_PTR_SCREENKB ) )
|
|
{
|
|
if( SDL_ANDROID_processTouchscreenKeyboard(x, y, action, pointerId) && action == MOUSE_DOWN )
|
|
touchPointers[pointerId] = TOUCH_PTR_SCREENKB;
|
|
if( touchPointers[pointerId] == TOUCH_PTR_SCREENKB )
|
|
{
|
|
if( action == MOUSE_UP )
|
|
touchPointers[pointerId] = TOUCH_PTR_UP;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if( action == MOUSE_DOWN )
|
|
{
|
|
touchPointers[pointerId] = TOUCH_PTR_MOUSE;
|
|
firstMousePointerId = -1;
|
|
for( i = 0; i < MAX_MULTITOUCH_POINTERS; i++ )
|
|
{
|
|
if( touchPointers[i] == TOUCH_PTR_MOUSE )
|
|
{
|
|
firstMousePointerId = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
x -= SDL_ANDROID_TouchscreenCalibrationX;
|
|
y -= SDL_ANDROID_TouchscreenCalibrationY;
|
|
#if SDL_VIDEO_RENDER_RESIZE
|
|
// Translate mouse coordinates
|
|
|
|
x = x * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_TouchscreenCalibrationWidth;
|
|
y = y * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_TouchscreenCalibrationHeight;
|
|
if( x < 0 )
|
|
x = 0;
|
|
if( x > SDL_ANDROID_sFakeWindowWidth )
|
|
x = SDL_ANDROID_sFakeWindowWidth;
|
|
if( y < 0 )
|
|
y = 0;
|
|
if( y > SDL_ANDROID_sFakeWindowHeight )
|
|
y = SDL_ANDROID_sFakeWindowHeight;
|
|
#else
|
|
x = x * SDL_ANDROID_sRealWindowWidth / SDL_ANDROID_TouchscreenCalibrationWidth;
|
|
y = y * SDL_ANDROID_sRealWindowHeight / SDL_ANDROID_TouchscreenCalibrationHeight;
|
|
#endif
|
|
|
|
if( action == MOUSE_UP )
|
|
{
|
|
multitouchGestureX = -1;
|
|
multitouchGestureY = -1;
|
|
multitouchGestureDist = -1;
|
|
for(i = 0; i < MAX_MULTITOUCH_GESTURES; i++)
|
|
{
|
|
if( multitouchGestureKeyPressed[i] )
|
|
{
|
|
multitouchGestureKeyPressed[i] = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[i] );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( firstMousePointerId != pointerId )
|
|
{
|
|
multitouchGestureX = x;
|
|
multitouchGestureY = y;
|
|
}
|
|
if( firstMousePointerId == pointerId && multitouchGestureX >= 0 )
|
|
{
|
|
int dist = abs( x - multitouchGestureX ) + abs( y - multitouchGestureY );
|
|
int angle = atan2i( y - multitouchGestureY, x - multitouchGestureX );
|
|
if( multitouchGestureDist < 0 )
|
|
{
|
|
multitouchGestureDist = dist;
|
|
multitouchGestureAngle = angle;
|
|
}
|
|
else
|
|
{
|
|
int distMaxDiff = SDL_ANDROID_sFakeWindowHeight / ( 1 + (1 + multitouchGestureSensitivity) * 2 );
|
|
int angleMaxDiff = atan2i_PI / ( 1 + (1 + multitouchGestureSensitivity) * 2 );
|
|
if( dist - multitouchGestureDist > distMaxDiff )
|
|
{
|
|
multitouchGestureKeyPressed[0] = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[0] );
|
|
}
|
|
else
|
|
if( multitouchGestureKeyPressed[0] )
|
|
{
|
|
multitouchGestureKeyPressed[0] = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[0] );
|
|
}
|
|
if( multitouchGestureDist - dist > distMaxDiff )
|
|
{
|
|
multitouchGestureKeyPressed[1] = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] );
|
|
}
|
|
else
|
|
if( multitouchGestureKeyPressed[1] )
|
|
{
|
|
multitouchGestureKeyPressed[1] = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[1] );
|
|
}
|
|
|
|
int angleDiff = angle - multitouchGestureAngle;
|
|
|
|
while( angleDiff < atan2i_PI )
|
|
angleDiff += atan2i_PI * 2;
|
|
while( angleDiff > atan2i_PI )
|
|
angleDiff -= atan2i_PI * 2;
|
|
|
|
if( angleDiff < -angleMaxDiff )
|
|
{
|
|
multitouchGestureKeyPressed[2] = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[2] );
|
|
}
|
|
else
|
|
if( multitouchGestureKeyPressed[2] )
|
|
{
|
|
multitouchGestureKeyPressed[2] = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[2] );
|
|
}
|
|
if( angleDiff > angleMaxDiff )
|
|
{
|
|
multitouchGestureKeyPressed[3] = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[3] );
|
|
}
|
|
else
|
|
if( multitouchGestureKeyPressed[3] )
|
|
{
|
|
multitouchGestureKeyPressed[3] = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[3] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( isMultitouchUsed )
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
// Use nifty SDL 1.3 multitouch API
|
|
if( action == MOUSE_MOVE )
|
|
SDL_ANDROID_MainThreadPushMultitouchMotion(pointerId, x, y, force*radius / 16);
|
|
else
|
|
SDL_ANDROID_MainThreadPushMultitouchButton(pointerId, action == MOUSE_DOWN ? 1 : 0, x, y, force*radius / 16);
|
|
#endif
|
|
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(pointerId+1, 0, x);
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(pointerId+1, 1, y);
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(pointerId+1, 2, force);
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(pointerId+1, 3, radius);
|
|
if( action == MOUSE_DOWN )
|
|
SDL_ANDROID_MainThreadPushJoystickButton(pointerId+1, 0, SDL_PRESSED);
|
|
if( action == MOUSE_UP )
|
|
SDL_ANDROID_MainThreadPushJoystickButton(pointerId+1, 0, SDL_RELEASED);
|
|
}
|
|
if( !isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed )
|
|
{
|
|
SDL_keysym keysym;
|
|
if( action != MOUSE_MOVE )
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( action == MOUSE_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_ANDROID_GetScreenKeyboardButtonKey(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0) );
|
|
return;
|
|
}
|
|
|
|
if( !isMouseUsed )
|
|
return;
|
|
|
|
if( pointerId == firstMousePointerId )
|
|
{
|
|
int oldX, oldY;
|
|
SDL_GetMouseState( &oldX, &oldY );
|
|
if( relativeMovement )
|
|
{
|
|
if( action == MOUSE_DOWN )
|
|
{
|
|
relativeMovementX = oldX - x;
|
|
relativeMovementY = oldY - y;
|
|
}
|
|
x += relativeMovementX;
|
|
y += relativeMovementY;
|
|
if( x < 0 )
|
|
x = 0;
|
|
if( x > SDL_ANDROID_sFakeWindowWidth )
|
|
x = SDL_ANDROID_sFakeWindowWidth;
|
|
if( y < 0 )
|
|
y = 0;
|
|
if( y > SDL_ANDROID_sFakeWindowHeight )
|
|
y = SDL_ANDROID_sFakeWindowHeight;
|
|
}
|
|
if( action == MOUSE_UP )
|
|
{
|
|
if( mouseInitialX >= 0 && mouseInitialY >= 0 && (
|
|
leftClickMethod == LEFT_CLICK_WITH_TAP || leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT ) &&
|
|
abs(mouseInitialX - x) < SDL_ANDROID_sFakeWindowHeight / 6 &&
|
|
abs(mouseInitialY - y) < SDL_ANDROID_sFakeWindowHeight / 6 &&
|
|
SDL_GetTicks() - mouseInitialTime < 300 )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY);
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT );
|
|
deferredMouseTap = 2;
|
|
mouseInitialX = -1;
|
|
mouseInitialY = -1;
|
|
}
|
|
else
|
|
{
|
|
if( SDL_GetMouseState( NULL, NULL ) & SDL_BUTTON(SDL_BUTTON_LEFT) )
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
|
if( SDL_GetMouseState( NULL, NULL ) & SDL_BUTTON(SDL_BUTTON_RIGHT) )
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT );
|
|
}
|
|
|
|
SDL_ANDROID_ShowScreenUnderFingerRect.w = SDL_ANDROID_ShowScreenUnderFingerRect.h = 0;
|
|
SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = 0;
|
|
if( SDL_ANDROID_ShowScreenUnderFinger )
|
|
{
|
|
// Move mouse by 1 pixel so it will force screen update and mouse-under-finger window will be removed
|
|
if( moveMouseWithKbX >= 0 )
|
|
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX > 0 ? moveMouseWithKbX-1 : 0, moveMouseWithKbY);
|
|
else
|
|
SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y);
|
|
}
|
|
moveMouseWithKbX = -1;
|
|
moveMouseWithKbY = -1;
|
|
moveMouseWithKbSpeedX = 0;
|
|
moveMouseWithKbSpeedY = 0;
|
|
}
|
|
if( action == MOUSE_DOWN )
|
|
{
|
|
if( (moveMouseWithKbX >= 0 || leftClickMethod == LEFT_CLICK_NEAR_CURSOR) &&
|
|
abs(oldX - x) < SDL_ANDROID_sFakeWindowWidth / 4 && abs(oldY - y) < SDL_ANDROID_sFakeWindowHeight / 4 )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT );
|
|
moveMouseWithKbX = oldX;
|
|
moveMouseWithKbY = oldY;
|
|
action == MOUSE_MOVE;
|
|
}
|
|
else
|
|
if( leftClickMethod == LEFT_CLICK_NORMAL )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT );
|
|
}
|
|
else
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
|
action == MOUSE_MOVE;
|
|
mouseInitialX = x;
|
|
mouseInitialY = y;
|
|
mouseInitialTime = SDL_GetTicks();
|
|
}
|
|
UpdateScreenUnderFingerRect(x, y);
|
|
}
|
|
if( action == MOUSE_MOVE )
|
|
{
|
|
if( moveMouseWithKbX >= 0 )
|
|
{
|
|
if( abs(moveMouseWithKbX - x) > SDL_ANDROID_sFakeWindowWidth / 10 )
|
|
moveMouseWithKbSpeedX += moveMouseWithKbX > x ? -1 : 1;
|
|
else
|
|
moveMouseWithKbSpeedX = moveMouseWithKbSpeedX * 2 / 3;
|
|
if( abs(moveMouseWithKbY - y) > SDL_ANDROID_sFakeWindowHeight / 10 )
|
|
moveMouseWithKbSpeedY += moveMouseWithKbY > y ? -1 : 1;
|
|
else
|
|
moveMouseWithKbSpeedY = moveMouseWithKbSpeedY * 2 / 3;
|
|
|
|
moveMouseWithKbX += moveMouseWithKbSpeedX;
|
|
moveMouseWithKbY += moveMouseWithKbSpeedY;
|
|
|
|
if( abs(moveMouseWithKbX - x) > SDL_ANDROID_sFakeWindowWidth / 5 ||
|
|
abs(moveMouseWithKbY - y) > SDL_ANDROID_sFakeWindowHeight / 5 )
|
|
{
|
|
moveMouseWithKbX = -1;
|
|
moveMouseWithKbY = -1;
|
|
moveMouseWithKbSpeedX = 0;
|
|
moveMouseWithKbSpeedY = 0;
|
|
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
|
}
|
|
else
|
|
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY);
|
|
}
|
|
else
|
|
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
|
|
|
if( rightClickMethod == RIGHT_CLICK_WITH_PRESSURE || leftClickMethod == LEFT_CLICK_WITH_PRESSURE )
|
|
{
|
|
int button = (leftClickMethod == LEFT_CLICK_WITH_PRESSURE) ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT;
|
|
int buttonState = ( force > maxForce || radius > maxRadius );
|
|
if( button == SDL_BUTTON_RIGHT && (SDL_GetMouseState( NULL, NULL ) & SDL_BUTTON(SDL_BUTTON_LEFT)) )
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
|
if( ( (SDL_GetMouseState( NULL, NULL ) & SDL_BUTTON(button)) != 0 ) != buttonState )
|
|
SDL_ANDROID_MainThreadPushMouseButton( buttonState ? SDL_PRESSED : SDL_RELEASED, button );
|
|
}
|
|
if( mouseInitialX >= 0 && mouseInitialY >= 0 && (
|
|
leftClickMethod == LEFT_CLICK_WITH_TIMEOUT || leftClickMethod == LEFT_CLICK_WITH_TAP ||
|
|
leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT || rightClickMethod == RIGHT_CLICK_WITH_TIMEOUT ) )
|
|
{
|
|
if( abs(mouseInitialX - x) >= SDL_ANDROID_sFakeWindowHeight / 6 || abs(mouseInitialY - y) >= SDL_ANDROID_sFakeWindowHeight / 6 )
|
|
{
|
|
mouseInitialX = -1;
|
|
mouseInitialY = -1;
|
|
}
|
|
else
|
|
{
|
|
if( leftClickMethod == LEFT_CLICK_WITH_TIMEOUT || leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT )
|
|
{
|
|
if( SDL_GetTicks() - mouseInitialTime > leftClickTimeout )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY);
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT );
|
|
mouseInitialX = -1;
|
|
mouseInitialY = -1;
|
|
}
|
|
}
|
|
if( rightClickMethod == RIGHT_CLICK_WITH_TIMEOUT )
|
|
{
|
|
if( SDL_GetTicks() - mouseInitialTime > rightClickTimeout )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY);
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT );
|
|
mouseInitialX = -1;
|
|
mouseInitialY = -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
UpdateScreenUnderFingerRect(x, y);
|
|
}
|
|
}
|
|
if( pointerId != firstMousePointerId && (action == MOUSE_DOWN || action == MOUSE_UP) )
|
|
{
|
|
if( leftClickMethod == LEFT_CLICK_WITH_MULTITOUCH )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseButton( (action == MOUSE_DOWN) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT );
|
|
}
|
|
else if( rightClickMethod == RIGHT_CLICK_WITH_MULTITOUCH )
|
|
{
|
|
if( SDL_GetMouseState( NULL, NULL ) & SDL_BUTTON(SDL_BUTTON_LEFT) )
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
|
SDL_ANDROID_MainThreadPushMouseButton( (action == MOUSE_DOWN) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT );
|
|
}
|
|
}
|
|
|
|
if( action == MOUSE_UP )
|
|
{
|
|
touchPointers[pointerId] = TOUCH_PTR_UP;
|
|
firstMousePointerId = -1;
|
|
for( i = 0; i < MAX_MULTITOUCH_POINTERS; i++ )
|
|
{
|
|
if( touchPointers[i] == TOUCH_PTR_MOUSE )
|
|
{
|
|
firstMousePointerId = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProcessDeferredMouseTap()
|
|
{
|
|
if( deferredMouseTap > 0 )
|
|
{
|
|
deferredMouseTap--;
|
|
if( !deferredMouseTap )
|
|
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
|
}
|
|
}
|
|
|
|
void SDL_ANDROID_WarpMouse(int x, int y)
|
|
{
|
|
if(!relativeMovement)
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
|
}
|
|
else
|
|
{
|
|
relativeMovementX = x;
|
|
relativeMovementY = y;
|
|
}
|
|
};
|
|
|
|
static int processAndroidTrackball(int key, int action);
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeKey) ( JNIEnv* env, jobject thiz, jint key, jint action )
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
#else
|
|
if( !SDL_CurrentVideoSurface )
|
|
return;
|
|
#endif
|
|
if( isTrackballUsed )
|
|
if( processAndroidTrackball(key, action) )
|
|
return;
|
|
if( key == rightClickKey && rightClickMethod == RIGHT_CLICK_WITH_KEY )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseButton( action ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT );
|
|
return;
|
|
}
|
|
if( (key == leftClickKey && leftClickMethod == LEFT_CLICK_WITH_KEY) || (clickMouseWithDpadCenter && key == KEYCODE_DPAD_CENTER) )
|
|
{
|
|
SDL_ANDROID_MainThreadPushMouseButton( action ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT );
|
|
return;
|
|
}
|
|
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( action ? SDL_PRESSED : SDL_RELEASED, TranslateKey(key) );
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(DemoRenderer_nativeTextInput) ( JNIEnv* env, jobject thiz, jint ascii, jint unicode )
|
|
{
|
|
SDL_ANDROID_MainThreadPushText(ascii, unicode);
|
|
}
|
|
|
|
|
|
static void updateOrientation ( float accX, float accY, float accZ );
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(AccelerometerReader_nativeAccelerometer) ( JNIEnv* env, jobject thiz, jfloat accPosX, jfloat accPosY, jfloat accPosZ )
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
#else
|
|
if( !SDL_CurrentVideoSurface )
|
|
return;
|
|
#endif
|
|
// Calculate two angles from three coordinates - TODO: this is faulty!
|
|
//float accX = atan2f(-accPosX, sqrtf(accPosY*accPosY+accPosZ*accPosZ) * ( accPosY > 0 ? 1.0f : -1.0f ) ) * M_1_PI * 180.0f;
|
|
//float accY = atan2f(accPosZ, accPosY) * M_1_PI;
|
|
|
|
float normal = sqrt(accPosX*accPosX+accPosY*accPosY+accPosZ*accPosZ);
|
|
if(normal <= 0.0000001f)
|
|
normal = 0.00001f;
|
|
|
|
|
|
updateOrientation (accPosX/normal, accPosY/normal, 0.0f);
|
|
}
|
|
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(AccelerometerReader_nativeOrientation) ( JNIEnv* env, jobject thiz, jfloat accX, jfloat accY, jfloat accZ )
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
#else
|
|
if( !SDL_CurrentVideoSurface )
|
|
return;
|
|
#endif
|
|
updateOrientation (accX, accY, accZ); // TODO: make values in range 0.0:1.0
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetTrackballUsed) ( JNIEnv* env, jobject thiz)
|
|
{
|
|
isTrackballUsed = 1;
|
|
}
|
|
|
|
static int getClickTimeout(int v)
|
|
{
|
|
switch(v)
|
|
{
|
|
case 0: return 300;
|
|
case 1: return 500;
|
|
case 2: return 700;
|
|
case 3: return 1000;
|
|
case 4: return 1500;
|
|
}
|
|
return 1000;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) ( JNIEnv* env, jobject thiz,
|
|
jint RightClickMethod, jint ShowScreenUnderFinger, jint LeftClickMethod,
|
|
jint MoveMouseWithJoystick, jint ClickMouseWithDpad,
|
|
jint MaxForce, jint MaxRadius,
|
|
jint MoveMouseWithJoystickSpeed, jint MoveMouseWithJoystickAccel,
|
|
jint LeftClickKeycode, jint RightClickKeycode,
|
|
jint LeftClickTimeout, jint RightClickTimeout,
|
|
jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel)
|
|
{
|
|
isMouseUsed = 1;
|
|
rightClickMethod = RightClickMethod;
|
|
SDL_ANDROID_ShowScreenUnderFinger = ShowScreenUnderFinger;
|
|
moveMouseWithArrowKeys = MoveMouseWithJoystick;
|
|
clickMouseWithDpadCenter = ClickMouseWithDpad;
|
|
leftClickMethod = LeftClickMethod;
|
|
maxForce = MaxForce;
|
|
maxRadius = MaxRadius;
|
|
moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1;
|
|
moveMouseWithKbAccel = MoveMouseWithJoystickAccel;
|
|
leftClickKey = LeftClickKeycode;
|
|
rightClickKey = RightClickKeycode;
|
|
leftClickTimeout = getClickTimeout(LeftClickTimeout);
|
|
rightClickTimeout = getClickTimeout(RightClickTimeout);
|
|
relativeMovement = RelativeMovement;
|
|
relativeMovementSpeed = RelativeMovementSpeed;
|
|
relativeMovementAccel = RelativeMovementAccel;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetJoystickUsed) ( JNIEnv* env, jobject thiz)
|
|
{
|
|
SDL_ANDROID_isJoystickUsed = 1;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetMultitouchUsed) ( JNIEnv* env, jobject thiz)
|
|
{
|
|
isMultitouchUsed = 1;
|
|
}
|
|
|
|
|
|
static float dx = 0.04, dy = 0.1, dz = 0.1, joystickSensitivity = 400.0f; // For accelerometer
|
|
enum { ACCELEROMETER_CENTER_FLOATING, ACCELEROMETER_CENTER_FIXED_START, ACCELEROMETER_CENTER_FIXED_HORIZ };
|
|
static int accelerometerCenterPos = ACCELEROMETER_CENTER_FLOATING;
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetAccelerometerSettings) ( JNIEnv* env, jobject thiz, jint sensitivity, jint centerPos)
|
|
{
|
|
dx = 0.04; dy = 0.08; dz = 0.08; joystickSensitivity = 32767.0f * 3.0f; // Fast sensitivity
|
|
if( sensitivity == 1 )
|
|
{
|
|
dx = 0.1; dy = 0.15; dz = 0.15; joystickSensitivity = 32767.0f * 2.0f; // Medium sensitivity
|
|
}
|
|
if( sensitivity == 2 )
|
|
{
|
|
dx = 0.2; dy = 0.25; dz = 0.25; joystickSensitivity = 32767.0f; // Slow sensitivity
|
|
}
|
|
accelerometerCenterPos = centerPos;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetTrackballDampening) ( JNIEnv* env, jobject thiz, jint value)
|
|
{
|
|
TrackballDampening = (value * 200);
|
|
}
|
|
|
|
void updateOrientation ( float accX, float accY, float accZ )
|
|
{
|
|
SDL_keysym keysym;
|
|
// TODO: ask user for accelerometer precision from Java
|
|
|
|
static float midX = 0, midY = 0, midZ = 0;
|
|
static int pressLeft = 0, pressRight = 0, pressUp = 0, pressDown = 0, pressR = 0, pressL = 0;
|
|
|
|
if( accelerometerCenterPos == ACCELEROMETER_CENTER_FIXED_START )
|
|
{
|
|
accelerometerCenterPos = ACCELEROMETER_CENTER_FIXED_HORIZ;
|
|
midX = accX;
|
|
midY = accY;
|
|
midZ = accZ;
|
|
}
|
|
|
|
// midX = 0.0f; // Do not remember old value for phone tilt, it feels weird
|
|
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): %f %f %f", accX, accY, accZ);
|
|
|
|
if( SDL_ANDROID_isJoystickUsed ) // TODO: mutex for that stuff?
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): sending joystick event");
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accX - midX) * joystickSensitivity))));
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accY - midY) * joystickSensitivity))));
|
|
SDL_ANDROID_MainThreadPushJoystickAxis(0, 2, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accZ - midZ) * joystickSensitivity))));
|
|
|
|
if( accelerometerCenterPos == ACCELEROMETER_CENTER_FLOATING )
|
|
{
|
|
if( accY < midY - dy*2 )
|
|
midY = accY + dy*2;
|
|
if( accY > midY + dy*2 )
|
|
midY = accY - dy*2;
|
|
if( accZ < midZ - dz*2 )
|
|
midZ = accZ + dz*2;
|
|
if( accZ > midZ + dz*2 )
|
|
midZ = accZ - dz*2;
|
|
}
|
|
}
|
|
|
|
if(SDL_ANDROID_isJoystickUsed)
|
|
return;
|
|
|
|
if( accX < midX - dx )
|
|
{
|
|
if( !pressLeft )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press left, acc %f mid %f d %f", accX, midX, dx);
|
|
pressLeft = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_LEFT) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pressLeft )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release left, acc %f mid %f d %f", accX, midX, dx);
|
|
pressLeft = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) );
|
|
}
|
|
}
|
|
if( accX < midX - dx*2 )
|
|
midX = accX + dx*2;
|
|
|
|
if( accX > midX + dx )
|
|
{
|
|
if( !pressRight )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press right, acc %f mid %f d %f", accX, midX, dx);
|
|
pressRight = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_RIGHT) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pressRight )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release right, acc %f mid %f d %f", accX, midX, dx);
|
|
pressRight = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) );
|
|
}
|
|
}
|
|
if( accX > midX + dx*2 )
|
|
midX = accX - dx*2;
|
|
|
|
if( accY < midY - dy )
|
|
{
|
|
if( !pressUp )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press up, acc %f mid %f d %f", accY, midY, dy);
|
|
pressUp = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pressUp )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release up, acc %f mid %f d %f", accY, midY, dy);
|
|
pressUp = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) );
|
|
}
|
|
}
|
|
if( accY < midY - dy*2 )
|
|
midY = accY + dy*2;
|
|
|
|
if( accY > midY + dy )
|
|
{
|
|
if( !pressDown )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press down, acc %f mid %f d %f", accY, midY, dy);
|
|
pressDown = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pressDown )
|
|
{
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release down, acc %f mid %f d %f", accY, midY, dy);
|
|
pressDown = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) );
|
|
}
|
|
}
|
|
if( accY > midY + dy*2 )
|
|
midY = accY - dy*2;
|
|
|
|
if( accZ < midZ - dz )
|
|
{
|
|
if( !pressL )
|
|
{
|
|
pressL = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_ALT_LEFT) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pressL )
|
|
{
|
|
pressL = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_ALT_LEFT) );
|
|
}
|
|
}
|
|
if( accZ < midZ - dz*2 )
|
|
midZ = accZ + dz*2;
|
|
|
|
if( accZ > midZ + dz )
|
|
{
|
|
if( !pressR )
|
|
{
|
|
pressR = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_ALT_RIGHT) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pressR )
|
|
{
|
|
pressR = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_ALT_RIGHT) );
|
|
}
|
|
}
|
|
if( accZ > midZ + dz*2 )
|
|
midZ = accZ - dz*2;
|
|
|
|
}
|
|
|
|
static int leftPressed = 0, rightPressed = 0, upPressed = 0, downPressed = 0;
|
|
|
|
int processAndroidTrackball(int key, int action)
|
|
{
|
|
SDL_keysym keysym;
|
|
|
|
if( ! action && (
|
|
key == KEYCODE_DPAD_UP ||
|
|
key == KEYCODE_DPAD_DOWN ||
|
|
key == KEYCODE_DPAD_LEFT ||
|
|
key == KEYCODE_DPAD_RIGHT ) )
|
|
return 1;
|
|
lastTrackballAction = SDL_GetTicks();
|
|
|
|
if( key == KEYCODE_DPAD_UP )
|
|
{
|
|
if( downPressed )
|
|
{
|
|
downPressed = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) );
|
|
return 1;
|
|
}
|
|
if( !upPressed )
|
|
{
|
|
upPressed = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
else
|
|
{
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) );
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
if( key == KEYCODE_DPAD_DOWN )
|
|
{
|
|
if( upPressed )
|
|
{
|
|
upPressed = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) );
|
|
return 1;
|
|
}
|
|
if( !upPressed )
|
|
{
|
|
downPressed = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
else
|
|
{
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) );
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
if( key == KEYCODE_DPAD_LEFT )
|
|
{
|
|
if( rightPressed )
|
|
{
|
|
rightPressed = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) );
|
|
return 1;
|
|
}
|
|
if( !leftPressed )
|
|
{
|
|
leftPressed = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
else
|
|
{
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) );
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
if( key == KEYCODE_DPAD_RIGHT )
|
|
{
|
|
if( leftPressed )
|
|
{
|
|
leftPressed = 0;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) );
|
|
return 1;
|
|
}
|
|
if( !rightPressed )
|
|
{
|
|
rightPressed = 1;
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
else
|
|
{
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) );
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) );
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void SDL_ANDROID_processAndroidTrackballDampening()
|
|
{
|
|
if( !TrackballDampening )
|
|
return;
|
|
if( SDL_GetTicks() > TrackballDampening + lastTrackballAction )
|
|
{
|
|
if( upPressed )
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) );
|
|
if( downPressed )
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) );
|
|
if( leftPressed )
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) );
|
|
if( rightPressed )
|
|
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) );
|
|
upPressed = 0;
|
|
downPressed = 0;
|
|
leftPressed = 0;
|
|
rightPressed = 0;
|
|
}
|
|
}
|
|
|
|
int SDL_SYS_JoystickInit(void)
|
|
{
|
|
SDL_numjoysticks = 0;
|
|
if( SDL_ANDROID_isJoystickUsed )
|
|
SDL_numjoysticks = 1;
|
|
if( isMultitouchUsed )
|
|
SDL_numjoysticks = MAX_MULTITOUCH_POINTERS+1;
|
|
|
|
return(SDL_numjoysticks);
|
|
}
|
|
|
|
/* Function to get the device-dependent name of a joystick */
|
|
const char *SDL_SYS_JoystickName(int index)
|
|
{
|
|
if(index)
|
|
return("Android multitouch");
|
|
return("Android accelerometer/orientation sensor");
|
|
}
|
|
|
|
/* Function to open a joystick for use.
|
|
The joystick to open is specified by the index field of the joystick.
|
|
This should fill the nbuttons and naxes fields of the joystick structure.
|
|
It returns 0, or -1 if there is an error.
|
|
*/
|
|
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
|
|
{
|
|
joystick->nbuttons = 0; // Ignored
|
|
joystick->nhats = 0;
|
|
joystick->nballs = 0;
|
|
if( joystick->index == 0 )
|
|
joystick->naxes = 3;
|
|
else
|
|
{
|
|
joystick->naxes = 4;
|
|
joystick->nbuttons = 1;
|
|
}
|
|
SDL_ANDROID_CurrentJoysticks[joystick->index] = joystick;
|
|
return(0);
|
|
}
|
|
|
|
/* Function to update the state of a joystick - called as a device poll.
|
|
* This function shouldn't update the joystick structure directly,
|
|
* but instead should call SDL_PrivateJoystick*() to deliver events
|
|
* and update joystick device state.
|
|
*/
|
|
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Function to close a joystick after use */
|
|
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
|
|
{
|
|
SDL_ANDROID_CurrentJoysticks[joystick->index] = NULL;
|
|
return;
|
|
}
|
|
|
|
/* Function to perform any system-specific joystick related cleanup */
|
|
void SDL_SYS_JoystickQuit(void)
|
|
{
|
|
int i;
|
|
for(i=0; i<MAX_MULTITOUCH_POINTERS+1; i++)
|
|
SDL_ANDROID_CurrentJoysticks[i] = NULL;
|
|
return;
|
|
}
|
|
|
|
|
|
enum { MAX_BUFFERED_EVENTS = 64 };
|
|
static SDL_Event BufferedEvents[MAX_BUFFERED_EVENTS];
|
|
static int BufferedEventsStart = 0, BufferedEventsEnd = 0;
|
|
static SDL_mutex * BufferedEventsMutex = NULL;
|
|
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
|
|
#define SDL_SendKeyboardKey(state, keysym) SDL_SendKeyboardKey(state, (keysym)->sym)
|
|
|
|
#else
|
|
|
|
#define SDL_SendMouseMotion(A,B,X,Y) SDL_PrivateMouseMotion(0, 0, X, Y)
|
|
#define SDL_SendMouseButton(N, A, B) SDL_PrivateMouseButton( A, B, 0, 0 )
|
|
#define SDL_SendKeyboardKey(state, keysym) SDL_PrivateKeyboard(state, keysym)
|
|
|
|
#endif
|
|
|
|
extern void SDL_ANDROID_PumpEvents()
|
|
{
|
|
SDL_ANDROID_processAndroidTrackballDampening();
|
|
SDL_ANDROID_processMoveMouseWithKeyboard();
|
|
|
|
if( !BufferedEventsMutex )
|
|
BufferedEventsMutex = SDL_CreateMutex();
|
|
SDL_mutexP(BufferedEventsMutex);
|
|
while( BufferedEventsStart != BufferedEventsEnd )
|
|
{
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsStart];
|
|
|
|
switch( ev->type )
|
|
{
|
|
case SDL_MOUSEMOTION:
|
|
SDL_SendMouseMotion(NULL, 0, ev->motion.x, ev->motion.y);
|
|
break;
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
SDL_SendMouseButton( NULL, ev->button.state, ev->button.button );
|
|
break;
|
|
case SDL_KEYDOWN:
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_KEYDOWN: %i %i", ev->key.keysym.sym, ev->key.state);
|
|
SDL_SendKeyboardKey( ev->key.state, &ev->key.keysym );
|
|
break;
|
|
case SDL_JOYAXISMOTION:
|
|
if( ev->jaxis.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev->jaxis.which] )
|
|
SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[ev->jaxis.which], ev->jaxis.axis, ev->jaxis.value );
|
|
break;
|
|
case SDL_JOYBUTTONDOWN:
|
|
if( ev->jbutton.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev->jbutton.which] )
|
|
SDL_PrivateJoystickButton( SDL_ANDROID_CurrentJoysticks[ev->jbutton.which], ev->jbutton.button, ev->jbutton.state );
|
|
break;
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
case SDL_FINGERMOTION:
|
|
SDL_SendTouchMotion(0, ev->tfinger.fingerId, 0, ev->tfinger.x, ev->tfinger.y, ev->tfinger.pressure);
|
|
break;
|
|
case SDL_FINGERDOWN:
|
|
SDL_SendFingerDown(0, ev->tfinger.fingerId, ev->tfinger.state ? 1 : 0, ev->tfinger.x, ev->tfinger.y, ev->tfinger.pressure);
|
|
break;
|
|
case SDL_TEXTINPUT:
|
|
SDL_SendKeyboardText(ev->text.text);
|
|
break;
|
|
#endif
|
|
}
|
|
|
|
ev->type = 0;
|
|
BufferedEventsStart++;
|
|
if( BufferedEventsStart >= MAX_BUFFERED_EVENTS )
|
|
BufferedEventsStart = 0;
|
|
}
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
// Queue events to main thread
|
|
static int getNextEvent()
|
|
{
|
|
int nextEvent;
|
|
if( !BufferedEventsMutex )
|
|
return -1;
|
|
SDL_mutexP(BufferedEventsMutex);
|
|
nextEvent = BufferedEventsEnd;
|
|
nextEvent++;
|
|
if( nextEvent >= MAX_BUFFERED_EVENTS )
|
|
nextEvent = 0;
|
|
while( nextEvent == BufferedEventsStart )
|
|
{
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
if( SDL_ANDROID_InsideVideoThread() )
|
|
SDL_ANDROID_PumpEvents();
|
|
else
|
|
SDL_Delay(100);
|
|
SDL_mutexP(BufferedEventsMutex);
|
|
nextEvent = BufferedEventsEnd;
|
|
nextEvent++;
|
|
if( nextEvent >= MAX_BUFFERED_EVENTS )
|
|
nextEvent = 0;
|
|
}
|
|
return nextEvent;
|
|
}
|
|
|
|
extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y)
|
|
{
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
ev->type = SDL_MOUSEMOTION;
|
|
ev->motion.x = x;
|
|
ev->motion.y = y;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button)
|
|
{
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
ev->type = SDL_MOUSEBUTTONDOWN;
|
|
ev->button.state = pressed;
|
|
ev->button.button = button;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
|
|
extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key)
|
|
{
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
|
|
if( moveMouseWithArrowKeys && (
|
|
key == SDL_KEY(UP) || key == SDL_KEY(DOWN) ||
|
|
key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) )
|
|
{
|
|
if( moveMouseWithKbX < 0 )
|
|
SDL_GetMouseState( &moveMouseWithKbX, &moveMouseWithKbY );
|
|
|
|
if( pressed )
|
|
{
|
|
if( key == SDL_KEY(LEFT) )
|
|
{
|
|
if( moveMouseWithKbSpeedX > 0 )
|
|
moveMouseWithKbSpeedX = 0;
|
|
moveMouseWithKbSpeedX -= moveMouseWithKbSpeed;
|
|
moveMouseWithKbAccelX = -moveMouseWithKbAccel;
|
|
moveMouseWithKbAccelUpdateNeeded |= 1;
|
|
}
|
|
else if( key == SDL_KEY(RIGHT) )
|
|
{
|
|
if( moveMouseWithKbSpeedX < 0 )
|
|
moveMouseWithKbSpeedX = 0;
|
|
moveMouseWithKbSpeedX += moveMouseWithKbSpeed;
|
|
moveMouseWithKbAccelX = moveMouseWithKbAccel;
|
|
moveMouseWithKbAccelUpdateNeeded |= 1;
|
|
}
|
|
|
|
if( key == SDL_KEY(UP) )
|
|
{
|
|
if( moveMouseWithKbSpeedY > 0 )
|
|
moveMouseWithKbSpeedY = 0;
|
|
moveMouseWithKbSpeedY -= moveMouseWithKbSpeed;
|
|
moveMouseWithKbAccelY = -moveMouseWithKbAccel;
|
|
moveMouseWithKbAccelUpdateNeeded |= 2;
|
|
}
|
|
else if( key == SDL_KEY(DOWN) )
|
|
{
|
|
if( moveMouseWithKbSpeedY < 0 )
|
|
moveMouseWithKbSpeedY = 0;
|
|
moveMouseWithKbSpeedY += moveMouseWithKbSpeed;
|
|
moveMouseWithKbAccelY = moveMouseWithKbAccel;
|
|
moveMouseWithKbAccelUpdateNeeded |= 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) )
|
|
{
|
|
moveMouseWithKbSpeedX = 0;
|
|
moveMouseWithKbAccelX = 0;
|
|
moveMouseWithKbAccelUpdateNeeded &= ~1;
|
|
}
|
|
if( key == SDL_KEY(UP) || key == SDL_KEY(DOWN) )
|
|
{
|
|
moveMouseWithKbSpeedY = 0;
|
|
moveMouseWithKbAccelY = 0;
|
|
moveMouseWithKbAccelUpdateNeeded &= ~2;
|
|
}
|
|
}
|
|
|
|
moveMouseWithKbX += moveMouseWithKbSpeedX;
|
|
moveMouseWithKbY += moveMouseWithKbSpeedY;
|
|
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
|
|
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY);
|
|
return;
|
|
}
|
|
|
|
ev->type = SDL_KEYDOWN;
|
|
ev->key.state = pressed;
|
|
ev->key.keysym.scancode = key;
|
|
ev->key.keysym.sym = key;
|
|
ev->key.keysym.mod = KMOD_NONE;
|
|
ev->key.keysym.unicode = 0;
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
#else
|
|
if ( SDL_TranslateUNICODE )
|
|
ev->key.keysym.unicode = key;
|
|
#endif
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
|
|
extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value)
|
|
{
|
|
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
|
|
return;
|
|
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
ev->type = SDL_JOYAXISMOTION;
|
|
ev->jaxis.which = joy;
|
|
ev->jaxis.axis = axis;
|
|
ev->jaxis.value = value;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed)
|
|
{
|
|
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
|
|
return;
|
|
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
ev->type = SDL_JOYBUTTONDOWN;
|
|
ev->jbutton.which = joy;
|
|
ev->jbutton.button = button;
|
|
ev->jbutton.state = pressed;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force)
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
ev->type = SDL_FINGERDOWN;
|
|
ev->tfinger.fingerId = id;
|
|
ev->tfinger.state = pressed;
|
|
ev->tfinger.x = x;
|
|
ev->tfinger.y = y;
|
|
ev->tfinger.pressure = force;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
#endif
|
|
};
|
|
extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force)
|
|
{
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
ev->type = SDL_FINGERMOTION;
|
|
ev->tfinger.fingerId = id;
|
|
ev->tfinger.x = x;
|
|
ev->tfinger.y = y;
|
|
ev->tfinger.pressure = force;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
#endif
|
|
};
|
|
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
extern void SDL_ANDROID_DeferredTextInput()
|
|
{
|
|
};
|
|
#else
|
|
|
|
enum { DEFERRED_TEXT_COUNT = 128 };
|
|
static struct { int scancode; int unicode; int down; } deferredText[DEFERRED_TEXT_COUNT];
|
|
static int deferredTextIdx1 = 0;
|
|
static int deferredTextIdx2 = 0;
|
|
static SDL_mutex * deferredTextMutex = NULL;
|
|
|
|
void SDL_ANDROID_DeferredTextInput()
|
|
{
|
|
int count = 2;
|
|
if( !deferredTextMutex )
|
|
deferredTextMutex = SDL_CreateMutex();
|
|
|
|
SDL_mutexP(deferredTextMutex);
|
|
|
|
while( deferredTextIdx1 != deferredTextIdx2 && count > 0 )
|
|
{
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
{
|
|
SDL_mutexV(deferredTextMutex);
|
|
return;
|
|
}
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
deferredTextIdx1++;
|
|
if( deferredTextIdx1 >= DEFERRED_TEXT_COUNT )
|
|
deferredTextIdx1 = 0;
|
|
|
|
ev->type = SDL_KEYDOWN;
|
|
ev->key.state = deferredText[deferredTextIdx1].down;
|
|
ev->key.keysym.scancode = deferredText[deferredTextIdx1].scancode;
|
|
ev->key.keysym.sym = deferredText[deferredTextIdx1].scancode;
|
|
ev->key.keysym.mod = KMOD_NONE;
|
|
ev->key.keysym.unicode = 0;
|
|
if ( SDL_TranslateUNICODE )
|
|
ev->key.keysym.unicode = deferredText[deferredTextIdx1].unicode;
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
count --;
|
|
}
|
|
|
|
SDL_mutexV(deferredTextMutex);
|
|
};
|
|
#endif
|
|
|
|
extern void SDL_ANDROID_MainThreadPushText( int scancode, int unicode )
|
|
{
|
|
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_MainThreadPushText(): %i %i", scancode, unicode);
|
|
int nextEvent = getNextEvent();
|
|
if( nextEvent == -1 )
|
|
return;
|
|
|
|
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
|
|
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
|
|
|
// TODO: convert to UTF-8
|
|
ev->type = SDL_TEXTINPUT;
|
|
ev->text.text[0] = scancode;
|
|
ev->text.text[1] = 0;
|
|
|
|
#else
|
|
|
|
if( !deferredTextMutex )
|
|
deferredTextMutex = SDL_CreateMutex();
|
|
|
|
SDL_mutexP(deferredTextMutex);
|
|
|
|
ev->type = 0;
|
|
|
|
if( deferredTextIdx1 == deferredTextIdx2 )
|
|
{
|
|
ev->type = SDL_KEYDOWN;
|
|
ev->key.state = SDL_PRESSED;
|
|
ev->key.keysym.scancode = scancode;
|
|
ev->key.keysym.sym = scancode;
|
|
ev->key.keysym.mod = KMOD_NONE;
|
|
ev->key.keysym.unicode = 0;
|
|
if ( SDL_TranslateUNICODE )
|
|
ev->key.keysym.unicode = unicode;
|
|
}
|
|
else
|
|
{
|
|
deferredTextIdx2++;
|
|
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
|
deferredTextIdx2 = 0;
|
|
deferredText[deferredTextIdx2].down = SDL_PRESSED;
|
|
deferredText[deferredTextIdx2].scancode = scancode;
|
|
deferredText[deferredTextIdx2].unicode = unicode;
|
|
}
|
|
|
|
deferredTextIdx2++;
|
|
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
|
deferredTextIdx2 = 0;
|
|
deferredText[deferredTextIdx2].down = SDL_RELEASED;
|
|
deferredText[deferredTextIdx2].scancode = scancode;
|
|
deferredText[deferredTextIdx2].unicode = unicode;
|
|
|
|
SDL_mutexV(deferredTextMutex);
|
|
|
|
#endif
|
|
|
|
BufferedEventsEnd = nextEvent;
|
|
SDL_mutexV(BufferedEventsMutex);
|
|
};
|
|
|
|
|
|
Uint32 lastMoveMouseWithKeyboardUpdate = 0;
|
|
|
|
void SDL_ANDROID_processMoveMouseWithKeyboard()
|
|
{
|
|
if( ! moveMouseWithKbAccelUpdateNeeded )
|
|
return;
|
|
|
|
Uint32 ticks = SDL_GetTicks();
|
|
|
|
if( ticks - lastMoveMouseWithKeyboardUpdate < 20 ) // Update at 50 FPS max, or it will not work properlty on very fast devices
|
|
return;
|
|
|
|
lastMoveMouseWithKeyboardUpdate = ticks;
|
|
|
|
moveMouseWithKbSpeedX += moveMouseWithKbAccelX;
|
|
moveMouseWithKbSpeedY += moveMouseWithKbAccelY;
|
|
|
|
moveMouseWithKbX += moveMouseWithKbSpeedX;
|
|
moveMouseWithKbY += moveMouseWithKbSpeedY;
|
|
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY);
|
|
};
|
|
|
|
extern void SDL_ANDROID_ProcessDeferredEvents()
|
|
{
|
|
SDL_ANDROID_DeferredTextInput();
|
|
ProcessDeferredMouseTap();
|
|
};
|
|
|
|
void ANDROID_InitOSKeymap()
|
|
{
|
|
#if (SDL_VERSION_ATLEAST(1,3,0))
|
|
SDLKey defaultKeymap[SDL_NUM_SCANCODES];
|
|
SDL_GetDefaultKeymap(defaultKeymap);
|
|
SDL_SetKeymap(0, defaultKeymap, SDL_NUM_SCANCODES);
|
|
|
|
SDL_Touch touch;
|
|
memset( &touch, 0, sizeof(touch) );
|
|
touch.x_min = touch.y_min = touch.pressure_min = 0.0f;
|
|
touch.pressure_max = 1000000;
|
|
touch.x_max = SDL_ANDROID_sWindowWidth;
|
|
touch.y_max = SDL_ANDROID_sWindowHeight;
|
|
|
|
// These constants are hardcoded inside SDL_touch.c, which makes no sense for me.
|
|
touch.xres = touch.yres = 32768;
|
|
touch.native_xres = touch.native_yres = 32768.0f;
|
|
|
|
touch.pressureres = 1;
|
|
touch.native_pressureres = 1.0f;
|
|
touch.id = 0;
|
|
|
|
SDL_AddTouch(&touch, "Android touch screen");
|
|
#endif
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeGetKeymapKey) (JNIEnv* env, jobject thiz, jint code)
|
|
{
|
|
if( code < 0 || code > KEYCODE_LAST )
|
|
return SDL_KEY(UNKNOWN);
|
|
return SDL_android_keymap[code];
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetKeymapKey) (JNIEnv* env, jobject thiz, jint javakey, jint key)
|
|
{
|
|
if( javakey < 0 || javakey > KEYCODE_LAST )
|
|
return;
|
|
SDL_android_keymap[javakey] = key;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeGetKeymapKeyScreenKb) (JNIEnv* env, jobject thiz, jint keynum)
|
|
{
|
|
if( keynum < 0 || keynum > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 + 4 )
|
|
return SDL_KEY(UNKNOWN);
|
|
|
|
if( keynum <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 )
|
|
return SDL_ANDROID_GetScreenKeyboardButtonKey(keynum + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0);
|
|
|
|
return SDL_KEY(UNKNOWN);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetKeymapKeyScreenKb) (JNIEnv* env, jobject thiz, jint keynum, jint key)
|
|
{
|
|
if( keynum < 0 || keynum > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 + 4 )
|
|
return;
|
|
|
|
if( keynum <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 )
|
|
SDL_ANDROID_SetScreenKeyboardButtonKey(keynum + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, key);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetScreenKbKeyUsed) (JNIEnv* env, jobject thiz, jint keynum, jint used)
|
|
{
|
|
SDL_Rect rect = {0, 0, 0, 0};
|
|
int key = -1;
|
|
if( keynum == 0 )
|
|
key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD;
|
|
if( keynum == 1 )
|
|
key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT;
|
|
if( keynum - 2 >= 0 && keynum - 2 <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 )
|
|
key = keynum - 2 + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0;
|
|
|
|
if( key >= 0 && !used )
|
|
SDL_ANDROID_SetScreenKeyboardButtonPos(key, &rect);
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeGetKeymapKeyMultitouchGesture) (JNIEnv* env, jobject thiz, jint keynum)
|
|
{
|
|
if( keynum < 0 || keynum >= MAX_MULTITOUCH_GESTURES )
|
|
return SDL_KEY(UNKNOWN);
|
|
return multitouchGestureKeycode[keynum];
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetKeymapKeyMultitouchGesture) (JNIEnv* env, jobject thiz, jint keynum, jint keycode)
|
|
{
|
|
if( keynum < 0 || keynum >= MAX_MULTITOUCH_GESTURES )
|
|
return;
|
|
multitouchGestureKeycode[keynum] = keycode;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetMultitouchGestureSensitivity) (JNIEnv* env, jobject thiz, jint sensitivity)
|
|
{
|
|
multitouchGestureSensitivity = sensitivity;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenCalibration) (JNIEnv* env, jobject thiz, jint x1, jint y1, jint x2, jint y2)
|
|
{
|
|
SDL_ANDROID_TouchscreenCalibrationX = x1;
|
|
SDL_ANDROID_TouchscreenCalibrationY = y1;
|
|
SDL_ANDROID_TouchscreenCalibrationWidth = x2 - x1;
|
|
SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1;
|
|
}
|
|
|
|
static int ScreenKbRedefinedByUser = 0;
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeSetScreenKbKeyLayout) (JNIEnv* env, jobject thiz, jint keynum, jint x1, jint y1, jint x2, jint y2)
|
|
{
|
|
SDL_Rect rect = {x1, y1, x2-x1, y2-y1};
|
|
int key = -1;
|
|
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "nativeSetScreenKbKeyLayout: %d %d %d %d", (int)rect.x, (int)rect.y, (int)rect.w, (int)rect.h);
|
|
if( keynum == 0 )
|
|
key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD;
|
|
if( keynum == 1 )
|
|
key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT;
|
|
if( keynum - 2 >= 0 && keynum - 2 <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 )
|
|
key = keynum - 2 + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0;
|
|
|
|
if( key >= 0 )
|
|
{
|
|
ScreenKbRedefinedByUser = 1;
|
|
SDL_ANDROID_SetScreenKeyboardButtonPos(key, &rect);
|
|
}
|
|
}
|
|
|
|
int SDL_ANDROID_GetScreenKeyboardRedefinedByUser()
|
|
{
|
|
return ScreenKbRedefinedByUser;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz )
|
|
{
|
|
int i;
|
|
SDLKey * keymap = SDL_android_keymap;
|
|
|
|
// TODO: keys are mapped rather randomly
|
|
|
|
for (i=0; i<SDL_arraysize(SDL_android_keymap); ++i)
|
|
SDL_android_keymap[i] = SDL_KEY(UNKNOWN);
|
|
|
|
keymap[KEYCODE_UNKNOWN] = SDL_KEY(UNKNOWN);
|
|
|
|
keymap[KEYCODE_BACK] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_5));
|
|
|
|
keymap[KEYCODE_MENU] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_4));
|
|
|
|
keymap[KEYCODE_DPAD_CENTER] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_1));
|
|
keymap[KEYCODE_SEARCH] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_9));
|
|
keymap[KEYCODE_CALL] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_10));
|
|
|
|
keymap[KEYCODE_VOLUME_UP] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_2));
|
|
keymap[KEYCODE_VOLUME_DOWN] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_3));
|
|
|
|
keymap[KEYCODE_HOME] = SDL_KEY(HOME); // Cannot be used in application
|
|
|
|
keymap[KEYCODE_CAMERA] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_6));
|
|
|
|
keymap[KEYCODE_0] = SDL_KEY(0);
|
|
keymap[KEYCODE_1] = SDL_KEY(1);
|
|
keymap[KEYCODE_2] = SDL_KEY(2);
|
|
keymap[KEYCODE_3] = SDL_KEY(3);
|
|
keymap[KEYCODE_4] = SDL_KEY(4);
|
|
keymap[KEYCODE_5] = SDL_KEY(5);
|
|
keymap[KEYCODE_6] = SDL_KEY(6);
|
|
keymap[KEYCODE_7] = SDL_KEY(7);
|
|
keymap[KEYCODE_8] = SDL_KEY(8);
|
|
keymap[KEYCODE_9] = SDL_KEY(9);
|
|
keymap[KEYCODE_STAR] = SDL_KEY(KP_DIVIDE);
|
|
keymap[KEYCODE_POUND] = SDL_KEY(KP_MULTIPLY);
|
|
|
|
keymap[KEYCODE_DPAD_UP] = SDL_KEY(UP);
|
|
keymap[KEYCODE_DPAD_DOWN] = SDL_KEY(DOWN);
|
|
keymap[KEYCODE_DPAD_LEFT] = SDL_KEY(LEFT);
|
|
keymap[KEYCODE_DPAD_RIGHT] = SDL_KEY(RIGHT);
|
|
|
|
keymap[KEYCODE_SOFT_LEFT] = SDL_KEY(KP_4);
|
|
keymap[KEYCODE_SOFT_RIGHT] = SDL_KEY(KP_6);
|
|
keymap[KEYCODE_ENTER] = SDL_KEY(RETURN); //SDL_KEY(KP_ENTER);
|
|
|
|
|
|
keymap[KEYCODE_CLEAR] = SDL_KEY(BACKSPACE);
|
|
keymap[KEYCODE_A] = SDL_KEY(A);
|
|
keymap[KEYCODE_B] = SDL_KEY(B);
|
|
keymap[KEYCODE_C] = SDL_KEY(C);
|
|
keymap[KEYCODE_D] = SDL_KEY(D);
|
|
keymap[KEYCODE_E] = SDL_KEY(E);
|
|
keymap[KEYCODE_F] = SDL_KEY(F);
|
|
keymap[KEYCODE_G] = SDL_KEY(G);
|
|
keymap[KEYCODE_H] = SDL_KEY(H);
|
|
keymap[KEYCODE_I] = SDL_KEY(I);
|
|
keymap[KEYCODE_J] = SDL_KEY(J);
|
|
keymap[KEYCODE_K] = SDL_KEY(K);
|
|
keymap[KEYCODE_L] = SDL_KEY(L);
|
|
keymap[KEYCODE_M] = SDL_KEY(M);
|
|
keymap[KEYCODE_N] = SDL_KEY(N);
|
|
keymap[KEYCODE_O] = SDL_KEY(O);
|
|
keymap[KEYCODE_P] = SDL_KEY(P);
|
|
keymap[KEYCODE_Q] = SDL_KEY(Q);
|
|
keymap[KEYCODE_R] = SDL_KEY(R);
|
|
keymap[KEYCODE_S] = SDL_KEY(S);
|
|
keymap[KEYCODE_T] = SDL_KEY(T);
|
|
keymap[KEYCODE_U] = SDL_KEY(U);
|
|
keymap[KEYCODE_V] = SDL_KEY(V);
|
|
keymap[KEYCODE_W] = SDL_KEY(W);
|
|
keymap[KEYCODE_X] = SDL_KEY(X);
|
|
keymap[KEYCODE_Y] = SDL_KEY(Y);
|
|
keymap[KEYCODE_Z] = SDL_KEY(Z);
|
|
keymap[KEYCODE_COMMA] = SDL_KEY(COMMA);
|
|
keymap[KEYCODE_PERIOD] = SDL_KEY(PERIOD);
|
|
keymap[KEYCODE_TAB] = SDL_KEY(TAB);
|
|
keymap[KEYCODE_SPACE] = SDL_KEY(SPACE);
|
|
keymap[KEYCODE_DEL] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_8));
|
|
keymap[KEYCODE_GRAVE] = SDL_KEY(GRAVE);
|
|
keymap[KEYCODE_MINUS] = SDL_KEY(KP_MINUS);
|
|
keymap[KEYCODE_PLUS] = SDL_KEY(KP_PLUS);
|
|
keymap[KEYCODE_EQUALS] = SDL_KEY(EQUALS);
|
|
keymap[KEYCODE_LEFT_BRACKET] = SDL_KEY(LEFTBRACKET);
|
|
keymap[KEYCODE_RIGHT_BRACKET] = SDL_KEY(RIGHTBRACKET);
|
|
keymap[KEYCODE_BACKSLASH] = SDL_KEY(BACKSLASH);
|
|
keymap[KEYCODE_SEMICOLON] = SDL_KEY(SEMICOLON);
|
|
keymap[KEYCODE_APOSTROPHE] = SDL_KEY(APOSTROPHE);
|
|
keymap[KEYCODE_SLASH] = SDL_KEY(SLASH);
|
|
keymap[KEYCODE_AT] = SDL_KEY(KP_PERIOD);
|
|
|
|
keymap[KEYCODE_MEDIA_PLAY_PAUSE] = SDL_KEY(KP_2);
|
|
keymap[KEYCODE_MEDIA_STOP] = SDL_KEY(HELP);
|
|
keymap[KEYCODE_MEDIA_NEXT] = SDL_KEY(KP_8);
|
|
keymap[KEYCODE_MEDIA_PREVIOUS] = SDL_KEY(KP_5);
|
|
keymap[KEYCODE_MEDIA_REWIND] = SDL_KEY(KP_1);
|
|
keymap[KEYCODE_MEDIA_FAST_FORWARD] = SDL_KEY(KP_3);
|
|
keymap[KEYCODE_MUTE] = SDL_KEY(KP_0);
|
|
|
|
keymap[KEYCODE_SYM] = SDL_KEY(LGUI);
|
|
keymap[KEYCODE_NUM] = SDL_KEY(NUMLOCKCLEAR);
|
|
|
|
keymap[KEYCODE_ALT_LEFT] = SDL_KEY(KP_7);
|
|
keymap[KEYCODE_ALT_RIGHT] = SDL_KEY(KP_9);
|
|
|
|
keymap[KEYCODE_SHIFT_LEFT] = SDL_KEY(F1);
|
|
keymap[KEYCODE_SHIFT_RIGHT] = SDL_KEY(F2);
|
|
|
|
keymap[KEYCODE_EXPLORER] = SDL_KEY(F3);
|
|
keymap[KEYCODE_ENVELOPE] = SDL_KEY(F4);
|
|
|
|
keymap[KEYCODE_HEADSETHOOK] = SDL_KEY(F5);
|
|
keymap[KEYCODE_FOCUS] = SDL_KEY(F6);
|
|
keymap[KEYCODE_NOTIFICATION] = SDL_KEY(F7);
|
|
|
|
// Cannot be received by application, OS internal
|
|
keymap[KEYCODE_ENDCALL] = SDL_KEY(LSHIFT);
|
|
keymap[KEYCODE_POWER] = SDL_KEY(RALT);
|
|
|
|
}
|