Files
commandergenius/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-fast.c
2018-12-05 20:19:39 +02:00

371 lines
11 KiB
C

/*
Simple DirectMedia Layer
Copyright (C) 2009-2014 Sergii Pylypenko
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
This source code is distibuted under ZLIB license, however when compiling with SDL 1.2,
which is licensed under LGPL, the resulting library, and all it's source code,
falls under "stronger" LGPL terms, so is this file.
If you compile this code with SDL 1.3 or newer, or use in some other way, the license stays ZLIB.
*/
#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"
#ifndef SDL_COMPATIBILITY_HACKS_SLOW_COMPATIBLE_EVENT_QUEUE
#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
static volatile int joystickEventsCount;
static int oldMouseButtons = 0;
extern void SDL_ANDROID_PumpEvents()
{
joystickEventsCount = 0;
SDL_ANDROID_processMoveMouseWithKeyboard();
};
extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y)
{
SDL_ANDROID_currentMouseX = x;
SDL_ANDROID_currentMouseY = y;
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "MainThreadPushMouseMotion: %4d %4d", x, y);
SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, x, y );
}
extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button)
{
if( ((oldMouseButtons & SDL_BUTTON(button)) != 0) != pressed )
{
oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(button)) | (pressed ? SDL_BUTTON(button) : 0);
SDL_SendMouseButton( ANDROID_CurrentWindow, pressed, button );
}
if(pressed)
SDL_ANDROID_currentMouseButtons |= SDL_BUTTON(button);
else
SDL_ANDROID_currentMouseButtons &= ~(SDL_BUTTON(button));
}
extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key, int unicode)
{
SDL_keysym keysym;
if( SDL_ANDROID_moveMouseWithArrowKeys && (
key == SDL_KEY(UP) || key == SDL_KEY(DOWN) ||
key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) )
{
if( !SDL_ANDROID_moveMouseWithKbActive )
{
SDL_ANDROID_moveMouseWithKbActive = 1;
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;
if (SDL_ANDROID_moveMouseWithKbX < 0)
SDL_ANDROID_moveMouseWithKbX = 0;
if (SDL_ANDROID_moveMouseWithKbY < 0)
SDL_ANDROID_moveMouseWithKbY = 0;
if (SDL_ANDROID_moveMouseWithKbX >= SDL_ANDROID_sFakeWindowWidth)
SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_sFakeWindowWidth - 1;
if (SDL_ANDROID_moveMouseWithKbY >= SDL_ANDROID_sFakeWindowHeight)
SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_sFakeWindowHeight - 1;
SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY);
return;
}
if ( key >= SDLK_MOUSE_LEFT && key <= SDLK_MOUSE_X2 )
{
SDL_ANDROID_MainThreadPushMouseButton(pressed, key - SDLK_MOUSE_LEFT + SDL_BUTTON_LEFT);
return;
}
keysym.scancode = key;
if ( key < SDLK_LAST )
keysym.scancode = SDL_android_keysym_to_scancode[key];
keysym.sym = key;
keysym.mod = KMOD_NONE;
keysym.unicode = 0;
#if SDL_VERSION_ATLEAST(1,3,0)
#else
if ( SDL_TranslateUNICODE )
#endif
keysym.unicode = unicode;
if( (keysym.unicode & 0xFF80) != 0 )
keysym.sym = SDLK_WORLD_0;
if( pressed == SDL_RELEASED )
keysym.unicode = 0;
else if( keysym.sym < 0x80 )
keysym.unicode = keysym.sym;
//__android_log_print(ANDROID_LOG_INFO, "libSDL","SDL_SendKeyboardKey sym %d scancode %d unicode %d", keysym.sym, keysym.scancode, keysym.unicode);
SDL_SendKeyboardKey( pressed, &keysym );
}
extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value)
{
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
return;
if( joystickEventsCount > 64 )
{
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "Too many joystick events in the queue - dropping some events");
return;
}
joystickEventsCount++;
SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[joy], axis, MAX( -32768, MIN( 32767, value ) ) );
}
extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed)
{
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
return;
SDL_PrivateJoystickButton( SDL_ANDROID_CurrentJoysticks[joy], button, pressed );
}
extern void SDL_ANDROID_MainThreadPushJoystickBall(int joy, int ball, int x, int y)
{
if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) )
return;
SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[joy], ball, x, y );
}
extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force)
{
#if SDL_VERSION_ATLEAST(1,3,0)
SDL_SendFingerDown(0, id, pressed ? 1 : 0, (float)x / (float)window->w, (float)y / (float)window->h, force);
#endif
}
extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force)
{
#if SDL_VERSION_ATLEAST(1,3,0)
SDL_SendTouchMotion(0, id, 0, (float)x / (float)window->w, (float)y / (float)window->h, force);
#endif
}
extern void SDL_ANDROID_MainThreadPushMouseWheel(int x, int y)
{
#if SDL_VERSION_ATLEAST(1,3,0)
SDL_SendMouseWheel( ANDROID_CurrentWindow, x, y );
#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
SDL_PrivateAppActive(active, SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
#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 )
{
SDL_keysym keysym;
deferredTextIdx1++;
if( deferredTextIdx1 >= DEFERRED_TEXT_COUNT )
deferredTextIdx1 = 0;
keysym = asciiToKeysym( deferredText[deferredTextIdx1].scancode, deferredText[deferredTextIdx1].unicode );
if( deferredText[deferredTextIdx1].down == SDL_RELEASED )
keysym.unicode = 0;
SDL_SendKeyboardKey( deferredText[deferredTextIdx1].down, &keysym );
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_IsScreenKeyboardShownFlag = 0;
}
}
SDL_mutexV(deferredTextMutex);
}
extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode )
{
int shiftRequired;
#if SDL_VERSION_ATLEAST(1,3,0)
{
char text[32];
UnicodeToUtf8(unicode, text);
SDL_SendKeyboardText(text);
}
#endif
if( !deferredTextMutex )
deferredTextMutex = SDL_CreateMutex();
SDL_mutexP(deferredTextMutex);
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);
}
#endif