Merge branch 'sdl_android' of github.com:pelya/commandergenius into sdl_android

This commit is contained in:
Gerhard Stein
2013-11-12 07:32:55 +01:00
8 changed files with 135 additions and 27 deletions

View File

@@ -11,4 +11,4 @@ tar -c -z --exclude-vcs --exclude="*.o" --exclude="*.d" --exclude="*.dep" \
`find project/jni/application -maxdepth 1 -type f -o -type l` \ `find project/jni/application -maxdepth 1 -type f -o -type l` \
project/jni/application/src \ project/jni/application/src \
project/jni/application/`readlink project/jni/application/src` \ project/jni/application/`readlink project/jni/application/src` \
project/AndroidManifest.xml project/src project/AndroidManifest.xml project/src "$@"

View File

@@ -23,7 +23,7 @@ InhibitSuspend=n
# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir - # If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir -
# these files are put inside .apk package by build system # these files are put inside .apk package by build system
# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS # Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS
AppDataDownloadUrl="!!Data files|:data.tar.gz:http://10.0.0.99/dist-gimp-wheezy.tar.gz|:data.tar.gz:http://sourceforge.net/projects/libsdl-android/files/ubuntu/dist-gimp-wheezy.tar.gz/download^!!Data files|:busybox:busybox^!!Data files|:DroidSansMono.ttf:DroidSansMono.ttf" AppDataDownloadUrl="!!Data files|:data.tar.gz:http://sourceforge.net/projects/libsdl-android/files/ubuntu/dist-gimp-wheezy.tar.gz/download^!!Data files|:busybox:busybox^!!Data files|:DroidSansMono.ttf:DroidSansMono.ttf"
# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only # Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only
# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32) # with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32)

View File

@@ -40,15 +40,17 @@ img-gimp-wheezy.sh
from directory img. from directory img.
This will create Debian system image under directory This will create Debian system image under directory
dist-debug-wheezy-armhf-gimp. Execute commands (<SDL> is path to this repo): dist-gimp-wheezy. Execute commands (<SDL> is path to this repo):
sudo cp -a <SDL>/project/jni/application/src/xserver/data/usr/ dist-debug-wheezy-armhf-gimp/ sudo cp -a <SDL>/project/jni/application/src/xserver/data/usr/ dist-gimp-wheezy/
sudo cp -a <SDL>/project/jni/application/src/xserver/android/xhost dist-debug-wheezy-armhf-gimp/usr/bin/ sudo cp -a <SDL>/project/jni/application/src/xserver/android/xhost dist-gimp-wheezy/usr/bin/
sudo cp -a <SDL>/project/jni/application/src/xserver/android/xkbcomp dist-debug-wheezy-armhf-gimp/usr/bin/ sudo cp -a <SDL>/project/jni/application/src/xserver/android/xkbcomp dist-gimp-wheezy/usr/bin/
sudo cp -a <SDL>/project/jni/application/src/xserver/android/xli dist-debug-wheezy-armhf-gimp/usr/bin/ sudo cp -a <SDL>/project/jni/application/src/xserver/android/xli dist-gimp-wheezy/usr/bin/
cd dist-debug-wheezy-armhf-gimp Re-generate system image
sudo tar cvzf ../dist-debug-wheezy-armhf-gimp.tar.gz *
cd dist-gimp-wheezy
sudo tar cvzf ../dist-gimp-wheezy.tar.gz *
Upload resulting system image somewhere, and change download URL inside Upload resulting system image somewhere, and change download URL inside
AndroidAppSettings.cfg, then recompile .apk file. AndroidAppSettings.cfg, then recompile .apk file.

View File

@@ -39,12 +39,15 @@ void * unpackFilesThread(void * unused)
return 1; return 1;
} }
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Unpacking data");
strcpy( fname, getenv("SECURE_STORAGE_DIR") ); strcpy( fname, getenv("SECURE_STORAGE_DIR") );
strcat( fname, "/busybox" ); strcat( fname, "/busybox" );
FILE * ff = fopen("busybox", "rb"); FILE * ff = fopen("busybox", "rb");
FILE * fo = fopen(fname, "wb"); FILE * fo = fopen(fname, "wb");
if( !ff || !fo ) if( !ff || !fo )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Cannot copy busybox");
unpackFinished = 1; unpackFinished = 1;
return 0; return 0;
} }
@@ -55,6 +58,7 @@ void * unpackFilesThread(void * unused)
int cnt = fread( buf, 1, sizeof(buf), ff ); int cnt = fread( buf, 1, sizeof(buf), ff );
if( cnt < 0 ) if( cnt < 0 )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Cannot copy busybox");
unpackFinished = 1; unpackFinished = 1;
return 1; return 1;
} }
@@ -68,6 +72,7 @@ void * unpackFilesThread(void * unused)
if( chmod(fname, 0755) != 0 ) if( chmod(fname, 0755) != 0 )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Cannot chmod busybox");
unpackFinished = 1; unpackFinished = 1;
return 0; return 0;
} }
@@ -85,6 +90,7 @@ void * unpackFilesThread(void * unused)
fo = popen(fname, "w"); fo = popen(fname, "w");
if( !ff || !fo ) if( !ff || !fo )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Error extracting data");
unpackFinished = 1; unpackFinished = 1;
return 0; return 0;
} }
@@ -96,6 +102,7 @@ void * unpackFilesThread(void * unused)
int cnt = fread( buf, 1, sizeof(buf), ff ); int cnt = fread( buf, 1, sizeof(buf), ff );
if( cnt < 0 ) if( cnt < 0 )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Error extracting data");
unpackFinished = 1; unpackFinished = 1;
return 1; return 1;
} }
@@ -113,27 +120,42 @@ void * unpackFilesThread(void * unused)
fclose(ff); fclose(ff);
if( pclose(fo) != 0 ) if( pclose(fo) != 0 )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Error extracting data");
unpackFinished = 1; unpackFinished = 1;
return 0; return 0;
} }
remove("data.tar.gz"); remove("data.tar.gz");
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Extracting data finished");
strcpy( fname, getenv("SECURE_STORAGE_DIR") ); strcpy( fname, getenv("SECURE_STORAGE_DIR") );
strcat( fname, "/postinstall.sh" ); strcat( fname, "/postinstall.sh" );
if( stat( fname, &st ) != 0 ) if( stat( fname, &st ) != 0 )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "No postinstall script");
unpackFinished = 1; unpackFinished = 1;
return 1; return 1;
} }
fo = popen(fname, "w"); __android_log_print(ANDROID_LOG_INFO, "XSDL", "Running postinstall scipt");
fo = popen(fname, "r");
if( !fo ) if( !fo )
{ {
__android_log_print(ANDROID_LOG_INFO, "XSDL", "ERROR: Cannot launch postinstall scipt");
unpackFinished = 1; unpackFinished = 1;
return 0; return 0;
} }
pclose(fo); for(;;)
{
char buf[1024];
if( !fgets(buf, sizeof(buf), fo) )
break;
__android_log_print(ANDROID_LOG_INFO, "XSDL", "> %s", buf);
}
__android_log_print(ANDROID_LOG_INFO, "XSDL", "Postinstall scipt exited with status %d", pclose(fo));
unpackFinished = 1; unpackFinished = 1;
return 1; return 1;
@@ -170,7 +192,7 @@ void XSDL_showConfigMenu(int * resolutionW, int * displayW, int * resolutionH, i
SDL_Event event; SDL_Event event;
int res = -1, dpi = -1; int res = -1, dpi = -1;
char native[32] = "0x0"; char native[32] = "0x0";
float dpiScale = 1.0f; //float dpiScale = 1.0f;
const char * resStr[] = { const char * resStr[] = {
native, "1920x1080", "1280x960", "1280x720", native, "1920x1080", "1280x960", "1280x720",
@@ -223,10 +245,10 @@ void XSDL_showConfigMenu(int * resolutionW, int * displayW, int * resolutionH, i
renderString(resStr[i*4+ii], VID_X/8 + (ii*VID_X/4), VID_Y/4 + (i*VID_Y/2)); renderString(resStr[i*4+ii], VID_X/8 + (ii*VID_X/4), VID_Y/4 + (i*VID_Y/2));
SDL_GetMouseState(&x, &y); SDL_GetMouseState(&x, &y);
renderString("X", x, y); renderString("X", x, y);
SDL_Delay(200); SDL_Delay(150);
SDL_Flip(SDL_GetVideoSurface()); SDL_Flip(SDL_GetVideoSurface());
} }
dpiScale = (float)resVal[res][0] / (float)*resolutionW; //dpiScale = (float)resVal[res][0] / (float)*resolutionW;
*resolutionW = resVal[res][0]; *resolutionW = resVal[res][0];
*resolutionH = resVal[res][1]; *resolutionH = resVal[res][1];
while ( dpi < 0 ) while ( dpi < 0 )
@@ -256,11 +278,11 @@ void XSDL_showConfigMenu(int * resolutionW, int * displayW, int * resolutionH, i
renderString(fontsStr[i*4+ii], VID_X/8 + (ii*VID_X/4), VID_Y/8 + (i*VID_Y/4)); renderString(fontsStr[i*4+ii], VID_X/8 + (ii*VID_X/4), VID_Y/8 + (i*VID_Y/4));
SDL_GetMouseState(&x, &y); SDL_GetMouseState(&x, &y);
renderString("X", x, y); renderString("X", x, y);
SDL_Delay(200); SDL_Delay(150);
SDL_Flip(SDL_GetVideoSurface()); SDL_Flip(SDL_GetVideoSurface());
} }
*displayW = *displayW * (dpiScale / fontsVal[dpi]); *displayW = *displayW / fontsVal[dpi];
*displayH = *displayH * (dpiScale / fontsVal[dpi]); *displayH = *displayH / fontsVal[dpi];
} }
void XSDL_generateBackground(const char * port, int showHelp) void XSDL_generateBackground(const char * port, int showHelp)
@@ -329,15 +351,34 @@ void XSDL_generateBackground(const char * port, int showHelp)
SDL_FreeSurface(surf); SDL_FreeSurface(surf);
} }
void XSDL_showServerLaunchErrorMessage()
{
showErrorMessage( "Error: X server failed to launch,\n"
"because of stale Unix socket with non-existing path.\n\n"
"Power off your device and power it on,\n"
"and everything will work again.");
}
void showErrorMessage(const char *msg) void showErrorMessage(const char *msg)
{ {
SDL_Event event; SDL_Event event;
const char * s;
int y = VID_Y/3;
SDL_FillRect(SDL_GetVideoSurface(), NULL, 0); SDL_FillRect(SDL_GetVideoSurface(), NULL, 0);
renderString(msg, VID_X/2, VID_Y/2); for( s = msg; s && s[0]; s = strchr(s, '\n'), s += (s ? 1 : 0), y += 30 )
{
const char * s1 = strchr(s, '\n');
int len = s1 ? s1 - s : strlen(s);
char buf[512];
strncpy(buf, s, len);
buf[len] = 0;
if( len > 0 )
renderString(buf, VID_X/2, y);
}
SDL_Flip(SDL_GetVideoSurface()); SDL_Flip(SDL_GetVideoSurface());
while (1) while (1)
{ {
while (SDL_PollEvent(&event)) while (SDL_WaitEvent(&event))
{ {
switch (event.type) switch (event.type)
{ {

View File

@@ -8,5 +8,6 @@ void XSDL_deinitSDL();
void XSDL_unpackFiles(); void XSDL_unpackFiles();
void XSDL_showConfigMenu(int * resolutionW, int * displayW, int * resolutionH, int * displayH); void XSDL_showConfigMenu(int * resolutionW, int * displayW, int * resolutionH, int * displayH);
void XSDL_generateBackground(const char * port, int showHelp); void XSDL_generateBackground(const char * port, int showHelp);
void XSDL_showServerLaunchErrorMessage();
#endif #endif

View File

@@ -1,9 +1,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/un.h>
#include <errno.h>
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <android/log.h> #include <android/log.h>
@@ -11,6 +15,9 @@
extern int android_main( int argc, char *argv[], char *envp[] ); 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 main( int argc, char* argv[] )
{ {
int i; int i;
@@ -38,6 +45,7 @@ int main( int argc, char* argv[] )
int displayH = atoi(getenv("DISPLAY_HEIGHT_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); __android_log_print(ANDROID_LOG_INFO, "XSDL", "Actual video resolution %d/%dx%d/%d", resolutionW, displayW, resolutionH, displayH);
setupEnv();
XSDL_initSDL(); XSDL_initSDL();
@@ -45,22 +53,51 @@ int main( int argc, char* argv[] )
XSDL_showConfigMenu(&resolutionW, &displayW, &resolutionH, &displayH); XSDL_showConfigMenu(&resolutionW, &displayW, &resolutionH, &displayH);
int s = socket(AF_INET, SOCK_STREAM, 0); for(i = 0; i < 1024; i++)
if( s >= 0 )
{ {
for(i = 0; i < 1024; i++) int s = socket(AF_INET, SOCK_STREAM, 0);
if( s >= 0 )
{ {
struct sockaddr_in addr; struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY; addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(6000 + i); addr.sin_port = htons(6000 + i);
if( bind (s, (struct sockaddr *) &addr, sizeof(addr) ) < 0 ) 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; continue;
sprintf( port, ":%d", i ); }
close(s);
} }
close(s);
// Cannot create socket with non-existing path, but Xserver code somehow does that
/*
s = socket(AF_UNIX, SOCK_STREAM, 0);
if( s >= 0 )
{
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
sprintf(addr.sun_path, "/tmp/.X11-unix/X%d", i);
if( bind(s, (struct sockaddr *) &addr, strlen(addr.sun_path) + sizeof(addr.sun_family)) != 0 )
{
__android_log_print(ANDROID_LOG_INFO, "XSDL", "UNIX path %s already used, trying next one: %s", addr.sun_path, strerror(errno));
close(s);
continue;
}
close(s);
}
*/
sprintf( port, ":%d", i );
break;
} }
if( argc > 1 && strcmp(argv[1], "-nohelp") == 0 ) if( argc > 1 && strcmp(argv[1], "-nohelp") == 0 )
@@ -95,5 +132,32 @@ int main( int argc, char* argv[] )
for( i = 0; i < ARGNUM; i++ ) for( i = 0; i < ARGNUM; i++ )
__android_log_print(ANDROID_LOG_INFO, "XSDL", "> %s", args[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 ); 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();
}