qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 9/9] fbdev: add display scaling support


From: Stefano Stabellini
Subject: Re: [Qemu-devel] [PATCH 9/9] fbdev: add display scaling support
Date: Tue, 18 Sep 2012 16:02:13 +0100
User-agent: Alpine 2.02 (DEB 1266 2009-07-14)

On Tue, 18 Sep 2012, Gerd Hoffmann wrote:
> Add support for scaling the guest display.
> Ctrl-Alt-S hotkey toggles scaling.

We could make sdl_zoom generic: sdl_zoom_blit doesn't actually depend on
sdl.


> Signed-off-by: Gerd Hoffmann <address@hidden>
> ---
>  ui/fbdev.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 51 insertions(+), 10 deletions(-)
> 
> diff --git a/ui/fbdev.c b/ui/fbdev.c
> index 6835fef..55793ab 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;
> @@ -912,6 +924,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));
> @@ -937,16 +954,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);
> @@ -957,7 +990,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) {
> @@ -1049,6 +1089,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
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]