diff options
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/console.c | 33 | ||||
| -rw-r--r-- | ui/sdl2.c | 68 | ||||
| -rw-r--r-- | ui/vnc-enc-tight.c | 8 | ||||
| -rw-r--r-- | ui/vnc.c | 61 |
4 files changed, 135 insertions, 35 deletions
diff --git a/ui/console.c b/ui/console.c index 75ec3afcf7..2ce55a69d0 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1109,6 +1109,39 @@ void kbd_put_keysym_console(QemuConsole *s, int keysym) } } +static const int qcode_to_keysym[Q_KEY_CODE_MAX] = { + [Q_KEY_CODE_UP] = QEMU_KEY_UP, + [Q_KEY_CODE_DOWN] = QEMU_KEY_DOWN, + [Q_KEY_CODE_RIGHT] = QEMU_KEY_RIGHT, + [Q_KEY_CODE_LEFT] = QEMU_KEY_LEFT, + [Q_KEY_CODE_HOME] = QEMU_KEY_HOME, + [Q_KEY_CODE_END] = QEMU_KEY_END, + [Q_KEY_CODE_PGUP] = QEMU_KEY_PAGEUP, + [Q_KEY_CODE_PGDN] = QEMU_KEY_PAGEDOWN, + [Q_KEY_CODE_DELETE] = QEMU_KEY_DELETE, +}; + +bool kbd_put_qcode_console(QemuConsole *s, int qcode) +{ + int keysym; + + keysym = qcode_to_keysym[qcode]; + if (keysym == 0) { + return false; + } + kbd_put_keysym_console(s, keysym); + return true; +} + +void kbd_put_string_console(QemuConsole *s, const char *str, int len) +{ + int i; + + for (i = 0; i < len && str[i]; i++) { + kbd_put_keysym_console(s, str[i]); + } +} + void kbd_put_keysym(int keysym) { kbd_put_keysym_console(active_console, keysym); diff --git a/ui/sdl2.c b/ui/sdl2.c index 0e884f96fd..fcac87b4be 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -49,6 +49,7 @@ static struct sdl2_state { int idx; int last_vm_running; /* per console for caption reasons */ int x, y; + int hidden; } *sdl2_console; static SDL_Surface *guest_sprite_surface; @@ -136,6 +137,9 @@ static void do_sdl_resize(struct sdl2_state *scon, int width, int height, } else { flags |= SDL_WINDOW_RESIZABLE; } + if (scon->hidden) { + flags |= SDL_WINDOW_HIDDEN; + } scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -210,6 +214,23 @@ static void sdl_process_key(struct sdl2_state *scon, 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: @@ -305,6 +326,11 @@ static void sdl_show_cursor(void) static void sdl_grab_start(struct sdl2_state *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 @@ -458,7 +484,7 @@ static void toggle_full_screen(struct sdl2_state *scon) static void handle_keydown(SDL_Event *ev) { - int mod_state; + int mod_state, win; struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); if (alt_grab) { @@ -473,6 +499,27 @@ static void handle_keydown(SDL_Event *ev) if (gui_key_modifier_pressed) { switch (ev->key.keysym.scancode) { + case SDL_SCANCODE_2: + case SDL_SCANCODE_3: + case SDL_SCANCODE_4: + case SDL_SCANCODE_5: + case SDL_SCANCODE_6: + case SDL_SCANCODE_7: + case SDL_SCANCODE_8: + case SDL_SCANCODE_9: + win = ev->key.keysym.scancode - SDL_SCANCODE_1; + if (win < sdl2_num_outputs) { + sdl2_console[win].hidden = !sdl2_console[win].hidden; + if (sdl2_console[win].real_window) { + if (sdl2_console[win].hidden) { + SDL_HideWindow(sdl2_console[win].real_window); + } else { + SDL_ShowWindow(sdl2_console[win].real_window); + } + } + gui_keysym = 1; + } + break; case SDL_SCANCODE_F: toggle_full_screen(scon); gui_keysym = 1; @@ -544,6 +591,17 @@ static void handle_keyup(SDL_Event *ev) } } +static void handle_textinput(SDL_Event *ev) +{ + struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + QemuConsole *con = scon ? scon->dcl.con : NULL; + + if (qemu_console_is_graphic(con)) { + return; + } + kbd_put_string_console(con, ev->text.text, strlen(ev->text.text)); +} + static void handle_mousemotion(SDL_Event *ev) { int max_x, max_y; @@ -680,6 +738,9 @@ static void sdl_refresh(DisplayChangeListener *dcl) case SDL_KEYUP: handle_keyup(ev); break; + case SDL_TEXTINPUT: + handle_textinput(ev); + break; case SDL_QUIT: if (!no_quit) { no_shutdown = 0; @@ -808,7 +869,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) for (i = 0;; i++) { QemuConsole *con = qemu_console_lookup_by_index(i); - if (!con || !qemu_console_is_graphic(con)) { + if (!con) { break; } } @@ -816,6 +877,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) sdl2_console = g_new0(struct sdl2_state, sdl2_num_outputs); for (i = 0; i < sdl2_num_outputs; i++) { QemuConsole *con = qemu_console_lookup_by_index(i); + if (!qemu_console_is_graphic(con)) { + sdl2_console[i].hidden = true; + } sdl2_console[i].dcl.ops = &dcl_ops; sdl2_console[i].dcl.con = con; register_displaychangelistener(&sdl2_console[i].dcl); diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 59b59c0c79..f02352cc46 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -181,6 +181,10 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) } } + if (pixels == 0) { + return 0; + } + /* 95% smooth or more ... */ if (stats[0] * 33 / pixels >= 95) { return 0; @@ -267,7 +271,9 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) y += w; \ } \ } \ - \ + if (pixels == 0) { \ + return 0; \ + } \ if ((stats[0] + stats[1]) * 100 / pixels >= 90) { \ return 0; \ } \ diff --git a/ui/vnc.c b/ui/vnc.c index 2d7def9aa2..61b1f933bf 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -26,6 +26,7 @@ #include "vnc.h" #include "vnc-jobs.h" +#include "trace.h" #include "sysemu/sysemu.h" #include "qemu/sockets.h" #include "qemu/timer.h" @@ -1597,6 +1598,10 @@ static void kbd_leds(void *opaque, int ledstate) int caps, num, scr; bool has_changed = (ledstate != current_led_state(vs)); + trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED), + (ledstate & QEMU_NUM_LOCK_LED), + (ledstate & QEMU_SCROLL_LOCK_LED)); + caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0; num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0; scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0; @@ -1659,11 +1664,13 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) */ if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) { if (!vs->modifiers_state[0x45]) { + trace_vnc_key_sync_numlock(true); vs->modifiers_state[0x45] = 1; press_key(vs, 0xff7f); } } else { if (vs->modifiers_state[0x45]) { + trace_vnc_key_sync_numlock(false); vs->modifiers_state[0x45] = 0; press_key(vs, 0xff7f); } @@ -1682,11 +1689,13 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) int capslock = !!(vs->modifiers_state[0x3a]); if (capslock) { if (uppercase == shift) { + trace_vnc_key_sync_capslock(false); vs->modifiers_state[0x3a] = 0; press_key(vs, 0xffe5); } } else { if (uppercase != shift) { + trace_vnc_key_sync_capslock(true); vs->modifiers_state[0x3a] = 1; press_key(vs, 0xffe5); } @@ -1819,6 +1828,11 @@ static void vnc_release_modifiers(VncState *vs) } } +static const char *code2name(int keycode) +{ + return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)]; +} + static void key_event(VncState *vs, int down, uint32_t sym) { int keycode; @@ -1829,6 +1843,7 @@ static void key_event(VncState *vs, int down, uint32_t sym) } keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK; + trace_vnc_key_event_map(down, sym, keycode, code2name(keycode)); do_key_event(vs, down, keycode, sym); } @@ -1836,10 +1851,12 @@ static void ext_key_event(VncState *vs, int down, uint32_t sym, uint16_t keycode) { /* if the user specifies a keyboard layout, always use it */ - if (keyboard_layout) + if (keyboard_layout) { key_event(vs, down, sym); - else + } else { + trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode)); do_key_event(vs, down, keycode, sym); + } } static void framebuffer_update_request(VncState *vs, int incremental, @@ -2929,10 +2946,12 @@ void vnc_display_init(DisplayState *ds) QTAILQ_INIT(&vs->clients); vs->expires = TIME_MAX; - if (keyboard_layout) + if (keyboard_layout) { + trace_vnc_key_map_init(keyboard_layout); vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout); - else + } else { vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us"); + } if (!vs->kbd_layout) exit(1); @@ -2976,26 +2995,6 @@ static void vnc_display_close(DisplayState *ds) #endif } -static int vnc_display_disable_login(DisplayState *ds) -{ - VncDisplay *vs = vnc_display; - - if (!vs) { - return -1; - } - - if (vs->password) { - g_free(vs->password); - } - - vs->password = NULL; - if (vs->auth == VNC_AUTH_NONE) { - vs->auth = VNC_AUTH_VNC; - } - - return 0; -} - int vnc_display_password(DisplayState *ds, const char *password) { VncDisplay *vs = vnc_display; @@ -3003,20 +3002,18 @@ int vnc_display_password(DisplayState *ds, const char *password) if (!vs) { return -EINVAL; } - - if (!password) { - /* This is not the intention of this interface but err on the side - of being safe */ - return vnc_display_disable_login(ds); + if (vs->auth == VNC_AUTH_NONE) { + error_printf_unless_qmp("If you want use passwords please enable " + "password auth using '-vnc ${dpy},password'."); + return -EINVAL; } if (vs->password) { g_free(vs->password); vs->password = NULL; } - vs->password = g_strdup(password); - if (vs->auth == VNC_AUTH_NONE) { - vs->auth = VNC_AUTH_VNC; + if (password) { + vs->password = g_strdup(password); } return 0; |