qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 1/3] cursor: add cursor functions.
Date: Wed,  5 May 2010 14:51:42 +0200	[thread overview]
Message-ID: <1273063904-6028-2-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1273063904-6028-1-git-send-email-kraxel@redhat.com>

Add a new cursor type to console.h and a bunch of functions to
deal with cursors the (new) cursor.c file.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs |    3 +-
 console.h     |   24 ++++++-
 cursor.c      |  208 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+), 3 deletions(-)
 create mode 100644 cursor.c

diff --git a/Makefile.objs b/Makefile.objs
index ecdd53e..1ee6e9d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -48,7 +48,8 @@ common-obj-y = $(block-obj-y)
 common-obj-y += $(net-obj-y)
 common-obj-y += $(qobject-obj-y)
 common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
-common-obj-y += readline.o console.o async.o qemu-error.o
+common-obj-y += readline.o console.o cursor.o async.o qemu-error.o
+
 common-obj-y += tcg-runtime.o host-utils.o
 common-obj-y += irq.o ioport.o input.o
 common-obj-$(CONFIG_PTIMER) += ptimer.o
diff --git a/console.h b/console.h
index 6def115..88861cb 100644
--- a/console.h
+++ b/console.h
@@ -126,6 +126,27 @@ struct DisplaySurface {
     struct PixelFormat pf;
 };
 
+/* cursor data format is 32bit RGBA */
+typedef struct QEMUCursor {
+    int                 width, height;
+    int                 hot_x, hot_y;
+    int                 refcount;
+    uint32_t            data[];
+} QEMUCursor;
+
+QEMUCursor *cursor_alloc(int width, int height);
+void cursor_get(QEMUCursor *c);
+void cursor_put(QEMUCursor *c);
+QEMUCursor *cursor_builtin_hidden(void);
+QEMUCursor *cursor_builtin_left_ptr(void);
+void cursor_print_ascii_art(QEMUCursor *c, const char *prefix);
+int cursor_get_mono_bpl(QEMUCursor *c);
+void cursor_set_mono(QEMUCursor *c,
+                     uint32_t foreground, uint32_t background, uint8_t *image,
+                     int transparent, uint8_t *mask);
+void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
+void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
+
 struct DisplayChangeListener {
     int idle;
     uint64_t gui_timer_interval;
@@ -158,8 +179,7 @@ struct DisplayState {
     struct DisplayChangeListener* listeners;
 
     void (*mouse_set)(int x, int y, int on);
-    void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
-                          uint8_t *image, uint8_t *mask);
+    void (*cursor_define)(QEMUCursor *cursor);
 
     struct DisplayState *next;
 };
diff --git a/cursor.c b/cursor.c
new file mode 100644
index 0000000..3995a31
--- /dev/null
+++ b/cursor.c
@@ -0,0 +1,208 @@
+#include "qemu-common.h"
+#include "console.h"
+
+static const char cursor_hidden_32[32*32];
+static const char cursor_left_ptr_32[32*32] = {
+    "                                "
+    " X                              "
+    " XX                             "
+    " X.X                            "
+    " X..X                           "
+    " X...X                          "
+    " X....X                         "
+    " X.....X                        "
+    " X......X                       "
+    " X.......X                      "
+    " X........X                     "
+    " X.....XXXXX                    "
+    " X..X..X                        "
+    " X.X X..X                       "
+    " XX  X..X                       "
+    " X    X..X                      "
+    "      X..X                      "
+    "       X..X                     "
+    "       X..X                     "
+    "        XX                      "
+    "                                "
+};
+
+/* for creating built-in cursors */
+static void cursor_parse_ascii_art(QEMUCursor *c, const char *ptr)
+{
+    int i, pixels;
+
+    pixels = c->width * c->height;
+    for (i = 0; i < pixels; i++) {
+        switch (ptr[i]) {
+        case 'X': /* black */
+            c->data[i] = 0xff000000;
+            break;
+        case '.': /* white */
+            c->data[i] = 0xffffffff;
+            break;
+        case ' ': /* transparent */
+        default:
+            c->data[i] = 0x00000000;
+            break;
+        }
+    }
+}
+
+/* nice for debugging */
+void cursor_print_ascii_art(QEMUCursor *c, const char *prefix)
+{
+    uint32_t *data = c->data;
+    int x,y;
+
+    for (y = 0; y < c->height; y++) {
+        fprintf(stderr, "%s: %2d: |", prefix, y);
+        for (x = 0; x < c->width; x++, data++) {
+            if ((*data & 0xff000000) != 0xff000000) {
+                fprintf(stderr, " "); /* transparent */
+            } else if ((*data & 0x00ffffff) == 0x00ffffff) {
+                fprintf(stderr, "."); /* white */
+            } else if ((*data & 0x00ffffff) == 0x00000000) {
+                fprintf(stderr, "X"); /* black */
+            } else {
+                fprintf(stderr, "o"); /* other */
+            }
+        }
+        fprintf(stderr, "|\n");
+    }
+}
+
+QEMUCursor *cursor_builtin_hidden(void)
+{
+    QEMUCursor *c;
+
+    c = cursor_alloc(32, 32);
+    cursor_parse_ascii_art(c, cursor_hidden_32);
+    return c;
+}
+
+QEMUCursor *cursor_builtin_left_ptr(void)
+{
+    QEMUCursor *c;
+
+    c = cursor_alloc(32, 32);
+    cursor_parse_ascii_art(c, cursor_left_ptr_32);
+    c->hot_x = 1;
+    c->hot_y = 1;
+    return c;
+}
+
+QEMUCursor *cursor_alloc(int width, int height)
+{
+    QEMUCursor *c;
+    int datasize = width * height * sizeof(uint32_t);
+
+    c = qemu_mallocz(sizeof(QEMUCursor) + datasize);
+    c->width  = width;
+    c->height = height;
+    c->refcount = 1;
+    return c;
+}
+
+void cursor_get(QEMUCursor *c)
+{
+    c->refcount++;
+}
+
+void cursor_put(QEMUCursor *c)
+{
+    if (c == NULL)
+        return;
+    c->refcount--;
+    if (c->refcount)
+        return;
+    qemu_free(c);
+}
+
+int cursor_get_mono_bpl(QEMUCursor *c)
+{
+    return (c->width + 7) / 8;
+}
+
+void cursor_set_mono(QEMUCursor *c,
+                     uint32_t foreground, uint32_t background, uint8_t *image,
+                     int transparent, uint8_t *mask)
+{
+    uint32_t *data = c->data;
+    uint8_t bit;
+    int x,y,bpl;
+
+    bpl = cursor_get_mono_bpl(c);
+    for (y = 0; y < c->height; y++) {
+        bit = 0x80;
+        for (x = 0; x < c->width; x++, data++) {
+            if (transparent && mask[x/8] & bit) {
+                *data = 0x00000000;
+            } else if (!transparent && !(mask[x/8] & bit)) {
+                *data = 0x00000000;
+            } else if (image[x/8] & bit) {
+                *data = 0xff000000 | foreground;
+            } else {
+                *data = 0xff000000 | background;
+            }
+            bit >>= 1;
+            if (bit == 0) {
+                bit = 0x80;
+            }
+        }
+        mask  += bpl;
+        image += bpl;
+    }
+}
+
+void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image)
+{
+    uint32_t *data = c->data;
+    uint8_t bit;
+    int x,y,bpl;
+
+    bpl = cursor_get_mono_bpl(c);
+    memset(image, 0, bpl * c->height);
+    for (y = 0; y < c->height; y++) {
+        bit = 0x80;
+        for (x = 0; x < c->width; x++, data++) {
+            if (((*data & 0xff000000) == 0xff000000) &&
+                ((*data & 0x00ffffff) == foreground)) {
+                image[x/8] |= bit;
+            }
+            bit >>= 1;
+            if (bit == 0) {
+                bit = 0x80;
+            }
+        }
+        image += bpl;
+    }
+}
+
+void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask)
+{
+    uint32_t *data = c->data;
+    uint8_t bit;
+    int x,y,bpl;
+
+    bpl = cursor_get_mono_bpl(c);
+    memset(mask, 0, bpl * c->height);
+    for (y = 0; y < c->height; y++) {
+        bit = 0x80;
+        for (x = 0; x < c->width; x++, data++) {
+            if ((*data & 0xff000000) != 0xff000000) {
+                if (transparent != 0) {
+                    mask[x/8] |= bit;
+                }
+            } else {
+                if (transparent == 0) {
+                    mask[x/8] |= bit;
+                }
+            }
+            bit >>= 1;
+            if (bit == 0) {
+                bit = 0x80;
+            }
+        }
+        mask += bpl;
+    }
+}
-- 
1.6.6.1

  reply	other threads:[~2010-05-05 12:51 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-05 12:51 [Qemu-devel] [PATCH 0/3] local cursor patches Gerd Hoffmann
2010-05-05 12:51 ` Gerd Hoffmann [this message]
2010-05-06 18:12   ` [Qemu-devel] [PATCH 1/3] cursor: add cursor functions Blue Swirl
2010-05-06 19:27     ` Gerd Hoffmann
2010-05-06 19:42       ` Blue Swirl
2010-05-07  7:05     ` [Qemu-devel] " Paolo Bonzini
2010-05-07 15:23       ` Blue Swirl
2010-05-19  8:16         ` Gerd Hoffmann
2010-05-19 18:57           ` Blue Swirl
2010-05-19 19:08             ` Anthony Liguori
2010-05-20 12:49               ` Gerd Hoffmann
2010-05-20 13:17                 ` Anthony Liguori
2010-05-05 12:51 ` [Qemu-devel] [PATCH 2/3] use new cursor struct + functions for vmware vga and sdl Gerd Hoffmann
2010-05-05 12:51 ` [Qemu-devel] [PATCH 3/3] vnc: rich cursor support Gerd Hoffmann
  -- strict thread matches above, loose matches on Subject: below --
2010-05-21  9:54 [Qemu-devel] [PATCH 0/3] cursor patches Gerd Hoffmann
2010-05-21  9:54 ` [Qemu-devel] [PATCH 1/3] cursor: add cursor functions Gerd Hoffmann
2010-05-21 12:29   ` Anthony Liguori
2010-05-21 18:53     ` Blue Swirl
2010-05-24 20:30   ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1273063904-6028-2-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).