On 5/5/10, Gerd Hoffmann <kra...@redhat.com> 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 <kra...@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 " > + " " > +};
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 > > > >