diff mbox series

[RFC,1/6] ui: add more cursor helper methods

Message ID 20250123191536.142753-2-berrange@redhat.com (mailing list archive)
State New
Headers show
Series RFC: hw/display/virtio-gpu: problems with coloured cursors | expand

Commit Message

Daniel P. Berrangé Jan. 23, 2025, 7:15 p.m. UTC
This adds helper methods to the QEMUCursor APIs for multiplying /
unmultiplying the alpha channel into the RGB components; for swapping
the RGB component order; for copying cursor objects; auto-freeing
cursor objects.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 include/ui/console.h |  6 ++++++
 ui/cursor.c          | 49 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
diff mbox series

Patch

diff --git a/include/ui/console.h b/include/ui/console.h
index 46b3128185..e5eb903feb 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -175,6 +175,12 @@  void cursor_set_mono(QEMUCursor *c,
                      int transparent, uint8_t *mask);
 void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
 
+void cursor_multiply_alpha(QEMUCursor *c);
+void cursor_unmultiply_alpha(QEMUCursor *c);
+void cursor_swap_rgb(QEMUCursor *c);
+QEMUCursor *cursor_copy(QEMUCursor *c);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QEMUCursor, cursor_unref);
+
 typedef void *QEMUGLContext;
 typedef struct QEMUGLParams QEMUGLParams;
 
diff --git a/ui/cursor.c b/ui/cursor.c
index 6e23244fbe..536e022548 100644
--- a/ui/cursor.c
+++ b/ui/cursor.c
@@ -225,3 +225,52 @@  void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask)
         mask += bpl;
     }
 }
+
+void cursor_multiply_alpha(QEMUCursor *c)
+{
+    int i;
+
+    for (i = 0 ; i < (c->width * c->height); i++) {
+        guint8 *pixels = (guint8 *)c->data + (i * 4);
+        pixels[0] = (unsigned)pixels[0] * pixels[3] / 255;
+        pixels[1] = (unsigned)pixels[1] * pixels[3] / 255;
+        pixels[2] = (unsigned)pixels[2] * pixels[3] / 255;
+    }
+}
+
+void cursor_unmultiply_alpha(QEMUCursor *c)
+{
+    int i;
+
+    for (i = 0 ; i < (c->width * c->height); i++) {
+        guint8 *pixels = (guint8 *)c->data + (i * 4);
+        guint8 alpha = pixels[3] ? pixels[3] : 1;
+        pixels[0] = (unsigned)pixels[0] * 255 / alpha;
+        pixels[1] = (unsigned)pixels[1] * 255 / alpha;
+        pixels[2] = (unsigned)pixels[2] * 255 / alpha;
+    }
+}
+
+void cursor_swap_rgb(QEMUCursor *c)
+{
+    int i;
+
+    for (i = 0 ; i < (c->width * c->height); i++) {
+        guint8 *pixels = (guint8 *)c->data + (i * 4);
+        pixels[0] ^= pixels[2];
+        pixels[2] ^= pixels[0];
+        pixels[0] ^= pixels[2];
+    }
+}
+
+QEMUCursor *cursor_copy(QEMUCursor *c)
+{
+    QEMUCursor *ret = cursor_alloc(c->width, c->height);
+
+    ret->hot_x = c->hot_x;
+    ret->hot_y = c->hot_y;
+
+    memcpy(ret->data, c->data, c->width * c->height * 4);
+
+    return ret;
+}