root / cursor.c @ 3c85e74f
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 | } |