qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/3] cursor: add cursor functions.


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 1/3] cursor: add cursor functions.
Date: Thu, 6 May 2010 21:12:15 +0300

On 5/5/10, Gerd Hoffmann <address@hidden> wrote:
> 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 <address@hidden>
>  ---
>   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                      "
>  +    "                                "
>  +};

Is this format standard? How about using X bitmap format instead:
$ cat /usr/include/X11/bitmaps/left_ptr
#define left_ptr_width 16
#define left_ptr_height 16
#define left_ptr_x_hot 3
#define left_ptr_y_hot 1
static char left_ptr_bits[] = {
   0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00,
   0xf8, 0x01, 0xf8, 0x03, 0xf8, 0x07, 0xf8, 0x00, 0xd8, 0x00, 0x88, 0x01,
   0x80, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00};

Then there would be no need of parsing.

>  +
>  +/* 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 via email to

[Prev in Thread] Current Thread [Next in Thread]