aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.android2
-rw-r--r--android/main-common.c533
-rw-r--r--android/main-common.h43
-rw-r--r--android/main-ui.c465
-rw-r--r--android/main.c477
5 files changed, 582 insertions, 938 deletions
diff --git a/Makefile.android b/Makefile.android
index 811b58a..5faab57 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -879,6 +879,7 @@ VL_SOURCES := framebuffer.c \
android/looper-qemu.c \
android/protocol/ui-commands-qemu.c \
android/protocol/core-commands-qemu.c \
+ android/main-common.c \
android/main.c \
# Add common system libraries
@@ -1212,6 +1213,7 @@ VL_SOURCES := framebuffer.c \
android/looper-generic.c \
android/snapshot.c \
android/core-connection.c \
+ android/main-common.c \
android/main-ui.c \
qemu-timer-ui.c \
vl-android-ui.c \
diff --git a/android/main-common.c b/android/main-common.c
new file mode 100644
index 0000000..189f10c
--- /dev/null
+++ b/android/main-common.c
@@ -0,0 +1,533 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program 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 General Public License for more details.
+*/
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <fcntl.h>
+#ifdef _WIN32
+#include <process.h>
+#endif
+
+#include <SDL.h>
+#include <SDL_syswm.h>
+
+#include "console.h"
+
+#include "android/utils/debug.h"
+#include "android/utils/path.h"
+#include "android/utils/bufprint.h"
+#include "android/main-common.h"
+#include "android/globals.h"
+#include "android/resource.h"
+#include "android/user-config.h"
+#include "android/qemulator.h"
+#include "android/display.h"
+#include "android/skin/image.h"
+#include "android/skin/trackball.h"
+#include "android/skin/keyboard.h"
+#include "android/skin/file.h"
+#include "android/skin/window.h"
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** U T I L I T Y R O U T I N E S *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
+
+/*** CONFIGURATION
+ ***/
+
+static AUserConfig* userConfig;
+
+void
+emulator_config_init( void )
+{
+ userConfig = auserConfig_new( android_avdInfo );
+}
+
+/* only call this function on normal exits, so that ^C doesn't save the configuration */
+void
+emulator_config_done( void )
+{
+ int win_x, win_y;
+
+ if (!userConfig) {
+ D("no user configuration?");
+ return;
+ }
+
+ SDL_WM_GetPos( &win_x, &win_y );
+ auserConfig_setWindowPos(userConfig, win_x, win_y);
+ auserConfig_save(userConfig);
+}
+
+void
+emulator_config_get_window_pos( int *window_x, int *window_y )
+{
+ *window_x = *window_y = 10;
+
+ if (userConfig)
+ auserConfig_getWindowPos(userConfig, window_x, window_y);
+}
+
+unsigned convertBytesToMB( uint64_t size )
+{
+ if (size == 0)
+ return 0;
+
+ size = (size + ONE_MB-1) >> 20;
+ if (size > UINT_MAX)
+ size = UINT_MAX;
+
+ return (unsigned) size;
+}
+
+uint64_t convertMBToBytes( unsigned megaBytes )
+{
+ return ((uint64_t)megaBytes << 20);
+}
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** K E Y S E T R O U T I N E S *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+#define KEYSET_FILE "default.keyset"
+
+SkinKeyset* android_keyset = NULL;
+
+static int
+load_keyset(const char* path)
+{
+ if (path_can_read(path)) {
+ AConfig* root = aconfig_node("","");
+ if (!aconfig_load_file(root, path)) {
+ android_keyset = skin_keyset_new(root);
+ if (android_keyset != NULL) {
+ D( "keyset loaded from: %s", path);
+ return 0;
+ }
+ }
+ }
+ return -1;
+}
+
+void
+parse_keyset(const char* keyset, AndroidOptions* opts)
+{
+ char kname[MAX_PATH];
+ char temp[MAX_PATH];
+ char* p;
+ char* end;
+
+ /* append .keyset suffix if needed */
+ if (strchr(keyset, '.') == NULL) {
+ p = kname;
+ end = p + sizeof(kname);
+ p = bufprint(p, end, "%s.keyset", keyset);
+ if (p >= end) {
+ derror( "keyset name too long: '%s'\n", keyset);
+ exit(1);
+ }
+ keyset = kname;
+ }
+
+ /* look for a the keyset file */
+ p = temp;
+ end = p + sizeof(temp);
+ p = bufprint_config_file(p, end, keyset);
+ if (p < end && load_keyset(temp) == 0)
+ return;
+
+ p = temp;
+ p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->sysdir, keyset);
+ if (p < end && load_keyset(temp) == 0)
+ return;
+
+ p = temp;
+ p = bufprint_app_dir(p, end);
+ p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
+ if (p < end && load_keyset(temp) == 0)
+ return;
+
+ return;
+}
+
+void
+write_default_keyset( void )
+{
+ char path[MAX_PATH];
+
+ bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
+
+ /* only write if there is no file here */
+ if ( !path_exists(path) ) {
+ int fd = open( path, O_WRONLY | O_CREAT, 0666 );
+ int ret;
+ const char* ks = skin_keyset_get_default();
+
+
+ D( "writing default keyset file to %s", path );
+
+ if (fd < 0) {
+ D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
+ return;
+ }
+ CHECKED(ret, write(fd, ks, strlen(ks)));
+ close(fd);
+ }
+}
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** S D L S U P P O R T *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
+
+#ifdef CONFIG_DARWIN
+# define ANDROID_ICON_PNG "android_icon_256.png"
+#else
+# define ANDROID_ICON_PNG "android_icon_16.png"
+#endif
+
+static void
+sdl_set_window_icon( void )
+{
+ static int window_icon_set;
+
+ if (!window_icon_set)
+ {
+#ifdef _WIN32
+ HANDLE handle = GetModuleHandle( NULL );
+ HICON icon = LoadIcon( handle, MAKEINTRESOURCE(1) );
+ SDL_SysWMinfo wminfo;
+
+ SDL_GetWMInfo(&wminfo);
+
+ SetClassLong( wminfo.window, GCL_HICON, (LONG)icon );
+#else /* !_WIN32 */
+ unsigned icon_w, icon_h;
+ size_t icon_bytes;
+ const unsigned char* icon_data;
+ void* icon_pixels;
+
+ window_icon_set = 1;
+
+ icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
+ if ( !icon_data )
+ return;
+
+ icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
+ if ( !icon_pixels )
+ return;
+
+ /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
+ * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
+ * on our CPU endianess
+ */
+ {
+ unsigned* d = icon_pixels;
+ unsigned* d_end = d + icon_w*icon_h;
+
+ for ( ; d < d_end; d++ ) {
+ unsigned pix = d[0];
+#if HOST_WORDS_BIGENDIAN
+ /* R,G,B,A read as RGBA => ARGB */
+ pix = ((pix >> 8) & 0xffffff) | (pix << 24);
+#else
+ /* R,G,B,A read as ABGR => ARGB */
+ pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
+#endif
+ d[0] = pix;
+ }
+ }
+
+ SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
+ if (icon != NULL) {
+ SDL_WM_SetIcon(icon, NULL);
+ SDL_FreeSurface(icon);
+ free( icon_pixels );
+ }
+#endif /* !_WIN32 */
+ }
+}
+
+/***********************************************************************/
+/***********************************************************************/
+/***** *****/
+/***** S K I N S U P P O R T *****/
+/***** *****/
+/***********************************************************************/
+/***********************************************************************/
+
+const char* skin_network_speed = NULL;
+const char* skin_network_delay = NULL;
+
+
+static void sdl_at_exit(void)
+{
+ emulator_config_done();
+ qemulator_done(qemulator_get());
+ SDL_Quit();
+}
+
+
+void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
+{
+ QEmulator* emulator = qemulator_get();
+ SkinDisplay* disp = skin_layout_get_display(emulator->layout);
+ int width, height;
+ char buf[128];
+
+ if (disp->rotation & 1) {
+ width = disp->rect.size.h;
+ height = disp->rect.size.w;
+ } else {
+ width = disp->rect.size.w;
+ height = disp->rect.size.h;
+ }
+
+ snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
+ android_display_init(ds, qframebuffer_fifo_get());
+}
+
+/* list of skin aliases */
+static const struct {
+ const char* name;
+ const char* alias;
+} skin_aliases[] = {
+ { "QVGA-L", "320x240" },
+ { "QVGA-P", "240x320" },
+ { "HVGA-L", "480x320" },
+ { "HVGA-P", "320x480" },
+ { "QVGA", "320x240" },
+ { "HVGA", "320x480" },
+ { NULL, NULL }
+};
+
+/* this is used by hw/events_device.c to send the charmap name to the system */
+const char* android_skin_keycharmap = NULL;
+
+void init_skinned_ui(const char *path, const char *name, AndroidOptions* opts)
+{
+ char tmp[1024];
+ AConfig* root;
+ AConfig* n;
+ int win_x, win_y, flags;
+
+ signal(SIGINT, SIG_DFL);
+#ifndef _WIN32
+ signal(SIGQUIT, SIG_DFL);
+#endif
+
+ /* we're not a game, so allow the screensaver to run */
+ putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");
+
+ flags = SDL_INIT_NOPARACHUTE;
+ if (!opts->no_window)
+ flags |= SDL_INIT_VIDEO;
+
+ if(SDL_Init(flags)){
+ fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
+ exit(1);
+ }
+
+ if (!opts->no_window) {
+ SDL_EnableUNICODE(!opts->raw_keys);
+ SDL_EnableKeyRepeat(0,0);
+
+ sdl_set_window_icon();
+ }
+ else
+ {
+#ifndef _WIN32
+ /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
+ * able to run the emulator in the background (e.g. "emulator &").
+ * despite the fact that the emulator should not grab input or try to
+ * write to the output in normal cases, we're stopped on some systems
+ * (e.g. OS X)
+ */
+ signal(SIGTTIN, SIG_IGN);
+ signal(SIGTTOU, SIG_IGN);
+#endif
+ }
+ atexit(sdl_at_exit);
+
+ root = aconfig_node("", "");
+
+ if(name) {
+ /* Support skin aliases like QVGA-H QVGA-P, etc...
+ But first we check if it's a directory that exist before applying
+ the alias */
+ int checkAlias = 1;
+
+ if (path != NULL) {
+ bufprint(tmp, tmp+sizeof(tmp), "%s/%s", path, name);
+ if (path_exists(tmp)) {
+ checkAlias = 0;
+ } else {
+ D("there is no '%s' skin in '%s'", name, path);
+ }
+ }
+
+ if (checkAlias) {
+ int nn;
+
+ for (nn = 0; ; nn++ ) {
+ const char* skin_name = skin_aliases[nn].name;
+ const char* skin_alias = skin_aliases[nn].alias;
+
+ if ( !skin_name )
+ break;
+
+ if ( !strcasecmp( skin_name, name ) ) {
+ D("skin name '%s' aliased to '%s'", name, skin_alias);
+ name = skin_alias;
+ break;
+ }
+ }
+ }
+
+ /* Magically support skins like "320x240" or "320x240x16" */
+ if(isdigit(name[0])) {
+ char *x = strchr(name, 'x');
+ if(x && isdigit(x[1])) {
+ int width = atoi(name);
+ int height = atoi(x+1);
+ int bpp = 16;
+ char* y = strchr(x+1, 'x');
+ if (y && isdigit(y[1])) {
+ bpp = atoi(y+1);
+ }
+ sprintf(tmp,"display {\n width %d\n height %d\n bpp %d}\n",
+ width, height,bpp);
+ aconfig_load(root, strdup(tmp));
+ path = ":";
+ goto found_a_skin;
+ }
+ }
+
+ if (path == NULL) {
+ derror("unknown skin name '%s'", name);
+ exit(1);
+ }
+
+ sprintf(tmp, "%s/%s/layout", path, name);
+ D("trying to load skin file '%s'", tmp);
+
+ if(aconfig_load_file(root, tmp) >= 0) {
+ sprintf(tmp, "%s/%s/", path, name);
+ path = tmp;
+ goto found_a_skin;
+ } else {
+ dwarning("could not load skin file '%s', using built-in one\n",
+ tmp);
+ }
+ }
+
+ {
+ const unsigned char* layout_base;
+ size_t layout_size;
+
+ name = "<builtin>";
+
+ layout_base = android_resource_find( "layout", &layout_size );
+ if (layout_base != NULL) {
+ char* base = malloc( layout_size+1 );
+ memcpy( base, layout_base, layout_size );
+ base[layout_size] = 0;
+
+ D("parsing built-in skin layout file (size=%d)", (int)layout_size);
+ aconfig_load(root, base);
+ path = ":";
+ } else {
+ fprintf(stderr, "Couldn't load builtin skin\n");
+ exit(1);
+ }
+ }
+
+found_a_skin:
+ emulator_config_get_window_pos(&win_x, &win_y);
+
+ if ( qemulator_init(qemulator_get(), root, path, win_x, win_y, opts ) < 0 ) {
+ fprintf(stderr, "### Error: could not load emulator skin '%s'\n", name);
+ exit(1);
+ }
+
+ android_skin_keycharmap = skin_keyboard_charmap_name(qemulator_get()->keyboard);
+
+ /* the default network speed and latency can now be specified by the device skin */
+ n = aconfig_find(root, "network");
+ if (n != NULL) {
+ skin_network_speed = aconfig_str(n, "speed", 0);
+ skin_network_delay = aconfig_str(n, "delay", 0);
+ }
+
+#if 0
+ /* create a trackball if needed */
+ n = aconfig_find(root, "trackball");
+ if (n != NULL) {
+ SkinTrackBallParameters params;
+
+ params.x = aconfig_unsigned(n, "x", 0);
+ params.y = aconfig_unsigned(n, "y", 0);
+ params.diameter = aconfig_unsigned(n, "diameter", 20);
+ params.ring = aconfig_unsigned(n, "ring", 1);
+
+ params.ball_color = aconfig_unsigned(n, "ball-color", 0xffe0e0e0);
+ params.dot_color = aconfig_unsigned(n, "dot-color", 0xff202020 );
+ params.ring_color = aconfig_unsigned(n, "ring-color", 0xff000000 );
+
+ qemu_disp->trackball = skin_trackball_create( &params );
+ skin_trackball_refresh( qemu_disp->trackball );
+ }
+#endif
+
+ /* add an onion overlay image if needed */
+ if (opts->onion) {
+ SkinImage* onion = skin_image_find_simple( opts->onion );
+ int alpha, rotate;
+
+ if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
+ alpha = (256*alpha)/100;
+ } else
+ alpha = 128;
+
+ if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
+ rotate &= 3;
+ } else
+ rotate = SKIN_ROTATION_0;
+
+ qemulator_get()->onion = onion;
+ qemulator_get()->onion_alpha = alpha;
+ qemulator_get()->onion_rotation = rotate;
+ }
+}
+
diff --git a/android/main-common.h b/android/main-common.h
new file mode 100644
index 0000000..0adc4a2
--- /dev/null
+++ b/android/main-common.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program 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 General Public License for more details.
+*/
+#ifndef ANDROID_MAIN_COMMON_H
+#define ANDROID_MAIN_COMMON_H
+
+#include <stdint.h>
+#include "android/cmdline-option.h"
+#include "android/skin/keyset.h"
+
+/* Common routines used by both android/main.c and android/main-ui.c */
+
+/** Emulator user configuration (e.g. last window position)
+ **/
+
+void emulator_config_init( void );
+void emulator_config_done( void );
+
+void emulator_config_get_window_pos( int *window_x, int *window_y );
+
+#define ONE_MB (1024*1024)
+
+unsigned convertBytesToMB( uint64_t size );
+uint64_t convertMBToBytes( unsigned megaBytes );
+
+extern SkinKeyset* android_keyset;
+void parse_keyset(const char* keyset, AndroidOptions* opts);
+void write_default_keyset( void );
+
+extern const char* skin_network_speed;
+extern const char* skin_network_delay;
+
+void init_skinned_ui(const char *path, const char *name, AndroidOptions* opts);
+
+#endif /* ANDROID_MAIN_COMMON_H */
diff --git a/android/main-ui.c b/android/main-ui.c
index 541d83b..fdd1d58 100644
--- a/android/main-ui.c
+++ b/android/main-ui.c
@@ -50,7 +50,7 @@
#include "android/utils/path.h"
#include "android/utils/tempfile.h"
-#include "android/cmdline-option.h"
+#include "android/main-common.h"
#include "android/help.h"
#include "hw/goldfish_nand.h"
@@ -111,387 +111,9 @@ char* core_ui_settings = "";
/* Emulator's core port. */
int android_base_port = 0;
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** U T I L I T Y R O U T I N E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-/*** CONFIGURATION
- ***/
-
-static AUserConfig* userConfig;
-
-void
-emulator_config_init( void )
-{
- userConfig = auserConfig_new( android_avdInfo );
-}
-
-/* only call this function on normal exits, so that ^C doesn't save the configuration */
-void
-emulator_config_done( void )
-{
- int win_x, win_y;
-
- if (!userConfig) {
- D("no user configuration?");
- return;
- }
-
- SDL_WM_GetPos( &win_x, &win_y );
- auserConfig_setWindowPos(userConfig, win_x, win_y);
- auserConfig_save(userConfig);
-}
-
-void *loadpng(const char *fn, unsigned *_width, unsigned *_height);
-void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
-
-#ifdef CONFIG_DARWIN
-# define ANDROID_ICON_PNG "android_icon_256.png"
-#else
-# define ANDROID_ICON_PNG "android_icon_16.png"
-#endif
-
-static void
-sdl_set_window_icon( void )
-{
- static int window_icon_set;
-
- if (!window_icon_set)
- {
-#ifdef _WIN32
- HANDLE handle = GetModuleHandle( NULL );
- HICON icon = LoadIcon( handle, MAKEINTRESOURCE(1) );
- SDL_SysWMinfo wminfo;
-
- SDL_GetWMInfo(&wminfo);
-
- SetClassLong( wminfo.window, GCL_HICON, (LONG)icon );
-#else /* !_WIN32 */
- unsigned icon_w, icon_h;
- size_t icon_bytes;
- const unsigned char* icon_data;
- void* icon_pixels;
-
- window_icon_set = 1;
-
- icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
- if ( !icon_data )
- return;
-
- icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
- if ( !icon_pixels )
- return;
-
- /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
- * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
- * on our CPU endianess
- */
- {
- unsigned* d = icon_pixels;
- unsigned* d_end = d + icon_w*icon_h;
-
- for ( ; d < d_end; d++ ) {
- unsigned pix = d[0];
-#if HOST_WORDS_BIGENDIAN
- /* R,G,B,A read as RGBA => ARGB */
- pix = ((pix >> 8) & 0xffffff) | (pix << 24);
-#else
- /* R,G,B,A read as ABGR => ARGB */
- pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
-#endif
- d[0] = pix;
- }
- }
-
- SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
- if (icon != NULL) {
- SDL_WM_SetIcon(icon, NULL);
- SDL_FreeSurface(icon);
- free( icon_pixels );
- }
-#endif /* !_WIN32 */
- }
-}
-
-#define ONE_MB (1024*1024)
-
-unsigned convertBytesToMB( uint64_t size )
-{
- if (size == 0)
- return 0;
-
- size = (size + ONE_MB-1) >> 20;
- if (size > UINT_MAX)
- size = UINT_MAX;
-
- return (unsigned) size;
-}
-
-uint64_t convertMBToBytes( unsigned megaBytes )
-{
- return ((uint64_t)megaBytes << 20);
-}
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** S K I N I M A G E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-static void sdl_at_exit(void)
-{
- emulator_config_done();
- qemulator_done(qemulator_get());
- SDL_Quit();
-}
-
-
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
-{
- QEmulator* emulator = qemulator_get();
- SkinDisplay* disp = skin_layout_get_display(emulator->layout);
- int width, height;
- char buf[128];
-
- if (disp->rotation & 1) {
- width = disp->rect.size.h;
- height = disp->rect.size.w;
- } else {
- width = disp->rect.size.w;
- height = disp->rect.size.h;
- }
-
- snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
- android_display_init(ds, qframebuffer_fifo_get());
-}
-
-
-static const char* skin_network_speed = NULL;
-static const char* skin_network_delay = NULL;
-
-/* list of skin aliases */
-static const struct {
- const char* name;
- const char* alias;
-} skin_aliases[] = {
- { "QVGA-L", "320x240" },
- { "QVGA-P", "240x320" },
- { "HVGA-L", "480x320" },
- { "HVGA-P", "320x480" },
- { "QVGA", "320x240" },
- { "HVGA", "320x480" },
- { NULL, NULL }
-};
-
/* this is used by hw/events_device.c to send the charmap name to the system */
-const char* android_skin_keycharmap = NULL;
-
-void init_skinned_ui(const char *path, const char *name, AndroidOptions* opts)
-{
- char tmp[1024];
- AConfig* root;
- AConfig* n;
- int win_x, win_y, flags;
-
- signal(SIGINT, SIG_DFL);
-#ifndef _WIN32
- signal(SIGQUIT, SIG_DFL);
-#endif
-
- /* we're not a game, so allow the screensaver to run */
- putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");
+extern const char* android_skin_keycharmap;
- flags = SDL_INIT_NOPARACHUTE;
- if (!opts->no_window)
- flags |= SDL_INIT_VIDEO;
-
- if(SDL_Init(flags)){
- fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
- exit(1);
- }
-
- if (!opts->no_window) {
- SDL_EnableUNICODE(!opts->raw_keys);
- SDL_EnableKeyRepeat(0,0);
-
- sdl_set_window_icon();
- }
- else
- {
-#ifndef _WIN32
- /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
- * able to run the emulator in the background (e.g. "emulator &").
- * despite the fact that the emulator should not grab input or try to
- * write to the output in normal cases, we're stopped on some systems
- * (e.g. OS X)
- */
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
-#endif
- }
- atexit(sdl_at_exit);
-
- root = aconfig_node("", "");
-
- if(name) {
- /* Support skin aliases like QVGA-H QVGA-P, etc...
- But first we check if it's a directory that exist before applying
- the alias */
- int checkAlias = 1;
-
- if (path != NULL) {
- bufprint(tmp, tmp+sizeof(tmp), "%s/%s", path, name);
- if (path_exists(tmp)) {
- checkAlias = 0;
- } else {
- D("there is no '%s' skin in '%s'", name, path);
- }
- }
-
- if (checkAlias) {
- int nn;
-
- for (nn = 0; ; nn++ ) {
- const char* skin_name = skin_aliases[nn].name;
- const char* skin_alias = skin_aliases[nn].alias;
-
- if ( !skin_name )
- break;
-
- if ( !strcasecmp( skin_name, name ) ) {
- D("skin name '%s' aliased to '%s'", name, skin_alias);
- name = skin_alias;
- break;
- }
- }
- }
-
- /* Magically support skins like "320x240" */
- if(isdigit(name[0])) {
- char *x = strchr(name, 'x');
- if(x && isdigit(x[1])) {
- int width = atoi(name);
- int height = atoi(x + 1);
- int bpp = 16;
- char* y = strchr(x+1, 'x');
- if (y && isdigit(y[1])) {
- bpp = atoi(y+1);
- }
- sprintf(tmp,"display {\n width %d\n height %d\n bpp %d}\n",
- width, height,bpp);
- aconfig_load(root, strdup(tmp));
- path = ":";
- goto found_a_skin;
- }
- }
-
- if (path == NULL) {
- derror("unknown skin name '%s'", name);
- exit(1);
- }
-
- sprintf(tmp, "%s/%s/layout", path, name);
- D("trying to load skin file '%s'", tmp);
-
- if(aconfig_load_file(root, tmp) >= 0) {
- sprintf(tmp, "%s/%s/", path, name);
- path = tmp;
- goto found_a_skin;
- } else {
- dwarning("could not load skin file '%s', using built-in one\n",
- tmp);
- }
- }
-
- {
- const unsigned char* layout_base;
- size_t layout_size;
-
- name = "<builtin>";
-
- layout_base = android_resource_find( "layout", &layout_size );
- if (layout_base != NULL) {
- char* base = malloc( layout_size+1 );
- memcpy( base, layout_base, layout_size );
- base[layout_size] = 0;
-
- D("parsing built-in skin layout file (size=%d)", (int)layout_size);
- aconfig_load(root, base);
- path = ":";
- } else {
- fprintf(stderr, "Couldn't load builtin skin\n");
- exit(1);
- }
- }
-
-found_a_skin:
- {
- win_x = 10;
- win_y = 10;
-
- if (userConfig)
- auserConfig_getWindowPos(userConfig, &win_x, &win_y);
- }
-
- if ( qemulator_init(qemulator_get(), root, path, win_x, win_y, opts ) < 0 ) {
- fprintf(stderr, "### Error: could not load emulator skin '%s'\n", name);
- exit(1);
- }
-
- android_skin_keycharmap = skin_keyboard_charmap_name(qemulator_get()->keyboard);
-
- /* the default network speed and latency can now be specified by the device skin */
- n = aconfig_find(root, "network");
- if (n != NULL) {
- skin_network_speed = aconfig_str(n, "speed", 0);
- skin_network_delay = aconfig_str(n, "delay", 0);
- }
-
-#if 0
- /* create a trackball if needed */
- n = aconfig_find(root, "trackball");
- if (n != NULL) {
- SkinTrackBallParameters params;
-
- params.x = aconfig_unsigned(n, "x", 0);
- params.y = aconfig_unsigned(n, "y", 0);
- params.diameter = aconfig_unsigned(n, "diameter", 20);
- params.ring = aconfig_unsigned(n, "ring", 1);
-
- params.ball_color = aconfig_unsigned(n, "ball-color", 0xffe0e0e0);
- params.dot_color = aconfig_unsigned(n, "dot-color", 0xff202020 );
- params.ring_color = aconfig_unsigned(n, "ring-color", 0xff000000 );
-
- qemu_disp->trackball = skin_trackball_create( &params );
- skin_trackball_refresh( qemu_disp->trackball );
- }
-#endif
-
- /* add an onion overlay image if needed */
- if (opts->onion) {
- SkinImage* onion = skin_image_find_simple( opts->onion );
- int alpha, rotate;
-
- if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
- alpha = (256*alpha)/100;
- } else
- alpha = 128;
-
- if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
- rotate &= 3;
- } else
- rotate = SKIN_ROTATION_0;
-
- qemulator_get()->onion = onion;
- qemulator_get()->onion_alpha = alpha;
- qemulator_get()->onion_rotation = rotate;
- }
-}
int qemu_main(int argc, char **argv);
@@ -508,88 +130,6 @@ verbose_options[] = {
{ 0, 0, 0 }
};
-static int
-load_keyset(const char* path)
-{
- if (path_can_read(path)) {
- AConfig* root = aconfig_node("","");
- if (!aconfig_load_file(root, path)) {
- android_keyset = skin_keyset_new(root);
- if (android_keyset != NULL) {
- D( "keyset loaded from: %s", path);
- return 0;
- }
- }
- }
- return -1;
-}
-
-static void
-parse_keyset(const char* keyset, AndroidOptions* opts)
-{
- char kname[MAX_PATH];
- char temp[MAX_PATH];
- char* p;
- char* end;
-
- /* append .keyset suffix if needed */
- if (strchr(keyset, '.') == NULL) {
- p = kname;
- end = p + sizeof(kname);
- p = bufprint(p, end, "%s.keyset", keyset);
- if (p >= end) {
- derror( "keyset name too long: '%s'\n", keyset);
- exit(1);
- }
- keyset = kname;
- }
-
- /* look for a the keyset file */
- p = temp;
- end = p + sizeof(temp);
- p = bufprint_config_file(p, end, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->sysdir, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint_app_dir(p, end);
- p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- return;
-}
-
-static void
-write_default_keyset( void )
-{
- char path[MAX_PATH];
-
- bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
-
- /* only write if there is no file here */
- if ( !path_exists(path) ) {
- int fd = open( path, O_WRONLY | O_CREAT, 0666 );
- int ret;
- const char* ks = skin_keyset_get_default();
-
-
- D( "writing default keyset file to %s", path );
-
- if (fd < 0) {
- D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
- return;
- }
- CHECKED(ret, write(fd, ks, strlen(ks)));
- close(fd);
- }
-}
-
void emulator_help( void )
{
STRALLOC_DEFINE(out);
@@ -1654,6 +1194,7 @@ int main(int argc, char **argv)
} else if (opts->no_snapshot) {
D("ignoring redundant option '-no-snapshot' implied by '-no-snapstorage'");
}
+
if (opts->snapshot_list) {
snapshot_print_and_exit(opts->snapstorage);
}
diff --git a/android/main.c b/android/main.c
index d6c2d8d..078cfbb 100644
--- a/android/main.c
+++ b/android/main.c
@@ -33,17 +33,9 @@
#include "android/charmap.h"
#include "android/utils/debug.h"
-#include "android/resource.h"
#include "android/config.h"
#include "android/config/config.h"
-#include "android/skin/image.h"
-#include "android/skin/trackball.h"
-#include "android/skin/keyboard.h"
-#include "android/skin/file.h"
-#include "android/skin/window.h"
-#include "android/skin/keyset.h"
-
#include "android/user-config.h"
#include "android/utils/bufprint.h"
#include "android/utils/dirscanner.h"
@@ -51,7 +43,7 @@
#include "android/utils/timezone.h"
#include "android/utils/tempfile.h"
-#include "android/cmdline-option.h"
+#include "android/main-common.h"
#include "android/help.h"
#include "hw/goldfish_nand.h"
@@ -76,9 +68,6 @@ AndroidRotation android_framebuffer_rotation;
# define VERSION_STRING "standalone"
#endif
-#define KEYSET_FILE "default.keyset"
-SkinKeyset* android_keyset;
-
#define D(...) do { if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
extern int control_console_start( int port ); /* in control.c */
@@ -100,388 +89,6 @@ extern void stop_tracing(void);
unsigned long android_verbose;
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** U T I L I T Y R O U T I N E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-
-/*** CONFIGURATION
- ***/
-
-static AUserConfig* userConfig;
-
-void
-emulator_config_init( void )
-{
- userConfig = auserConfig_new( android_avdInfo );
-}
-
-/* only call this function on normal exits, so that ^C doesn't save the configuration */
-void
-emulator_config_done( void )
-{
- int win_x, win_y;
-
- if (!userConfig) {
- D("no user configuration?");
- return;
- }
-
- SDL_WM_GetPos( &win_x, &win_y );
- auserConfig_setWindowPos(userConfig, win_x, win_y);
- auserConfig_save(userConfig);
-}
-
-void *loadpng(const char *fn, unsigned *_width, unsigned *_height);
-void *readpng(const unsigned char* base, size_t size, unsigned *_width, unsigned *_height);
-
-#ifdef CONFIG_DARWIN
-# define ANDROID_ICON_PNG "android_icon_256.png"
-#else
-# define ANDROID_ICON_PNG "android_icon_16.png"
-#endif
-
-static void
-sdl_set_window_icon( void )
-{
- static int window_icon_set;
-
- if (!window_icon_set)
- {
-#ifdef _WIN32
- HANDLE handle = GetModuleHandle( NULL );
- HICON icon = LoadIcon( handle, MAKEINTRESOURCE(1) );
- SDL_SysWMinfo wminfo;
-
- SDL_GetWMInfo(&wminfo);
-
- SetClassLong( wminfo.window, GCL_HICON, (LONG)icon );
-#else /* !_WIN32 */
- unsigned icon_w, icon_h;
- size_t icon_bytes;
- const unsigned char* icon_data;
- void* icon_pixels;
-
- window_icon_set = 1;
-
- icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
- if ( !icon_data )
- return;
-
- icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
- if ( !icon_pixels )
- return;
-
- /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
- * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
- * on our CPU endianess
- */
- {
- unsigned* d = icon_pixels;
- unsigned* d_end = d + icon_w*icon_h;
-
- for ( ; d < d_end; d++ ) {
- unsigned pix = d[0];
-#if HOST_WORDS_BIGENDIAN
- /* R,G,B,A read as RGBA => ARGB */
- pix = ((pix >> 8) & 0xffffff) | (pix << 24);
-#else
- /* R,G,B,A read as ABGR => ARGB */
- pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
-#endif
- d[0] = pix;
- }
- }
-
- SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
- if (icon != NULL) {
- SDL_WM_SetIcon(icon, NULL);
- SDL_FreeSurface(icon);
- free( icon_pixels );
- }
-#endif /* !_WIN32 */
- }
-}
-
-#define ONE_MB (1024*1024)
-
-unsigned convertBytesToMB( uint64_t size )
-{
- if (size == 0)
- return 0;
-
- size = (size + ONE_MB-1) >> 20;
- if (size > UINT_MAX)
- size = UINT_MAX;
-
- return (unsigned) size;
-}
-
-uint64_t convertMBToBytes( unsigned megaBytes )
-{
- return ((uint64_t)megaBytes << 20);
-}
-
-/***********************************************************************/
-/***********************************************************************/
-/***** *****/
-/***** S K I N I M A G E S *****/
-/***** *****/
-/***********************************************************************/
-/***********************************************************************/
-static void sdl_at_exit(void)
-{
- emulator_config_done();
- qemulator_done(qemulator_get());
- SDL_Quit();
-}
-
-
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
-{
- QEmulator* emulator = qemulator_get();
- SkinDisplay* disp = skin_layout_get_display(emulator->layout);
- int width, height;
- char buf[128];
-
- if (disp->rotation & 1) {
- width = disp->rect.size.h;
- height = disp->rect.size.w;
- } else {
- width = disp->rect.size.w;
- height = disp->rect.size.h;
- }
-
- snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
- android_display_init(ds, qframebuffer_fifo_get());
-}
-
-
-static const char* skin_network_speed = NULL;
-static const char* skin_network_delay = NULL;
-
-/* list of skin aliases */
-static const struct {
- const char* name;
- const char* alias;
-} skin_aliases[] = {
- { "QVGA-L", "320x240" },
- { "QVGA-P", "240x320" },
- { "HVGA-L", "480x320" },
- { "HVGA-P", "320x480" },
- { "QVGA", "320x240" },
- { "HVGA", "320x480" },
- { NULL, NULL }
-};
-
-/* this is used by hw/events_device.c to send the charmap name to the system */
-const char* android_skin_keycharmap = NULL;
-
-void init_skinned_ui(const char *path, const char *name, AndroidOptions* opts)
-{
- char tmp[1024];
- AConfig* root;
- AConfig* n;
- int win_x, win_y, flags;
-
- signal(SIGINT, SIG_DFL);
-#ifndef _WIN32
- signal(SIGQUIT, SIG_DFL);
-#endif
-
- /* we're not a game, so allow the screensaver to run */
- putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");
-
- flags = SDL_INIT_NOPARACHUTE;
- if (!opts->no_window)
- flags |= SDL_INIT_VIDEO;
-
- if(SDL_Init(flags)){
- fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
- exit(1);
- }
-
- if (!opts->no_window) {
- SDL_EnableUNICODE(!opts->raw_keys);
- SDL_EnableKeyRepeat(0,0);
-
- sdl_set_window_icon();
- }
- else
- {
-#ifndef _WIN32
- /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
- * able to run the emulator in the background (e.g. "emulator &").
- * despite the fact that the emulator should not grab input or try to
- * write to the output in normal cases, we're stopped on some systems
- * (e.g. OS X)
- */
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
-#endif
- }
- atexit(sdl_at_exit);
-
- root = aconfig_node("", "");
-
- if(name) {
- /* Support skin aliases like QVGA-H QVGA-P, etc...
- But first we check if it's a directory that exist before applying
- the alias */
- int checkAlias = 1;
-
- if (path != NULL) {
- bufprint(tmp, tmp+sizeof(tmp), "%s/%s", path, name);
- if (path_exists(tmp)) {
- checkAlias = 0;
- } else {
- D("there is no '%s' skin in '%s'", name, path);
- }
- }
-
- if (checkAlias) {
- int nn;
-
- for (nn = 0; ; nn++ ) {
- const char* skin_name = skin_aliases[nn].name;
- const char* skin_alias = skin_aliases[nn].alias;
-
- if ( !skin_name )
- break;
-
- if ( !strcasecmp( skin_name, name ) ) {
- D("skin name '%s' aliased to '%s'", name, skin_alias);
- name = skin_alias;
- break;
- }
- }
- }
-
- /* Magically support skins like "320x240" or "320x240x16" */
- if(isdigit(name[0])) {
- char *x = strchr(name, 'x');
- if(x && isdigit(x[1])) {
- int width = atoi(name);
- int height = atoi(x+1);
- int bpp = 16;
- char* y = strchr(x+1, 'x');
- if (y && isdigit(y[1])) {
- bpp = atoi(y+1);
- }
- sprintf(tmp,"display {\n width %d\n height %d\n bpp %d}\n",
- width, height,bpp);
- aconfig_load(root, strdup(tmp));
- path = ":";
- goto found_a_skin;
- }
- }
-
- if (path == NULL) {
- derror("unknown skin name '%s'", name);
- exit(1);
- }
-
- sprintf(tmp, "%s/%s/layout", path, name);
- D("trying to load skin file '%s'", tmp);
-
- if(aconfig_load_file(root, tmp) >= 0) {
- sprintf(tmp, "%s/%s/", path, name);
- path = tmp;
- goto found_a_skin;
- } else {
- dwarning("could not load skin file '%s', using built-in one\n",
- tmp);
- }
- }
-
- {
- const unsigned char* layout_base;
- size_t layout_size;
-
- name = "<builtin>";
-
- layout_base = android_resource_find( "layout", &layout_size );
- if (layout_base != NULL) {
- char* base = malloc( layout_size+1 );
- memcpy( base, layout_base, layout_size );
- base[layout_size] = 0;
-
- D("parsing built-in skin layout file (size=%d)", (int)layout_size);
- aconfig_load(root, base);
- path = ":";
- } else {
- fprintf(stderr, "Couldn't load builtin skin\n");
- exit(1);
- }
- }
-
-found_a_skin:
- {
- win_x = 10;
- win_y = 10;
-
- if (userConfig)
- auserConfig_getWindowPos(userConfig, &win_x, &win_y);
- }
-
- if ( qemulator_init(qemulator_get(), root, path, win_x, win_y, opts ) < 0 ) {
- fprintf(stderr, "### Error: could not load emulator skin '%s'\n", name);
- exit(1);
- }
-
- android_skin_keycharmap = skin_keyboard_charmap_name(qemulator_get()->keyboard);
-
- /* the default network speed and latency can now be specified by the device skin */
- n = aconfig_find(root, "network");
- if (n != NULL) {
- skin_network_speed = aconfig_str(n, "speed", 0);
- skin_network_delay = aconfig_str(n, "delay", 0);
- }
-
-#if 0
- /* create a trackball if needed */
- n = aconfig_find(root, "trackball");
- if (n != NULL) {
- SkinTrackBallParameters params;
-
- params.x = aconfig_unsigned(n, "x", 0);
- params.y = aconfig_unsigned(n, "y", 0);
- params.diameter = aconfig_unsigned(n, "diameter", 20);
- params.ring = aconfig_unsigned(n, "ring", 1);
-
- params.ball_color = aconfig_unsigned(n, "ball-color", 0xffe0e0e0);
- params.dot_color = aconfig_unsigned(n, "dot-color", 0xff202020 );
- params.ring_color = aconfig_unsigned(n, "ring-color", 0xff000000 );
-
- qemu_disp->trackball = skin_trackball_create( &params );
- skin_trackball_refresh( qemu_disp->trackball );
- }
-#endif
-
- /* add an onion overlay image if needed */
- if (opts->onion) {
- SkinImage* onion = skin_image_find_simple( opts->onion );
- int alpha, rotate;
-
- if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
- alpha = (256*alpha)/100;
- } else
- alpha = 128;
-
- if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
- rotate &= 3;
- } else
- rotate = SKIN_ROTATION_0;
-
- qemulator_get()->onion = onion;
- qemulator_get()->onion_alpha = alpha;
- qemulator_get()->onion_rotation = rotate;
- }
-}
-
int qemu_main(int argc, char **argv);
/* this function dumps the QEMU help */
@@ -497,88 +104,6 @@ verbose_options[] = {
{ 0, 0, 0 }
};
-static int
-load_keyset(const char* path)
-{
- if (path_can_read(path)) {
- AConfig* root = aconfig_node("","");
- if (!aconfig_load_file(root, path)) {
- android_keyset = skin_keyset_new(root);
- if (android_keyset != NULL) {
- D( "keyset loaded from: %s", path);
- return 0;
- }
- }
- }
- return -1;
-}
-
-static void
-parse_keyset(const char* keyset, AndroidOptions* opts)
-{
- char kname[MAX_PATH];
- char temp[MAX_PATH];
- char* p;
- char* end;
-
- /* append .keyset suffix if needed */
- if (strchr(keyset, '.') == NULL) {
- p = kname;
- end = p + sizeof(kname);
- p = bufprint(p, end, "%s.keyset", keyset);
- if (p >= end) {
- derror( "keyset name too long: '%s'\n", keyset);
- exit(1);
- }
- keyset = kname;
- }
-
- /* look for a the keyset file */
- p = temp;
- end = p + sizeof(temp);
- p = bufprint_config_file(p, end, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->sysdir, keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- p = temp;
- p = bufprint_app_dir(p, end);
- p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
- if (p < end && load_keyset(temp) == 0)
- return;
-
- return;
-}
-
-static void
-write_default_keyset( void )
-{
- char path[MAX_PATH];
-
- bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
-
- /* only write if there is no file here */
- if ( !path_exists(path) ) {
- int fd = open( path, O_WRONLY | O_CREAT, 0666 );
- int ret;
- const char* ks = skin_keyset_get_default();
-
-
- D( "writing default keyset file to %s", path );
-
- if (fd < 0) {
- D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
- return;
- }
- CHECKED(ret, write(fd, ks, strlen(ks)));
- close(fd);
- }
-}
-
void emulator_help( void )
{
STRALLOC_DEFINE(out);