From patchwork Thu Sep 13 09:19:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 183572 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1A2DA2C007C for ; Thu, 13 Sep 2012 19:20:20 +1000 (EST) Received: from localhost ([::1]:58140 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TC5ar-0003vI-VN for incoming@patchwork.ozlabs.org; Thu, 13 Sep 2012 05:20:17 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44942) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TC5aW-0003gC-Se for qemu-devel@nongnu.org; Thu, 13 Sep 2012 05:20:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TC5aT-0004hv-VU for qemu-devel@nongnu.org; Thu, 13 Sep 2012 05:19:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39452) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TC5aT-0004hd-MU for qemu-devel@nongnu.org; Thu, 13 Sep 2012 05:19:53 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q8D9JrgY012588 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 13 Sep 2012 05:19:53 -0400 Received: from rincewind.home.kraxel.org (ovpn-116-20.ams2.redhat.com [10.36.116.20]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q8D9Jp4d011410; Thu, 13 Sep 2012 05:19:52 -0400 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id 4836640C7F; Thu, 13 Sep 2012 11:19:50 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 13 Sep 2012 11:19:48 +0200 Message-Id: <1347527989-3986-9-git-send-email-kraxel@redhat.com> In-Reply-To: <1347527989-3986-1-git-send-email-kraxel@redhat.com> References: <1347527989-3986-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2 8/9] fbdev: add mouse pointer support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 07fa693..5e700e8 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); @@ -865,6 +871,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 */ @@ -906,6 +957,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) @@ -933,9 +987,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) @@ -963,6 +1056,8 @@ int fbdev_display_init(DisplayState *ds, const char *device) dcl->dpy_update = fbdev_update; dcl->dpy_resize = fbdev_resize; 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();