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 ); }
static void handle_key_command( void* opaque, SkinKeyCommand command, int down ) { static const struct { SkinKeyCommand cmd; AndroidKeyCode kcode; } keycodes[] = { { SKIN_KEY_COMMAND_BUTTON_CALL, kKeyCodeCall }, { SKIN_KEY_COMMAND_BUTTON_HOME, kKeyCodeHome }, { SKIN_KEY_COMMAND_BUTTON_BACK, kKeyCodeBack }, { SKIN_KEY_COMMAND_BUTTON_HANGUP, kKeyCodeEndCall }, { SKIN_KEY_COMMAND_BUTTON_POWER, kKeyCodePower }, { SKIN_KEY_COMMAND_BUTTON_SEARCH, kKeyCodeSearch }, { SKIN_KEY_COMMAND_BUTTON_MENU, kKeyCodeMenu }, { SKIN_KEY_COMMAND_BUTTON_DPAD_UP, kKeyCodeDpadUp }, { SKIN_KEY_COMMAND_BUTTON_DPAD_LEFT, kKeyCodeDpadLeft }, { SKIN_KEY_COMMAND_BUTTON_DPAD_RIGHT, kKeyCodeDpadRight }, { SKIN_KEY_COMMAND_BUTTON_DPAD_DOWN, kKeyCodeDpadDown }, { SKIN_KEY_COMMAND_BUTTON_DPAD_CENTER, kKeyCodeDpadCenter }, { SKIN_KEY_COMMAND_BUTTON_VOLUME_UP, kKeyCodeVolumeUp }, { SKIN_KEY_COMMAND_BUTTON_VOLUME_DOWN, kKeyCodeVolumeDown }, { SKIN_KEY_COMMAND_BUTTON_CAMERA, kKeyCodeCamera }, { SKIN_KEY_COMMAND_BUTTON_TV, kKeyCodeTV }, { SKIN_KEY_COMMAND_BUTTON_EPG, kKeyCodeEPG }, { SKIN_KEY_COMMAND_BUTTON_DVR, kKeyCodeDVR }, { SKIN_KEY_COMMAND_BUTTON_PREV, kKeyCodePrevious }, { SKIN_KEY_COMMAND_BUTTON_NEXT, kKeyCodeNext }, { SKIN_KEY_COMMAND_BUTTON_PLAY, kKeyCodePlay }, { SKIN_KEY_COMMAND_BUTTON_PAUSE, kKeyCodePause }, { SKIN_KEY_COMMAND_BUTTON_STOP, kKeyCodeStop }, { SKIN_KEY_COMMAND_BUTTON_REWIND, kKeyCodeRewind }, { SKIN_KEY_COMMAND_BUTTON_FFWD, kKeyCodeFastForward }, { SKIN_KEY_COMMAND_BUTTON_BOOKMARKS, kKeyCodeBookmarks }, { SKIN_KEY_COMMAND_BUTTON_WINDOW, kKeyCodeCycleWindows }, { SKIN_KEY_COMMAND_BUTTON_CHANNELUP, kKeyCodeChannelUp }, { SKIN_KEY_COMMAND_BUTTON_CHANNELDOWN, kKeyCodeChannelDown }, { SKIN_KEY_COMMAND_NONE, 0 } }; int nn; #ifdef CONFIG_TRACE static int tracing = 0; #endif QEmulator* emulator = opaque; for (nn = 0; keycodes[nn].kcode != 0; nn++) { if (command == keycodes[nn].cmd) { unsigned code = keycodes[nn].kcode; if (down) code |= 0x200; user_event_keycode( code ); return; } } if (command == SKIN_KEY_COMMAND_SHOW_TRACKBALL) { emulator->show_trackball = (down != 0); skin_window_show_trackball( emulator->window, emulator->show_trackball ); return; } if (down == 0) return; switch (command) { case SKIN_KEY_COMMAND_TOGGLE_NETWORK: { corecmd_toggle_network(); D( "network is now %s", corecmd_is_network_disabled() ? "disconnected" : "connected" ); } break; case SKIN_KEY_COMMAND_TOGGLE_FULLSCREEN: if (emulator->window) { skin_window_toggle_fullscreen(emulator->window); } break; case SKIN_KEY_COMMAND_TOGGLE_TRACING: { #ifdef CONFIG_TRACE tracing = !tracing; corecmd_trace_control(tracing); #endif } break; case SKIN_KEY_COMMAND_TOGGLE_TRACKBALL: emulator->show_trackball = !emulator->show_trackball; skin_window_show_trackball( emulator->window, emulator->show_trackball ); qemulator_set_title(emulator); break; case SKIN_KEY_COMMAND_ONION_ALPHA_UP: case SKIN_KEY_COMMAND_ONION_ALPHA_DOWN: if (emulator->onion) { int alpha = emulator->onion_alpha; if (command == SKIN_KEY_COMMAND_ONION_ALPHA_UP) alpha += 16; else alpha -= 16; if (alpha > 256) alpha = 256; else if (alpha < 0) alpha = 0; emulator->onion_alpha = alpha; skin_window_set_onion( emulator->window, emulator->onion, emulator->onion_rotation, alpha ); skin_window_redraw( emulator->window, NULL ); } break; case SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV: case SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT: { SkinLayout* layout = NULL; if (command == SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT) { layout = emulator->layout->next; if (layout == NULL) layout = emulator->layout_file->layouts; } else if (command == SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV) { layout = emulator->layout_file->layouts; while (layout->next && layout->next != emulator->layout) layout = layout->next; } if (layout != NULL) { SkinRotation rotation; emulator->layout = layout; skin_window_reset( emulator->window, layout ); rotation = skin_layout_get_dpad_rotation( layout ); if (emulator->keyboard) skin_keyboard_set_rotation( emulator->keyboard, rotation ); if (emulator->trackball) { skin_trackball_set_rotation( emulator->trackball, rotation ); skin_window_set_trackball( emulator->window, emulator->trackball ); skin_window_show_trackball( emulator->window, emulator->show_trackball ); } skin_window_set_lcd_brightness( emulator->window, emulator->lcd_brightness ); qframebuffer_invalidate_all(); qframebuffer_check_updates(); } } break; default: ; } }
bool skin_ui_process_events(SkinUI* ui) { SkinEvent ev; #ifdef _WIN32 if (ui->ui_params.win32_ignore_events) { // In QT, Windows messages are received by the QT thread, which is // the thread that creates all of its windows, so that should be // okay. However, in GPU accelerated images, there's a native window // that's created that represents the actual OpenGL output pane, and // that window is created from this thread and not the QT thread. We // need to keep its message queue from getting jammed up with // messages, so we need to grab any messages we see and drop // unnecessary ones on the floor. MSG message; PeekMessage(&message, NULL, 0, 0, PM_REMOVE); } #endif // _WIN32 while(skin_event_poll(&ev)) { switch(ev.type) { case kEventVideoExpose: DE("EVENT: kEventVideoExpose\n"); skin_window_redraw(ui->window, NULL); break; case kEventKeyDown: DE("EVENT: kEventKeyDown scancode=%d mod=0x%x\n", ev.u.key.keycode, ev.u.key.mod); skin_keyboard_process_event(ui->keyboard, &ev, 1); break; case kEventKeyUp: DE("EVENT: kEventKeyUp scancode=%d mod=0x%x\n", ev.u.key.keycode, ev.u.key.mod); skin_keyboard_process_event(ui->keyboard, &ev, 0); break; case kEventTextInput: DE("EVENT: kEventTextInput text=[%s] down=%s\n", ev.u.text.text, ev.u.text.down ? "true" : "false"); skin_keyboard_process_event(ui->keyboard, &ev, ev.u.text.down); break; case kEventMouseMotion: DE("EVENT: kEventMouseMotion x=%d y=%d xrel=%d yrel=%d button=%d\n", ev.u.mouse.x, ev.u.mouse.y, ev.u.mouse.xrel, ev.u.mouse.yrel, ev.u.mouse.button); skin_window_process_event(ui->window, &ev); break; case kEventMouseButtonDown: case kEventMouseButtonUp: DE("EVENT: kEventMouseButton x=%d y=%d xrel=%d yrel=%d button=%d\n", ev.u.mouse.x, ev.u.mouse.y, ev.u.mouse.xrel, ev.u.mouse.yrel, ev.u.mouse.button); { int down = (ev.type == kEventMouseButtonDown); if (ev.u.mouse.button == kMouseButtonScrollUp) { /* scroll-wheel simulates DPad up */ SkinKeyCode kcode; kcode = skin_keycode_rotate(kKeyCodeDpadUp, skin_layout_get_dpad_rotation( ui->layout)); ui->ui_funcs->keyboard_event(NULL, kcode, down); } else if (ev.u.mouse.button == kMouseButtonScrollDown) { /* scroll-wheel simulates DPad down */ SkinKeyCode kcode; kcode = skin_keycode_rotate(kKeyCodeDpadDown, skin_layout_get_dpad_rotation( ui->layout)); ui->ui_funcs->keyboard_event(NULL, kcode, down); } else if (ev.u.mouse.button == kMouseButtonLeft) { skin_window_process_event(ui->window, &ev); } } break; case kEventQuit: DE("EVENT: kEventQuit\n"); /* only save emulator config through clean exit */ return true; } } skin_keyboard_flush(ui->keyboard); return false; }
/* used to respond to a given keyboard command shortcut */ static void _skin_ui_handle_key_command(void* opaque, SkinKeyCommand command, int down) { SkinUI* ui = opaque; static const struct { SkinKeyCommand cmd; SkinKeyCode kcode; } keycodes[] = { { SKIN_KEY_COMMAND_BUTTON_CALL, kKeyCodeCall }, { SKIN_KEY_COMMAND_BUTTON_HOME, kKeyCodeHome }, { SKIN_KEY_COMMAND_BUTTON_BACK, kKeyCodeBack }, { SKIN_KEY_COMMAND_BUTTON_HANGUP, kKeyCodeEndCall }, { SKIN_KEY_COMMAND_BUTTON_POWER, kKeyCodePower }, { SKIN_KEY_COMMAND_BUTTON_SEARCH, kKeyCodeSearch }, { SKIN_KEY_COMMAND_BUTTON_MENU, kKeyCodeMenu }, { SKIN_KEY_COMMAND_BUTTON_DPAD_UP, kKeyCodeDpadUp }, { SKIN_KEY_COMMAND_BUTTON_DPAD_LEFT, kKeyCodeDpadLeft }, { SKIN_KEY_COMMAND_BUTTON_DPAD_RIGHT, kKeyCodeDpadRight }, { SKIN_KEY_COMMAND_BUTTON_DPAD_DOWN, kKeyCodeDpadDown }, { SKIN_KEY_COMMAND_BUTTON_DPAD_CENTER, kKeyCodeDpadCenter }, { SKIN_KEY_COMMAND_BUTTON_VOLUME_UP, kKeyCodeVolumeUp }, { SKIN_KEY_COMMAND_BUTTON_VOLUME_DOWN, kKeyCodeVolumeDown }, { SKIN_KEY_COMMAND_BUTTON_CAMERA, kKeyCodeCamera }, { SKIN_KEY_COMMAND_BUTTON_TV, kKeyCodeTV }, { SKIN_KEY_COMMAND_BUTTON_EPG, kKeyCodeEPG }, { SKIN_KEY_COMMAND_BUTTON_DVR, kKeyCodeDVR }, { SKIN_KEY_COMMAND_BUTTON_PREV, kKeyCodePrevious }, { SKIN_KEY_COMMAND_BUTTON_NEXT, kKeyCodeNext }, { SKIN_KEY_COMMAND_BUTTON_PLAY, kKeyCodePlay }, { SKIN_KEY_COMMAND_BUTTON_PAUSE, kKeyCodePause }, { SKIN_KEY_COMMAND_BUTTON_STOP, kKeyCodeStop }, { SKIN_KEY_COMMAND_BUTTON_REWIND, kKeyCodeRewind }, { SKIN_KEY_COMMAND_BUTTON_FFWD, kKeyCodeFastForward }, { SKIN_KEY_COMMAND_BUTTON_BOOKMARKS, kKeyCodeBookmarks }, { SKIN_KEY_COMMAND_BUTTON_WINDOW, kKeyCodeCycleWindows }, { SKIN_KEY_COMMAND_BUTTON_CHANNELUP, kKeyCodeChannelUp }, { SKIN_KEY_COMMAND_BUTTON_CHANNELDOWN, kKeyCodeChannelDown }, { SKIN_KEY_COMMAND_NONE, 0 } }; int nn; for (nn = 0; keycodes[nn].kcode != 0; nn++) { if (command == keycodes[nn].cmd) { unsigned code = keycodes[nn].kcode; ui->ui_funcs->keyboard_event(NULL, code, down); return; } } // for the show-trackball command, handle down events to enable, and // up events to disable if (command == SKIN_KEY_COMMAND_SHOW_TRACKBALL) { ui->show_trackball = (down != 0); skin_window_show_trackball(ui->window, ui->show_trackball); return; } // only handle down events for the rest if (down == 0) return; switch (command) { case SKIN_KEY_COMMAND_TOGGLE_NETWORK: { bool enabled = ui->ui_funcs->network_toggle(); D( "network is now %s", enabled ? "connected" : "disconnected"); } break; case SKIN_KEY_COMMAND_TOGGLE_FULLSCREEN: if (ui->window) { skin_window_toggle_fullscreen(ui->window); } break; case SKIN_KEY_COMMAND_TOGGLE_TRACKBALL: ui->show_trackball = !ui->show_trackball; skin_window_show_trackball(ui->window, ui->show_trackball); skin_ui_reset_title(ui); break; case SKIN_KEY_COMMAND_ONION_ALPHA_UP: case SKIN_KEY_COMMAND_ONION_ALPHA_DOWN: if (ui->onion) { int alpha = ui->onion_alpha; if (command == SKIN_KEY_COMMAND_ONION_ALPHA_UP) alpha += 16; else alpha -= 16; if (alpha > 256) alpha = 256; else if (alpha < 0) alpha = 0; ui->onion_alpha = alpha; skin_window_set_onion(ui->window, ui->onion, ui->onion_rotation, ui->onion_alpha); skin_window_redraw(ui->window, NULL); //dprint( "onion alpha set to %d (%.f %%)", alpha, alpha/2.56 ); } break; case SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV: case SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT: { SkinLayout* layout = NULL; if (command == SKIN_KEY_COMMAND_CHANGE_LAYOUT_NEXT) { layout = ui->layout->next; if (layout == NULL) layout = ui->layout_file->layouts; } else if (command == SKIN_KEY_COMMAND_CHANGE_LAYOUT_PREV) { layout = ui->layout_file->layouts; while (layout->next && layout->next != ui->layout) layout = layout->next; } if (layout != NULL) { ui->layout = layout; skin_window_reset(ui->window, layout); SkinRotation rotation = skin_layout_get_dpad_rotation(layout); if (ui->keyboard) skin_keyboard_set_rotation(ui->keyboard, rotation); if (ui->trackball) { skin_trackball_set_rotation(ui->trackball, rotation); skin_window_set_trackball(ui->window, ui->trackball); skin_window_show_trackball(ui->window, ui->show_trackball); } skin_window_set_lcd_brightness(ui->window, ui->lcd_brightness); ui->ui_funcs->framebuffer_invalidate(); } } break; default: /* XXX: TODO ? */ ; } }
/* 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 ); }
bool skin_ui_process_events(SkinUI* ui) { SkinEvent ev; while(skin_event_poll(&ev)) { switch(ev.type) { case kEventVideoExpose: DE("EVENT: kEventVideoExpose\n"); skin_window_redraw(ui->window, NULL); break; case kEventKeyDown: DE("EVENT: kEventKeyDown scancode=%d mod=0x%x\n", ev.u.key.keycode, ev.u.key.mod); skin_keyboard_process_event(ui->keyboard, &ev, 1); break; case kEventKeyUp: DE("EVENT: kEventKeyUp scancode=%d mod=0x%x\n", ev.u.key.keycode, ev.u.key.mod); skin_keyboard_process_event(ui->keyboard, &ev, 0); break; case kEventTextInput: DE("EVENT: kEventTextInput text=[%s] down=%s\n", ev.u.text.text, ev.u.text.down ? "true" : "false"); skin_keyboard_process_event(ui->keyboard, &ev, ev.u.text.down); break; case kEventMouseMotion: DE("EVENT: kEventMouseMotion x=%d y=%d xrel=%d yrel=%d button=%d\n", ev.u.mouse.x, ev.u.mouse.y, ev.u.mouse.xrel, ev.u.mouse.yrel, ev.u.mouse.button); skin_window_process_event(ui->window, &ev); break; case kEventMouseButtonDown: case kEventMouseButtonUp: DE("EVENT: kEventMouseButton x=%d y=%d xrel=%d yrel=%d button=%d\n", ev.u.mouse.x, ev.u.mouse.y, ev.u.mouse.xrel, ev.u.mouse.yrel, ev.u.mouse.button); { int down = (ev.type == kEventMouseButtonDown); if (ev.u.mouse.button == kMouseButtonScrollUp) { /* scroll-wheel simulates DPad up */ SkinKeyCode kcode; kcode = skin_keycode_rotate(kKeyCodeDpadUp, skin_layout_get_dpad_rotation( ui->layout)); ui->ui_funcs->keyboard_event(NULL, kcode, down); } else if (ev.u.mouse.button == kMouseButtonScrollDown) { /* scroll-wheel simulates DPad down */ SkinKeyCode kcode; kcode = skin_keycode_rotate(kKeyCodeDpadDown, skin_layout_get_dpad_rotation( ui->layout)); ui->ui_funcs->keyboard_event(NULL, kcode, down); } else if (ev.u.mouse.button == kMouseButtonLeft) { skin_window_process_event(ui->window, &ev); } } break; case kEventQuit: DE("EVENT: kEventQuit\n"); /* only save emulator config through clean exit */ return true; } } skin_keyboard_flush(ui->keyboard); return false; }