[Qemu-devel] [PATCH 8/9] fbdev: add mouse pointer support

2012-09-19 Thread Gerd Hoffmann
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

2012-09-18 Thread Gerd Hoffmann
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