211 lines
5.6 KiB
C
211 lines
5.6 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <limits.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <pwd.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/un.h>
|
|
#include <errno.h>
|
|
#include <SDL/SDL.h>
|
|
#include <SDL/SDL_screenkeyboard.h>
|
|
#include <android/log.h>
|
|
|
|
#include "gfx.h"
|
|
|
|
extern int android_main( int argc, char *argv[], char *envp[] );
|
|
|
|
static void setupEnv(void);
|
|
static void showError(void);
|
|
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
int i;
|
|
char screenres[128] = "640x480x24";
|
|
char clientcmd[PATH_MAX] = "";
|
|
char port[16] = ":1111";
|
|
char * cmd = "";
|
|
char* args[64] = {
|
|
"XSDL",
|
|
port,
|
|
"-nolock",
|
|
"-noreset",
|
|
"-screen",
|
|
screenres,
|
|
};
|
|
int argnum = 6;
|
|
enum { ARGNUM = 8 };
|
|
char * envp[] = { NULL };
|
|
int printHelp = 1;
|
|
int screenResOverride = 0;
|
|
int screenButtons = 0;
|
|
|
|
int resolutionW = atoi(getenv("DISPLAY_RESOLUTION_WIDTH"));
|
|
int resolutionH = atoi(getenv("DISPLAY_RESOLUTION_HEIGHT"));
|
|
int displayW = atoi(getenv("DISPLAY_WIDTH_MM"));
|
|
int displayH = atoi(getenv("DISPLAY_HEIGHT_MM"));
|
|
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Actual video resolution %d/%dx%d/%d", resolutionW, displayW, resolutionH, displayH);
|
|
setupEnv();
|
|
|
|
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);
|
|
|
|
XSDL_initSDL();
|
|
|
|
XSDL_unpackFiles();
|
|
|
|
XSDL_showConfigMenu(&resolutionW, &displayW, &resolutionH, &displayH);
|
|
|
|
for(i = 0; i < 1024; i++)
|
|
{
|
|
int s = socket(AF_INET, SOCK_STREAM, 0);
|
|
if( s >= 0 )
|
|
{
|
|
struct sockaddr_in addr;
|
|
|
|
memset(&addr, 0, sizeof(addr));
|
|
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr = INADDR_ANY;
|
|
addr.sin_port = htons(6000 + i);
|
|
|
|
if( bind (s, (struct sockaddr *) &addr, sizeof(addr) ) != 0 )
|
|
{
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "TCP port %d already used, trying next one: %s", 6000 + i, strerror(errno));
|
|
close(s);
|
|
continue;
|
|
}
|
|
close(s);
|
|
}
|
|
|
|
FILE * ff = fopen("/proc/net/unix", "rb");
|
|
if( ff )
|
|
{
|
|
char buf[512], name[512];
|
|
int found = 0;
|
|
sprintf(name, "/tmp/.X11-unix/X%d", i);
|
|
while( fgets(buf, sizeof(buf), ff) )
|
|
{
|
|
if( strstr(buf, name) != NULL )
|
|
{
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "UNIX path %s already used, trying next one", name);
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
fclose(ff);
|
|
if( found )
|
|
continue;
|
|
}
|
|
|
|
sprintf( port, ":%d", i );
|
|
break;
|
|
}
|
|
|
|
while( argc > 1 )
|
|
{
|
|
if( argv[1][0] == ':')
|
|
{
|
|
strcpy(port, argv[1]);
|
|
}
|
|
else if( strcmp(argv[1], "-nohelp") == 0 )
|
|
{
|
|
printHelp = 0;
|
|
}
|
|
else if( strcmp(argv[1], "-screen") == 0 )
|
|
{
|
|
screenResOverride = 1;
|
|
argc--;
|
|
argv++;
|
|
strcpy(screenres, argv[1]);
|
|
}
|
|
else if( strcmp(argv[1], "-screenbuttons") == 0 )
|
|
{
|
|
screenButtons = 1;
|
|
}
|
|
else
|
|
{
|
|
args[argnum] = argv[1];
|
|
argnum++;
|
|
}
|
|
argc--;
|
|
argv++;
|
|
}
|
|
|
|
XSDL_generateBackground(port, printHelp, resolutionW, resolutionH);
|
|
|
|
XSDL_deinitSDL();
|
|
|
|
if( !screenResOverride )
|
|
sprintf( screenres, "%d/%dx%d/%dx%d", resolutionW, displayW, resolutionH, displayH, SDL_GetVideoInfo()->vfmt->BitsPerPixel );
|
|
|
|
if( printHelp )
|
|
{
|
|
sprintf( clientcmd, "%s/usr/bin/xhost + ; %s/usr/bin/xli -onroot -center background.bmp",
|
|
getenv("SECURE_STORAGE_DIR"), getenv("SECURE_STORAGE_DIR") );
|
|
args[argnum] = "-exec";
|
|
args[argnum+1] = clientcmd;
|
|
argnum += 2;
|
|
}
|
|
|
|
if( screenButtons )
|
|
{
|
|
SDL_Rect pos;
|
|
pos.x = 0;
|
|
pos.h = SDL_ListModes(NULL, 0)[0]->h / 10;
|
|
pos.y = SDL_ListModes(NULL, 0)[0]->h - pos.h;
|
|
pos.w = 40 * SDL_ListModes(NULL, 0)[0]->w / resolutionW;
|
|
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
|
|
}
|
|
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "XSDL video resolution %s, args:", screenres);
|
|
for( i = 0; i < argnum; i++ )
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "> %s", args[i]);
|
|
|
|
// We should never quit. If that happens, then the server did not start - show error.
|
|
atexit(&showError);
|
|
return android_main( argnum, args, envp );
|
|
}
|
|
|
|
void setupEnv(void)
|
|
{
|
|
uid_t uid = geteuid();
|
|
struct passwd * pwd;
|
|
char buf[32];
|
|
errno = 0;
|
|
pwd = getpwuid(uid);
|
|
if( !pwd )
|
|
{
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Cannot determine user name for ID %d: %s", uid, strerror(errno));
|
|
return;
|
|
}
|
|
sprintf( buf, "%d", uid );
|
|
__android_log_print(ANDROID_LOG_INFO, "XSDL", "User %s ID %s", pwd->pw_name, buf);
|
|
setenv("USER_ID", buf, 1);
|
|
setenv("USER", pwd->pw_name, 1);
|
|
}
|
|
|
|
void showError(void)
|
|
{
|
|
XSDL_initSDL();
|
|
XSDL_showServerLaunchErrorMessage();
|
|
XSDL_deinitSDL();
|
|
}
|