/* Attaches starting UI to a running core process. * This routine is called from main() when -attach-core parameter is set, * indicating that this UI instance should attach to a running core, rather than * start a new core process. * Param: * opts Android options containing non-NULL attach_core. * Return: * 0 on success, or -1 on failure. */ static int attach_to_core(AndroidOptions* opts) { int iter; SockAddress console_socket; SockAddress** sockaddr_list; QEmulator* emulator; // Parse attach_core param extracting the host name, and the port name. char* console_address = strdup(opts->attach_core); char* host_name = console_address; char* port_num = strchr(console_address, ':'); if (port_num == NULL) { // The host name is ommited, indicating the localhost host_name = "localhost"; port_num = console_address; } else if (port_num == console_address) { // Invalid. derror("Invalid value %s for -attach-core parameter\n", opts->attach_core); return -1; } else { *port_num = '\0'; port_num++; if (*port_num == '\0') { // Invalid. derror("Invalid value %s for -attach-core parameter\n", opts->attach_core); return -1; } } /* Create socket address list for the given address, and pull appropriate * address to use for connection. Note that we're fine copying that address * out of the list, since INET and IN6 will entirely fit into SockAddress * structure. */ sockaddr_list = sock_address_list_create(host_name, port_num, SOCKET_LIST_FORCE_INET); free(console_address); if (sockaddr_list == NULL) { derror("Unable to resolve address %s: %s\n", opts->attach_core, errno_str); return -1; } for (iter = 0; sockaddr_list[iter] != NULL; iter++) { if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_INET || sock_address_get_family(sockaddr_list[iter]) == SOCKET_IN6) { memcpy(&console_socket, sockaddr_list[iter], sizeof(SockAddress)); break; } } if (sockaddr_list[iter] == NULL) { derror("Unable to resolve address %s. Note that 'port' parameter passed to -attach-core\n" "must be resolvable into an IP address.\n", opts->attach_core); sock_address_list_free(sockaddr_list); return -1; } sock_address_list_free(sockaddr_list); if (attachUiImpl_create(&console_socket)) { return -1; } // Save core's port, and set the title. android_base_port = sock_address_get_port(&console_socket); emulator = qemulator_get(); qemulator_set_title(emulator); return 0; }
static void qemulator_refresh(QEmulator* emulator) { SDL_Event ev; SkinWindow* window = emulator->window; SkinKeyboard* keyboard = emulator->keyboard; qframebuffer_check_updates(); if (window == NULL) return; while(SDL_PollEvent(&ev)){ switch(ev.type){ case SDL_VIDEOEXPOSE: skin_window_redraw( window, NULL ); break; case SDL_KEYDOWN: #ifdef _WIN32 if (ev.key.keysym.sym == SDLK_F4 && ev.key.keysym.mod & KMOD_ALT) { goto CleanExit; } #endif #ifdef __APPLE__ if (ev.key.keysym.sym == SDLK_q && ev.key.keysym.mod & KMOD_META) { goto CleanExit; } #endif skin_keyboard_process_event( keyboard, &ev, 1 ); break; case SDL_KEYUP: skin_keyboard_process_event( keyboard, &ev, 0 ); break; case SDL_MOUSEMOTION: skin_window_process_event( window, &ev ); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { int down = (ev.type == SDL_MOUSEBUTTONDOWN); if (ev.button.button == 4) { AndroidKeyCode kcode; kcode = android_keycode_rotate(kKeyCodeDpadUp, skin_layout_get_dpad_rotation(qemulator_get_layout(qemulator_get()))); user_event_key( kcode, down ); } else if (ev.button.button == 5) { AndroidKeyCode kcode; kcode = android_keycode_rotate(kKeyCodeDpadDown, skin_layout_get_dpad_rotation(qemulator_get_layout(qemulator_get()))); user_event_key( kcode, down ); } else if (ev.button.button == SDL_BUTTON_LEFT) { skin_window_process_event( window, &ev ); } #if 0 else { fprintf(stderr, "... mouse button %s: button=%d state=%04x x=%d y=%d\n", down ? "down" : "up ", ev.button.button, ev.button.state, ev.button.x, ev.button.y); } #endif } break; case SDL_QUIT: #if defined _WIN32 || defined __APPLE__ CleanExit: #endif qemulator_done(qemulator_get()); qemu_system_shutdown_request(); return; } } skin_keyboard_flush( keyboard ); }
/* called periodically to poll for user input events */ static void qemulator_refresh(QEmulator* emulator) { SDL_Event ev; SkinWindow* window = emulator->window; SkinKeyboard* keyboard = emulator->keyboard; /* this will eventually call sdl_update if the content of the VGA framebuffer * has changed */ qframebuffer_check_updates(); if (window == NULL) return; while(SDL_PollEvent(&ev)){ switch(ev.type){ case SDL_VIDEOEXPOSE: skin_window_redraw( window, NULL ); break; case SDL_KEYDOWN: #ifdef _WIN32 /* special code to deal with Alt-F4 properly */ if (ev.key.keysym.sym == SDLK_F4 && ev.key.keysym.mod & KMOD_ALT) { goto CleanExit; } #endif #ifdef __APPLE__ /* special code to deal with Command-Q properly */ if (ev.key.keysym.sym == SDLK_q && ev.key.keysym.mod & KMOD_META) { goto CleanExit; } #endif skin_keyboard_process_event( keyboard, &ev, 1 ); break; case SDL_KEYUP: skin_keyboard_process_event( keyboard, &ev, 0 ); break; case SDL_MOUSEMOTION: skin_window_process_event( window, &ev ); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { int down = (ev.type == SDL_MOUSEBUTTONDOWN); if (ev.button.button == 4) { /* scroll-wheel simulates DPad up */ AndroidKeyCode kcode; kcode = // qemulator_rotate_keycode(kKeyCodeDpadUp); android_keycode_rotate(kKeyCodeDpadUp, skin_layout_get_dpad_rotation(qemulator_get_layout(qemulator_get()))); user_event_key( kcode, down ); } else if (ev.button.button == 5) { /* scroll-wheel simulates DPad down */ AndroidKeyCode kcode; kcode = // qemulator_rotate_keycode(kKeyCodeDpadDown); android_keycode_rotate(kKeyCodeDpadDown, skin_layout_get_dpad_rotation(qemulator_get_layout(qemulator_get()))); user_event_key( kcode, down ); } else if (ev.button.button == SDL_BUTTON_LEFT) { skin_window_process_event( window, &ev ); } #if 0 else { fprintf(stderr, "... mouse button %s: button=%d state=%04x x=%d y=%d\n", down ? "down" : "up ", ev.button.button, ev.button.state, ev.button.x, ev.button.y); } #endif } break; case SDL_QUIT: #if defined _WIN32 || defined __APPLE__ CleanExit: #endif /* only save emulator config through clean exit */ qemulator_done(qemulator_get()); qemu_system_shutdown_request(); return; } } skin_keyboard_flush( keyboard ); }