diff options
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | docs/specs/standard-vga.txt | 13 | ||||
-rw-r--r-- | hw/audio/hda-codec.c | 3 | ||||
-rw-r--r-- | hw/display/cirrus_vga.c | 4 | ||||
-rw-r--r-- | hw/display/qxl.c | 2 | ||||
-rw-r--r-- | hw/display/vga-isa-mm.c | 2 | ||||
-rw-r--r-- | hw/display/vga-isa.c | 2 | ||||
-rw-r--r-- | hw/display/vga-pci.c | 63 | ||||
-rw-r--r-- | hw/display/vga.c | 8 | ||||
-rw-r--r-- | hw/display/vga_int.h | 2 | ||||
-rw-r--r-- | hw/display/vmware_vga.c | 2 | ||||
-rw-r--r-- | tests/Makefile | 5 | ||||
-rw-r--r-- | tests/display-vga-test.c | 52 | ||||
-rw-r--r-- | ui/gtk.c | 88 | ||||
-rw-r--r-- | ui/sdl2.c | 51 |
15 files changed, 204 insertions, 96 deletions
@@ -1233,6 +1233,7 @@ Advanced options (experts only): --with-sdlabi select preferred SDL ABI 1.2 or 2.0 --disable-gtk disable gtk UI --enable-gtk enable gtk UI + --with-gtkabi select preferred GTK ABI 2.0 or 3.0 --disable-virtfs disable VirtFS --enable-virtfs enable VirtFS --disable-vnc disable VNC @@ -4349,6 +4350,7 @@ if test "$modules" = "yes"; then fi if test "$sdl" = "yes" ; then echo "CONFIG_SDL=y" >> $config_host_mak + echo "CONFIG_SDLABI=$sdlabi" >> $config_host_mak echo "SDL_CFLAGS=$sdl_cflags" >> $config_host_mak fi if test "$cocoa" = "yes" ; then @@ -4432,6 +4434,7 @@ fi echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak if test "$gtk" = "yes" ; then echo "CONFIG_GTK=y" >> $config_host_mak + echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak fi if test "$vte" = "yes" ; then diff --git a/docs/specs/standard-vga.txt b/docs/specs/standard-vga.txt index 8a4c1e93cd..f82773e677 100644 --- a/docs/specs/standard-vga.txt +++ b/docs/specs/standard-vga.txt @@ -5,9 +5,10 @@ QEMU Standard VGA Exists in two variants, for isa and pci. command line switches: - -vga std [ picks isa for -M isapc, otherwise pci ] - -device VGA [ pci variant ] - -device isa-vga [ isa variant ] + -vga std [ picks isa for -M isapc, otherwise pci ] + -device VGA [ pci variant ] + -device isa-vga [ isa variant ] + -device secondary-vga [ legacy-free pci variant ] PCI spec @@ -31,9 +32,15 @@ PCI ROM Region: Holds the vgabios (qemu 0.14+). +The legacy-free variant has no ROM and has PCI_CLASS_DISPLAY_OTHER +instead of PCI_CLASS_DISPLAY_VGA. + + IO ports used ------------- +Doesn't apply to the legacy-free pci variant, use the MMIO bar instead. + 03c0 - 03df : standard vga ports 01ce : bochs vbe interface index port 01cf : bochs vbe interface data port (x86 only) diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index a67ca91ca7..48c6eadb03 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -261,6 +261,9 @@ static void hda_audio_set_amp(HDAAudioStream *st) left = left * 255 / QEMU_HDA_AMP_STEPS; right = right * 255 / QEMU_HDA_AMP_STEPS; + if (!st->state->mixer) { + return; + } if (st->output) { AUD_set_volume_out(st->voice.out, muted, left, right); } else { diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 0d3127da21..d1afc765fb 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2913,7 +2913,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev); VGACommonState *s = &d->cirrus_vga.vga; - vga_common_init(s, OBJECT(dev)); + vga_common_init(s, OBJECT(dev), true); cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, isa_address_space(isadev), isa_address_space_io(isadev)); @@ -2960,7 +2960,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) int16_t device_id = pc->device_id; /* setup VGA */ - vga_common_init(&s->vga, OBJECT(dev)); + vga_common_init(&s->vga, OBJECT(dev), true); cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev), pci_address_space_io(dev)); s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s->vga); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 47bbf1f1fe..e9c54d7399 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2061,7 +2061,7 @@ static int qxl_init_primary(PCIDevice *dev) qxl->id = 0; qxl_init_ramsize(qxl); vga->vram_size_mb = qxl->vga.vram_size >> 20; - vga_common_init(vga, OBJECT(dev)); + vga_common_init(vga, OBJECT(dev), true); vga_init(vga, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), false); portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c index afc46b8c9d..4efc222789 100644 --- a/hw/display/vga-isa-mm.c +++ b/hw/display/vga-isa-mm.c @@ -132,7 +132,7 @@ int isa_vga_mm_init(hwaddr vram_base, s = g_malloc0(sizeof(*s)); s->vga.vram_size_mb = VGA_RAM_SIZE >> 20; - vga_common_init(&s->vga, NULL); + vga_common_init(&s->vga, NULL, true); vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space); s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s); diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 1d9ea6b51d..2b480bd44d 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -56,7 +56,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) MemoryRegion *vga_io_memory; const MemoryRegionPortio *vga_ports, *vbe_ports; - vga_common_init(s, OBJECT(dev)); + vga_common_init(s, OBJECT(dev), true); s->legacy_address_space = isa_address_space(isadev); vga_io_memory = vga_init_io(s, OBJECT(dev), &vga_ports, &vbe_ports); isa_register_portio_list(isadev, 0x3b0, vga_ports, s, "vga"); diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 574ea0e7f9..0865dc490e 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -147,7 +147,7 @@ static int pci_std_vga_initfn(PCIDevice *dev) VGACommonState *s = &d->vga; /* vga + console init */ - vga_common_init(s, OBJECT(dev)); + vga_common_init(s, OBJECT(dev), true); vga_init(s, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), true); @@ -179,12 +179,51 @@ static int pci_std_vga_initfn(PCIDevice *dev) return 0; } +static int pci_secondary_vga_initfn(PCIDevice *dev) +{ + PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev); + VGACommonState *s = &d->vga; + + /* vga + console init */ + vga_common_init(s, OBJECT(dev), false); + s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s); + + /* mmio bar */ + memory_region_init(&d->mmio, OBJECT(dev), "vga.mmio", 4096); + memory_region_init_io(&d->ioport, OBJECT(dev), &pci_vga_ioport_ops, d, + "vga ioports remapped", PCI_VGA_IOPORT_SIZE); + memory_region_init_io(&d->bochs, OBJECT(dev), &pci_vga_bochs_ops, d, + "bochs dispi interface", PCI_VGA_BOCHS_SIZE); + + memory_region_add_subregion(&d->mmio, PCI_VGA_IOPORT_OFFSET, + &d->ioport); + memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET, + &d->bochs); + + pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); + pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); + + return 0; +} + +static void pci_secondary_vga_reset(DeviceState *dev) +{ + PCIVGAState *d = DO_UPCAST(PCIVGAState, dev.qdev, dev); + + vga_common_reset(&d->vga); +} + static Property vga_pci_properties[] = { DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16), DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true), DEFINE_PROP_END_OF_LIST(), }; +static Property secondary_pci_properties[] = { + DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16), + DEFINE_PROP_END_OF_LIST(), +}; + static void vga_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -201,6 +240,20 @@ static void vga_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); } +static void secondary_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = pci_secondary_vga_initfn; + k->vendor_id = PCI_VENDOR_ID_QEMU; + k->device_id = PCI_DEVICE_ID_QEMU_VGA; + k->class_id = PCI_CLASS_DISPLAY_OTHER; + dc->vmsd = &vmstate_vga_pci; + dc->props = secondary_pci_properties; + dc->reset = pci_secondary_vga_reset; +} + static const TypeInfo vga_info = { .name = "VGA", .parent = TYPE_PCI_DEVICE, @@ -208,9 +261,17 @@ static const TypeInfo vga_info = { .class_init = vga_class_init, }; +static const TypeInfo secondary_info = { + .name = "secondary-vga", + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCIVGAState), + .class_init = secondary_class_init, +}; + static void vga_register_types(void) { type_register_static(&vga_info); + type_register_static(&secondary_info); } type_init(vga_register_types) diff --git a/hw/display/vga.c b/hw/display/vga.c index 063319d34d..c4c3238d5f 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -171,6 +171,10 @@ static void vga_update_memory_access(VGACommonState *s) MemoryRegion *region, *old_region = s->chain4_alias; hwaddr base, offset, size; + if (s->legacy_address_space == NULL) { + return; + } + s->chain4_alias = NULL; if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) == @@ -2252,7 +2256,7 @@ static const GraphicHwOps vga_ops = { .text_update = vga_update_text, }; -void vga_common_init(VGACommonState *s, Object *obj) +void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) { int i, j, v, b; @@ -2289,7 +2293,7 @@ void vga_common_init(VGACommonState *s, Object *obj) s->is_vbe_vmstate = 1; memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size); - vmstate_register_ram_global(&s->vram); + vmstate_register_ram(&s->vram, global_vmstate ? NULL : DEVICE(obj)); xen_register_framebuffer(&s->vram); s->vram_ptr = memory_region_get_ram_ptr(&s->vram); s->get_bpp = vga_get_bpp; diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index e6418906a7..d42ac926e3 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -177,7 +177,7 @@ static inline int c6_to_8(int v) return (v << 2) | (b << 1) | b; } -void vga_common_init(VGACommonState *s, Object *obj); +void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate); void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, MemoryRegion *address_space_io, bool init_vga_ports); MemoryRegion *vga_init_io(VGACommonState *s, Object *obj, diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 6ae3348deb..9ba47e6c63 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -1207,7 +1207,7 @@ static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s, vmstate_register_ram_global(&s->fifo_ram); s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); - vga_common_init(&s->vga, OBJECT(dev)); + vga_common_init(&s->vga, OBJECT(dev), true); vga_init(&s->vga, OBJECT(dev), address_space, io, true); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); s->new_depth = 32; diff --git a/tests/Makefile b/tests/Makefile index 88f7105d02..c6b661472b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -113,6 +113,10 @@ check-qtest-pci-y += tests/tpci200-test$(EXESUF) gcov-files-pci-y += hw/ipack/tpci200.c check-qtest-pci-y += $(check-qtest-ipack-y) gcov-files-pci-y += $(gcov-files-ipack-y) +check-qtest-pci-y += tests/display-vga-test$(EXESUF) +gcov-files-pci-y += hw/display/vga.c +gcov-files-pci-y += hw/display/cirrus_vga.c +gcov-files-pci-y += hw/display/vga-pci.c check-qtest-i386-y = tests/endianness-test$(EXESUF) check-qtest-i386-y += tests/fdc-test$(EXESUF) @@ -280,6 +284,7 @@ tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o tests/tpci200-test$(EXESUF): tests/tpci200-test.o +tests/display-vga-test$(EXESUF): tests/display-vga-test.o tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o tests/qom-test$(EXESUF): tests/qom-test.o tests/blockdev-test$(EXESUF): tests/blockdev-test.o $(libqos-pc-obj-y) diff --git a/tests/display-vga-test.c b/tests/display-vga-test.c new file mode 100644 index 0000000000..17f59101e8 --- /dev/null +++ b/tests/display-vga-test.c @@ -0,0 +1,52 @@ +/* + * QTest testcase for vga cards + * + * Copyright (c) 2014 Red Hat, Inc + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include <glib.h> +#include <string.h> +#include "libqtest.h" +#include "qemu/osdep.h" + +static void pci_cirrus(void) +{ + qtest_start("-vga none -device cirrus-vga"); + qtest_end(); +} + +static void pci_stdvga(void) +{ + qtest_start("-vga none -device VGA"); + qtest_end(); +} + +static void pci_secondary(void) +{ + qtest_start("-vga none -device secondary-vga"); + qtest_end(); +} + +static void pci_multihead(void) +{ + qtest_start("-vga none -device VGA -device secondary-vga"); + qtest_end(); +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/display/pci/cirrus", pci_cirrus); + qtest_add_func("/display/pci/stdvga", pci_stdvga); + qtest_add_func("/display/pci/secondary", pci_secondary); + qtest_add_func("/display/pci/multihead", pci_multihead); + ret = g_test_run(); + + return ret; +} @@ -93,13 +93,12 @@ static inline void gdk_drawable_get_size(GdkWindow *w, gint *ww, gint *wh) #define GDK_KEY_2 GDK_2 #define GDK_KEY_f GDK_f #define GDK_KEY_g GDK_g +#define GDK_KEY_q GDK_q #define GDK_KEY_plus GDK_plus #define GDK_KEY_minus GDK_minus #endif #define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK) -#define IGNORE_MODIFIER_MASK \ - (GDK_MODIFIER_MASK & ~(GDK_LOCK_MASK | GDK_MOD2_MASK)) static const int modifier_keycode[] = { /* shift, control, alt keys, meta keys, both left & right */ @@ -114,7 +113,6 @@ typedef struct VirtualConsole GtkWidget *scrolled_window; CharDriverState *chr; #endif - int fd; } VirtualConsole; typedef struct GtkDisplayState @@ -489,24 +487,6 @@ static void gd_mouse_mode_change(Notifier *notify, void *data) /** GTK Events **/ -static gboolean gd_window_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque) -{ - GtkDisplayState *s = opaque; - gboolean handled = FALSE; - - if (!gd_is_grab_active(s) || - (key->state & IGNORE_MODIFIER_MASK) == HOTKEY_MODIFIERS) { - handled = gtk_window_activate_key(GTK_WINDOW(widget), key); - } - if (handled) { - gtk_release_modifiers(s); - } else { - handled = gtk_window_propagate_key_event(GTK_WINDOW(widget), key); - } - - return handled; -} - static gboolean gd_window_close(GtkWidget *widget, GdkEvent *event, void *opaque) { @@ -1161,9 +1141,12 @@ static gboolean gd_focus_out_event(GtkWidget *widget, static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { +#if defined(CONFIG_VTE) VirtualConsole *vc = chr->opaque; - return vc ? write(vc->fd, buf, len) : len; + vte_terminal_feed(VTE_TERMINAL(vc->terminal), (const char *)buf, len); +#endif + return len; } static int nb_vcs; @@ -1189,19 +1172,12 @@ void early_gtk_display_init(void) } #if defined(CONFIG_VTE) -static gboolean gd_vc_in(GIOChannel *chan, GIOCondition cond, void *opaque) +static gboolean gd_vc_in(VteTerminal *terminal, gchar *text, guint size, + gpointer user_data) { - VirtualConsole *vc = opaque; - uint8_t buffer[1024]; - ssize_t len; - - len = read(vc->fd, buffer, sizeof(buffer)); - if (len <= 0) { - return FALSE; - } - - qemu_chr_be_write(vc->chr, buffer, len); + VirtualConsole *vc = user_data; + qemu_chr_be_write(vc->chr, (uint8_t *)text, (unsigned int)size); return TRUE; } #endif @@ -1213,13 +1189,8 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL const char *label; char buffer[32]; char path[32]; -#if VTE_CHECK_VERSION(0, 26, 0) - VtePty *pty; -#endif - GIOChannel *chan; GtkWidget *scrolled_window; GtkAdjustment *vadjustment; - int master_fd, slave_fd; snprintf(buffer, sizeof(buffer), "vc%d", index); snprintf(path, sizeof(path), "<QEMU>/View/VC%d", index); @@ -1238,27 +1209,21 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL gtk_accel_map_add_entry(path, GDK_KEY_2 + index, HOTKEY_MODIFIERS); vc->terminal = vte_terminal_new(); - - master_fd = qemu_openpty_raw(&slave_fd, NULL); - g_assert(master_fd != -1); - -#if VTE_CHECK_VERSION(0, 26, 0) - pty = vte_pty_new_foreign(master_fd, NULL); - vte_terminal_set_pty_object(VTE_TERMINAL(vc->terminal), pty); -#else - vte_terminal_set_pty(VTE_TERMINAL(vc->terminal), master_fd); -#endif + g_signal_connect(vc->terminal, "commit", G_CALLBACK(gd_vc_in), vc); vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->terminal), -1); +#if VTE_CHECK_VERSION(0, 28, 0) && GTK_CHECK_VERSION(3, 0, 0) + vadjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vc->terminal)); +#else vadjustment = vte_terminal_get_adjustment(VTE_TERMINAL(vc->terminal)); +#endif scrolled_window = gtk_scrolled_window_new(NULL, vadjustment); gtk_container_add(GTK_CONTAINER(scrolled_window), vc->terminal); vte_terminal_set_size(VTE_TERMINAL(vc->terminal), 80, 25); - vc->fd = slave_fd; vc->chr->opaque = vc; vc->scrolled_window = scrolled_window; @@ -1276,9 +1241,6 @@ static GSList *gd_vc_init(GtkDisplayState *s, VirtualConsole *vc, int index, GSL vc->chr->init(vc->chr); } - chan = g_io_channel_unix_new(vc->fd); - g_io_add_watch(chan, G_IO_IN, gd_vc_in, vc); - #endif /* CONFIG_VTE */ return group; } @@ -1290,8 +1252,6 @@ static void gd_connect_signals(GtkDisplayState *s) g_signal_connect(s->show_tabs_item, "activate", G_CALLBACK(gd_menu_show_tabs), s); - g_signal_connect(s->window, "key-press-event", - G_CALLBACK(gd_window_key_event), s); g_signal_connect(s->window, "delete-event", G_CALLBACK(gd_window_close), s); @@ -1351,7 +1311,6 @@ static GtkWidget *gd_create_menu_machine(GtkDisplayState *s, GtkAccelGroup *acce { GtkWidget *machine_menu; GtkWidget *separator; - GtkStockItem item; machine_menu = gtk_menu_new(); gtk_menu_set_accel_group(GTK_MENU(machine_menu), accel_group); @@ -1362,20 +1321,20 @@ static GtkWidget *gd_create_menu_machine(GtkDisplayState *s, GtkAccelGroup *acce separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), separator); - s->reset_item = gtk_image_menu_item_new_with_mnemonic(_("_Reset")); + s->reset_item = gtk_menu_item_new_with_mnemonic(_("_Reset")); gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->reset_item); - s->powerdown_item = gtk_image_menu_item_new_with_mnemonic(_("Power _Down")); + s->powerdown_item = gtk_menu_item_new_with_mnemonic(_("Power _Down")); gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->powerdown_item); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), separator); - s->quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL); - gtk_stock_lookup(GTK_STOCK_QUIT, &item); + s->quit_item = gtk_menu_item_new_with_mnemonic(_("_Quit")); gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->quit_item), "<QEMU>/Machine/Quit"); - gtk_accel_map_add_entry("<QEMU>/Machine/Quit", item.keyval, item.modifier); + gtk_accel_map_add_entry("<QEMU>/Machine/Quit", + GDK_KEY_q, HOTKEY_MODIFIERS); gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->quit_item); return machine_menu; @@ -1391,8 +1350,7 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s, GtkAccelGroup *accel_g view_menu = gtk_menu_new(); gtk_menu_set_accel_group(GTK_MENU(view_menu), accel_group); - s->full_screen_item = - gtk_image_menu_item_new_from_stock(GTK_STOCK_FULLSCREEN, NULL); + s->full_screen_item = gtk_menu_item_new_with_mnemonic(_("_Fullscreen")); gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->full_screen_item), "<QEMU>/View/Full Screen"); gtk_accel_map_add_entry("<QEMU>/View/Full Screen", GDK_KEY_f, @@ -1402,21 +1360,21 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s, GtkAccelGroup *accel_g separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator); - s->zoom_in_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_IN, NULL); + s->zoom_in_item = gtk_menu_item_new_with_mnemonic(_("Zoom _In")); gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_in_item), "<QEMU>/View/Zoom In"); gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_plus, HOTKEY_MODIFIERS); gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_in_item); - s->zoom_out_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_OUT, NULL); + s->zoom_out_item = gtk_menu_item_new_with_mnemonic(_("Zoom _Out")); gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_out_item), "<QEMU>/View/Zoom Out"); gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus, HOTKEY_MODIFIERS); gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_out_item); - s->zoom_fixed_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_100, NULL); + s->zoom_fixed_item = gtk_menu_item_new_with_mnemonic(_("Best _Fit")); gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_fixed_item), "<QEMU>/View/Zoom Fixed"); gtk_accel_map_add_entry("<QEMU>/View/Zoom Fixed", GDK_KEY_0, @@ -359,16 +359,12 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) } static void sdl_send_mouse_event(struct sdl2_state *scon, int dx, int dy, - int dz, int x, int y, int state) + int x, int y, int state) { static uint32_t bmap[INPUT_BUTTON_MAX] = { [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), -#if 0 - [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), - [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), -#endif }; static uint32_t prev_state; @@ -566,7 +562,7 @@ static void handle_mousemotion(SDL_Event *ev) } } if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { - sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel, 0, + sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel, ev->motion.x, ev->motion.y, ev->motion.state); } } @@ -576,7 +572,6 @@ static void handle_mousebutton(SDL_Event *ev) int buttonstate = SDL_GetMouseState(NULL, NULL); SDL_MouseButtonEvent *bev; struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); - int dz; bev = &ev->button; if (!gui_grab && !qemu_input_is_absolute()) { @@ -585,25 +580,35 @@ static void handle_mousebutton(SDL_Event *ev) sdl_grab_start(scon); } } else { - dz = 0; if (ev->type == SDL_MOUSEBUTTONDOWN) { buttonstate |= SDL_BUTTON(bev->button); } else { buttonstate &= ~SDL_BUTTON(bev->button); } -#ifdef SDL_BUTTON_WHEELUP - if (bev->button == SDL_BUTTON_WHEELUP && - ev->type == SDL_MOUSEBUTTONDOWN) { - dz = -1; - } else if (bev->button == SDL_BUTTON_WHEELDOWN && - ev->type == SDL_MOUSEBUTTONDOWN) { - dz = 1; - } -#endif - sdl_send_mouse_event(scon, 0, 0, dz, bev->x, bev->y, buttonstate); + sdl_send_mouse_event(scon, 0, 0, bev->x, bev->y, buttonstate); } } +static void handle_mousewheel(SDL_Event *ev) +{ + struct sdl2_state *scon = get_scon_from_window(ev->key.windowID); + SDL_MouseWheelEvent *wev = &ev->wheel; + InputButton btn; + + if (wev->y > 0) { + btn = INPUT_BUTTON_WHEEL_UP; + } else if (wev->y < 0) { + btn = INPUT_BUTTON_WHEEL_DOWN; + } else { + return; + } + + qemu_input_queue_btn(scon->dcl.con, btn, true); + qemu_input_event_sync(); + qemu_input_queue_btn(scon->dcl.con, btn, false); + qemu_input_event_sync(); +} + static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) { int w, h; @@ -612,6 +617,13 @@ static void handle_windowevent(DisplayChangeListener *dcl, SDL_Event *ev) switch (ev->window.event) { case SDL_WINDOWEVENT_RESIZED: sdl_scale(scon, ev->window.data1, ev->window.data2); + { + QemuUIInfo info; + memset(&info, 0, sizeof(info)); + info.width = ev->window.data1; + info.height = ev->window.data2; + dpy_set_ui_info(scon->dcl.con, &info); + } graphic_hw_invalidate(scon->dcl.con); graphic_hw_update(scon->dcl.con); break; @@ -678,6 +690,9 @@ static void sdl_refresh(DisplayChangeListener *dcl) case SDL_MOUSEBUTTONUP: handle_mousebutton(ev); break; + case SDL_MOUSEWHEEL: + handle_mousewheel(ev); + break; case SDL_WINDOWEVENT: handle_windowevent(dcl, ev); break; |