Statistics
| Branch: | Revision:

root / ui / cursor.c @ feature-archipelago

History | View | Annotate | Download (5.3 kB)

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