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