static void toggle_full_screen(void) { int width = surface_width(surface); int height = surface_height(surface); int bpp = surface_bits_per_pixel(surface); gui_fullscreen = !gui_fullscreen; if (gui_fullscreen) { gui_saved_width = real_screen->w; gui_saved_height = real_screen->h; gui_saved_scaling = scaling_active; do_sdl_resize(width, height, bpp); scaling_active = 0; gui_saved_grab = gui_grab; sdl_grab_start(); } else { if (gui_saved_scaling) { sdl_scale(gui_saved_width, gui_saved_height); } else { do_sdl_resize(width, height, 0); } if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) { sdl_grab_end(); } } graphic_hw_invalidate(NULL); graphic_hw_update(NULL); }
static void sdl_grab_start(struct sdl2_console *scon) { QemuConsole *con = scon ? scon->dcl.con : NULL; if (!con || !qemu_console_is_graphic(con)) { return; } /* * If the application is not active, do not try to enter grab state. This * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the * application (SDL bug). */ if (!(SDL_GetWindowFlags(scon->real_window) & SDL_WINDOW_INPUT_FOCUS)) { return; } if (guest_cursor) { SDL_SetCursor(guest_sprite); if (!qemu_input_is_absolute() && !absolute_enabled) { SDL_WarpMouseInWindow(scon->real_window, guest_x, guest_y); } } else { sdl_hide_cursor(); } SDL_SetWindowGrab(scon->real_window, SDL_TRUE); gui_grab = 1; sdl_update_caption(scon); }
/* The guest OS has started discussing with us, finish initializing BrlAPI */ static int baum_deferred_init(BaumDriverState *baum) { int tty = BRLAPI_TTY_DEFAULT; QemuConsole *con; if (baum->deferred_init) { return 1; } if (brlapi__getDisplaySize(baum->brlapi, &baum->x, &baum->y) == -1) { brlapi_perror("baum: brlapi__getDisplaySize"); return 0; } con = qemu_console_lookup_by_index(0); if (con && qemu_console_is_graphic(con)) { tty = qemu_console_get_window_id(con); if (tty == -1) tty = BRLAPI_TTY_DEFAULT; } if (brlapi__enterTtyMode(baum->brlapi, tty, NULL) == -1) { brlapi_perror("baum: brlapi__enterTtyMode"); return 0; } baum->deferred_init = 1; return 1; }
static void sdl_process_key(struct sdl2_state *scon, SDL_KeyboardEvent *ev) { int qcode = sdl2_scancode_to_qcode[ev->keysym.scancode]; QemuConsole *con = scon ? scon->dcl.con : NULL; if (!qemu_console_is_graphic(con)) { if (ev->type == SDL_KEYDOWN) { switch (ev->keysym.scancode) { case SDL_SCANCODE_RETURN: kbd_put_keysym_console(con, '\n'); break; case SDL_SCANCODE_BACKSPACE: kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE); break; default: kbd_put_qcode_console(con, qcode); break; } } return; } switch (ev->keysym.scancode) { #if 0 case SDL_SCANCODE_NUMLOCKCLEAR: case SDL_SCANCODE_CAPSLOCK: /* SDL does not send the key up event, so we generate it */ qemu_input_event_send_key_qcode(con, qcode, true); qemu_input_event_send_key_qcode(con, qcode, false); return; #endif case SDL_SCANCODE_LCTRL: case SDL_SCANCODE_LSHIFT: case SDL_SCANCODE_LALT: case SDL_SCANCODE_LGUI: case SDL_SCANCODE_RCTRL: case SDL_SCANCODE_RSHIFT: case SDL_SCANCODE_RALT: case SDL_SCANCODE_RGUI: if (ev->type == SDL_KEYUP) { modifiers_state[ev->keysym.scancode] = 0; } else { modifiers_state[ev->keysym.scancode] = 1; } /* fall though */ default: qemu_input_event_send_key_qcode(con, qcode, ev->type == SDL_KEYDOWN); } }
static void sdl_show_cursor(void) { if (!cursor_hide) return; if (!qemu_input_is_absolute() || !qemu_console_is_graphic(NULL)) { SDL_ShowCursor(1); if (guest_cursor && (gui_grab || qemu_input_is_absolute() || absolute_enabled)) SDL_SetCursor(guest_sprite); else SDL_SetCursor(sdl_cursor_normal); } }
static QemuConsole* find_graphic_console() { // find the first graphic console (Android emulator has only one usually) for (int i = 0;; i++) { QemuConsole* const c = qemu_console_lookup_by_index(i); if (!c) { break; } if (qemu_console_is_graphic(c)) { return c; } } return NULL; }
static void sdl_mouse_mode_change(Notifier *notify, void *data) { if (qemu_input_is_absolute()) { if (!absolute_enabled) { absolute_enabled = 1; if (qemu_console_is_graphic(NULL)) { absolute_mouse_grab(); } } } else if (absolute_enabled) { if (!gui_fullscreen) { sdl_grab_end(); } absolute_enabled = 0; } }
static void curses_cursor_position(DisplayChangeListener *dcl, int x, int y) { if (x >= 0) { x = sminx + x - px; y = sminy + y - py; if (x >= 0 && y >= 0 && x < COLS && y < LINES) { move(y, x); curs_set(1); /* it seems that curs_set(1) must always be called before * curs_set(2) for the latter to have effect */ if (!qemu_console_is_graphic(NULL)) { curs_set(2); } return; } } curs_set(0); }
static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) { QemuConsole *con; egl_dpy *edpy; int idx; if (egl_rendernode_init(NULL) < 0) { error_report("egl: render node init failed"); exit(1); } for (idx = 0;; idx++) { con = qemu_console_lookup_by_index(idx); if (!con || !qemu_console_is_graphic(con)) { break; } edpy = g_new0(egl_dpy, 1); edpy->dcl.con = con; edpy->dcl.ops = &egl_ops; edpy->gls = qemu_gl_init_shader(); register_displaychangelistener(&edpy->dcl); } }
static void curses_refresh(DisplayChangeListener *dcl) { int chr, keysym, keycode, keycode_alt; curses_winch_check(); if (invalidate) { clear(); refresh(); curses_calc_pad(); graphic_hw_invalidate(NULL); invalidate = 0; } graphic_hw_text_update(NULL, screen); while (1) { /* while there are any pending key strokes to process */ chr = getch(); if (chr == ERR) break; #ifdef KEY_RESIZE /* this shouldn't occur when we use a custom SIGWINCH handler */ if (chr == KEY_RESIZE) { clear(); refresh(); curses_calc_pad(); curses_update(dcl, 0, 0, width, height); continue; } #endif keycode = curses2keycode[chr]; keycode_alt = 0; /* alt key */ if (keycode == 1) { int nextchr = getch(); if (nextchr != ERR) { chr = nextchr; keycode_alt = ALT; keycode = curses2keycode[chr]; if (keycode != -1) { keycode |= ALT; /* process keys reserved for qemu */ if (keycode >= QEMU_KEY_CONSOLE0 && keycode < QEMU_KEY_CONSOLE0 + 9) { erase(); wnoutrefresh(stdscr); console_select(keycode - QEMU_KEY_CONSOLE0); invalidate = 1; continue; } } } } if (kbd_layout) { keysym = -1; if (chr < CURSES_KEYS) keysym = curses2keysym[chr]; if (keysym == -1) { if (chr < ' ') { keysym = chr + '@'; if (keysym >= 'A' && keysym <= 'Z') keysym += 'a' - 'A'; keysym |= KEYSYM_CNTRL; } else keysym = chr; } keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK, false, false, false); if (keycode == 0) continue; keycode |= (keysym & ~KEYSYM_MASK) >> 16; keycode |= keycode_alt; } if (keycode == -1) continue; if (qemu_console_is_graphic(NULL)) { /* since terminals don't know about key press and release * events, we need to emit both for each key received */ if (keycode & SHIFT) { qemu_input_event_send_key_number(NULL, SHIFT_CODE, true); qemu_input_event_send_key_delay(0); } if (keycode & CNTRL) { qemu_input_event_send_key_number(NULL, CNTRL_CODE, true); qemu_input_event_send_key_delay(0); } if (keycode & ALT) { qemu_input_event_send_key_number(NULL, ALT_CODE, true); qemu_input_event_send_key_delay(0); } if (keycode & ALTGR) { qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, true); qemu_input_event_send_key_delay(0); } qemu_input_event_send_key_number(NULL, keycode & KEY_MASK, true); qemu_input_event_send_key_delay(0); qemu_input_event_send_key_number(NULL, keycode & KEY_MASK, false); qemu_input_event_send_key_delay(0); if (keycode & ALTGR) { qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, false); qemu_input_event_send_key_delay(0); } if (keycode & ALT) { qemu_input_event_send_key_number(NULL, ALT_CODE, false); qemu_input_event_send_key_delay(0); } if (keycode & CNTRL) { qemu_input_event_send_key_number(NULL, CNTRL_CODE, false); qemu_input_event_send_key_delay(0); } if (keycode & SHIFT) { qemu_input_event_send_key_number(NULL, SHIFT_CODE, false); qemu_input_event_send_key_delay(0); } } else { keysym = -1; if (chr < CURSES_KEYS) { keysym = curses2qemu[chr]; } if (keysym == -1) keysym = chr; kbd_put_keysym(keysym); } } }
static void handle_keydown(SDL_Event *ev) { int mod_state; int keycode; if (alt_grab) { mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) == (gui_grab_code | KMOD_LSHIFT); } else if (ctrl_grab) { mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL; } else { mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code; } gui_key_modifier_pressed = mod_state; if (gui_key_modifier_pressed) { keycode = sdl_keyevent_to_keycode(&ev->key); switch (keycode) { case 0x21: /* 'f' key on US keyboard */ toggle_full_screen(); gui_keysym = 1; break; case 0x16: /* 'u' key on US keyboard */ if (scaling_active) { scaling_active = 0; sdl_switch(dcl, NULL); graphic_hw_invalidate(NULL); graphic_hw_update(NULL); } gui_keysym = 1; break; case 0x02 ... 0x0a: /* '1' to '9' keys */ /* Reset the modifiers sent to the current console */ reset_keys(); console_select(keycode - 0x02); gui_keysym = 1; if (gui_fullscreen) { break; } if (!qemu_console_is_graphic(NULL)) { /* release grab if going to a text console */ if (gui_grab) { sdl_grab_end(); } else if (absolute_enabled) { sdl_show_cursor(); } } else if (absolute_enabled) { sdl_hide_cursor(); absolute_mouse_grab(); } break; case 0x1b: /* '+' */ case 0x35: /* '-' */ if (!gui_fullscreen) { int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50), 160); int height = (surface_height(surface) * width) / surface_width(surface); sdl_scale(width, height); graphic_hw_invalidate(NULL); graphic_hw_update(NULL); gui_keysym = 1; } default: break; } } else if (!qemu_console_is_graphic(NULL)) {