qemu/cursor.c
<<
>>
Prefs
   1#include "qemu-common.h"
   2#include "console.h"
   3
   4#include "cursor_hidden.xpm"
   5#include "cursor_left_ptr.xpm"
   6
   7/* for creating built-in cursors */
   8static QEMUCursor *cursor_parse_xpm(const char *xpm[])
   9{
  10    QEMUCursor *c;
  11    uint32_t ctab[128];
  12    unsigned int width, height, colors, chars;
  13    unsigned int line = 0, i, r, g, b, x, y, pixel;
  14    char name[16];
  15    uint8_t idx;
  16
  17    /* parse header line: width, height, #colors, #chars */
  18    if (sscanf(xpm[line], "%d %d %d %d", &width, &height, &colors, &chars) != 4) {
  19        fprintf(stderr, "%s: header parse error: \"%s\"\n",
  20                __FUNCTION__, xpm[line]);
  21        return NULL;
  22    }
  23    if (chars != 1) {
  24        fprintf(stderr, "%s: chars != 1 not supported\n", __FUNCTION__);
  25        return NULL;
  26    }
  27    line++;
  28
  29    /* parse color table */
  30    for (i = 0; i < colors; i++, line++) {
  31        if (sscanf(xpm[line], "%c c %15s", &idx, name) == 2) {
  32            if (sscanf(name, "#%02x%02x%02x", &r, &g, &b) == 3) {
  33                ctab[idx] = (0xff << 24) | (b << 16) | (g << 8) | r;
  34                continue;
  35            }
  36            if (strcmp(name, "None") == 0) {
  37                ctab[idx] = 0x00000000;
  38                continue;
  39            }
  40        }
  41        fprintf(stderr, "%s: color parse error: \"%s\"\n",
  42                __FUNCTION__, xpm[line]);
  43        return NULL;
  44    }
  45
  46    /* parse pixel data */
  47    c = cursor_alloc(width, height);
  48    for (pixel = 0, y = 0; y < height; y++, line++) {
  49        for (x = 0; x < height; x++, pixel++) {
  50            idx = xpm[line][x];
  51            c->data[pixel] = ctab[idx];
  52        }
  53    }
  54    return c;
  55}
  56
  57/* nice for debugging */
  58void cursor_print_ascii_art(QEMUCursor *c, const char *prefix)
  59{
  60    uint32_t *data = c->data;
  61    int x,y;
  62
  63    for (y = 0; y < c->height; y++) {
  64        fprintf(stderr, "%s: %2d: |", prefix, y);
  65        for (x = 0; x < c->width; x++, data++) {
  66            if ((*data & 0xff000000) != 0xff000000) {
  67                fprintf(stderr, " "); /* transparent */
  68            } else if ((*data & 0x00ffffff) == 0x00ffffff) {
  69                fprintf(stderr, "."); /* white */
  70            } else if ((*data & 0x00ffffff) == 0x00000000) {
  71                fprintf(stderr, "X"); /* black */
  72            } else {
  73                fprintf(stderr, "o"); /* other */
  74            }
  75        }
  76        fprintf(stderr, "|\n");
  77    }
  78}
  79
  80QEMUCursor *cursor_builtin_hidden(void)
  81{
  82    QEMUCursor *c;
  83
  84    c = cursor_parse_xpm(cursor_hidden_xpm);
  85    return c;
  86}
  87
  88QEMUCursor *cursor_builtin_left_ptr(void)
  89{
  90    QEMUCursor *c;
  91
  92    c = cursor_parse_xpm(cursor_left_ptr_xpm);
  93    return c;
  94}
  95
  96QEMUCursor *cursor_alloc(int width, int height)
  97{
  98    QEMUCursor *c;
  99    int datasize = width * height * sizeof(uint32_t);
 100
 101    c = qemu_mallocz(sizeof(QEMUCursor) + datasize);
 102    c->width  = width;
 103    c->height = height;
 104    c->refcount = 1;
 105    return c;
 106}
 107
 108void cursor_get(QEMUCursor *c)
 109{
 110    c->refcount++;
 111}
 112
 113void cursor_put(QEMUCursor *c)
 114{
 115    if (c == NULL)
 116        return;
 117    c->refcount--;
 118    if (c->refcount)
 119        return;
 120    qemu_free(c);
 121}
 122
 123int cursor_get_mono_bpl(QEMUCursor *c)
 124{
 125    return (c->width + 7) / 8;
 126}
 127
 128void cursor_set_mono(QEMUCursor *c,
 129                     uint32_t foreground, uint32_t background, uint8_t *image,
 130                     int transparent, uint8_t *mask)
 131{
 132    uint32_t *data = c->data;
 133    uint8_t bit;
 134    int x,y,bpl;
 135
 136    bpl = cursor_get_mono_bpl(c);
 137    for (y = 0; y < c->height; y++) {
 138        bit = 0x80;
 139        for (x = 0; x < c->width; x++, data++) {
 140            if (transparent && mask[x/8] & bit) {
 141                *data = 0x00000000;
 142            } else if (!transparent && !(mask[x/8] & bit)) {
 143                *data = 0x00000000;
 144            } else if (image[x/8] & bit) {
 145                *data = 0xff000000 | foreground;
 146            } else {
 147                *data = 0xff000000 | background;
 148            }
 149            bit >>= 1;
 150            if (bit == 0) {
 151                bit = 0x80;
 152            }
 153        }
 154        mask  += bpl;
 155        image += bpl;
 156    }
 157}
 158
 159void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image)
 160{
 161    uint32_t *data = c->data;
 162    uint8_t bit;
 163    int x,y,bpl;
 164
 165    bpl = cursor_get_mono_bpl(c);
 166    memset(image, 0, bpl * c->height);
 167    for (y = 0; y < c->height; y++) {
 168        bit = 0x80;
 169        for (x = 0; x < c->width; x++, data++) {
 170            if (((*data & 0xff000000) == 0xff000000) &&
 171                ((*data & 0x00ffffff) == foreground)) {
 172                image[x/8] |= bit;
 173            }
 174            bit >>= 1;
 175            if (bit == 0) {
 176                bit = 0x80;
 177            }
 178        }
 179        image += bpl;
 180    }
 181}
 182
 183void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask)
 184{
 185    uint32_t *data = c->data;
 186    uint8_t bit;
 187    int x,y,bpl;
 188
 189    bpl = cursor_get_mono_bpl(c);
 190    memset(mask, 0, bpl * c->height);
 191    for (y = 0; y < c->height; y++) {
 192        bit = 0x80;
 193        for (x = 0; x < c->width; x++, data++) {
 194            if ((*data & 0xff000000) != 0xff000000) {
 195                if (transparent != 0) {
 196                    mask[x/8] |= bit;
 197                }
 198            } else {
 199                if (transparent == 0) {
 200                    mask[x/8] |= bit;
 201                }
 202            }
 203            bit >>= 1;
 204            if (bit == 0) {
 205                bit = 0x80;
 206            }
 207        }
 208        mask += bpl;
 209    }
 210}
 211