aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure3
-rw-r--r--docs/specs/standard-vga.txt13
-rw-r--r--hw/audio/hda-codec.c3
-rw-r--r--hw/display/cirrus_vga.c4
-rw-r--r--hw/display/qxl.c2
-rw-r--r--hw/display/vga-isa-mm.c2
-rw-r--r--hw/display/vga-isa.c2
-rw-r--r--hw/display/vga-pci.c63
-rw-r--r--hw/display/vga.c8
-rw-r--r--hw/display/vga_int.h2
-rw-r--r--hw/display/vmware_vga.c2
-rw-r--r--tests/Makefile5
-rw-r--r--tests/display-vga-test.c52
-rw-r--r--ui/gtk.c88
-rw-r--r--ui/sdl2.c51
15 files changed, 204 insertions, 96 deletions
diff --git a/configure b/configure
index 2fbec59e96..870c939f1d 100755
--- a/configure
+++ b/configure
@@ -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;
+}
diff --git a/ui/gtk.c b/ui/gtk.c
index 00fbbccb34..9f5061a1be 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -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,
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 7506e2e13f..361de619fa 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -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;