diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-01-31 18:41:33 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-01-31 18:41:33 +0000 |
commit | 6fe791b5e3aca8a6de8a322e85e76d2f13338a7e (patch) | |
tree | 8a0f77286af93af73c645ecef5443724fa6b35e8 | |
parent | a0def594286d9110a6035e02eef558cf3cf5d847 (diff) | |
parent | 3ef0c573d37b117867352a8bd8c567d3b774fe37 (diff) | |
download | qemu-6fe791b5e3aca8a6de8a322e85e76d2f13338a7e.zip qemu-6fe791b5e3aca8a6de8a322e85e76d2f13338a7e.tar.gz qemu-6fe791b5e3aca8a6de8a322e85e76d2f13338a7e.tar.bz2 |
Merge remote-tracking branch 'remotes/kraxel/tags/pull-ui-20170131-2' into staging
ui: bugfixes and small improvements all over the place.
# gpg: Signature made Tue 31 Jan 2017 15:48:20 GMT
# gpg: using RSA key 0x4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138
* remotes/kraxel/tags/pull-ui-20170131-2:
console: fix console resize
gtk: Hardcode LC_CTYPE as C.utf-8
vnc: fix overflow in vnc_update_stats
spice: wakeup QXL worker to pick up mouse changes
ui/gtk.c: add ctrl-alt-= support for zoom in acceleration
ui: fix format specfier in vnc to avoid break in build.
ui/gtk: Fix mouse wheel on 3.4.0 or later
vnc: track LED state separately
ui: add support for mice with extra/side buttons
ps2: add support for mice with extra/side buttons
qapi: add support for mice with extra/side buttons
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/input/ps2.c | 8 | ||||
-rw-r--r-- | include/hw/input/ps2.h | 6 | ||||
-rw-r--r-- | qapi-schema.json | 7 | ||||
-rw-r--r-- | ui/console.c | 2 | ||||
-rw-r--r-- | ui/gtk.c | 32 | ||||
-rw-r--r-- | ui/input-linux.c | 6 | ||||
-rw-r--r-- | ui/spice-display.c | 2 | ||||
-rw-r--r-- | ui/vnc.c | 67 | ||||
-rw-r--r-- | ui/vnc.h | 3 |
9 files changed, 80 insertions, 53 deletions
diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 8485a4e..1d3a440 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -881,9 +881,11 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { static const int bmap[INPUT_BUTTON__MAX] = { - [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, - [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, - [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, + [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT, + [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE, + [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT, + [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE, + [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA, }; PS2MouseState *s = (PS2MouseState *)dev; InputMoveEvent *move; diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h index b9ceee4..0fec91c 100644 --- a/include/hw/input/ps2.h +++ b/include/hw/input/ps2.h @@ -25,6 +25,12 @@ #ifndef HW_PS2_H #define HW_PS2_H +#define PS2_MOUSE_BUTTON_LEFT 0x01 +#define PS2_MOUSE_BUTTON_MIDDLE 0x02 +#define PS2_MOUSE_BUTTON_RIGHT 0x04 +#define PS2_MOUSE_BUTTON_SIDE 0x08 +#define PS2_MOUSE_BUTTON_EXTRA 0x10 + /* ps2.c */ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg); diff --git a/qapi-schema.json b/qapi-schema.json index 82fabc6..cbdffdd 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -5390,10 +5390,15 @@ # # Button of a pointer input device (mouse, tablet). # +# @side: front side button of a 5-button mouse (since 2.9) +# +# @extra: rear side button of a 5-button mouse (since 2.9) +# # Since: 2.0 ## { 'enum' : 'InputButton', - 'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down' ] } + 'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side', + 'extra' ] } ## # @InputAxis: diff --git a/ui/console.c b/ui/console.c index fe03a66..e353c85 100644 --- a/ui/console.c +++ b/ui/console.c @@ -2116,7 +2116,7 @@ void qemu_console_resize(QemuConsole *s, int width, int height) assert(s->console_type == GRAPHIC_CONSOLE); - if (s->surface && + if (s->surface && (s->surface->flags & QEMU_ALLOCATED_FLAG) && pixman_image_get_width(s->surface->image) == width && pixman_image_get_height(s->surface->image) == height) { return; @@ -105,6 +105,7 @@ #define GDK_KEY_g GDK_g #define GDK_KEY_q GDK_q #define GDK_KEY_plus GDK_plus +#define GDK_KEY_equal GDK_equal #define GDK_KEY_minus GDK_minus #define GDK_KEY_Pause GDK_Pause #define GDK_KEY_Delete GDK_Delete @@ -1007,6 +1008,10 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button, btn = INPUT_BUTTON_MIDDLE; } else if (button->button == 3) { btn = INPUT_BUTTON_RIGHT; + } else if (button->button == 8) { + btn = INPUT_BUTTON_SIDE; + } else if (button->button == 9) { + btn = INPUT_BUTTON_EXTRA; } else { return TRUE; } @@ -1027,6 +1032,19 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll, btn = INPUT_BUTTON_WHEEL_UP; } else if (scroll->direction == GDK_SCROLL_DOWN) { btn = INPUT_BUTTON_WHEEL_DOWN; +#if GTK_CHECK_VERSION(3, 4, 0) + } else if (scroll->direction == GDK_SCROLL_SMOOTH) { + gdouble delta_x, delta_y; + if (!gdk_event_get_scroll_deltas((GdkEvent *)scroll, + &delta_x, &delta_y)) { + return TRUE; + } + if (delta_y > 0) { + btn = INPUT_BUTTON_WHEEL_DOWN; + } else { + btn = INPUT_BUTTON_WHEEL_UP; + } +#endif } else { return TRUE; } @@ -1325,6 +1343,12 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque) gd_update_windowsize(vc); } +static void gd_accel_zoom_in(void *opaque) +{ + GtkDisplayState *s = opaque; + gtk_menu_item_activate(GTK_MENU_ITEM(s->zoom_in_item)); +} + static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque) { GtkDisplayState *s = opaque; @@ -2092,6 +2116,8 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s) "<QEMU>/View/Zoom In"); gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_plus, HOTKEY_MODIFIERS); + gtk_accel_group_connect(s->accel_group, GDK_KEY_equal, HOTKEY_MODIFIERS, 0, + g_cclosure_new_swap(G_CALLBACK(gd_accel_zoom_in), s, NULL)); gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_in_item); s->zoom_out_item = gtk_menu_item_new_with_mnemonic(_("Zoom _Out")); @@ -2232,8 +2258,12 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover) s->free_scale = FALSE; - /* LC_MESSAGES only. See early_gtk_display_init() for details */ + /* Mostly LC_MESSAGES only. See early_gtk_display_init() for details. For + * LC_CTYPE, we need to make sure that non-ASCII characters are considered + * printable, but without changing any of the character classes to make + * sure that we don't accidentally break implicit assumptions. */ setlocale(LC_MESSAGES, ""); + setlocale(LC_CTYPE, "C.UTF-8"); bindtextdomain("qemu", CONFIG_QEMU_LOCALEDIR); textdomain("qemu"); diff --git a/ui/input-linux.c b/ui/input-linux.c index f345317..ac31f47 100644 --- a/ui/input-linux.c +++ b/ui/input-linux.c @@ -291,6 +291,12 @@ static void input_linux_handle_mouse(InputLinux *il, struct input_event *event) qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN, event->value); break; + case BTN_SIDE: + qemu_input_queue_btn(NULL, INPUT_BUTTON_SIDE, event->value); + break; + case BTN_EXTRA: + qemu_input_queue_btn(NULL, INPUT_BUTTON_EXTRA, event->value); + break; }; break; case EV_REL: diff --git a/ui/spice-display.c b/ui/spice-display.c index 5e6f78a..64e472e 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -769,6 +769,7 @@ static void display_mouse_set(DisplayChangeListener *dcl, g_free(ssd->ptr_move); ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL, on); qemu_mutex_unlock(&ssd->lock); + qemu_spice_wakeup(ssd); } static void display_mouse_define(DisplayChangeListener *dcl, @@ -787,6 +788,7 @@ static void display_mouse_define(DisplayChangeListener *dcl, g_free(ssd->ptr_define); ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0); qemu_mutex_unlock(&ssd->lock); + qemu_spice_wakeup(ssd); } static const DisplayChangeListenerOps display_listener_ops = { @@ -1231,8 +1231,6 @@ void vnc_disconnect_finish(VncState *vs) vnc_update_server_surface(vs->vd); } - if (vs->vd->lock_key_sync) - qemu_remove_led_event_handler(vs->led); vnc_unlock_output(vs); qemu_mutex_destroy(&vs->output_mutex); @@ -1259,7 +1257,7 @@ ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp) if (ret == 0) { VNC_DEBUG("Closing down client sock: EOF\n"); } else if (ret != QIO_CHANNEL_ERR_BLOCK) { - VNC_DEBUG("Closing down client sock: ret %d (%s)\n", + VNC_DEBUG("Closing down client sock: ret %zd (%s)\n", ret, errp ? error_get_pretty(*errp) : "Unknown"); } @@ -1665,69 +1663,39 @@ static void press_key(VncState *vs, int keysym) qemu_input_event_send_key_delay(vs->vd->key_delay_ms); } -static int current_led_state(VncState *vs) -{ - int ledstate = 0; - - if (vs->modifiers_state[0x46]) { - ledstate |= QEMU_SCROLL_LOCK_LED; - } - if (vs->modifiers_state[0x45]) { - ledstate |= QEMU_NUM_LOCK_LED; - } - if (vs->modifiers_state[0x3a]) { - ledstate |= QEMU_CAPS_LOCK_LED; - } - - return ledstate; -} - static void vnc_led_state_change(VncState *vs) { - int ledstate = 0; - if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) { return; } - ledstate = current_led_state(vs); vnc_lock_output(vs); vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); vnc_write_u8(vs, 0); vnc_write_u16(vs, 1); vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE); - vnc_write_u8(vs, ledstate); + vnc_write_u8(vs, vs->vd->ledstate); vnc_unlock_output(vs); vnc_flush(vs); } static void kbd_leds(void *opaque, int ledstate) { - VncState *vs = opaque; - int caps, num, scr; - bool has_changed = (ledstate != current_led_state(vs)); + VncDisplay *vd = opaque; + VncState *client; 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; - - if (vs->modifiers_state[0x3a] != caps) { - vs->modifiers_state[0x3a] = caps; - } - if (vs->modifiers_state[0x45] != num) { - vs->modifiers_state[0x45] = num; - } - if (vs->modifiers_state[0x46] != scr) { - vs->modifiers_state[0x46] = scr; + if (ledstate == vd->ledstate) { + return; } - /* Sending the current led state message to the client */ - if (has_changed) { - vnc_led_state_change(vs); + vd->ledstate = ledstate; + + QTAILQ_FOREACH(client, &vd->clients, next) { + vnc_led_state_change(client); } } @@ -2756,8 +2724,10 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) static int vnc_update_stats(VncDisplay *vd, struct timeval * tv) { - int width = pixman_image_get_width(vd->guest.fb); - int height = pixman_image_get_height(vd->guest.fb); + int width = MIN(pixman_image_get_width(vd->guest.fb), + pixman_image_get_width(vd->server)); + int height = MIN(pixman_image_get_height(vd->guest.fb), + pixman_image_get_height(vd->server)); int x, y; struct timeval res; int has_dirty = 0; @@ -3087,8 +3057,6 @@ void vnc_start_protocol(VncState *vs) vnc_write(vs, "RFB 003.008\n", 12); vnc_flush(vs); vnc_read_when(vs, protocol_version, 12); - if (vs->vd->lock_key_sync) - vs->led = qemu_add_led_event_handler(kbd_leds, vs); vs->mouse_mode_notifier.notify = check_pointer_type_change; qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier); @@ -3195,6 +3163,9 @@ static void vnc_display_close(VncDisplay *vd) } g_free(vd->tlsaclname); vd->tlsaclname = NULL; + if (vd->lock_key_sync) { + qemu_remove_led_event_handler(vd->led); + } } int vnc_display_password(const char *id, const char *password) @@ -3762,6 +3733,10 @@ void vnc_display_open(const char *id, Error **errp) } #endif vd->lock_key_sync = lock_key_sync; + if (lock_key_sync) { + vd->led = qemu_add_led_event_handler(kbd_leds, vd); + } + vd->ledstate = 0; vd->key_delay_ms = key_delay_ms; device_id = qemu_opt_get(opts, "display"); @@ -154,6 +154,8 @@ struct VncDisplay DisplayChangeListener dcl; kbd_layout_t *kbd_layout; int lock_key_sync; + QEMUPutLEDEntry *led; + int ledstate; int key_delay_ms; QemuMutex mutex; @@ -304,7 +306,6 @@ struct VncState size_t read_handler_expect; /* input */ uint8_t modifiers_state[256]; - QEMUPutLEDEntry *led; bool abort; QemuMutex output_mutex; |