From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:53827) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEIG1-0007PO-D2 for qemu-devel@nongnu.org; Wed, 19 Sep 2012 07:15:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TEIFv-0001Re-1y for qemu-devel@nongnu.org; Wed, 19 Sep 2012 07:15:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:28214) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEIFu-0001R9-Op for qemu-devel@nongnu.org; Wed, 19 Sep 2012 07:15:46 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q8JBFkLO019944 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 19 Sep 2012 07:15:46 -0400 From: Gerd Hoffmann Date: Wed, 19 Sep 2012 13:15:41 +0200 Message-Id: <1348053341-29212-10-git-send-email-kraxel@redhat.com> In-Reply-To: <1348053341-29212-1-git-send-email-kraxel@redhat.com> References: <1348053341-29212-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 9/9] fbdev: add display scaling support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Add support for scaling the guest display. Ctrl-Alt-S hotkey toggles scaling. Signed-off-by: Gerd Hoffmann --- ui/fbdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 51 insertions(+), 10 deletions(-) diff --git a/ui/fbdev.c b/ui/fbdev.c index d859d84..0f40259 100644 --- a/ui/fbdev.c +++ b/ui/fbdev.c @@ -81,6 +81,7 @@ static pixman_image_t *surface; static pixman_image_t *framebuffer; static pixman_transform_t transform; static pixman_region16_t dirty; +static double scale; static QEMUCursor *ptr_cursor; static pixman_image_t *ptr_image; @@ -88,6 +89,10 @@ static int ptr_refresh; static int px, py, pw, ph; static int mx, my, mon; +/* options */ +static int use_scale = 1; +static pixman_filter_t pfilter = PIXMAN_FILTER_GOOD; + /* fwd decls */ static int fbdev_activate_vt(int tty, int vtno, bool wait); @@ -182,13 +187,14 @@ static void read_mouse(void *opaque) if (ay < 0) { ay = 0; } - if (ax >= cw) { - ax = cw-1; + if (ax >= cw*scale) { + ax = cw*scale-1; } - if (ay >= ch) { - ay = ch-1; + if (ay >= ch*scale) { + ay = ch*scale-1; } - kbd_mouse_event(ax * 0x7FFF / cw, ay * 0x7FFF / ch, 0, b); + kbd_mouse_event(ax * 0x7FFF / (cw*scale), + ay * 0x7FFF / (ch*scale), 0, b); } else { kbd_mouse_event(x, y, 0, b); } @@ -543,6 +549,12 @@ static void read_mediumraw(void *opaque) "(ctrl-alt-esc) ===\n"); exit(1); } + if (keycode == KEY_S) { + use_scale = !use_scale; + resize_screen++; + redraw_screen++; + continue; + } if (keycode >= KEY_F1 && keycode <= KEY_F10) { fbdev_activate_vt(tty, keycode+1-KEY_F1, false); key_down[keycode] = false; @@ -913,6 +925,11 @@ static void fbdev_render_ptr(DisplayState *ds) pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(-cx), pixman_int_to_fixed(-cy)); + if (use_scale) { + pixman_transform_scale(&transform, NULL, + pixman_double_to_fixed(1/scale), + pixman_double_to_fixed(1/scale)); + } pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(-px), pixman_int_to_fixed(-py)); @@ -938,16 +955,32 @@ static void fbdev_update(DisplayState *ds, int x, int y, int w, int h) } if (resize_screen) { + double xs, ys; + trace_fbdev_dpy_resize(ds_get_width(ds), ds_get_height(ds)); resize_screen = 0; cx = 0; cy = 0; cw = ds_get_width(ds); ch = ds_get_height(ds); - if (ds_get_width(ds) < fb_var.xres) { - cx = (fb_var.xres - ds_get_width(ds)) / 2; - } - if (ds_get_height(ds) < fb_var.yres) { - cy = (fb_var.yres - ds_get_height(ds)) / 2; + + if (use_scale) { + xs = (double)fb_var.xres / cw; + ys = (double)fb_var.yres / ch; + if (xs > ys) { + scale = ys; + cx = (fb_var.xres - ds_get_width(ds)*scale) / 2; + } else { + scale = xs; + cy = (fb_var.yres - ds_get_height(ds)*scale) / 2; + } + } else { + scale = 1; + if (ds_get_width(ds) < fb_var.xres) { + cx = (fb_var.xres - ds_get_width(ds)) / 2; + } + if (ds_get_height(ds) < fb_var.yres) { + cy = (fb_var.yres - ds_get_height(ds)) / 2; + } } if (surface) { pixman_image_unref(surface); @@ -958,7 +991,14 @@ static void fbdev_update(DisplayState *ds, int x, int y, int w, int h) pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(-cx), pixman_int_to_fixed(-cy)); + if (use_scale) { + pixman_transform_scale(&transform, NULL, + pixman_double_to_fixed(1/scale), + pixman_double_to_fixed(1/scale)); + } pixman_image_set_transform(surface, &transform); + + pixman_image_set_filter(surface, pfilter, NULL, 0); } if (redraw_screen) { @@ -1050,6 +1090,7 @@ static void fbdev_cursor_define(DisplayState *ds, QEMUCursor *cursor) cursor->width, cursor->height, cursor->data, cursor->width * 4); + pixman_image_set_filter(ptr_image, pfilter, NULL, 0); } static void fbdev_exit_notifier(Notifier *notifier, void *data) -- 1.7.1