mirror of
https://github.com/qemu/qemu.git
synced 2025-07-30 12:58:51 +00:00
ui/gtk: Add scale option
Allow user to set a preferred scale (defaulting to 1) of the virtual display. Along with zoom-to-fix=false, this would be helpful for users running QEMU on hi-dpi host desktop to achieve pixel to pixel display -- e.g., if the scale factor of a user's host desktop is set to 200%, then they can set a 0.5 scale for the virtual display to avoid magnification that might cause blurriness. Signed-off-by: Weifeng Liu <weifeng.liu.z@gmail.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Tested-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20250601045245.36778-3-weifeng.liu.z@gmail.com>
This commit is contained in:

committed by
Marc-André Lureau

parent
c65680a76c
commit
0ba45b7945
@ -41,6 +41,7 @@ typedef struct VirtualGfxConsole {
|
||||
DisplaySurface *ds;
|
||||
pixman_image_t *convert;
|
||||
cairo_surface_t *surface;
|
||||
double preferred_scale;
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
#if defined(CONFIG_OPENGL)
|
||||
|
@ -1338,6 +1338,8 @@
|
||||
# @keep-aspect-ratio: Keep width/height aspect ratio of guest content when
|
||||
# resizing host window. Defaults to "on". (Since 10.1)
|
||||
#
|
||||
# @scale: Set preferred scale of the display. Defaults to 1.0. (Since 10.1)
|
||||
#
|
||||
# Since: 2.12
|
||||
##
|
||||
{ 'struct' : 'DisplayGTK',
|
||||
@ -1345,7 +1347,8 @@
|
||||
'*zoom-to-fit' : 'bool',
|
||||
'*show-tabs' : 'bool',
|
||||
'*show-menubar' : 'bool',
|
||||
'*keep-aspect-ratio' : 'bool' } }
|
||||
'*keep-aspect-ratio' : 'bool',
|
||||
'*scale' : 'number' } }
|
||||
|
||||
##
|
||||
# @DisplayEGLHeadless:
|
||||
|
46
ui/gtk.c
46
ui/gtk.c
@ -67,6 +67,7 @@
|
||||
#define VC_TERM_X_MIN 80
|
||||
#define VC_TERM_Y_MIN 25
|
||||
#define VC_SCALE_MIN 0.25
|
||||
#define VC_SCALE_MAX 4
|
||||
#define VC_SCALE_STEP 0.25
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
@ -272,15 +273,11 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
|
||||
if (!vc->gfx.ds) {
|
||||
return;
|
||||
}
|
||||
if (s->free_scale) {
|
||||
geo.min_width = surface_width(vc->gfx.ds) * VC_SCALE_MIN;
|
||||
geo.min_height = surface_height(vc->gfx.ds) * VC_SCALE_MIN;
|
||||
mask |= GDK_HINT_MIN_SIZE;
|
||||
} else {
|
||||
geo.min_width = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
|
||||
geo.min_height = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
|
||||
mask |= GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
double scale_x = s->free_scale ? VC_SCALE_MIN : vc->gfx.scale_x;
|
||||
double scale_y = s->free_scale ? VC_SCALE_MIN : vc->gfx.scale_y;
|
||||
geo.min_width = surface_width(vc->gfx.ds) * scale_x;
|
||||
geo.min_height = surface_height(vc->gfx.ds) * scale_y;
|
||||
mask |= GDK_HINT_MIN_SIZE;
|
||||
geo_widget = vc->gfx.drawing_area;
|
||||
gtk_widget_set_size_request(geo_widget, geo.min_width, geo.min_height);
|
||||
|
||||
@ -1579,8 +1576,8 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
|
||||
}
|
||||
s->full_screen = FALSE;
|
||||
if (vc->type == GD_VC_GFX) {
|
||||
vc->gfx.scale_x = 1.0;
|
||||
vc->gfx.scale_y = 1.0;
|
||||
vc->gfx.scale_x = vc->gfx.preferred_scale;
|
||||
vc->gfx.scale_y = vc->gfx.preferred_scale;
|
||||
gd_update_windowsize(vc);
|
||||
}
|
||||
}
|
||||
@ -1636,8 +1633,8 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
|
||||
GtkDisplayState *s = opaque;
|
||||
VirtualConsole *vc = gd_vc_find_current(s);
|
||||
|
||||
vc->gfx.scale_x = 1.0;
|
||||
vc->gfx.scale_y = 1.0;
|
||||
vc->gfx.scale_x = vc->gfx.preferred_scale;
|
||||
vc->gfx.scale_y = vc->gfx.preferred_scale;
|
||||
|
||||
gd_update_windowsize(vc);
|
||||
}
|
||||
@ -1651,8 +1648,8 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
|
||||
s->free_scale = TRUE;
|
||||
} else {
|
||||
s->free_scale = FALSE;
|
||||
vc->gfx.scale_x = 1.0;
|
||||
vc->gfx.scale_y = 1.0;
|
||||
vc->gfx.scale_x = vc->gfx.preferred_scale;
|
||||
vc->gfx.scale_y = vc->gfx.preferred_scale;
|
||||
}
|
||||
|
||||
gd_update_windowsize(vc);
|
||||
@ -2243,6 +2240,11 @@ static void gl_area_realize(GtkGLArea *area, VirtualConsole *vc)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool gd_scale_valid(double scale)
|
||||
{
|
||||
return scale >= VC_SCALE_MIN && scale <= VC_SCALE_MAX;
|
||||
}
|
||||
|
||||
static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
||||
QemuConsole *con, int idx,
|
||||
GSList *group, GtkWidget *view_menu)
|
||||
@ -2252,8 +2254,18 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
||||
|
||||
vc->label = qemu_console_get_label(con);
|
||||
vc->s = s;
|
||||
vc->gfx.scale_x = 1.0;
|
||||
vc->gfx.scale_y = 1.0;
|
||||
vc->gfx.preferred_scale = 1.0;
|
||||
if (s->opts->u.gtk.has_scale) {
|
||||
if (gd_scale_valid(s->opts->u.gtk.scale)) {
|
||||
vc->gfx.preferred_scale = s->opts->u.gtk.scale;
|
||||
} else {
|
||||
error_report("Invalid scale value %lf given, being ignored",
|
||||
s->opts->u.gtk.scale);
|
||||
s->opts->u.gtk.has_scale = false;
|
||||
}
|
||||
}
|
||||
vc->gfx.scale_x = vc->gfx.preferred_scale;
|
||||
vc->gfx.scale_y = vc->gfx.preferred_scale;
|
||||
|
||||
#if defined(CONFIG_OPENGL)
|
||||
if (display_opengl) {
|
||||
|
Reference in New Issue
Block a user