[Qemu-devel] [PATCH 8/9] fbdev: add mouse pointer support
Add mouse_set and cursor_define DisplayChangeListener callbacks and mouse pointer rendering support. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/fbdev.c | 95 1 files changed, 95 insertions(+), 0 deletions(-) diff --git a/ui/fbdev.c b/ui/fbdev.c index d55850e..d859d84 100644 --- a/ui/fbdev.c +++ b/ui/fbdev.c @@ -82,6 +82,12 @@ static pixman_image_t *framebuffer; static pixman_transform_t transform; static pixman_region16_t dirty; +static QEMUCursor *ptr_cursor; +static pixman_image_t *ptr_image; +static intptr_refresh; +static intpx, py, pw, ph; +static intmx, my, mon; + /* fwd decls */ static int fbdev_activate_vt(int tty, int vtno, bool wait); @@ -877,6 +883,51 @@ static void fbdev_render(DisplayState *ds) pixman_region_init(dirty); } +static void fbdev_unrender_ptr(DisplayState *ds) +{ +if (!pw !ph) { +return; +} +pixman_region_union_rect(dirty, dirty, px, py, pw, ph); +ph = pw = 0; +} + +static void fbdev_render_ptr(DisplayState *ds) +{ +pixman_region16_t region; +pixman_transform_t transform; + +if (!mon || !ptr_image) { +return; +} +if (mx 0 || mx = cw || my 0 || my = ch) { +return; +} + +px = mx - ptr_cursor-hot_x; +py = my - ptr_cursor-hot_y; +pw = ptr_cursor-width; +ph = ptr_cursor-height; + +pixman_transform_init_identity(transform); +pixman_transform_translate(transform, NULL, + pixman_int_to_fixed(-cx), + pixman_int_to_fixed(-cy)); +pixman_transform_translate(transform, NULL, + pixman_int_to_fixed(-px), + pixman_int_to_fixed(-py)); +pixman_image_set_transform(ptr_image, transform); + +pixman_region_init_rect(region, 0, 0, pw, ph); +pixman_image_set_clip_region(ptr_image, region); + +pixman_image_composite(PIXMAN_OP_OVER, ptr_image, NULL, framebuffer, + 0, 0, 0, 0, 0, 0, fb_var.xres, fb_var.yres); + +pixman_region_fini(region); +ptr_refresh = 0; +} + /* */ /* qemu interfaces */ @@ -918,6 +969,9 @@ static void fbdev_update(DisplayState *ds, int x, int y, int w, int h) } pixman_region_union_rect(dirty, dirty, x, y, w, h); +if (ptr_image mon pw ph) { +ptr_refresh++; +} } static void fbdev_resize(DisplayState *ds) @@ -954,9 +1008,48 @@ static void fbdev_refresh(DisplayState *ds) fbdev_update(ds, 0, 0, 0, 0); } +if (ptr_refresh) { +fbdev_unrender_ptr(ds); +} if (pixman_region_not_empty(dirty)) { fbdev_render(ds); } +if (ptr_refresh) { +fbdev_render_ptr(ds); +} +} + +static void fbdev_mouse_set(DisplayState *ds, int x, int y, int on) +{ +ptr_refresh++; +mx = x; +my = y; +mon = on; +} + +static void fbdev_cursor_define(DisplayState *ds, QEMUCursor *cursor) +{ +ptr_refresh++; + +if (ptr_cursor) { +cursor_put(ptr_cursor); +ptr_cursor = NULL; +} +if (ptr_image) { +pixman_image_unref(ptr_image); +ptr_image = NULL; +} + +if (!cursor) { +return; +} + +ptr_cursor = cursor; +cursor_get(ptr_cursor); +ptr_image = pixman_image_create_bits(PIXMAN_a8r8g8b8, + cursor-width, cursor-height, + cursor-data, + cursor-width * 4); } static void fbdev_exit_notifier(Notifier *notifier, void *data) @@ -985,6 +1078,8 @@ int fbdev_display_init(DisplayState *ds, const char *device, Error **err) dcl-dpy_resize = fbdev_resize; dcl-dpy_setdata = fbdev_setdata; dcl-dpy_refresh = fbdev_refresh; +dcl-dpy_mouse_set = fbdev_mouse_set; +dcl-dpy_cursor_define = fbdev_cursor_define; register_displaychangelistener(ds, dcl); trace_fbdev_enabled(); -- 1.7.1
[Qemu-devel] [PATCH 8/9] fbdev: add mouse pointer support
Add mouse_set and cursor_define DisplayChangeListener callbacks and mouse pointer rendering support. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/fbdev.c | 95 1 files changed, 95 insertions(+), 0 deletions(-) diff --git a/ui/fbdev.c b/ui/fbdev.c index 4cb4d1d..6835fef 100644 --- a/ui/fbdev.c +++ b/ui/fbdev.c @@ -82,6 +82,12 @@ static pixman_image_t *framebuffer; static pixman_transform_t transform; static pixman_region16_t dirty; +static QEMUCursor *ptr_cursor; +static pixman_image_t *ptr_image; +static intptr_refresh; +static intpx, py, pw, ph; +static intmx, my, mon; + /* fwd decls */ static int fbdev_activate_vt(int tty, int vtno, bool wait); @@ -876,6 +882,51 @@ static void fbdev_render(DisplayState *ds) pixman_region_init(dirty); } +static void fbdev_unrender_ptr(DisplayState *ds) +{ +if (!pw !ph) { +return; +} +pixman_region_union_rect(dirty, dirty, px, py, pw, ph); +ph = pw = 0; +} + +static void fbdev_render_ptr(DisplayState *ds) +{ +pixman_region16_t region; +pixman_transform_t transform; + +if (!mon || !ptr_image) { +return; +} +if (mx 0 || mx = cw || my 0 || my = ch) { +return; +} + +px = mx - ptr_cursor-hot_x; +py = my - ptr_cursor-hot_y; +pw = ptr_cursor-width; +ph = ptr_cursor-height; + +pixman_transform_init_identity(transform); +pixman_transform_translate(transform, NULL, + pixman_int_to_fixed(-cx), + pixman_int_to_fixed(-cy)); +pixman_transform_translate(transform, NULL, + pixman_int_to_fixed(-px), + pixman_int_to_fixed(-py)); +pixman_image_set_transform(ptr_image, transform); + +pixman_region_init_rect(region, 0, 0, pw, ph); +pixman_image_set_clip_region(ptr_image, region); + +pixman_image_composite(PIXMAN_OP_OVER, ptr_image, NULL, framebuffer, + 0, 0, 0, 0, 0, 0, fb_var.xres, fb_var.yres); + +pixman_region_fini(region); +ptr_refresh = 0; +} + /* */ /* qemu interfaces */ @@ -917,6 +968,9 @@ static void fbdev_update(DisplayState *ds, int x, int y, int w, int h) } pixman_region_union_rect(dirty, dirty, x, y, w, h); +if (ptr_image mon pw ph) { +ptr_refresh++; +} } static void fbdev_resize(DisplayState *ds) @@ -953,9 +1007,48 @@ static void fbdev_refresh(DisplayState *ds) fbdev_update(ds, 0, 0, 0, 0); } +if (ptr_refresh) { +fbdev_unrender_ptr(ds); +} if (pixman_region_not_empty(dirty)) { fbdev_render(ds); } +if (ptr_refresh) { +fbdev_render_ptr(ds); +} +} + +static void fbdev_mouse_set(DisplayState *ds, int x, int y, int on) +{ +ptr_refresh++; +mx = x; +my = y; +mon = on; +} + +static void fbdev_cursor_define(DisplayState *ds, QEMUCursor *cursor) +{ +ptr_refresh++; + +if (ptr_cursor) { +cursor_put(ptr_cursor); +ptr_cursor = NULL; +} +if (ptr_image) { +pixman_image_unref(ptr_image); +ptr_image = NULL; +} + +if (!cursor) { +return; +} + +ptr_cursor = cursor; +cursor_get(ptr_cursor); +ptr_image = pixman_image_create_bits(PIXMAN_a8r8g8b8, + cursor-width, cursor-height, + cursor-data, + cursor-width * 4); } static void fbdev_exit_notifier(Notifier *notifier, void *data) @@ -984,6 +1077,8 @@ int fbdev_display_init(DisplayState *ds, const char *device) dcl-dpy_resize = fbdev_resize; dcl-dpy_setdata = fbdev_setdata; dcl-dpy_refresh = fbdev_refresh; +dcl-dpy_mouse_set = fbdev_mouse_set; +dcl-dpy_cursor_define = fbdev_cursor_define; register_displaychangelistener(ds, dcl); trace_fbdev_enabled(); -- 1.7.1