Split input queue out of input events code.
This commit is contained in:
Submodule project/jni/application/openarena/engine updated: 17010dd99f...8ecd56f773
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
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 "unicodestuff.h"
|
||||
#include "atan2i.h"
|
||||
|
||||
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
|
||||
#define SDL_SendKeyboardKey(state, keysym) SDL_SendKeyboardKey(state, (keysym)->sym)
|
||||
extern SDL_Window * ANDROID_CurrentWindow;
|
||||
|
||||
#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
|
||||
|
||||
enum { MAX_BUFFERED_EVENTS = 64 };
|
||||
static SDL_Event BufferedEvents[MAX_BUFFERED_EVENTS];
|
||||
static int BufferedEventsStart = 0, BufferedEventsEnd = 0;
|
||||
static SDL_mutex * BufferedEventsMutex = NULL;
|
||||
|
||||
/* We need our own event queue, because Free Heroes 2 game uses
|
||||
* SDL_SetEventFilter(), and it calls SDL_Flip() from inside
|
||||
* it's custom filter function, and SDL_Flip() does not work
|
||||
* when it's not called from the main() thread.
|
||||
* So we, like, push the events into our own queue,
|
||||
* read each event from that queue inside SDL_ANDROID_PumpEvents(),
|
||||
* unlock the mutex, and push the event to SDL queue,
|
||||
* which is then immediately read by SDL from the same thread,
|
||||
* and then SDL invokes event filter function from FHeroes2.
|
||||
* FHeroes2 call SDL_Flip() from inside that event filter function,
|
||||
* and it works, because it is called from the main() thread.
|
||||
*/
|
||||
extern void SDL_ANDROID_PumpEvents()
|
||||
{
|
||||
static int oldMouseButtons = 0;
|
||||
SDL_Event ev;
|
||||
SDL_ANDROID_processAndroidTrackballDampening();
|
||||
SDL_ANDROID_processMoveMouseWithKeyboard();
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
SDL_Window * window = SDL_GetFocusWindow();
|
||||
if( !window )
|
||||
return;
|
||||
#endif
|
||||
|
||||
if( !BufferedEventsMutex )
|
||||
BufferedEventsMutex = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(BufferedEventsMutex);
|
||||
while( BufferedEventsStart != BufferedEventsEnd )
|
||||
{
|
||||
ev = BufferedEvents[BufferedEventsStart];
|
||||
BufferedEvents[BufferedEventsStart].type = 0;
|
||||
BufferedEventsStart++;
|
||||
if( BufferedEventsStart >= MAX_BUFFERED_EVENTS )
|
||||
BufferedEventsStart = 0;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
|
||||
switch( ev.type )
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, ev.motion.x, ev.motion.y );
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if( ((oldMouseButtons & SDL_BUTTON(ev.button.button)) != 0) != ev.button.state )
|
||||
{
|
||||
oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(ev.button.button)) | (ev.button.state ? SDL_BUTTON(ev.button.button) : 0);
|
||||
SDL_SendMouseButton( ANDROID_CurrentWindow, 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;
|
||||
case SDL_JOYBALLMOTION:
|
||||
if( ev.jball.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] )
|
||||
SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[ev.jball.which], ev.jball.ball, ev.jball.xrel, ev.jball.yrel );
|
||||
break;
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
//if( ANDROID_CurrentWindow )
|
||||
// SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
#else
|
||||
case SDL_ACTIVEEVENT:
|
||||
SDL_PrivateAppActive(ev.active.gain, ev.active.state);
|
||||
break;
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
case SDL_FINGERMOTION:
|
||||
SDL_SendTouchMotion(0, ev.tfinger.fingerId, 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure);
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
SDL_SendFingerDown(0, ev.tfinger.fingerId, ev.tfinger.state ? 1 : 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
SDL_SendKeyboardText(ev.text.text);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
SDL_SendMouseWheel( ANDROID_CurrentWindow, ev.wheel.x, ev.wheel.y );
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_mutexP(BufferedEventsMutex);
|
||||
}
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
// Queue events to main thread
|
||||
static int getNextEventAndLock()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static int getPrevEventNoLock()
|
||||
{
|
||||
int prevEvent;
|
||||
if(BufferedEventsStart == BufferedEventsEnd)
|
||||
return -1;
|
||||
prevEvent = BufferedEventsEnd;
|
||||
prevEvent--;
|
||||
if( prevEvent < 0 )
|
||||
prevEvent = MAX_BUFFERED_EVENTS - 1;
|
||||
return prevEvent;
|
||||
}
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y)
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
int prevEvent = getPrevEventNoLock();
|
||||
if( prevEvent > 0 && BufferedEvents[prevEvent].type == SDL_MOUSEMOTION )
|
||||
{
|
||||
// Reuse previous mouse motion event, to prevent mouse movement lag
|
||||
BufferedEvents[prevEvent].motion.x = x;
|
||||
BufferedEvents[prevEvent].motion.y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
ev->type = SDL_MOUSEMOTION;
|
||||
ev->motion.x = x;
|
||||
ev->motion.y = y;
|
||||
}
|
||||
SDL_ANDROID_currentMouseX = x;
|
||||
SDL_ANDROID_currentMouseY = y;
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button)
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_MOUSEBUTTONDOWN;
|
||||
ev->button.state = pressed;
|
||||
ev->button.button = button;
|
||||
|
||||
if(pressed)
|
||||
SDL_ANDROID_currentMouseButtons |= SDL_BUTTON(button);
|
||||
else
|
||||
SDL_ANDROID_currentMouseButtons &= ~(SDL_BUTTON(button));
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key)
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
if( SDL_ANDROID_moveMouseWithArrowKeys && (
|
||||
key == SDL_KEY(UP) || key == SDL_KEY(DOWN) ||
|
||||
key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) )
|
||||
{
|
||||
if( SDL_ANDROID_moveMouseWithKbX < 0 )
|
||||
{
|
||||
SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_currentMouseX;
|
||||
SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_currentMouseY;
|
||||
}
|
||||
|
||||
if( pressed )
|
||||
{
|
||||
if( key == SDL_KEY(LEFT) )
|
||||
{
|
||||
if( SDL_ANDROID_moveMouseWithKbSpeedX > 0 )
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX -= SDL_ANDROID_moveMouseWithKbSpeed;
|
||||
SDL_ANDROID_moveMouseWithKbAccelX = -SDL_ANDROID_moveMouseWithKbAccel;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 1;
|
||||
}
|
||||
else if( key == SDL_KEY(RIGHT) )
|
||||
{
|
||||
if( SDL_ANDROID_moveMouseWithKbSpeedX < 0 )
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX += SDL_ANDROID_moveMouseWithKbSpeed;
|
||||
SDL_ANDROID_moveMouseWithKbAccelX = SDL_ANDROID_moveMouseWithKbAccel;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 1;
|
||||
}
|
||||
|
||||
if( key == SDL_KEY(UP) )
|
||||
{
|
||||
if( SDL_ANDROID_moveMouseWithKbSpeedY > 0 )
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY -= SDL_ANDROID_moveMouseWithKbSpeed;
|
||||
SDL_ANDROID_moveMouseWithKbAccelY = -SDL_ANDROID_moveMouseWithKbAccel;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 2;
|
||||
}
|
||||
else if( key == SDL_KEY(DOWN) )
|
||||
{
|
||||
if( SDL_ANDROID_moveMouseWithKbSpeedY < 0 )
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY += SDL_ANDROID_moveMouseWithKbSpeed;
|
||||
SDL_ANDROID_moveMouseWithKbAccelY = SDL_ANDROID_moveMouseWithKbAccel;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) )
|
||||
{
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbAccelX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded &= ~1;
|
||||
}
|
||||
if( key == SDL_KEY(UP) || key == SDL_KEY(DOWN) )
|
||||
{
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbAccelY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded &= ~2;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_ANDROID_moveMouseWithKbX += SDL_ANDROID_moveMouseWithKbSpeedX;
|
||||
SDL_ANDROID_moveMouseWithKbY += SDL_ANDROID_moveMouseWithKbSpeedY;
|
||||
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_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 )
|
||||
#endif
|
||||
ev->key.keysym.unicode = key;
|
||||
|
||||
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 = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_JOYAXISMOTION;
|
||||
ev->jaxis.which = joy;
|
||||
ev->jaxis.axis = axis;
|
||||
ev->jaxis.value = MAX( -32768, MIN( 32767, 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 = getNextEventAndLock();
|
||||
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_MainThreadPushJoystickBall(int joy, int ball, int x, int y)
|
||||
{
|
||||
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
|
||||
return;
|
||||
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_JOYBALLMOTION;
|
||||
ev->jball.which = joy;
|
||||
ev->jball.ball = ball;
|
||||
ev->jball.xrel = x;
|
||||
ev->jball.yrel = y;
|
||||
|
||||
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 = getNextEventAndLock();
|
||||
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 = getNextEventAndLock();
|
||||
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
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushMouseWheel(int x, int y)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_MOUSEWHEEL;
|
||||
ev->wheel.x = x;
|
||||
ev->wheel.y = y;
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushAppActive(int active)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
//if( ANDROID_CurrentWindow )
|
||||
// SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
#else
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_ACTIVEEVENT;
|
||||
ev->active.gain = active;
|
||||
ev->active.state = SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS;
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
enum { DEFERRED_TEXT_COUNT = 256 };
|
||||
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()
|
||||
{
|
||||
if( !deferredTextMutex )
|
||||
deferredTextMutex = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(deferredTextMutex);
|
||||
|
||||
if( deferredTextIdx1 != deferredTextIdx2 )
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
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 = asciiToKeysym( deferredText[deferredTextIdx1].scancode, deferredText[deferredTextIdx1].unicode );
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
if( SDL_ANDROID_isMouseUsed )
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_currentMouseX + (SDL_ANDROID_currentMouseX % 2 ? -1 : 1), SDL_ANDROID_currentMouseY); // Force screen redraw
|
||||
}
|
||||
else
|
||||
{
|
||||
if( SDL_ANDROID_TextInputFinished )
|
||||
{
|
||||
SDL_ANDROID_TextInputFinished = 0;
|
||||
SDL_ANDROID_IsScreenKeyboardShownFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_mutexV(deferredTextMutex);
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode )
|
||||
{
|
||||
int shiftRequired;
|
||||
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
|
||||
ev->type = SDL_TEXTINPUT;
|
||||
UnicodeToUtf8(unicode, ev->text.text);
|
||||
|
||||
#endif
|
||||
|
||||
if( !deferredTextMutex )
|
||||
deferredTextMutex = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(deferredTextMutex);
|
||||
|
||||
ev->type = 0;
|
||||
|
||||
shiftRequired = checkShiftRequired(&ascii);
|
||||
|
||||
if( shiftRequired )
|
||||
{
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_PRESSED;
|
||||
deferredText[deferredTextIdx2].scancode = SDLK_LSHIFT;
|
||||
deferredText[deferredTextIdx2].unicode = 0;
|
||||
}
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_PRESSED;
|
||||
deferredText[deferredTextIdx2].scancode = ascii;
|
||||
deferredText[deferredTextIdx2].unicode = unicode;
|
||||
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_RELEASED;
|
||||
deferredText[deferredTextIdx2].scancode = ascii;
|
||||
deferredText[deferredTextIdx2].unicode = 0;
|
||||
if( shiftRequired )
|
||||
{
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_RELEASED;
|
||||
deferredText[deferredTextIdx2].scancode = SDLK_LSHIFT;
|
||||
deferredText[deferredTextIdx2].unicode = 0;
|
||||
}
|
||||
|
||||
SDL_mutexV(deferredTextMutex);
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
|
||||
@@ -42,12 +42,10 @@
|
||||
#include "SDL_androidinput.h"
|
||||
#include "SDL_screenkeyboard.h"
|
||||
#include "jniwrapperstuff.h"
|
||||
#include "unicodestuff.h"
|
||||
#include "atan2i.h"
|
||||
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
|
||||
static SDLKey SDL_android_keymap[KEYCODE_LAST+1];
|
||||
SDLKey SDL_android_keymap[KEYCODE_LAST+1];
|
||||
|
||||
static inline SDL_scancode TranslateKey(int scancode)
|
||||
{
|
||||
@@ -57,7 +55,7 @@ static inline SDL_scancode TranslateKey(int scancode)
|
||||
}
|
||||
|
||||
static int isTrackballUsed = 0;
|
||||
static int isMouseUsed = 0;
|
||||
int SDL_ANDROID_isMouseUsed = 0;
|
||||
|
||||
#define NORMALIZE_FLOAT_32767(X) (fminf(32767.0f, fmax(-32767.0f, (X) * 32767.0f)))
|
||||
|
||||
@@ -72,20 +70,20 @@ static int leftClickKey = KEYCODE_DPAD_CENTER;
|
||||
static int rightClickKey = KEYCODE_MENU;
|
||||
int SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE;
|
||||
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;
|
||||
int SDL_ANDROID_moveMouseWithArrowKeys = 0;
|
||||
int SDL_ANDROID_moveMouseWithKbSpeed = 0;
|
||||
int SDL_ANDROID_moveMouseWithKbAccel = 0;
|
||||
int SDL_ANDROID_moveMouseWithKbX = -1, SDL_ANDROID_moveMouseWithKbY = -1;
|
||||
int SDL_ANDROID_moveMouseWithKbSpeedX = 0, SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
int SDL_ANDROID_moveMouseWithKbAccelX = 0, SDL_ANDROID_moveMouseWithKbAccelY = 0;
|
||||
int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded = 0;
|
||||
static int maxForce = 0;
|
||||
static int maxRadius = 0;
|
||||
int SDL_ANDROID_isJoystickUsed = 0;
|
||||
static int SDL_ANDROID_isAccelerometerUsed = 0;
|
||||
static int isMultitouchUsed = 0;
|
||||
SDL_Joystick *SDL_ANDROID_CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1] = {NULL};
|
||||
SDL_Joystick *SDL_ANDROID_CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1];
|
||||
static int TrackballDampening = 0; // in milliseconds
|
||||
static Uint32 lastTrackballAction = 0;
|
||||
enum { TOUCH_PTR_UP = 0, TOUCH_PTR_MOUSE = 1, TOUCH_PTR_SCREENKB = 2 };
|
||||
@@ -120,45 +118,13 @@ static int relativeMovementAccel = 0;
|
||||
static int relativeMovementX = 0;
|
||||
static int relativeMovementY = 0;
|
||||
static unsigned int relativeMovementTime = 0;
|
||||
static int currentMouseX = 0;
|
||||
static int currentMouseY = 0;
|
||||
static int currentMouseButtons = 0;
|
||||
int SDL_ANDROID_currentMouseX = 0;
|
||||
int SDL_ANDROID_currentMouseY = 0;
|
||||
int SDL_ANDROID_currentMouseButtons = 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 UnicodeToUtf8(int src, char * dest)
|
||||
{
|
||||
int len = 0;
|
||||
if ( src <= 0x007f) {
|
||||
*dest++ = (char)src;
|
||||
len = 1;
|
||||
} else if (src <= 0x07ff) {
|
||||
*dest++ = (char)0xc0 | (src >> 6);
|
||||
*dest++ = (char)0x80 | (src & 0x003f);
|
||||
len = 2;
|
||||
} else if (src == 0xFEFF) {
|
||||
// nop -- zap the BOM
|
||||
} else if (src >= 0xD800 && src <= 0xDFFF) {
|
||||
// surrogates not supported
|
||||
} else if (src <= 0xffff) {
|
||||
*dest++ = (char)0xe0 | (src >> 12);
|
||||
*dest++ = (char)0x80 | ((src >> 6) & 0x003f);
|
||||
*dest++ = (char)0x80 | (src & 0x003f);
|
||||
len = 3;
|
||||
} else if (src <= 0xffff) {
|
||||
*dest++ = (char)0xf0 | (src >> 18);
|
||||
*dest++ = (char)0x80 | ((src >> 12) & 0x3f);
|
||||
*dest++ = (char)0x80 | ((src >> 6) & 0x3f);
|
||||
*dest++ = (char)0x80 | (src & 0x3f);
|
||||
len = 4;
|
||||
} else {
|
||||
// out of Unicode range
|
||||
}
|
||||
*dest = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
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 );
|
||||
@@ -397,7 +363,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
if( multitouchGestureDist - dist > distMaxDiff )
|
||||
{
|
||||
multitouchGestureKeyPressed[1] = 1;
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] );
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] );
|
||||
}
|
||||
else
|
||||
if( multitouchGestureKeyPressed[1] )
|
||||
@@ -456,7 +422,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
if( action == MOUSE_UP )
|
||||
SDL_ANDROID_MainThreadPushJoystickButton(JOY_TOUCHSCREEN, pointerId, SDL_RELEASED);
|
||||
}
|
||||
if( !isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed )
|
||||
if( !SDL_ANDROID_isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed )
|
||||
{
|
||||
SDL_keysym keysym;
|
||||
if( action != MOUSE_MOVE )
|
||||
@@ -464,7 +430,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
return;
|
||||
}
|
||||
|
||||
if( !isMouseUsed )
|
||||
if( !SDL_ANDROID_isMouseUsed )
|
||||
return;
|
||||
|
||||
if( pointerId == firstMousePointerId )
|
||||
@@ -473,14 +439,14 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
{
|
||||
if( action == MOUSE_DOWN )
|
||||
{
|
||||
relativeMovementX = currentMouseX - x;
|
||||
relativeMovementY = currentMouseY - y;
|
||||
relativeMovementX = SDL_ANDROID_currentMouseX - x;
|
||||
relativeMovementY = SDL_ANDROID_currentMouseY - y;
|
||||
}
|
||||
x += relativeMovementX;
|
||||
y += relativeMovementY;
|
||||
|
||||
int diffX = x - currentMouseX;
|
||||
int diffY = y - currentMouseY;
|
||||
int diffX = x - SDL_ANDROID_currentMouseX;
|
||||
int diffY = y - SDL_ANDROID_currentMouseY;
|
||||
int coeff = relativeMovementSpeed + 2;
|
||||
if( relativeMovementSpeed > 2 )
|
||||
coeff += relativeMovementSpeed - 2;
|
||||
@@ -496,8 +462,8 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
}
|
||||
relativeMovementTime = newTime;
|
||||
}
|
||||
diffX -= x - currentMouseX;
|
||||
diffY -= y - currentMouseY;
|
||||
diffX -= x - SDL_ANDROID_currentMouseX;
|
||||
diffY -= y - SDL_ANDROID_currentMouseY;
|
||||
x += diffX;
|
||||
y += diffY;
|
||||
relativeMovementX += diffX;
|
||||
@@ -544,33 +510,33 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER )
|
||||
{
|
||||
// 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);
|
||||
if( SDL_ANDROID_moveMouseWithKbX >= 0 )
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX > 0 ? SDL_ANDROID_moveMouseWithKbX-1 : 0, SDL_ANDROID_moveMouseWithKbY);
|
||||
else
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y);
|
||||
}
|
||||
moveMouseWithKbX = -1;
|
||||
moveMouseWithKbY = -1;
|
||||
moveMouseWithKbSpeedX = 0;
|
||||
moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbX = -1;
|
||||
SDL_ANDROID_moveMouseWithKbY = -1;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
}
|
||||
if( action == MOUSE_DOWN )
|
||||
{
|
||||
if( (moveMouseWithKbX >= 0 || leftClickMethod == LEFT_CLICK_NEAR_CURSOR) &&
|
||||
abs(currentMouseX - x) < SDL_ANDROID_sFakeWindowWidth / 10 && abs(currentMouseY - y) < SDL_ANDROID_sFakeWindowHeight / 10 )
|
||||
if( (SDL_ANDROID_moveMouseWithKbX >= 0 || leftClickMethod == LEFT_CLICK_NEAR_CURSOR) &&
|
||||
abs(SDL_ANDROID_currentMouseX - x) < SDL_ANDROID_sFakeWindowWidth / 10 && abs(SDL_ANDROID_currentMouseY - y) < SDL_ANDROID_sFakeWindowHeight / 10 )
|
||||
{
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT );
|
||||
moveMouseWithKbX = currentMouseX;
|
||||
moveMouseWithKbY = currentMouseY;
|
||||
moveMouseWithKbSpeedX = 0;
|
||||
moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_currentMouseX;
|
||||
SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_currentMouseY;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
action = MOUSE_MOVE;
|
||||
}
|
||||
else
|
||||
if( leftClickMethod == LEFT_CLICK_NORMAL )
|
||||
{
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
||||
if( !hardwareMouseDetected || currentMouseButtons == 0 )
|
||||
if( !hardwareMouseDetected || SDL_ANDROID_currentMouseButtons == 0 )
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT );
|
||||
}
|
||||
else
|
||||
@@ -585,7 +551,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
}
|
||||
if( action == MOUSE_MOVE )
|
||||
{
|
||||
if( moveMouseWithKbX >= 0 )
|
||||
if( SDL_ANDROID_moveMouseWithKbX >= 0 )
|
||||
{
|
||||
// Mouse lazily follows magnifying glass, not very intuitive for drag&drop
|
||||
/*
|
||||
@@ -602,17 +568,17 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t
|
||||
moveMouseWithKbY += moveMouseWithKbSpeedY;
|
||||
*/
|
||||
// Mouse follows touch instantly, when it's out of the snapping distance from mouse cursor
|
||||
if( abs(moveMouseWithKbX - x) >= SDL_ANDROID_sFakeWindowWidth / 10 ||
|
||||
abs(moveMouseWithKbY - y) >= SDL_ANDROID_sFakeWindowHeight / 10 )
|
||||
if( abs(SDL_ANDROID_moveMouseWithKbX - x) >= SDL_ANDROID_sFakeWindowWidth / 10 ||
|
||||
abs(SDL_ANDROID_moveMouseWithKbY - y) >= SDL_ANDROID_sFakeWindowHeight / 10 )
|
||||
{
|
||||
moveMouseWithKbX = -1;
|
||||
moveMouseWithKbY = -1;
|
||||
moveMouseWithKbSpeedX = 0;
|
||||
moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_moveMouseWithKbX = -1;
|
||||
SDL_ANDROID_moveMouseWithKbY = -1;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = 0;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = 0;
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
||||
}
|
||||
else
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY);
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -714,42 +680,42 @@ void ProcessDeferredMouseTap()
|
||||
#define SDL_ANDROID_sFakeWindowWidth window->w
|
||||
#define SDL_ANDROID_sFakeWindowHeight window->h
|
||||
#endif
|
||||
if( currentMouseX + 1 < SDL_ANDROID_sFakeWindowWidth )
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX + 1, currentMouseY);
|
||||
if( SDL_ANDROID_currentMouseX + 1 < SDL_ANDROID_sFakeWindowWidth )
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_currentMouseX + 1, SDL_ANDROID_currentMouseY);
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
||||
}
|
||||
else if( currentMouseX > 0 ) // Force application to redraw, and call SDL_Flip()
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX - 1, currentMouseY);
|
||||
else if( SDL_ANDROID_currentMouseX > 0 ) // Force application to redraw, and call SDL_Flip()
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_currentMouseX - 1, SDL_ANDROID_currentMouseY);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeTouchpad) ( JNIEnv* env, jobject thiz, jint x, jint y, jint down, jint multitouch)
|
||||
{
|
||||
if( !isMouseUsed )
|
||||
if( !SDL_ANDROID_isMouseUsed )
|
||||
return;
|
||||
if( ! down )
|
||||
{
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT );
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
||||
moveMouseWithKbX = -1;
|
||||
moveMouseWithKbY = -1;
|
||||
moveMouseWithKbAccelUpdateNeeded = 0;
|
||||
SDL_ANDROID_moveMouseWithKbX = -1;
|
||||
SDL_ANDROID_moveMouseWithKbY = -1;
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// x and y from 0 to 65535
|
||||
if( moveMouseWithKbX < 0 )
|
||||
if( SDL_ANDROID_moveMouseWithKbX < 0 )
|
||||
{
|
||||
moveMouseWithKbX = currentMouseX;
|
||||
moveMouseWithKbY = currentMouseY;
|
||||
SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_currentMouseX;
|
||||
SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_currentMouseY;
|
||||
}
|
||||
moveMouseWithKbSpeedX = (x - 32767) / 8192;
|
||||
moveMouseWithKbSpeedY = (y - 32767) / 8192;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX = (x - 32767) / 8192;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY = (y - 32767) / 8192;
|
||||
//moveMouseWithKbX += moveMouseWithKbSpeedX;
|
||||
//moveMouseWithKbY += moveMouseWithKbSpeedY;
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY);
|
||||
moveMouseWithKbAccelUpdateNeeded = 1;
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY);
|
||||
SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded = 1;
|
||||
|
||||
if( multitouch )
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT );
|
||||
@@ -767,9 +733,9 @@ void SDL_ANDROID_WarpMouse(int x, int y)
|
||||
}
|
||||
else
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_WarpMouse(): %dx%d rel %dx%d old %dx%d", x, y, relativeMovementX, relativeMovementY, currentMouseX, currentMouseY);
|
||||
relativeMovementX -= currentMouseX-x;
|
||||
relativeMovementY -= currentMouseY-y;
|
||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_WarpMouse(): %dx%d rel %dx%d old %dx%d", x, y, relativeMovementX, relativeMovementY, SDL_ANDROID_currentMouseX, SDL_ANDROID_currentMouseY);
|
||||
relativeMovementX -= SDL_ANDROID_currentMouseX-x;
|
||||
relativeMovementY -= SDL_ANDROID_currentMouseY-y;
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(x, y);
|
||||
}
|
||||
};
|
||||
@@ -922,16 +888,16 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
|
||||
jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel,
|
||||
jint ShowMouseCursor)
|
||||
{
|
||||
isMouseUsed = 1;
|
||||
SDL_ANDROID_isMouseUsed = 1;
|
||||
rightClickMethod = RightClickMethod;
|
||||
SDL_ANDROID_ShowScreenUnderFinger = ShowScreenUnderFinger;
|
||||
moveMouseWithArrowKeys = MoveMouseWithJoystick;
|
||||
SDL_ANDROID_moveMouseWithArrowKeys = MoveMouseWithJoystick;
|
||||
clickMouseWithDpadCenter = ClickMouseWithDpad;
|
||||
leftClickMethod = LeftClickMethod;
|
||||
maxForce = MaxForce;
|
||||
maxRadius = MaxRadius;
|
||||
moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1;
|
||||
moveMouseWithKbAccel = MoveMouseWithJoystickAccel;
|
||||
SDL_ANDROID_moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1;
|
||||
SDL_ANDROID_moveMouseWithKbAccel = MoveMouseWithJoystickAccel;
|
||||
leftClickKey = LeftClickKeycode;
|
||||
rightClickKey = RightClickKeycode;
|
||||
leftClickTimeout = getClickTimeout(LeftClickTimeout);
|
||||
@@ -946,7 +912,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz,
|
||||
JNIEXPORT void JNICALL
|
||||
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected)
|
||||
{
|
||||
if( !isMouseUsed )
|
||||
if( !SDL_ANDROID_isMouseUsed )
|
||||
return;
|
||||
|
||||
static struct {
|
||||
@@ -989,7 +955,7 @@ JNIEXPORT void JNICALL
|
||||
JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseButtonsPressed) (JNIEnv* env, jobject thiz, jint buttonId, jint pressedState)
|
||||
{
|
||||
int btn = SDL_BUTTON_LEFT;
|
||||
if( !isMouseUsed )
|
||||
if( !SDL_ANDROID_isMouseUsed )
|
||||
return;
|
||||
|
||||
switch(buttonId)
|
||||
@@ -1032,7 +998,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseWheel) (JNIEnv* env, jobject thiz,
|
||||
}
|
||||
for( ; scrollY > 0; scrollY-- )
|
||||
{
|
||||
if(!isMouseUsed)
|
||||
if(!SDL_ANDROID_isMouseUsed)
|
||||
{
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) );
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) );
|
||||
@@ -1045,7 +1011,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseWheel) (JNIEnv* env, jobject thiz,
|
||||
}
|
||||
for( ; scrollY < 0; scrollY++ )
|
||||
{
|
||||
if(!isMouseUsed)
|
||||
if(!SDL_ANDROID_isMouseUsed)
|
||||
{
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) );
|
||||
SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) );
|
||||
@@ -1484,601 +1450,11 @@ void SDL_SYS_JoystickQuit(void)
|
||||
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)
|
||||
extern SDL_Window * ANDROID_CurrentWindow;
|
||||
|
||||
#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
|
||||
|
||||
/* We need our own event queue, because Free Heroes 2 game uses
|
||||
* SDL_SetEventFilter(), and it calls SDL_Flip() from inside
|
||||
* it's custom filter function, and SDL_Flip() does not work
|
||||
* when it's not called from the main() thread.
|
||||
* So we, like, push the events into our own queue,
|
||||
* read each event from that queue inside SDL_ANDROID_PumpEvents(),
|
||||
* unlock the mutex, and push the event to SDL queue,
|
||||
* which is then immediately read by SDL from the same thread,
|
||||
* and then SDL invokes event filter function from FHeroes2.
|
||||
* FHeroes2 call SDL_Flip() from inside that event filter function,
|
||||
* and it works, because it is called from the main() thread.
|
||||
*/
|
||||
extern void SDL_ANDROID_PumpEvents()
|
||||
{
|
||||
static int oldMouseButtons = 0;
|
||||
SDL_Event ev;
|
||||
SDL_ANDROID_processAndroidTrackballDampening();
|
||||
SDL_ANDROID_processMoveMouseWithKeyboard();
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
SDL_Window * window = SDL_GetFocusWindow();
|
||||
if( !window )
|
||||
return;
|
||||
#endif
|
||||
|
||||
if( !BufferedEventsMutex )
|
||||
BufferedEventsMutex = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(BufferedEventsMutex);
|
||||
while( BufferedEventsStart != BufferedEventsEnd )
|
||||
{
|
||||
ev = BufferedEvents[BufferedEventsStart];
|
||||
BufferedEvents[BufferedEventsStart].type = 0;
|
||||
BufferedEventsStart++;
|
||||
if( BufferedEventsStart >= MAX_BUFFERED_EVENTS )
|
||||
BufferedEventsStart = 0;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
|
||||
switch( ev.type )
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, ev.motion.x, ev.motion.y );
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if( ((oldMouseButtons & SDL_BUTTON(ev.button.button)) != 0) != ev.button.state )
|
||||
{
|
||||
oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(ev.button.button)) | (ev.button.state ? SDL_BUTTON(ev.button.button) : 0);
|
||||
SDL_SendMouseButton( ANDROID_CurrentWindow, 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;
|
||||
case SDL_JOYBALLMOTION:
|
||||
if( ev.jball.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] )
|
||||
SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[ev.jball.which], ev.jball.ball, ev.jball.xrel, ev.jball.yrel );
|
||||
break;
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
//if( ANDROID_CurrentWindow )
|
||||
// SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
#else
|
||||
case SDL_ACTIVEEVENT:
|
||||
SDL_PrivateAppActive(ev.active.gain, ev.active.state);
|
||||
break;
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
case SDL_FINGERMOTION:
|
||||
SDL_SendTouchMotion(0, ev.tfinger.fingerId, 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure);
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
SDL_SendFingerDown(0, ev.tfinger.fingerId, ev.tfinger.state ? 1 : 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
SDL_SendKeyboardText(ev.text.text);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
SDL_SendMouseWheel( ANDROID_CurrentWindow, ev.wheel.x, ev.wheel.y );
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_mutexP(BufferedEventsMutex);
|
||||
}
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
// Queue events to main thread
|
||||
static int getNextEventAndLock()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static int getPrevEventNoLock()
|
||||
{
|
||||
int prevEvent;
|
||||
if(BufferedEventsStart == BufferedEventsEnd)
|
||||
return -1;
|
||||
prevEvent = BufferedEventsEnd;
|
||||
prevEvent--;
|
||||
if( prevEvent < 0 )
|
||||
prevEvent = MAX_BUFFERED_EVENTS - 1;
|
||||
return prevEvent;
|
||||
}
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y)
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
int prevEvent = getPrevEventNoLock();
|
||||
if( prevEvent > 0 && BufferedEvents[prevEvent].type == SDL_MOUSEMOTION )
|
||||
{
|
||||
// Reuse previous mouse motion event, to prevent mouse movement lag
|
||||
BufferedEvents[prevEvent].motion.x = x;
|
||||
BufferedEvents[prevEvent].motion.y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
ev->type = SDL_MOUSEMOTION;
|
||||
ev->motion.x = x;
|
||||
ev->motion.y = y;
|
||||
}
|
||||
currentMouseX = x;
|
||||
currentMouseY = y;
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button)
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_MOUSEBUTTONDOWN;
|
||||
ev->button.state = pressed;
|
||||
ev->button.button = button;
|
||||
|
||||
if(pressed)
|
||||
currentMouseButtons |= SDL_BUTTON(button);
|
||||
else
|
||||
currentMouseButtons &= ~(SDL_BUTTON(button));
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key)
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
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 )
|
||||
{
|
||||
moveMouseWithKbX = currentMouseX;
|
||||
moveMouseWithKbY = currentMouseY;
|
||||
}
|
||||
|
||||
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 )
|
||||
#endif
|
||||
ev->key.keysym.unicode = key;
|
||||
|
||||
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 = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_JOYAXISMOTION;
|
||||
ev->jaxis.which = joy;
|
||||
ev->jaxis.axis = axis;
|
||||
ev->jaxis.value = MAX( -32768, MIN( 32767, 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 = getNextEventAndLock();
|
||||
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_MainThreadPushJoystickBall(int joy, int ball, int x, int y)
|
||||
{
|
||||
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
|
||||
return;
|
||||
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_JOYBALLMOTION;
|
||||
ev->jball.which = joy;
|
||||
ev->jball.ball = ball;
|
||||
ev->jball.xrel = x;
|
||||
ev->jball.yrel = y;
|
||||
|
||||
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 = getNextEventAndLock();
|
||||
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 = getNextEventAndLock();
|
||||
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
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushMouseWheel(int x, int y)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_MOUSEWHEEL;
|
||||
ev->wheel.x = x;
|
||||
ev->wheel.y = y;
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushAppActive(int active)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
//if( ANDROID_CurrentWindow )
|
||||
// SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
#else
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
ev->type = SDL_ACTIVEEVENT;
|
||||
ev->active.gain = active;
|
||||
ev->active.state = SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS;
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
enum { DEFERRED_TEXT_COUNT = 256 };
|
||||
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;
|
||||
|
||||
static SDL_keysym asciiToKeysym(int ascii, int unicode)
|
||||
{
|
||||
SDL_keysym keysym;
|
||||
keysym.scancode = ascii;
|
||||
keysym.sym = ascii;
|
||||
keysym.mod = KMOD_NONE;
|
||||
keysym.unicode = 0;
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
keysym.sym = SDL_GetScancodeFromKey(ascii);
|
||||
#else
|
||||
if ( SDL_TranslateUNICODE )
|
||||
#endif
|
||||
keysym.unicode = unicode;
|
||||
return keysym;
|
||||
}
|
||||
|
||||
static int checkShiftRequired( int * sym )
|
||||
{
|
||||
switch( *sym )
|
||||
{
|
||||
case '!': *sym = '1'; return 1;
|
||||
case '@': *sym = '2'; return 1;
|
||||
case '#': *sym = '3'; return 1;
|
||||
case '$': *sym = '4'; return 1;
|
||||
case '%': *sym = '5'; return 1;
|
||||
case '^': *sym = '6'; return 1;
|
||||
case '&': *sym = '7'; return 1;
|
||||
case '*': *sym = '8'; return 1;
|
||||
case '(': *sym = '9'; return 1;
|
||||
case ')': *sym = '0'; return 1;
|
||||
case '_': *sym = '-'; return 1;
|
||||
case '+': *sym = '='; return 1;
|
||||
case '|': *sym = '\\';return 1;
|
||||
case '<': *sym = ','; return 1;
|
||||
case '>': *sym = '.'; return 1;
|
||||
case '?': *sym = '/'; return 1;
|
||||
case ':': *sym = ';'; return 1;
|
||||
case '"': *sym = '\'';return 1;
|
||||
case '{': *sym = '['; return 1;
|
||||
case '}': *sym = ']'; return 1;
|
||||
case '~': *sym = '`'; return 1;
|
||||
default: if( *sym >= 'A' && *sym <= 'Z' ) { *sym += 'a' - 'A'; return 1; };
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDL_ANDROID_DeferredTextInput()
|
||||
{
|
||||
if( !deferredTextMutex )
|
||||
deferredTextMutex = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(deferredTextMutex);
|
||||
|
||||
if( deferredTextIdx1 != deferredTextIdx2 )
|
||||
{
|
||||
int nextEvent = getNextEventAndLock();
|
||||
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 = asciiToKeysym( deferredText[deferredTextIdx1].scancode, deferredText[deferredTextIdx1].unicode );
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
if( isMouseUsed )
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX + (currentMouseX % 2 ? -1 : 1), currentMouseY); // Force screen redraw
|
||||
}
|
||||
else
|
||||
{
|
||||
if( SDL_ANDROID_TextInputFinished )
|
||||
{
|
||||
SDL_ANDROID_TextInputFinished = 0;
|
||||
SDL_ANDROID_IsScreenKeyboardShownFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_mutexV(deferredTextMutex);
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode )
|
||||
{
|
||||
int shiftRequired;
|
||||
|
||||
int nextEvent = getNextEventAndLock();
|
||||
if( nextEvent == -1 )
|
||||
return;
|
||||
|
||||
SDL_Event * ev = &BufferedEvents[BufferedEventsEnd];
|
||||
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
|
||||
ev->type = SDL_TEXTINPUT;
|
||||
UnicodeToUtf8(unicode, ev->text.text);
|
||||
|
||||
#endif
|
||||
|
||||
if( !deferredTextMutex )
|
||||
deferredTextMutex = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(deferredTextMutex);
|
||||
|
||||
ev->type = 0;
|
||||
|
||||
shiftRequired = checkShiftRequired(&ascii);
|
||||
|
||||
if( shiftRequired )
|
||||
{
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_PRESSED;
|
||||
deferredText[deferredTextIdx2].scancode = SDLK_LSHIFT;
|
||||
deferredText[deferredTextIdx2].unicode = 0;
|
||||
}
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_PRESSED;
|
||||
deferredText[deferredTextIdx2].scancode = ascii;
|
||||
deferredText[deferredTextIdx2].unicode = unicode;
|
||||
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_RELEASED;
|
||||
deferredText[deferredTextIdx2].scancode = ascii;
|
||||
deferredText[deferredTextIdx2].unicode = 0;
|
||||
if( shiftRequired )
|
||||
{
|
||||
deferredTextIdx2++;
|
||||
if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT )
|
||||
deferredTextIdx2 = 0;
|
||||
deferredText[deferredTextIdx2].down = SDL_RELEASED;
|
||||
deferredText[deferredTextIdx2].scancode = SDLK_LSHIFT;
|
||||
deferredText[deferredTextIdx2].unicode = 0;
|
||||
}
|
||||
|
||||
SDL_mutexV(deferredTextMutex);
|
||||
|
||||
BufferedEventsEnd = nextEvent;
|
||||
SDL_mutexV(BufferedEventsMutex);
|
||||
};
|
||||
|
||||
|
||||
Uint32 lastMoveMouseWithKeyboardUpdate = 0;
|
||||
|
||||
void SDL_ANDROID_processMoveMouseWithKeyboard()
|
||||
{
|
||||
if( ! moveMouseWithKbAccelUpdateNeeded )
|
||||
if( ! SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded )
|
||||
return;
|
||||
|
||||
Uint32 ticks = SDL_GetTicks();
|
||||
@@ -2088,12 +1464,12 @@ void SDL_ANDROID_processMoveMouseWithKeyboard()
|
||||
|
||||
lastMoveMouseWithKeyboardUpdate = ticks;
|
||||
|
||||
moveMouseWithKbSpeedX += moveMouseWithKbAccelX;
|
||||
moveMouseWithKbSpeedY += moveMouseWithKbAccelY;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedX += SDL_ANDROID_moveMouseWithKbAccelX;
|
||||
SDL_ANDROID_moveMouseWithKbSpeedY += SDL_ANDROID_moveMouseWithKbAccelY;
|
||||
|
||||
moveMouseWithKbX += moveMouseWithKbSpeedX;
|
||||
moveMouseWithKbY += moveMouseWithKbSpeedY;
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY);
|
||||
SDL_ANDROID_moveMouseWithKbX += SDL_ANDROID_moveMouseWithKbSpeedX;
|
||||
SDL_ANDROID_moveMouseWithKbY += SDL_ANDROID_moveMouseWithKbSpeedY;
|
||||
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY);
|
||||
};
|
||||
|
||||
extern void SDL_ANDROID_ProcessDeferredEvents()
|
||||
|
||||
@@ -203,4 +203,18 @@ extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode );
|
||||
extern void SDL_android_init_keymap(SDLKey *SDL_android_keymap);
|
||||
extern void SDL_ANDROID_MainThreadPushMouseWheel( int x, int y ); // SDL 1.3 only
|
||||
extern void SDL_ANDROID_MainThreadPushAppActive(int active);
|
||||
|
||||
// Internal input queue stuff
|
||||
extern SDLKey SDL_android_keymap[];
|
||||
extern SDL_Joystick *SDL_ANDROID_CurrentJoysticks[];
|
||||
extern int SDL_ANDROID_isMouseUsed;
|
||||
extern int SDL_ANDROID_currentMouseX, SDL_ANDROID_currentMouseY, SDL_ANDROID_currentMouseButtons;
|
||||
extern int SDL_ANDROID_moveMouseWithArrowKeys;
|
||||
extern int SDL_ANDROID_moveMouseWithKbSpeed;
|
||||
extern int SDL_ANDROID_moveMouseWithKbAccel;
|
||||
extern int SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY;
|
||||
extern int SDL_ANDROID_moveMouseWithKbSpeedX, SDL_ANDROID_moveMouseWithKbSpeedY;
|
||||
extern int SDL_ANDROID_moveMouseWithKbAccelX, SDL_ANDROID_moveMouseWithKbAccelY;
|
||||
extern int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,4 +30,7 @@ static inline int atan2i(int y, int x)
|
||||
return(angle);
|
||||
};
|
||||
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user