Statistics
| Branch: | Revision:

root / cursor.c @ 45664345

History | View | Annotate | Download (5.3 kB)

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