Files
xserver_xsdl/hw/kdrive/sdl/sdl.c
2019-09-09 18:22:20 +03:00

922 lines
24 KiB
C

/*
* Copyright © 2004 PillowElephantBadgerBankPond
* Copyright © 2014-2019 Sergii Pylypenko
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of PillowElephantBadgerBankPond not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. PillowElephantBadgerBankPond makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* PillowElephantBadgerBankPond DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL PillowElephantBadgerBankPond BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* It's really not my fault - see it was the elephants!!
* - jaymz
*
*/
#include "sdl_send_text.h"
#include "sdl_kdrive.h"
#include <xorg-config.h>
#include "kdrive.h"
#include "dix.h"
#include <SDL/SDL.h>
#include <X11/keysym.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pthread.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#ifdef __ANDROID__
#include <SDL/SDL_screenkeyboard.h>
#include <android/log.h>
// DEBUG
#define printf(...) __android_log_print(ANDROID_LOG_INFO, "XSDL", __VA_ARGS__)
#endif
static Bool xsdlInit(KdCardInfo *);
static void xsdlFini(KdCardInfo *);
static Bool sdlScreenInit(KdScreenInfo *screen);
static Bool sdlFinishInitScreen(ScreenPtr pScreen);
static Bool sdlCreateRes(ScreenPtr pScreen);
static void sdlKeyboardFini(KdKeyboardInfo *ki);
static Status sdlKeyboardInit(KdKeyboardInfo *ki);
static Status sdlKeyboardEnable (KdKeyboardInfo *ki);
static void sdlKeyboardDisable (KdKeyboardInfo *ki);
static void sdlKeyboardLeds (KdKeyboardInfo *ki, int leds);
static void sdlKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration);
static Bool sdlMouseInit(KdPointerInfo *pi);
static void sdlMouseFini(KdPointerInfo *pi);
static Status sdlMouseEnable (KdPointerInfo *pi);
static void sdlMouseDisable (KdPointerInfo *pi);
static Bool sdlScreenButtons = FALSE;
static void setScreenButtons(int mouseX);
static void sdlScreenBlockCallback(ScreenPtr pScreen, void *timeout);
enum sdlKeyboardType_t { KB_NATIVE = 0, KB_BUILTIN = 1, KB_BOTH = 2 };
enum sdlKeyboardType_t sdlKeyboardType = KB_NATIVE;
KdKeyboardInfo *sdlKeyboard = NULL;
KdPointerInfo *sdlPointer = NULL;
KdKeyboardDriver sdlKeyboardDriver = {
.name = "keyboard",
.Init = sdlKeyboardInit,
.Fini = sdlKeyboardFini,
.Enable = sdlKeyboardEnable,
.Disable = sdlKeyboardDisable,
.Leds = sdlKeyboardLeds,
.Bell = sdlKeyboardBell,
};
KdPointerDriver sdlMouseDriver = {
.name = "mouse",
.Init = sdlMouseInit,
.Fini = sdlMouseFini,
.Enable = sdlMouseEnable,
.Disable = sdlMouseDisable,
};
KdCardFuncs sdlFuncs = {
.cardinit = xsdlInit,
.cardfini = xsdlFini,
.scrinit = sdlScreenInit,
.finishInitScreen = sdlFinishInitScreen,
.createRes = sdlCreateRes,
};
int mouseState = 0;
enum { NUMRECTS = 32, FULLSCREEN_REFRESH_TIME = 1000 };
//Uint32 nextFullScreenRefresh = 0;
typedef struct
{
SDL_Surface *screen;
Rotation randr;
Bool shadow;
ScreenBlockHandlerProcPtr screenBlockCallback;
} SdlDriver;
//#undef RANDR
static Bool sdlMapFramebuffer (KdScreenInfo *screen)
{
SdlDriver *driver = screen->driver;
KdPointerMatrix m;
if (driver->randr != RR_Rotate_0)
driver->shadow = TRUE;
else
driver->shadow = FALSE;
KdComputePointerMatrix (&m, driver->randr, screen->width, screen->height);
KdSetPointerMatrix (&m);
screen->width = driver->screen->w;
screen->height = driver->screen->h;
printf("%s: shadow %d\n", __func__, driver->shadow);
if (driver->shadow)
{
if (!KdShadowFbAlloc (screen,
driver->randr & (RR_Rotate_90|RR_Rotate_270)))
return FALSE;
}
else
{
screen->fb.byteStride = driver->screen->pitch;
screen->fb.pixelStride = driver->screen->w;
screen->fb.frameBuffer = (CARD8 *) (driver->screen->pixels);
}
return TRUE;
}
static void
sdlSetScreenSizes (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *driver = screen->driver;
if (driver->randr & (RR_Rotate_0|RR_Rotate_180))
{
pScreen->width = driver->screen->w;
pScreen->height = driver->screen->h;
pScreen->mmWidth = screen->width_mm;
pScreen->mmHeight = screen->height_mm;
}
else
{
pScreen->width = driver->screen->h;
pScreen->height = driver->screen->w;
pScreen->mmWidth = screen->height_mm;
pScreen->mmHeight = screen->width_mm;
}
}
static Bool
sdlUnmapFramebuffer (KdScreenInfo *screen)
{
KdShadowFbFree (screen);
return TRUE;
}
static Bool sdlScreenInit(KdScreenInfo *screen)
{
SdlDriver *driver=calloc(1, sizeof(SdlDriver));
printf("%s\n", __func__);
if (!screen->width || !screen->height)
{
screen->width = 640;
screen->height = 480;
}
if (!screen->fb.depth)
screen->fb.depth = 24;
printf("Attempting for %dx%d/%dbpp mode\n", screen->width, screen->height, screen->fb.depth);
driver->screen = SDL_SetVideoMode(screen->width, screen->height, screen->fb.depth, 0);
if(driver->screen == NULL)
{
printf("%s: SDL_SetVideoMode failed!\n", __func__);
return FALSE;
}
driver->randr = screen->randr;
screen->driver = driver;
printf("Set %dx%d/%dbpp mode\n", driver->screen->w, driver->screen->h, driver->screen->format->BitsPerPixel);
screen->width = driver->screen->w;
screen->height = driver->screen->h;
screen->fb.depth = driver->screen->format->BitsPerPixel;
screen->fb.visuals = (1<<TrueColor);
screen->fb.redMask = driver->screen->format->Rmask;
screen->fb.greenMask = driver->screen->format->Gmask;
screen->fb.blueMask = driver->screen->format->Bmask;
screen->fb.bitsPerPixel = driver->screen->format->BitsPerPixel;
//screen->fb.shadow = FALSE;
screen->rate=30; // 60 is too intense for CPU
SDL_WM_SetCaption("Freedesktop.org X server (SDL)", NULL);
SDL_EnableUNICODE(1);
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
#ifdef __ANDROID__
set_clipboard_text(SDL_GetClipboardText());
sdlScreenButtons = SDL_ANDROID_GetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0);
#endif
setScreenButtons(10000);
if (getenv("XSDL_BUILTIN_KEYBOARD") != NULL)
{
sdlKeyboardType = atoi(getenv("XSDL_BUILTIN_KEYBOARD")) == KB_NATIVE ? KB_NATIVE :
atoi(getenv("XSDL_BUILTIN_KEYBOARD")) == KB_BUILTIN ? KB_BUILTIN : KB_BOTH;
}
unsetenv("XSDL_BUILTIN_KEYBOARD");
printf("sdlScreenButtons %d sdlKeyboardType %d\n", sdlScreenButtons, sdlKeyboardType);
return sdlMapFramebuffer (screen);
}
static void sdlShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *driver = screen->driver;
pixman_box16_t * rects;
int amount, i;
int updateRectsPixelCount = 0;
//printf("sdlShadowUpdate: time %d", SDL_GetTicks());
if (driver->shadow)
{
ShadowUpdateProc update;
if (driver->randr)
{
/*
if (driver->screen->format->BitsPerPixel == 16)
{
switch (driver->randr) {
case RR_Rotate_90:
update = shadowUpdateRotate16_90YX;
break;
case RR_Rotate_180:
update = shadowUpdateRotate16_180;
break;
case RR_Rotate_270:
update = shadowUpdateRotate16_270YX;
break;
default:
update = shadowUpdateRotate16;
break;
}
} else
*/
update = shadowUpdateRotatePacked;
}
else
update = shadowUpdatePacked;
update(pScreen, pBuf);
}
rects = pixman_region_rectangles(&pBuf->pDamage->damage, &amount);
for ( i = 0; i < amount; i++ )
{
updateRectsPixelCount += (pBuf->pDamage->damage.extents.x2 - pBuf->pDamage->damage.extents.x1) *
(pBuf->pDamage->damage.extents.y2 - pBuf->pDamage->damage.extents.y1);
}
// Each subrect is copied into temp buffer before uploading to OpenGL texture,
// so if total area of pixels copied is more than 1/3 of the whole screen area,
// there will be performance hit instead of optimization.
if ( amount > NUMRECTS || updateRectsPixelCount * 3 > driver->screen->w * driver->screen->h )
{
//printf("SDL_Flip\n");
SDL_Flip(driver->screen);
//nextFullScreenRefresh = 0;
}
else
{
SDL_Rect updateRects[NUMRECTS];
//if ( ! nextFullScreenRefresh )
// nextFullScreenRefresh = SDL_GetTicks() + FULLSCREEN_REFRESH_TIME;
for ( i = 0; i < amount; i++ )
{
updateRects[i].x = rects[i].x1;
updateRects[i].y = rects[i].y1;
updateRects[i].w = rects[i].x2 - rects[i].x1;
updateRects[i].h = rects[i].y2 - rects[i].y1;
//printf("sdlShadowUpdate: rect %d: %04d:%04d:%04d:%04d", i, rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
}
//printf("SDL_UpdateRects %d\n", amount);
SDL_UpdateRects(driver->screen, amount, updateRects);
}
}
static void *sdlShadowWindow (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, CARD32 *size, void *closure)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *driver = screen->driver;
// if (!pScreenPriv->enabled)
// return NULL;
*size = driver->screen->pitch;
//printf("%s\n", __func__);
return (void *)((CARD8 *)driver->screen->pixels + row * (*size) + offset);
}
static Bool sdlCreateRes(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *driver = screen->driver;
Bool oldShadow = screen->fb.shadow;
printf("%s\n", __func__);
// Hack: Kdrive assumes we have dumb videobuffer, which updates automatically,
// and does not call update callback if shadow flag is not set.
screen->fb.shadow = TRUE;
KdShadowSet (pScreen, driver->randr, sdlShadowUpdate, sdlShadowWindow);
screen->fb.shadow = oldShadow;
return TRUE;
}
#ifdef RANDR
typedef struct { int width; int height; } screen_size_t;
static Bool sdlRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *driver = screen->driver;
RRScreenSizePtr pSize;
Rotation randr;
int n;
screen_size_t sizes[] =
{
{ 1920, 1200 },
{ 1920, 1080 },
{ 1600, 1200 },
{ 1400, 1050 },
{ 1280, 1024 },
{ 1280, 960 },
{ 1280, 800 },
{ 1280, 720 },
{ 1152, 864 },
{ 1024, 768 },
{ 832, 624 },
{ 800, 600 },
{ 800, 480 },
{ 720, 400 },
{ 640, 480 },
{ 640, 400 },
{ 320, 240 },
{ 320, 200 },
{ 160, 160 },
{ 0, 0 }
};
printf("%s", __func__);
*rotations = RR_Rotate_All|RR_Reflect_All;
for (n = 0; n < pScreen->numDepths; n++)
if (pScreen->allowedDepths[n].numVids)
break;
if (n == pScreen->numDepths)
return FALSE;
pSize = RRRegisterSize (pScreen,
screen->width,
screen->height,
screen->width_mm,
screen->height_mm);
n = 0;
while (sizes[n].width != 0 && sizes[n].height != 0)
{
RRRegisterSize (pScreen,
sizes[n].width,
sizes[n].height,
(sizes[n].width * screen->width_mm)/screen->width,
(sizes[n].height *screen->height_mm)/screen->height
);
n++;
}
randr = KdSubRotation (driver->randr, screen->randr);
RRSetCurrentConfig (pScreen, randr, 0, pSize);
return TRUE;
}
static Bool sdlRandRSetConfig (ScreenPtr pScreen,
Rotation randr,
int rate,
RRScreenSizePtr pSize)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *driver = screen->driver;
Bool wasEnabled = pScreenPriv->enabled;
SdlDriver oldDriver;
int oldwidth;
int oldheight;
int oldmmwidth;
int oldmmheight;
if (wasEnabled)
KdDisableScreen (pScreen);
oldDriver = *driver;
oldwidth = screen->width;
oldheight = screen->height;
oldmmwidth = pScreen->mmWidth;
oldmmheight = pScreen->mmHeight;
/*
* Set new configuration
*/
driver->randr = KdAddRotation (screen->randr, randr);
printf("%s driver->randr %d", __func__, driver->randr);
sdlUnmapFramebuffer (screen);
if (!sdlMapFramebuffer (screen))
goto bail4;
KdShadowUnset (screen->pScreen);
if (!sdlCreateRes (screen->pScreen))
goto bail4;
sdlSetScreenSizes (screen->pScreen);
/*
* Set frame buffer mapping
*/
(*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
pScreen->width,
pScreen->height,
screen->fb.depth,
screen->fb.bitsPerPixel,
screen->fb.byteStride,
screen->fb.frameBuffer);
/* set the subpixel order */
KdSetSubpixelOrder (pScreen, driver->randr);
if (wasEnabled)
KdEnableScreen (pScreen);
return TRUE;
bail4:
sdlUnmapFramebuffer (screen);
*driver = oldDriver;
(void) sdlMapFramebuffer (screen);
pScreen->width = oldwidth;
pScreen->height = oldheight;
pScreen->mmWidth = oldmmwidth;
pScreen->mmHeight = oldmmheight;
if (wasEnabled)
KdEnableScreen (pScreen);
return FALSE;
}
static Bool sdlRandRInit (ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
printf("%s", __func__);
if (!RRScreenInit (pScreen))
return FALSE;
pScrPriv = rrGetScrPriv(pScreen);
pScrPriv->rrGetInfo = sdlRandRGetInfo;
pScrPriv->rrSetConfig = sdlRandRSetConfig;
return TRUE;
}
#endif
static Bool sdlFinishInitScreen(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *scrpriv = screen->driver;
if (!shadowSetup (pScreen))
return FALSE;
#ifdef RANDR
if (!sdlRandRInit (pScreen))
return FALSE;
#endif
scrpriv->screenBlockCallback = pScreen->BlockHandler;
pScreen->BlockHandler = sdlScreenBlockCallback;
return TRUE;
}
static void sdlKeyboardFini(KdKeyboardInfo *ki)
{
printf("sdlKeyboardFini() %p\n", ki);
sdlKeyboard = NULL;
}
static Status sdlKeyboardInit(KdKeyboardInfo *ki)
{
ki->minScanCode = 8;
ki->maxScanCode = 255;
ki->name = strdup("Android keyboard");
sdlKeyboard = ki;
printf("sdlKeyboardInit() %p\n", ki);
return Success;
}
static Status sdlKeyboardEnable (KdKeyboardInfo *ki)
{
return Success;
}
static void sdlKeyboardDisable (KdKeyboardInfo *ki)
{
}
static void sdlKeyboardLeds (KdKeyboardInfo *ki, int leds)
{
}
static void sdlKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
{
}
static Status sdlMouseInit (KdPointerInfo *pi)
{
pi->nButtons = 7;
pi->name = strdup("Android touchscreen and stylus");
sdlPointer = pi;
printf("sdlMouseInit() %p\n", pi);
return Success;
}
static void sdlMouseFini(KdPointerInfo *pi)
{
printf("sdlMouseFini() %p\n", pi);
sdlPointer = NULL;
}
static Status sdlMouseEnable (KdPointerInfo *pi)
{
return Success;
}
static void sdlMouseDisable (KdPointerInfo *pi)
{
return;
}
void InitCard(char *name)
{
KdCardInfoAdd (&sdlFuncs, 0);
printf("InitCard: %s\n", name);
}
void InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
{
KdInitOutput(pScreenInfo, argc, argv);
printf("InitOutput()\n");
}
void InitInput(int argc, char **argv)
{
KdPointerInfo *pi;
KdKeyboardInfo *ki;
KdAddKeyboardDriver(&sdlKeyboardDriver);
KdAddPointerDriver(&sdlMouseDriver);
ki = KdNewKeyboard();
ki->driver = &sdlKeyboardDriver;
KdAddKeyboard(ki);
pi = KdNewPointer();
pi->driver = &sdlMouseDriver;
KdAddPointer(pi);
KdInitInput();
}
#ifdef DDXBEFORERESET
void ddxBeforeReset(void)
{
}
#endif
void ddxUseMsg(void)
{
KdUseMsg();
}
int ddxProcessArgument(int argc, char **argv, int i)
{
return KdProcessArgument(argc, argv, i);
}
static void sdlPollInput(void)
{
static int buttonState=0;
static int pressure = 0;
SDL_Event event;
//printf("sdlPollInput() %d\n", SDL_GetTicks());
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_MOUSEMOTION:
//printf("SDL_MOUSEMOTION pressure %d\n", pressure);
KdEnqueuePointerEvent(sdlPointer, mouseState, event.motion.x, event.motion.y, pressure);
setScreenButtons(event.motion.x);
break;
case SDL_MOUSEBUTTONDOWN:
switch(event.button.button)
{
case SDL_BUTTON_LEFT:
buttonState = KD_BUTTON_1;
break;
case SDL_BUTTON_MIDDLE:
buttonState = KD_BUTTON_2;
break;
case SDL_BUTTON_RIGHT:
buttonState = KD_BUTTON_3;
break;
case SDL_BUTTON_WHEELUP:
buttonState = KD_BUTTON_4;
break;
case SDL_BUTTON_WHEELDOWN:
buttonState = KD_BUTTON_5;
break;
/*
case SDL_BUTTON_X1:
buttonState = KD_BUTTON_6;
break;
case SDL_BUTTON_X2:
buttonState = KD_BUTTON_7;
break;
*/
default:
buttonState = 1 << (event.button.button - 1);
break;
}
mouseState |= buttonState;
KdEnqueuePointerEvent(sdlPointer, mouseState|KD_MOUSE_DELTA, 0, 0, pressure);
break;
case SDL_MOUSEBUTTONUP:
switch(event.button.button)
{
case SDL_BUTTON_LEFT:
buttonState = KD_BUTTON_1;
pressure = 0;
break;
case SDL_BUTTON_MIDDLE:
buttonState = KD_BUTTON_2;
break;
case SDL_BUTTON_RIGHT:
buttonState = KD_BUTTON_3;
break;
case SDL_BUTTON_WHEELUP:
buttonState = KD_BUTTON_4;
break;
case SDL_BUTTON_WHEELDOWN:
buttonState = KD_BUTTON_5;
break;
/*
case SDL_BUTTON_X1:
buttonState = KD_BUTTON_6;
break;
case SDL_BUTTON_X2:
buttonState = KD_BUTTON_7;
break;
*/
default:
buttonState = 1 << (event.button.button - 1);
break;
}
mouseState &= ~buttonState;
KdEnqueuePointerEvent(sdlPointer, mouseState|KD_MOUSE_DELTA, 0, 0, pressure);
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
//printf("Key sym %d scancode %d unicode %d", event.key.keysym.sym, event.key.keysym.scancode, event.key.keysym.unicode);
#ifdef __ANDROID__
if (event.key.keysym.sym == SDLK_HELP)
{
if(event.type == SDL_KEYUP)
{
// SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput();
static int keyboard = 0;
keyboard++;
if (keyboard > 1 || (sdlKeyboardType != KB_BOTH && keyboard > 0))
keyboard = 0;
SDL_HideScreenKeyboard(NULL);
//SDL_Delay(150);
SDL_Flip(SDL_GetVideoSurface());
if (keyboard == 0)
{
SDL_Delay(100);
if (sdlKeyboardType == KB_NATIVE || sdlKeyboardType == KB_BOTH)
SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput();
if (sdlKeyboardType == KB_BUILTIN)
SDL_ANDROID_ToggleInternalScreenKeyboard(SDL_KEYBOARD_QWERTY);
SDL_Flip(SDL_GetVideoSurface());
}
if (keyboard == 1 && sdlKeyboardType == KB_BOTH)
{
SDL_Delay(100);
SDL_ANDROID_ToggleInternalScreenKeyboard(SDL_KEYBOARD_QWERTY);
SDL_Flip(SDL_GetVideoSurface());
}
}
setScreenButtons(10000);
}
else
#endif
if (event.key.keysym.sym == SDLK_UNDO)
{
if(event.type == SDL_KEYUP)
{
// Send Ctrl-Z
KdEnqueueKeyboardEvent (sdlKeyboard, 37, 0); // LCTRL
KdEnqueueKeyboardEvent (sdlKeyboard, 52, 0); // Z
KdEnqueueKeyboardEvent (sdlKeyboard, 52, 1); // Z
KdEnqueueKeyboardEvent (sdlKeyboard, 37, 1); // LCTRL
}
}
else if((event.key.keysym.unicode & 0xFF80) != 0)
{
send_unicode (event.key.keysym.unicode);
}
else
KdEnqueueKeyboardEvent (sdlKeyboard, event.key.keysym.scancode, event.type==SDL_KEYUP);
// Force SDL screen update, so SDL virtual on-screen buttons will change their images
{
SDL_Rect r = {0, 0, 1, 1};
SDL_UpdateRects(SDL_GetVideoSurface(), 1, &r);
}
break;
case SDL_JOYAXISMOTION:
if (event.jaxis.which == 0 && event.jaxis.axis == 4 && pressure != event.jaxis.value)
{
pressure = event.jaxis.value;
if (mouseState & KD_BUTTON_1)
KdEnqueuePointerEvent(sdlPointer, mouseState|KD_MOUSE_DELTA, 0, 0, pressure);
}
break;
case SDL_ACTIVEEVENT:
// We need this to re-init OpenGL and redraw screen
// And we need to also call this when OpenGL context was destroyed
// Oherwise SDL will stuck and we will get a permanent black screen
SDL_Flip(SDL_GetVideoSurface());
break;
case SDL_SYSWMEVENT:
process_clipboard_event(&event.syswm);
break;
//case SDL_QUIT:
/* this should never happen */
//SDL_Quit(); // SDL_Quit() on Android is buggy
}
}
/*
if ( nextFullScreenRefresh && nextFullScreenRefresh < SDL_GetTicks() )
{
//printf("SDL_Flip from sdlPollInput");
SDL_Flip(SDL_GetVideoSurface());
nextFullScreenRefresh = 0;
}
*/
}
void sdlScreenBlockCallback(ScreenPtr pScreen, void *timeout)
{
KdScreenPriv(pScreen);
KdScreenInfo *screen = pScreenPriv->screen;
SdlDriver *scrpriv = screen->driver;
pScreen->BlockHandler = scrpriv->screenBlockCallback;
(*pScreen->BlockHandler)(pScreen, timeout);
scrpriv->screenBlockCallback = pScreen->BlockHandler;
pScreen->BlockHandler = sdlScreenBlockCallback;
sdlPollInput();
}
static Bool xsdlInit(KdCardInfo * card)
{
printf("Calling SDL_Init()\n");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO);
SDL_JoystickOpen(0); // Receive pressure events
return TRUE;
}
static void xsdlFini(KdCardInfo * card)
{
//SDL_Quit(); // SDL_Quit() on Android is buggy
}
void
CloseInput (void)
{
KdCloseInput ();
}
void OsVendorInit (void)
{
}
void setScreenButtons(int mouseX)
{
#ifdef __ANDROID__
//printf ("setScreenButtons: kbShown %d sdlScreenButtons %d alignLeft %d", SDL_IsScreenKeyboardShown(NULL), sdlScreenButtons, mouseX > (((unsigned)SDL_GetVideoSurface()->w) >> 3));
if ( SDL_ANDROID_GetScreenKeyboardRedefinedByUser() )
return;
int kbShown = SDL_IsScreenKeyboardShown(NULL);
if (!sdlScreenButtons)
{
if (SDL_ANDROID_GetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0))
{
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, 0);
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, 0);
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 0);
}
return;
}
SDL_Rect pos;
SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos);
//printf ("setScreenButtons: pos %d %d shown %d", pos.x, pos.y, SDL_ANDROID_GetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0));
int alignLeft;
alignLeft = mouseX > (((unsigned)SDL_GetVideoSurface()->w) >> 3);
if (!kbShown && pos.y > 0 && (pos.x == 0) == alignLeft)
return;
if (kbShown && pos.y == 0 && (pos.x == 0) == alignLeft && SDL_ANDROID_GetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0))
return;
int resolutionW;
resolutionW = atoi(getenv("DISPLAY_RESOLUTION_WIDTH"));
if (resolutionW <= 0)
resolutionW = SDL_ListModes(NULL, 0)[0]->w;
pos.w = (kbShown ? 60 : 40) * SDL_ListModes(NULL, 0)[0]->w / resolutionW;
pos.h = SDL_ListModes(NULL, 0)[0]->h / 20;
pos.x = alignLeft ? 0 : SDL_ListModes(NULL, 0)[0]->w - pos.w;
pos.y = kbShown ? 0 : SDL_ListModes(NULL, 0)[0]->h - pos.h * 3;
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, 1);
SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos);
SDL_ANDROID_SetScreenKeyboardButtonImagePos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos);
SDL_ANDROID_SetScreenKeyboardButtonStayPressedAfterTouch(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, 1);
pos.y += pos.h;
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, 1);
SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &pos);
SDL_ANDROID_SetScreenKeyboardButtonImagePos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &pos);
SDL_ANDROID_SetScreenKeyboardButtonStayPressedAfterTouch(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, 1);
pos.y += pos.h;
SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 1);
SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &pos);
SDL_ANDROID_SetScreenKeyboardButtonImagePos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &pos);
SDL_ANDROID_SetScreenKeyboardButtonStayPressedAfterTouch(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 1);
SDL_ANDROID_SetScreenKeyboardTransparency(255); // opaque
#endif
}