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 | } |