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 */ 9 static 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 */ 60 void 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 82 QEMUCursor *cursor_builtin_hidden(void) 83 { 84 QEMUCursor *c; 85 86 c = cursor_parse_xpm(cursor_hidden_xpm); 87 return c; 88 } 89 90 QEMUCursor *cursor_builtin_left_ptr(void) 91 { 92 QEMUCursor *c; 93 94 c = cursor_parse_xpm(cursor_left_ptr_xpm); 95 return c; 96 } 97 98 QEMUCursor *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 110 void cursor_get(QEMUCursor *c) 111 { 112 c->refcount++; 113 } 114 115 void 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 125 int cursor_get_mono_bpl(QEMUCursor *c) 126 { 127 return (c->width + 7) / 8; 128 } 129 130 void 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 161 void 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 185 void 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