From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1OA5Yj-0004LV-Jg for qemu-devel@nongnu.org; Thu, 06 May 2010 14:12:29 -0400 Received: from [140.186.70.92] (port=49111 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OA5Ye-0004Gk-1T for qemu-devel@nongnu.org; Thu, 06 May 2010 14:12:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OA5YW-0004L6-VX for qemu-devel@nongnu.org; Thu, 06 May 2010 14:12:23 -0400 Received: from mail-pw0-f45.google.com ([209.85.160.45]:53197) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OA5YW-0004Kg-If for qemu-devel@nongnu.org; Thu, 06 May 2010 14:12:16 -0400 Received: by pwi6 with SMTP id 6so106573pwi.4 for ; Thu, 06 May 2010 11:12:15 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1273063904-6028-2-git-send-email-kraxel@redhat.com> References: <1273063904-6028-1-git-send-email-kraxel@redhat.com> <1273063904-6028-2-git-send-email-kraxel@redhat.com> Date: Thu, 6 May 2010 21:12:15 +0300 Message-ID: Subject: Re: [Qemu-devel] [PATCH 1/3] cursor: add cursor functions. From: Blue Swirl Content-Type: text/plain; charset=UTF-8 List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann Cc: qemu-devel@nongnu.org On 5/5/10, Gerd Hoffmann 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 > --- > 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 > > > >