4 * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * DoHyung Hong <don.hong@samsung.com>
8 * SeokYeon Hwang <syeon.hwang@samsung.com>
9 * Hyunjun Son <hj79.son@samsung.com>
10 * SangJin Kim <sangjin3.kim@samsung.com>
11 * MunKyu Im <munkyu.im@samsung.com>
12 * KiTae Kim <kt920.kim@samsung.com>
13 * JinHyung Jo <jinhyung.jo@samsung.com>
14 * SungMin Ha <sungmin82.ha@samsung.com>
15 * JiHye Kim <jihye1128.kim@samsung.com>
16 * GiWoong Kim <giwoong.kim@samsung.com>
17 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
18 * DongKyun Yun <dk77.yun@samsung.com>
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
42 * @brief main implementation file of emulator for controling player screen, initialization function, etc.
43 * @mainpage emulator for ISE
45 * program module name: ISE emulator
46 * emulator program can run both standalone and with ISE
50 #include "about_version.h"
52 #include "sensor_server.h"
55 /* changes for saving emulator state */
59 #include <sys/socket.h>
60 #include <arpa/inet.h>
71 #include <sys/utsname.h>
72 #include <linux/version.h>
77 #include "opengl_server.h"
82 //DEFAULT_DEBUG_CHANNEL(tizen);
83 MULTI_DEBUG_CHANNEL(tizen, main);
86 #define MAX_COMMANDS 5
88 #define MAX_TIME_STR 100
90 /* enable opengl_server thread */
91 #define ENABLE_OPENGL_SERVER
93 /* configuration : global variable for saving config file
94 * sysinfo : global variable for using in this program
95 * startup_option : global variable for loading emulator option
98 CONFIGURATION configuration;
100 STARTUP_OPTION startup_option;
101 PHONEMODELINFO *phone_info;
102 VIRTUALTARGETINFO virtual_target_info;
108 .button_press_flag = -1,
109 .key_button_press_flag = 0,
110 .frame_buffer_ctrl = 0,
118 .is_compass_run = FALSE,
119 .is_screenshot_run = FALSE,
120 .sub_window_flag = FALSE,
121 .network_read_flag = FALSE,
124 int _emulator_condition = 0;
125 PHONEMODELINFO PHONE;
126 GtkWidget *g_main_window;
128 GtkWidget *pixmap_widget;
131 struct utsname host_uname_buf;
134 /* Widgets for savevm */
135 GtkWidget *savevm_window;
136 GtkProgressBar *savevm_progress;
137 GtkWidget *savevm_label;
140 int device_count = 0;
141 GIOChannel *channel=NULL;
143 int get_emulator_condition(void)
145 return _emulator_condition;
148 void set_emulator_condition(int state)
150 _emulator_condition = state;
154 char *argv[QEMUARGC];
158 static arglist g_qemu_arglist = {{0,}, 0};
159 int tizen_base_port = 0;
160 void append_argvlist(arglist* al, const char *fmt, ...)
166 vsnprintf(buf, sizeof buf, fmt, va);
168 al->argv[al->argc++] = strdup(buf);
169 assert(al->argc < QEMUARGC);
173 static GSList* emul_process_list = NULL; /**<linked list of running terminal*/
174 pthread_t unfsd_thread;
179 #ifdef ENABLE_OPENGL_SERVER
180 pthread_t thread_opengl_id;
181 #endif /* ENABLE_OPENGL_SERVER */
185 static pthread_mutex_t mutex_emul = PTHREAD_MUTEX_INITIALIZER;
187 void emulator_mutex_lock(void)
189 pthread_mutex_lock(&mutex_emul);
192 void emulator_mutex_unlock(void)
194 pthread_mutex_unlock(&mutex_emul);
197 static void emulator_mutex_init(void)
203 static HANDLE mutex_emul;
205 void emulator_mutex_lock(void)
207 WaitForSingleObject(mutex_emul, INFINITE);
210 void emulator_mutex_unlock(void)
212 ReleaseMutex(mutex_emul);
215 static void emulator_mutex_init(void)
217 mutex_emul = CreateMutex(NULL, 0, NULL);
224 * @brief called when command window closed.
225 * it registered with g_child_watch_add function when creating each process
226 * @param pid: pid of each process been created by emulator
227 * @param status: dummy
229 * @see create_cmdwindow
231 static void emul_process_close_handle (GPid pid, gint status, gpointer data)
233 TRACE( "remove pid=%d\n", pid);
234 g_spawn_close_pid (pid);
235 emul_process_list = g_slist_remove(emul_process_list, (gpointer) pid);
236 TRACE( "remove complete pid=%d\n", pid);
240 @brief send SIGTERM to process
241 @param data: pid of terminal
244 static void emul_kill_process(gpointer data, gpointer user_data)
246 WARN( "kill terminal pid=%d\n", (int)data);
247 kill( (pid_t)(gpointer)data, SIGTERM);
251 @brief call emul_kill_process for all the node in emul_process_list
253 void emul_kill_all_process(void)
255 g_slist_foreach(emul_process_list, emul_kill_process, NULL);
259 @brief create a process
260 @param data: command of starting process
261 @return success: TRUE
263 int emul_create_process(const gchar cmd[])
266 GError* error = NULL;
272 emulator_mutex_lock();
274 g_shell_parse_argv (cmd, &argc_fork, &argv_fork, NULL);
276 if (g_spawn_async_with_pipes ("./", argv_fork, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, NULL, NULL, &error) == TRUE) {
277 emul_process_list = g_slist_append(emul_process_list, (gpointer)pid);
278 g_child_watch_add(pid, emul_process_close_handle, NULL);
282 // ERR( "Error in g_spawn_async\n");
286 g_strfreev (argv_fork);
289 //g_error(error->message);
293 TRACE("create PID = %d\n", pid);
295 emulator_mutex_unlock();
301 void emul_kill_all_process(void)
305 int emul_create_process(const gchar cmd[])
312 void socket_cleanup(void)
318 int socket_init(void)
324 ret = WSAStartup(MAKEWORD(2,0), &Data);
326 err = WSAGetLastError();
327 fprintf(stderr, "WSAStartup: %d\n", err);
330 atexit(socket_cleanup);
335 void exit_emulator_post_process( void ) {
337 set_emulator_condition(EMUL_SHUTTING_DOWN);
339 free_dbi_file(&PHONE);
341 /* 1. emulator and driver destroy */
343 INFO( "Emulator Stop: destroy emulator \n");
345 /* 2. destroy hash */
346 window_hash_destroy();
353 INFO( "Emulator Stop: shutdown qemu system, gtk_main quit complete \n");
355 /* 5. Flush output */
359 /* 6. close fp which is opened when redirect_log() */
363 INFO( "Close fp which is opened when redirect_log()\n");
365 #ifdef ENABLE_OPENGL_SERVER
366 pthread_cancel(thread_opengl_id);
367 INFO( "opengl_server thread is quited.\n");
368 #endif /* ENABLE_OPENGL_SERVER */
373 static int send_info_to_emuld(char *send_buf, int buf_size)
377 s = tcp_socket_outgoing("127.0.0.1", (uint16_t)(get_sdb_base_port() + SDB_TCP_EMULD_INDEX));
379 TRACE( "can't create socket to talk to the sdb forwarding session \n");
380 TRACE( "[127.0.0.1:%d/tcp] connect fail (%d:%s)\n"
381 , get_sdb_base_port() + SDB_TCP_EMULD_INDEX
382 , errno, strerror(errno)
387 socket_send(s, "system\n\n\n\n", 10);
388 socket_send(s, &buf_size, 4);
389 socket_send(s, send_buf, buf_size);
391 INFO( "send(size: %d) te 127.0.0.1:%d/tcp \n"
392 , buf_size, get_sdb_base_port() + SDB_TCP_EMULD_INDEX);
405 static void *graceful_shutdown_ftn(void* arg)
409 INFO("send command shutdown to emuld \n");
410 send_info_to_emuld("shutdown", 8);
413 INFO("wait 7 seconds \n");
422 INFO("qemu_system_shutdown_request call \n");
423 qemu_system_shutdown_request();
430 * @brief destroy emulator
435 void exit_emulator(void)
438 #if 1 /* graceful shutdown */
440 /* 1st way : long press => power key */
441 ps2kbd_put_keycode( 103 & 0x7f );
443 Sleep( 1.6 * 1000 ); // 1.6 seconds
445 usleep( 1.6 * 1000 * 1000 ); // 1.6 seconds
447 ps2kbd_put_keycode( 103 | 0x80 );
448 // If user selects 'Yes' in Power off poup, 'qemu_system_shutdown_request' in vl.c is supposed to be called.
451 /* 2nd way : send command shutdown to emuld in guest image */
453 if (pthread_create(&thread_id, NULL, graceful_shutdown_ftn, NULL) != 0) {
454 ERR("pthread_create fail \n");
455 qemu_system_shutdown_request();
461 /* 1. emulator and driver destroy */
465 INFO( "Emulator Stop: destroy emulator \n");
467 /* 2. destroy hash */
469 window_hash_destroy();
475 /* 4. shutdown qemu system */
477 qemu_system_shutdown_request();
482 INFO( "Emulator Stop: shutdown qemu system, gtk_main quit complete \n");
484 #ifdef ENABLE_OPENGL_SERVER
485 pthread_cancel(thread_opengl_id);
486 INFO( "opengl_server thread is quited.\n");
487 #endif /* ENABLE_OPENGL_SERVER */
491 #endif /* graceful shutdown */
497 @brief enumerates display monitors
498 @param dwData: host screen resolution
499 @return success: TRUE
501 static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
505 mi.cbSize = sizeof(MONITORINFO);
506 GetMonitorInfo(hMonitor, &mi);
508 pHostScreen = (RECT *)dwData;
509 pHostScreen->left = MIN(lprcMonitor->left, pHostScreen->left);
510 pHostScreen->top = MIN(lprcMonitor->top, pHostScreen->top);
511 pHostScreen->right = MAX(lprcMonitor->right, pHostScreen->right);
512 pHostScreen->bottom = MAX(lprcMonitor->bottom,pHostScreen->bottom);
518 static void construct_main_window(void)
521 gchar emul_img_dir[512] = {0,};
524 GdkBitmap *SkinMask = NULL;
525 GtkWidget *popup_menu = NULL;
526 GtkWidget *sdl_widget = NULL;
528 UISTATE.current_mode = 0;
530 /* 1. create main_window without border */
532 g_main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
533 add_window (g_main_window, EMULATOR_ID);
534 #if GTK_CHECK_VERSION(2,20,0)
535 gtk_widget_set_can_focus(g_main_window,TRUE);
537 GTK_WIDGET_SET_FLAGS(g_main_window, GTK_CAN_FOCUS);
540 color.red = color.green = color.blue = 0x8888;
541 gtk_widget_modify_bg(g_main_window, GTK_STATE_NORMAL, &color);
542 INFO("sets the emulator window background color (%x, %x, %x)\n", color.red, color.green, color.blue);
544 gtk_window_set_decorated (GTK_WINDOW (g_main_window), FALSE);
546 /* 2.1 emulator taskbar icon image */
548 skin = get_skin_path();
550 ERR( "getting skin path is failed!!\n");
555 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
556 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
559 if ((osvi.dwMajorVersion >= 6) && (osvi.dwMinorVersion >= 1))
560 sprintf(emul_img_dir, "%s/icons/Emulator.ico", skin);
562 sprintf(emul_img_dir, "%s/icons/Emulator_20x20.png", skin);
565 sprintf(emul_img_dir, "%s/icons/Emulator.ico", skin);
568 if (g_file_test(emul_img_dir, G_FILE_TEST_EXISTS) == FALSE) {
569 ERR( "emulator icon directory %s doesn't exist!!\n", emul_img_dir);
571 gtk_window_set_icon_from_file(GTK_WINDOW(g_main_window), emul_img_dir, NULL);
574 /* 2.2 emulator taskbar name */
576 name = g_strdup_printf("emulator-%d", get_sdb_base_port());
577 gtk_window_set_title (GTK_WINDOW (g_main_window), name);
582 if (load_skin_image(&PHONE) < 0) {
583 ERR( "emulator skin image is not loaded.\n");
587 /* 4. skin mask process */
589 pixmap_widget = gtk_image_new_from_pixbuf (PHONE.mode_SkinImg[UISTATE.current_mode].pPixImg);
590 gdk_pixbuf_render_pixmap_and_mask (PHONE.mode_SkinImg[UISTATE.current_mode].pPixImg, NULL, &SkinMask, 1);
591 gtk_widget_shape_combine_mask (g_main_window, SkinMask, 0, 0);
592 INFO("sets a shape for emulator window\n");
594 if (SkinMask != NULL) {
595 g_object_unref (SkinMask);
598 /* 5. emulator container */
600 fixed = gtk_fixed_new ();
601 if (!qemu_widget_new(&sdl_widget)) {
602 ERR( "sdl_widget is failed!!\n");
606 gtk_fixed_put (GTK_FIXED (fixed), pixmap_widget, 0, 0);
607 gtk_fixed_put (GTK_FIXED (fixed), sdl_widget, PHONE.mode[UISTATE.current_mode].lcd_list[0].lcd_region.x,
608 PHONE.mode[UISTATE.current_mode].lcd_list[0].lcd_region.y);
609 gtk_container_add (GTK_CONTAINER (g_main_window), fixed);
612 if (strcmp(host_uname_buf.release, "2.6.35-22-generic") == 0) { // for ubuntu 10.10 resize window bug
613 gtk_window_resize (GTK_WINDOW(g_main_window),
614 PHONE.mode_SkinImg[0].nImgHeight, PHONE.mode_SkinImg[0].nImgHeight);
618 /* 6. emulator start position */
619 UISTATE.scale = ((float)get_config_type(SYSTEMINFO.virtual_target_info_file, EMULATOR_GROUP, SCALE_KEY)) / 100;
620 if (UISTATE.scale <= 0 || UISTATE.scale > 1.0) {
623 TRACE("scale = %f\n", UISTATE.scale);
627 int emulator_w, emulator_h;
630 emulator_w = emulator_h = 0;
631 ZeroMemory(&host_screen, sizeof(RECT));
632 EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&host_screen);
634 if (host_screen.left < 0) {
635 int shift = host_screen.left * -1;
636 host_screen.left += shift;
637 host_screen.right += shift;
639 if (host_screen.top < 0) {
640 int shift = host_screen.top * -1;
641 host_screen.top += shift;
642 host_screen.bottom += shift;
645 emulator_w = PHONE.mode_SkinImg[UISTATE.current_mode].nImgWidth * UISTATE.scale;
646 emulator_h = PHONE.mode_SkinImg[UISTATE.current_mode].nImgHeight * UISTATE.scale;
648 // position correction of x
649 range = host_screen.left - emulator_w;
650 if (configuration.main_x <= range)
652 INFO("configuration.main_x=%d is out of monitor range. (%d ~ %d)\n",
653 configuration.main_x, range, host_screen.right);
654 configuration.main_x = host_screen.left;
656 else if (configuration.main_x >= host_screen.right)
658 INFO("configuration.main_x=%d is out of monitor range. (%d ~ %d)\n",
659 configuration.main_x, range, host_screen.right);
660 configuration.main_x = host_screen.right - emulator_w;
663 // position correction of y
664 range = host_screen.top - emulator_h;
665 if (configuration.main_y <= range)
667 INFO("configuration.main_y=%d is out of monitor range. (%d ~ %d)\n",
668 configuration.main_x, range, host_screen.bottom);
669 configuration.main_y = host_screen.top;
671 else if (configuration.main_y >= host_screen.bottom)
673 INFO("configuration.main_y=%d is out of monitor range. (%d ~ %d)\n",
674 configuration.main_x, range, host_screen.bottom);
675 configuration.main_y = host_screen.bottom - emulator_h;
679 gtk_window_move (GTK_WINDOW (g_main_window), configuration.main_x, configuration.main_y);
680 INFO("emulator window is moved (%d, %d)\n", configuration.main_x, configuration.main_y);
682 /* 7. create popup menu */
683 create_popup_menu (&popup_menu, &PHONE, &configuration);
684 INFO("popup menu is created\n");
686 /* 8. Signal connect */
688 g_signal_connect (G_OBJECT(g_main_window), "motion_notify_event", G_CALLBACK(motion_notify_event_handler), NULL);
689 g_signal_connect (G_OBJECT(g_main_window), "button_press_event", G_CALLBACK(motion_notify_event_handler), NULL);
690 g_signal_connect (G_OBJECT(g_main_window), "button_release_event", G_CALLBACK(motion_notify_event_handler), NULL);
691 g_signal_connect (G_OBJECT(g_main_window), "key_press_event", G_CALLBACK(key_event_handler), NULL);
692 g_signal_connect (G_OBJECT(g_main_window), "key_release_event", G_CALLBACK(key_event_handler), NULL);
693 g_signal_connect (G_OBJECT(g_main_window), "delete-event", G_CALLBACK(exit_emulator), NULL);
694 g_signal_connect (G_OBJECT(g_main_window), "configure_event", G_CALLBACK(configure_event), NULL);
696 gtk_widget_set_has_tooltip(g_main_window, TRUE);
697 g_signal_connect (G_OBJECT(g_main_window), "query-tooltip", G_CALLBACK(query_tooltip_event), NULL);
699 gtk_widget_set_events (g_main_window, GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK |
700 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);// | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
702 /* 9. widget show all */
704 gtk_window_set_keep_above(GTK_WINDOW (g_main_window), configuration.always_on_top);
705 gtk_widget_show_all (g_main_window);
706 gtk_widget_queue_resize (g_main_window);
708 if (UISTATE.scale != 1.0) {
709 scale_event_callback(&PHONE, UISTATE.current_mode);
713 static void* run_gtk_main(void* arg)
715 /* 10. gtk main start */
716 init_sensor_server();
723 static void* construct_main_window_and_run_gtk_main(void* arg)
725 construct_main_window();
726 init_sensor_server();
735 * @brief init startup structure
736 * @return success 0, fail -1
740 static void init_startup_option(void)
742 memset(&(startup_option), 0x00, sizeof(startup_option));
743 startup_option.run_level = 5;
744 startup_option.mountPort = 1301;
745 startup_option.telnet_port = 1201;
746 startup_option.ssh_port = 1202;
749 while(check_port(LOCALHOST, startup_option.mountPort) == 0)
750 startup_option.mountPort++;
753 startup_option.no_dump = FALSE;
754 startup_option.vtm = "default";
759 * @brief startup option
760 * kill application and load kernel driver
762 * @return success 0, fail -1
766 static int startup_option_parser(int *argc, char ***argv)
768 /* 1. Goption handling */
770 gboolean version = FALSE;
771 GOptionContext *context = NULL;
772 GError *error = NULL;
773 char timeinfo[256] = { 0, };
779 char *arch = getenv(EMULATOR_ARCH);
780 const gchar *exec_path = get_exec_path();
781 if(!arch) /* for stand alone */
783 char *binary = g_path_get_basename(exec_path);
784 if(strstr(binary, EMULATOR_X86))
785 arch = g_strdup_printf(X86);
786 else if(strstr(binary, EMULATOR_ARM))
787 arch = g_strdup_printf(ARM);
790 ERR( "binary setting failed\n");
796 GOptionEntry options[] = {
797 {"disk", 0, 0, G_OPTION_ARG_STRING, &startup_option.disk, "Disk image path", "\"disk path\""},
798 {"vtm", 0, 0, G_OPTION_ARG_STRING, &startup_option.vtm, "Virtual target image file", "\"*.x86 or *.arm\""},
799 {"run-level", 0, 0, G_OPTION_ARG_INT, &startup_option.run_level, "Run level", "5"},
800 {"version", 0, 0, G_OPTION_ARG_NONE, &version, "Version info", NULL},
801 {"Port", 0, 0, G_OPTION_ARG_INT, &startup_option.mountPort, "Port for NFS mounting", "\"default is 1301\""},
802 {"ssh-port", 0, 0, G_OPTION_ARG_INT, &startup_option.ssh_port, "Port for ssh to guest", NULL},
803 {"telnet-port", 0, 0, G_OPTION_ARG_INT, &startup_option.telnet_port, "Port for telnet to guest", NULL},
804 {"no-dump", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &startup_option.no_dump, "Disable dump feature", NULL},
808 /* 2. Goption parsing */
810 context = g_option_context_new ("- Tizen SDK Emulator");
811 g_option_context_set_help_enabled(context, FALSE);
812 g_option_context_add_main_entries (context, options, NULL);
813 g_option_context_add_group (context, gtk_get_option_group (TRUE));
815 if (!g_option_context_parse (context, argc, argv, &error)) {
816 fprintf(stderr, "%s: option parsing failed\n", (*argv)[0]);
820 /* 3. starting info */
821 gettimeofday(&tval, NULL);
822 tm_time = localtime(&(tval.tv_sec));
823 strftime(timeinfo, sizeof(timeinfo), "%Y/%m/%d %H:%M:%S", tm_time);
824 INFO("=========INFO START========\n");
825 INFO("Current time : %s\n", timeinfo);
826 INFO("SDK version : %s(%s), Build date : %s\n", build_version, build_git, build_date);
828 INFO("Qemu build machine linux kernel version : (%d, %d, %d)\n",
829 LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xff , LINUX_VERSION_CODE & 0xff);
831 if (uname(&host_uname_buf) == 0) {
832 INFO("Host uname : %s %s %s %s %s\n", host_uname_buf.sysname, host_uname_buf.nodename,
833 host_uname_buf.release, host_uname_buf.version, host_uname_buf.machine);
837 INFO("Host sdl version : (%d, %d, %d)\n", SDL_Linked_Version()->major, SDL_Linked_Version()->minor, SDL_Linked_Version()->patch);
839 char *virtual_target_path = get_virtual_target_path(startup_option.vtm);
840 info_file = g_strdup_printf("%sconfig.ini", virtual_target_path);
841 if( (fp = fopen(info_file, "r")) == NULL )
843 ERR("can't open %s", info_file);
847 if (!startup_option.vtm)
848 startup_option.vtm = g_strdup_printf("default");
849 startup_option.disk = g_strdup_printf("%semulimg-%s.%s",virtual_target_path, startup_option.vtm, arch);
850 INFO("target name : %s, disk path : %s\n", startup_option.vtm, startup_option.disk);
853 while(fgets(string, MAXBUF, fp)!=NULL)
856 INFO("=========INFO END========\n");
859 free(virtual_target_path);
867 * @brief init structure
868 * @return success 0, fail -1
872 static int init_structure(void)
875 /* 3. make startup option structure */
877 init_startup_option();
884 * @brief init emulator
885 * @param argc number of argument
886 * @param argv argument vector
891 static void init_emulator(int *argc, char ***argv)
895 emulator_mutex_init();
903 gtk_init (argc, argv);
905 /* 4. structure init */
909 /* 5. make hash init */
916 * @brief function to load config parsed to qemu option
917 * @return success 0, fail -1
921 static int load_config_passed_to_qemu (arglist* al, int argc, char **argv)
925 /* 1. load configuration and show option window */
927 if (load_config_file(&SYSTEMINFO) < 0) {
928 ERR( "load configuration file error!!\n");
932 TRACE( "load config file complete\n");
936 if (determine_skin(&virtual_target_info, &configuration) < 0) {
937 ERR( "invalid skin file\n");
941 /* 2. skin parse dbi file and fill the structure */
943 if (skin_parser(configuration.skin_path, &PHONE) < 0) {
944 ERR( "skin parse error\n");
948 TRACE( "skin parse complete\n");
950 /* 3. parsed to qemu startup option when ok clicked */
952 qemu_option_set_to_config(al);
955 * note: g_option_context_parse modifies argc and argv
956 * Append args after -- to QEMU command line
958 if (argc > 2 && !strcmp(argv[1], "--")) {
959 for (i=2; i<argc; i++) {
960 /* if snapshot boot set then skip -loadvm snapshot option */
961 if(configuration.qemu_configuration.save_emulator_state == 0 && strcmp(argv[i],"-loadvm") == 0){
962 i++; // skip snapshot id
964 else append_argvlist(al, "%s", argv[i]);
972 static void emul_prepare_process(void)
976 /* start the vmodem*/
977 if(qemu_arch_is_arm()) {
978 const char* target_path = get_target_path();
980 if(configuration.qemu_configuration.diskimg_type)
981 sprintf (cmd, "/opt/tizen_sdk/simulator/vmodem_arm");
983 sprintf (cmd, "%s/usr/bin/vmodem_arm", target_path);
985 if(emul_create_process(cmd) == FALSE)
986 fprintf(stderr, "create vmodem failed\n");
989 /* start serial console */
990 if(configuration.qemu_configuration.serial_console_command_type == 1 &&
991 configuration.qemu_configuration.telnet_type == 1) {
992 sprintf(cmd, "%s", configuration.qemu_configuration.serial_console_command);
994 if(emul_create_process(cmd) == FALSE)
995 fprintf(stderr, "create serial console failed\n");
1002 char *virtual_target_path = NULL;
1003 virtual_target_path = get_virtual_target_path(startup_option.vtm);
1004 tizen_base_port = get_sdb_base_port();
1007 char *shared_memory;
1008 shmid = shmget((key_t)tizen_base_port, MAXPATH, 0666|IPC_CREAT);
1011 ERR("shmget failed");
1014 shared_memory = shmat(shmid, (char*)0x00, 0);
1015 if (shared_memory == (void *)-1)
1017 ERR("shmat failed");
1020 sprintf(shared_memory, "%s", virtual_target_path);
1021 INFO( "shared memory key: %d value: %s\n", tizen_base_port, (char*)shared_memory);
1026 char *shared_memory;
1027 shared_memory = g_strdup_printf("%s", virtual_target_path);
1028 port_in_use = g_strdup_printf("%d", tizen_base_port);
1029 hMapFile = CreateFileMapping(
1030 INVALID_HANDLE_VALUE, // use paging file
1031 NULL, // default security
1032 PAGE_READWRITE, // read/write access
1033 0, // maximum object size (high-order DWORD)
1034 50, // maximum object size (low-order DWORD)
1035 port_in_use); // name of mapping object
1036 if (hMapFile == NULL)
1038 ERR("Could not create file mapping object (%d).\n", GetLastError());
1041 pBuf = MapViewOfFile(hMapFile, // handle to map object
1042 FILE_MAP_ALL_ACCESS, // read/write permission
1049 ERR("Could not map view of file (%d).\n", GetLastError());
1050 CloseHandle(hMapFile);
1054 CopyMemory((PVOID)pBuf, shared_memory, strlen(shared_memory));
1056 free(shared_memory);
1058 free(virtual_target_path);
1063 static void redirect_log(void)
1065 static char logfile[256] = { 0, };
1067 strcpy(logfile, get_virtual_target_log_path(startup_option.vtm));
1068 strcat(logfile, EMUL_LOGFILE);
1070 g_out_fp = freopen(logfile, "a+", stdout);
1071 if (g_out_fp ==NULL) {
1072 fprintf(stderr, "log file open error\n");
1075 g_err_fp = freopen(logfile, "a+", stderr);
1076 if (g_err_fp ==NULL) {
1077 fprintf(stderr, "log file open error\n");
1080 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
1081 setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
1086 * @brief function to create emulator
1087 * @param argc number of argument
1088 * @param argv argument vector
1090 * @return success 0, fail -1
1091 * @date Apr 22. 2009
1094 int main(int argc, char** argv)
1096 //int sensor_port = SENSOR_PORT;
1098 pthread_t thread_gtk_id;
1100 init_emulator(&argc, &argv);
1102 startup_option_parser(&argc, &argv);
1104 /* redirect stderr, stdout to log file */
1108 /* initailize socket for windows */
1112 /* make shared memory not for launching multiple instance of one target */
1114 INFO("created a shared memory\n");
1116 /* option parsed and pass to qemu option */
1118 r = load_config_passed_to_qemu(&g_qemu_arglist, argc, argv);
1120 ERR( "option parsed and pass to qemu option error!!\n");
1123 INFO("Arguments : ");
1124 for(i=0; i<g_qemu_arglist.argc; i++){
1125 dbg_printf_nonewline("%s ", g_qemu_arglist.argv[i]);
1129 /* signal handler */
1131 register_sig_handler();
1134 construct_main_window();
1136 /* create gtk thread */
1137 if (pthread_create(&thread_gtk_id, NULL, run_gtk_main, NULL) != 0) {
1138 ERR( "error creating gtk_id thread!!\n");
1142 /* if _WIN32, window creation and gtk main must be run in a thread */
1143 if (pthread_create(&thread_gtk_id, NULL, construct_main_window_and_run_gtk_main, NULL) != 0) {
1144 ERR( "error creating gtk_id thread!!\n");
1148 INFO("run_gtk_main\n");
1150 #ifdef ENABLE_OPENGL_SERVER
1151 /* create OPENGL server thread */
1152 if (pthread_create(&thread_opengl_id, NULL, init_opengl_server, NULL) != 0) {
1153 ERR( "error creating opengl_id thread!!");
1156 #endif /* ENABLE_OPENGL_SERVER */
1158 /* create serial console and vmodem, and other processes */
1160 emul_prepare_process();
1163 qemu_main(g_qemu_arglist.argc, g_qemu_arglist.argv, NULL);
1168 gboolean update_progress_bar(GIOChannel *channel, GIOCondition condition, gpointer data)
1170 unsigned int len = 0;
1175 struct tm *timeinfo;
1176 char time_str[MAX_TIME_STR];
1177 char telnet_commands[MAX_COMMANDS][MAX_LENGTH] = {
1178 "read", //dummy command for local use
1180 "read", //dummy command for local use
1181 "savevm snapshot\r",
1182 "read", //dummy command for local use
1185 if((condition==G_IO_IN) && !(vmstate%2))
1187 status = g_io_channel_read_line(channel, &recvbuffer, NULL, NULL, NULL);
1188 if(status!=G_IO_STATUS_NORMAL)
1190 printf("recv() failed or connection closed prematurely %d\n", status);
1192 g_io_channel_unref (channel);
1193 g_io_channel_shutdown(channel, TRUE, NULL);
1199 if((ptr = strstr(recvbuffer, "Completed="))!=NULL)
1202 gdouble fraction = atof(ptr+10);
1203 gtk_progress_bar_set_fraction(savevm_progress,fraction);
1205 else if (strstr(recvbuffer, "SaveVM Complete"))
1207 gtk_progress_bar_set_fraction(savevm_progress,1);
1208 gtk_progress_bar_set_text(savevm_progress,"Save State Successful");
1209 gtk_label_set_text(GTK_LABEL(savevm_label), "Please close this dialog");
1211 g_io_channel_shutdown(channel, TRUE, NULL);
1212 g_io_channel_unref (channel);
1214 rawtime = time(NULL);
1215 timeinfo = localtime(&rawtime);
1216 strftime(time_str, MAX_TIME_STR, "%Y-%m-%d %H:%M:%S", timeinfo);
1217 printf("%s\n", time_str);
1219 virtual_target_info.snapshot_saved = 1;
1220 snprintf(virtual_target_info.snapshot_saved_date, MAXBUF, "%s", time_str);
1221 set_config_type(SYSTEMINFO.virtual_target_info_file, ETC_GROUP, SNAPSHOT_SAVED_KEY, virtual_target_info.snapshot_saved);
1222 set_config_value(SYSTEMINFO.virtual_target_info_file, ETC_GROUP, SNAPSHOT_SAVED_DATE_KEY, virtual_target_info.snapshot_saved_date);
1229 if(vmstate<(MAX_COMMANDS-1))
1238 error = g_io_channel_write(channel,telnet_commands[vmstate],\
1239 strlen(telnet_commands[vmstate]), \
1241 if(error!=G_IO_ERROR_NONE)
1243 g_io_channel_unref (channel);
1244 g_io_channel_shutdown(channel, TRUE, NULL);
1246 printf("send() failed or connection closed prematurely %d\n", G_IO_ERROR_UNKNOWN);
1251 if(vmstate<MAX_COMMANDS)
1257 if(((condition==G_IO_ERR) || (condition==G_IO_HUP))&&(vmstate<=(MAX_COMMANDS-1)))
1259 g_io_channel_unref (channel);
1260 g_io_channel_shutdown(channel, TRUE, NULL);
1268 void save_emulator_state(void)
1270 /* Connect to the monitor console */
1271 struct sockaddr_in server;
1272 unsigned short server_port = 9000;
1273 char *server_ip = "127.0.0.1";
1277 GtkBuilder *builder = gtk_builder_new();
1278 char full_glade_path[256];
1279 sprintf(full_glade_path, "%s/savevm.glade", get_root_path());
1280 gtk_builder_add_from_file(builder, full_glade_path, NULL);
1282 //get objects from the UI
1283 savevm_window = (GtkWidget *)gtk_builder_get_object(builder, "savevm_window");
1284 savevm_progress = (GtkProgressBar *)gtk_builder_get_object(builder, "savevm_progress");
1285 savevm_label = (GtkWidget *)gtk_builder_get_object(builder, "savevm_label");
1286 gtk_progress_bar_set_text(savevm_progress,"Saving State in progress...");
1287 //gtk_builder_connect_signals(builder, NULL);
1288 gtk_widget_show(savevm_window);
1290 if ((vmsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
1292 printf("socket() failed\n");
1295 memset(&server, 0, sizeof(server));
1296 server.sin_family = AF_INET;
1297 server.sin_addr.s_addr = inet_addr(server_ip);
1298 server.sin_port = htons(server_port);
1299 if (connect(vmsock, (struct sockaddr *) &server, sizeof(server)) < 0)
1301 printf("connect() failed\n");
1306 channel=g_io_channel_unix_new(vmsock);
1309 printf("gnet_tcp_socket_get_io_channel() failed\n");
1313 //g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
1315 guint sourceid = g_io_add_watch(channel, G_IO_IN|G_IO_ERR|G_IO_HUP, \
1316 update_progress_bar, NULL);
1320 printf("g_io_add_watch() failed\n");
1321 g_io_channel_unref(channel);
1325 printf("Added to gmain loop = %d\n", sourceid);