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    QEMUCursor *c;
  85
  86    c = cursor_parse_xpm(cursor_hidden_xpm);
  87    return c;
  88}
  89
  90QEMUCursor *cursor_builtin_left_ptr(void)
  91{
  92    QEMUCursor *c;
  93
  94    c = cursor_parse_xpm(cursor_left_ptr_xpm);
  95    return c;
  96}
  97
  98QEMUCursor *cursor_alloc(int width, int height)
  99{
 100    QEMUCursor *c;
 101    int datasize = width * height * sizeof(uint32_t);
 102
 103    c = g_malloc0(sizeof(QEMUCursor) + datasize);
 104    c->width  = width;
 105    c->height = height;
 106    c->refcount = 1;
 107    return c;
 108}
 109
 110void cursor_get(QEMUCursor *c)
 111{
 112    c->refcount++;
 113}
 114
 115void cursor_put(QEMUCursor *c)
 116{
 117    if (c == NULL)
 118        return;
 119    c->refcount--;
 120    if (c->refcount)
 121        return;
 122    g_free(c);
 123}
 124
 125int cursor_get_mono_bpl(QEMUCursor *c)
 126{
 127    return (c->width + 7) / 8;
 128}
 129
 130void cursor_set_mono(QEMUCursor *c,
 131                     uint32_t foreground, uint32_t background, uint8_t *image,
 132                     int transparent, uint8_t *mask)
 133{
 134    uint32_t *data = c->data;
 135    uint8_t bit;
 136    int x,y,bpl;
 137
 138    bpl = cursor_get_mono_bpl(c);
 139    for (y = 0; y < c->height; y++) {
 140        bit = 0x80;
 141        for (x = 0; x < c->width; x++, data++) {
 142            if (transparent && mask[x/8] & bit) {
 143                *data = 0x00000000;
 144            } else if (!transparent && !(mask[x/8] & bit)) {
 145                *data = 0x00000000;
 146            } else if (image[x/8] & bit) {
 147                *data = 0xff000000 | foreground;
 148            } else {
 149                *data = 0xff000000 | background;
 150            }
 151            bit >>= 1;
 152            if (bit == 0) {
 153                bit = 0x80;
 154            }
 155        }
 156        mask  += bpl;
 157        image += bpl;
 158    }
 159}
 160
 161void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image)
 162{
 163    uint32_t *data = c->data;
 164    uint8_t bit;
 165    int x,y,bpl;
 166
 167    bpl = cursor_get_mono_bpl(c);
 168    memset(image, 0, bpl * c->height);
 169    for (y = 0; y < c->height; y++) {
 170        bit = 0x80;
 171        for (x = 0; x < c->width; x++, data++) {
 172            if (((*data & 0xff000000) == 0xff000000) &&
 173                ((*data & 0x00ffffff) == foreground)) {
 174                image[x/8] |= bit;
 175            }
 176            bit >>= 1;
 177            if (bit == 0) {
 178                bit = 0x80;
 179            }
 180        }
 181        image += bpl;
 182    }
 183}
 184
 185void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask)
 186{
 187    uint32_t *data = c->data;
 188    uint8_t bit;
 189    int x,y,bpl;
 190
 191    bpl = cursor_get_mono_bpl(c);
 192    memset(mask, 0, bpl * c->height);
 193    for (y = 0; y < c->height; y++) {
 194        bit = 0x80;
 195        for (x = 0; x < c->width; x++, data++) {
 196            if ((*data & 0xff000000) != 0xff000000) {
 197                if (transparent != 0) {
 198                    mask[x/8] |= bit;
 199                }
 200            } else {
 201                if (transparent == 0) {
 202                    mask[x/8] |= bit;
 203                }
 204            }
 205            bit >>= 1;
 206            if (bit == 0) {
 207                bit = 0x80;
 208            }
 209        }
 210        mask += bpl;
 211    }
 212}
 213