aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-11-07 18:59:04 +0800
committerStefan Hajnoczi <stefanha@redhat.com>2023-11-07 18:59:04 +0800
commit7eee58ae3bb15a2bceb368997ce1a48fd3c607e7 (patch)
tree50c2aeacd06094c690b6804fe3c08d3df4a7b9e3
parent3e34860a3a03f969ad0720ec9c12ea10e88738a6 (diff)
parentfb93569e422d4f4b5953dd953c92ba7838309972 (diff)
downloadqemu-7eee58ae3bb15a2bceb368997ce1a48fd3c607e7.zip
qemu-7eee58ae3bb15a2bceb368997ce1a48fd3c607e7.tar.gz
qemu-7eee58ae3bb15a2bceb368997ce1a48fd3c607e7.tar.bz2
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging
UI patch queue # -----BEGIN PGP SIGNATURE----- # # iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmVKA7McHG1hcmNhbmRy # ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5Z47D/4/SrS87f62a8Xczc4U # fj8idH8a9rC/Rbd/AXDDIIgEb3Om4xWI4M5FZrx2K+D38hgc4atRuQhTHPi/SdEK # zlNkKcePNRs7/hh8ZWUnLtu+EqJS3HqmcJfahkzV6U0vn6BxPrdX/5Qdryix4gr3 # C2RRxJx8RdZ5R7V9pm4JTgqGnXkKwDN4W06/btrhz7YNgyXls0PVrHm4lE01HDnX # D0ZxWo3gXAiK1dQlaT5qHsegpPPJ2LB3O6gU3yLDBpsD3elkjgbB5seycgeJmO1R # kMBA+HUf2PS0gdUATs/KqjVyoSbWoIeyOTTb8ol8cQSWruqfSLUnJLP4lFBCKbMt # NH4KqqPvZZuJh4K1ir1/eANC6Du7hotavmV+57Vv73N91IQ0PUEzoUbLL1PN25RZ # +q5chBClAvc9IRbnDSM6EXpxznzAkPYQo8JyRPkHE9w9dFfOIRsAK3WGcVkwMmaQ # 4v4OAM/CQlfqcwpVsmT/prkoaCceJHE6IO7hOkV1QOe+I5yzZF9PJpVsONhhCXUD # XVaoOMeZYmT8lIEPm099MwjmGKKxTroEo+n18xQOV+ZXGdIsmkvrYffqAO5y/hB3 # m8ucVWeoXq50IYPoxxdw86NyadHvSBb6fMNjU2fEtYId+Tm7T0ud77uIY8rU6euc # x7w6wDUm4C2K7fHrtYzBLhUj7A== # =upvZ # -----END PGP SIGNATURE----- # gpg: Signature made Tue 07 Nov 2023 17:30:27 HKT # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: issuer "marcandre.lureau@redhat.com" # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full] # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu: ui: Replacing pointer in function ui/cocoa: add zoom-to-fit display option ui/gtk-egl: apply scale factor when calculating window's dimension ui/gtk-egl: Check EGLSurface before doing scanout ui/gtk: force realization of drawing area Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--qapi/ui.json7
-rw-r--r--ui/cocoa.m32
-rw-r--r--ui/gtk-egl.c31
-rw-r--r--ui/gtk.c12
4 files changed, 55 insertions, 27 deletions
diff --git a/qapi/ui.json b/qapi/ui.json
index 006616a..3718d40 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1409,13 +1409,18 @@
# codes match their position on non-Mac keyboards and you can use
# Meta/Super and Alt where you expect them. (default: off)
#
+# @zoom-to-fit: Zoom guest display to fit into the host window. When
+# turned off the host window will be resized instead. Defaults to
+# "off". (Since 8.2)
+#
# Since: 7.0
##
{ 'struct': 'DisplayCocoa',
'data': {
'*left-command-key': 'bool',
'*full-grab': 'bool',
- '*swap-opt-cmd': 'bool'
+ '*swap-opt-cmd': 'bool',
+ '*zoom-to-fit': 'bool'
} }
##
diff --git a/ui/cocoa.m b/ui/cocoa.m
index d952760..cd069da 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -1247,7 +1247,6 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
[normalWindow makeKeyAndOrderFront:self];
[normalWindow center];
[normalWindow setDelegate: self];
- stretch_video = false;
/* Used for displaying pause on the screen */
pauseLabel = [NSTextField new];
@@ -1671,7 +1670,9 @@ static void create_initial_menus(void)
// View menu
menu = [[NSMenu alloc] initWithTitle:@"View"];
[menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen" action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; // Fullscreen
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease]];
+ menuItem = [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease];
+ [menuItem setState: stretch_video ? NSControlStateValueOn : NSControlStateValueOff];
+ [menu addItem: menuItem];
menuItem = [[[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""] autorelease];
[menuItem setSubmenu:menu];
[[NSApp mainMenu] addItem:menuItem];
@@ -2041,18 +2042,6 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
[QemuApplication sharedApplication];
- create_initial_menus();
-
- /*
- * Create the menu entries which depend on QEMU state (for consoles
- * and removable devices). These make calls back into QEMU functions,
- * which is OK because at this point we know that the second thread
- * holds the iothread lock and is synchronously waiting for us to
- * finish.
- */
- add_console_menu_entries();
- addRemovableDevicesMenuItems();
-
// Create an Application controller
QemuCocoaAppController *controller = [[QemuCocoaAppController alloc] init];
[NSApp setDelegate:controller];
@@ -2077,6 +2066,21 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
left_command_key_enabled = 0;
}
+ if (opts->u.cocoa.has_zoom_to_fit && opts->u.cocoa.zoom_to_fit) {
+ stretch_video = true;
+ }
+
+ create_initial_menus();
+ /*
+ * Create the menu entries which depend on QEMU state (for consoles
+ * and removable devices). These make calls back into QEMU functions,
+ * which is OK because at this point we know that the second thread
+ * holds the iothread lock and is synchronously waiting for us to
+ * finish.
+ */
+ add_console_menu_entries();
+ addRemovableDevicesMenuItems();
+
// register vga output callbacks
register_displaychangelistener(&dcl);
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index a1060fd..cd2f176 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -69,15 +69,16 @@ void gd_egl_draw(VirtualConsole *vc)
#ifdef CONFIG_GBM
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
#endif
- int ww, wh;
+ int ww, wh, ws;
if (!vc->gfx.gls) {
return;
}
window = gtk_widget_get_window(vc->gfx.drawing_area);
- ww = gdk_window_get_width(window);
- wh = gdk_window_get_height(window);
+ ws = gdk_window_get_scale_factor(window);
+ ww = gdk_window_get_width(window) * ws;
+ wh = gdk_window_get_height(window) * ws;
if (vc->gfx.scanout_mode) {
#ifdef CONFIG_GBM
@@ -243,12 +244,19 @@ void gd_egl_scanout_texture(DisplayChangeListener *dcl,
vc->gfx.h = h;
vc->gfx.y0_top = backing_y_0_top;
- eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, vc->gfx.ectx);
+ if (!vc->gfx.esurface) {
+ gd_egl_init(vc);
+ if (!vc->gfx.esurface) {
+ return;
+ }
+
+ eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
+ vc->gfx.esurface, vc->gfx.ectx);
- gtk_egl_set_scanout_mode(vc, true);
- egl_fb_setup_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
- backing_id, false);
+ gtk_egl_set_scanout_mode(vc, true);
+ egl_fb_setup_for_tex(&vc->gfx.guest_fb, backing_width, backing_height,
+ backing_id, false);
+ }
}
void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
@@ -312,7 +320,7 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
GdkWindow *window;
- int ww, wh;
+ int ww, wh, ws;
if (!vc->gfx.scanout_mode) {
return;
@@ -325,8 +333,9 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
vc->gfx.esurface, vc->gfx.ectx);
window = gtk_widget_get_window(vc->gfx.drawing_area);
- ww = gdk_window_get_width(window);
- wh = gdk_window_get_height(window);
+ ws = gdk_window_get_scale_factor(window);
+ ww = gdk_window_get_width(window) * ws;
+ wh = gdk_window_get_height(window) * ws;
egl_fb_setup_default(&vc->gfx.win_fb, ww, wh);
if (vc->gfx.cursor_fb.texture) {
egl_texture_blit(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.guest_fb,
diff --git a/ui/gtk.c b/ui/gtk.c
index 935de12..be047a4 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1400,7 +1400,7 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
eglDestroySurface(qemu_egl_display, vc->gfx.esurface);
vc->gfx.esurface = NULL;
}
- if (vc->gfx.esurface) {
+ if (vc->gfx.ectx) {
eglDestroyContext(qemu_egl_display, vc->gfx.ectx);
vc->gfx.ectx = NULL;
}
@@ -2371,6 +2371,7 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
GdkDisplay *window_display;
GtkIconTheme *theme;
char *dir;
+ int idx;
if (!gtkinit) {
fprintf(stderr, "gtk initialization failed\n");
@@ -2434,6 +2435,15 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
gtk_container_add(GTK_CONTAINER(s->window), s->vbox);
gtk_widget_show_all(s->window);
+
+ for (idx = 0;; idx++) {
+ QemuConsole *con = qemu_console_lookup_by_index(idx);
+ if (!con) {
+ break;
+ }
+ gtk_widget_realize(s->vc[idx].gfx.drawing_area);
+ }
+
if (opts->u.gtk.has_show_menubar &&
!opts->u.gtk.show_menubar) {
gtk_widget_hide(s->menu_bar);