From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:53840) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEIG2-0007RO-GE for qemu-devel@nongnu.org; Wed, 19 Sep 2012 07:16:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TEIFu-0001RN-V5 for qemu-devel@nongnu.org; Wed, 19 Sep 2012 07:15:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52675) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEIFu-0001Qy-Mb for qemu-devel@nongnu.org; Wed, 19 Sep 2012 07:15:46 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q8JBFk0w018767 (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:40 +0200 Message-Id: <1348053341-29212-9-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 8/9] fbdev: add mouse pointer support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Add mouse_set and cursor_define DisplayChangeListener callbacks and mouse pointer rendering support. Signed-off-by: Gerd Hoffmann --- 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 int ptr_refresh; +static int px, py, pw, ph; +static int mx, 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(®ion, 0, 0, pw, ph); + pixman_image_set_clip_region(ptr_image, ®ion); + + 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(®ion); + 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