1*e16f4c87SPeter Maydell #include "qemu/osdep.h" 228ecbaeeSPaolo Bonzini #include "qemu-common.h" 328ecbaeeSPaolo Bonzini #include "ui/console.h" 428ecbaeeSPaolo Bonzini 528ecbaeeSPaolo Bonzini #include "cursor_hidden.xpm" 628ecbaeeSPaolo Bonzini #include "cursor_left_ptr.xpm" 728ecbaeeSPaolo Bonzini 828ecbaeeSPaolo Bonzini /* for creating built-in cursors */ 928ecbaeeSPaolo Bonzini static QEMUCursor *cursor_parse_xpm(const char *xpm[]) 1028ecbaeeSPaolo Bonzini { 1128ecbaeeSPaolo Bonzini QEMUCursor *c; 1228ecbaeeSPaolo Bonzini uint32_t ctab[128]; 1328ecbaeeSPaolo Bonzini unsigned int width, height, colors, chars; 1428ecbaeeSPaolo Bonzini unsigned int line = 0, i, r, g, b, x, y, pixel; 1528ecbaeeSPaolo Bonzini char name[16]; 1628ecbaeeSPaolo Bonzini uint8_t idx; 1728ecbaeeSPaolo Bonzini 1828ecbaeeSPaolo Bonzini /* parse header line: width, height, #colors, #chars */ 1928ecbaeeSPaolo Bonzini if (sscanf(xpm[line], "%u %u %u %u", 2028ecbaeeSPaolo Bonzini &width, &height, &colors, &chars) != 4) { 2128ecbaeeSPaolo Bonzini fprintf(stderr, "%s: header parse error: \"%s\"\n", 2228ecbaeeSPaolo Bonzini __FUNCTION__, xpm[line]); 2328ecbaeeSPaolo Bonzini return NULL; 2428ecbaeeSPaolo Bonzini } 2528ecbaeeSPaolo Bonzini if (chars != 1) { 2628ecbaeeSPaolo Bonzini fprintf(stderr, "%s: chars != 1 not supported\n", __FUNCTION__); 2728ecbaeeSPaolo Bonzini return NULL; 2828ecbaeeSPaolo Bonzini } 2928ecbaeeSPaolo Bonzini line++; 3028ecbaeeSPaolo Bonzini 3128ecbaeeSPaolo Bonzini /* parse color table */ 3228ecbaeeSPaolo Bonzini for (i = 0; i < colors; i++, line++) { 3328ecbaeeSPaolo Bonzini if (sscanf(xpm[line], "%c c %15s", &idx, name) == 2) { 3428ecbaeeSPaolo Bonzini if (sscanf(name, "#%02x%02x%02x", &r, &g, &b) == 3) { 3528ecbaeeSPaolo Bonzini ctab[idx] = (0xff << 24) | (b << 16) | (g << 8) | r; 3628ecbaeeSPaolo Bonzini continue; 3728ecbaeeSPaolo Bonzini } 3828ecbaeeSPaolo Bonzini if (strcmp(name, "None") == 0) { 3928ecbaeeSPaolo Bonzini ctab[idx] = 0x00000000; 4028ecbaeeSPaolo Bonzini continue; 4128ecbaeeSPaolo Bonzini } 4228ecbaeeSPaolo Bonzini } 4328ecbaeeSPaolo Bonzini fprintf(stderr, "%s: color parse error: \"%s\"\n", 4428ecbaeeSPaolo Bonzini __FUNCTION__, xpm[line]); 4528ecbaeeSPaolo Bonzini return NULL; 4628ecbaeeSPaolo Bonzini } 4728ecbaeeSPaolo Bonzini 4828ecbaeeSPaolo Bonzini /* parse pixel data */ 4928ecbaeeSPaolo Bonzini c = cursor_alloc(width, height); 5028ecbaeeSPaolo Bonzini for (pixel = 0, y = 0; y < height; y++, line++) { 5128ecbaeeSPaolo Bonzini for (x = 0; x < height; x++, pixel++) { 5228ecbaeeSPaolo Bonzini idx = xpm[line][x]; 5328ecbaeeSPaolo Bonzini c->data[pixel] = ctab[idx]; 5428ecbaeeSPaolo Bonzini } 5528ecbaeeSPaolo Bonzini } 5628ecbaeeSPaolo Bonzini return c; 5728ecbaeeSPaolo Bonzini } 5828ecbaeeSPaolo Bonzini 5928ecbaeeSPaolo Bonzini /* nice for debugging */ 6028ecbaeeSPaolo Bonzini void cursor_print_ascii_art(QEMUCursor *c, const char *prefix) 6128ecbaeeSPaolo Bonzini { 6228ecbaeeSPaolo Bonzini uint32_t *data = c->data; 6328ecbaeeSPaolo Bonzini int x,y; 6428ecbaeeSPaolo Bonzini 6528ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 6628ecbaeeSPaolo Bonzini fprintf(stderr, "%s: %2d: |", prefix, y); 6728ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 6828ecbaeeSPaolo Bonzini if ((*data & 0xff000000) != 0xff000000) { 6928ecbaeeSPaolo Bonzini fprintf(stderr, " "); /* transparent */ 7028ecbaeeSPaolo Bonzini } else if ((*data & 0x00ffffff) == 0x00ffffff) { 7128ecbaeeSPaolo Bonzini fprintf(stderr, "."); /* white */ 7228ecbaeeSPaolo Bonzini } else if ((*data & 0x00ffffff) == 0x00000000) { 7328ecbaeeSPaolo Bonzini fprintf(stderr, "X"); /* black */ 7428ecbaeeSPaolo Bonzini } else { 7528ecbaeeSPaolo Bonzini fprintf(stderr, "o"); /* other */ 7628ecbaeeSPaolo Bonzini } 7728ecbaeeSPaolo Bonzini } 7828ecbaeeSPaolo Bonzini fprintf(stderr, "|\n"); 7928ecbaeeSPaolo Bonzini } 8028ecbaeeSPaolo Bonzini } 8128ecbaeeSPaolo Bonzini 8228ecbaeeSPaolo Bonzini QEMUCursor *cursor_builtin_hidden(void) 8328ecbaeeSPaolo Bonzini { 8428ecbaeeSPaolo Bonzini QEMUCursor *c; 8528ecbaeeSPaolo Bonzini 8628ecbaeeSPaolo Bonzini c = cursor_parse_xpm(cursor_hidden_xpm); 8728ecbaeeSPaolo Bonzini return c; 8828ecbaeeSPaolo Bonzini } 8928ecbaeeSPaolo Bonzini 9028ecbaeeSPaolo Bonzini QEMUCursor *cursor_builtin_left_ptr(void) 9128ecbaeeSPaolo Bonzini { 9228ecbaeeSPaolo Bonzini QEMUCursor *c; 9328ecbaeeSPaolo Bonzini 9428ecbaeeSPaolo Bonzini c = cursor_parse_xpm(cursor_left_ptr_xpm); 9528ecbaeeSPaolo Bonzini return c; 9628ecbaeeSPaolo Bonzini } 9728ecbaeeSPaolo Bonzini 9828ecbaeeSPaolo Bonzini QEMUCursor *cursor_alloc(int width, int height) 9928ecbaeeSPaolo Bonzini { 10028ecbaeeSPaolo Bonzini QEMUCursor *c; 10128ecbaeeSPaolo Bonzini int datasize = width * height * sizeof(uint32_t); 10228ecbaeeSPaolo Bonzini 10328ecbaeeSPaolo Bonzini c = g_malloc0(sizeof(QEMUCursor) + datasize); 10428ecbaeeSPaolo Bonzini c->width = width; 10528ecbaeeSPaolo Bonzini c->height = height; 10628ecbaeeSPaolo Bonzini c->refcount = 1; 10728ecbaeeSPaolo Bonzini return c; 10828ecbaeeSPaolo Bonzini } 10928ecbaeeSPaolo Bonzini 11028ecbaeeSPaolo Bonzini void cursor_get(QEMUCursor *c) 11128ecbaeeSPaolo Bonzini { 11228ecbaeeSPaolo Bonzini c->refcount++; 11328ecbaeeSPaolo Bonzini } 11428ecbaeeSPaolo Bonzini 11528ecbaeeSPaolo Bonzini void cursor_put(QEMUCursor *c) 11628ecbaeeSPaolo Bonzini { 11728ecbaeeSPaolo Bonzini if (c == NULL) 11828ecbaeeSPaolo Bonzini return; 11928ecbaeeSPaolo Bonzini c->refcount--; 12028ecbaeeSPaolo Bonzini if (c->refcount) 12128ecbaeeSPaolo Bonzini return; 12228ecbaeeSPaolo Bonzini g_free(c); 12328ecbaeeSPaolo Bonzini } 12428ecbaeeSPaolo Bonzini 12528ecbaeeSPaolo Bonzini int cursor_get_mono_bpl(QEMUCursor *c) 12628ecbaeeSPaolo Bonzini { 12728ecbaeeSPaolo Bonzini return (c->width + 7) / 8; 12828ecbaeeSPaolo Bonzini } 12928ecbaeeSPaolo Bonzini 13028ecbaeeSPaolo Bonzini void cursor_set_mono(QEMUCursor *c, 13128ecbaeeSPaolo Bonzini uint32_t foreground, uint32_t background, uint8_t *image, 13228ecbaeeSPaolo Bonzini int transparent, uint8_t *mask) 13328ecbaeeSPaolo Bonzini { 13428ecbaeeSPaolo Bonzini uint32_t *data = c->data; 13528ecbaeeSPaolo Bonzini uint8_t bit; 13628ecbaeeSPaolo Bonzini int x,y,bpl; 13728ecbaeeSPaolo Bonzini 13828ecbaeeSPaolo Bonzini bpl = cursor_get_mono_bpl(c); 13928ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 14028ecbaeeSPaolo Bonzini bit = 0x80; 14128ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 14228ecbaeeSPaolo Bonzini if (transparent && mask[x/8] & bit) { 14328ecbaeeSPaolo Bonzini *data = 0x00000000; 14428ecbaeeSPaolo Bonzini } else if (!transparent && !(mask[x/8] & bit)) { 14528ecbaeeSPaolo Bonzini *data = 0x00000000; 14628ecbaeeSPaolo Bonzini } else if (image[x/8] & bit) { 14728ecbaeeSPaolo Bonzini *data = 0xff000000 | foreground; 14828ecbaeeSPaolo Bonzini } else { 14928ecbaeeSPaolo Bonzini *data = 0xff000000 | background; 15028ecbaeeSPaolo Bonzini } 15128ecbaeeSPaolo Bonzini bit >>= 1; 15228ecbaeeSPaolo Bonzini if (bit == 0) { 15328ecbaeeSPaolo Bonzini bit = 0x80; 15428ecbaeeSPaolo Bonzini } 15528ecbaeeSPaolo Bonzini } 15628ecbaeeSPaolo Bonzini mask += bpl; 15728ecbaeeSPaolo Bonzini image += bpl; 15828ecbaeeSPaolo Bonzini } 15928ecbaeeSPaolo Bonzini } 16028ecbaeeSPaolo Bonzini 16128ecbaeeSPaolo Bonzini void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image) 16228ecbaeeSPaolo Bonzini { 16328ecbaeeSPaolo Bonzini uint32_t *data = c->data; 16428ecbaeeSPaolo Bonzini uint8_t bit; 16528ecbaeeSPaolo Bonzini int x,y,bpl; 16628ecbaeeSPaolo Bonzini 16728ecbaeeSPaolo Bonzini bpl = cursor_get_mono_bpl(c); 16828ecbaeeSPaolo Bonzini memset(image, 0, bpl * c->height); 16928ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 17028ecbaeeSPaolo Bonzini bit = 0x80; 17128ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 17228ecbaeeSPaolo Bonzini if (((*data & 0xff000000) == 0xff000000) && 17328ecbaeeSPaolo Bonzini ((*data & 0x00ffffff) == foreground)) { 17428ecbaeeSPaolo Bonzini image[x/8] |= bit; 17528ecbaeeSPaolo Bonzini } 17628ecbaeeSPaolo Bonzini bit >>= 1; 17728ecbaeeSPaolo Bonzini if (bit == 0) { 17828ecbaeeSPaolo Bonzini bit = 0x80; 17928ecbaeeSPaolo Bonzini } 18028ecbaeeSPaolo Bonzini } 18128ecbaeeSPaolo Bonzini image += bpl; 18228ecbaeeSPaolo Bonzini } 18328ecbaeeSPaolo Bonzini } 18428ecbaeeSPaolo Bonzini 18528ecbaeeSPaolo Bonzini void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask) 18628ecbaeeSPaolo Bonzini { 18728ecbaeeSPaolo Bonzini uint32_t *data = c->data; 18828ecbaeeSPaolo Bonzini uint8_t bit; 18928ecbaeeSPaolo Bonzini int x,y,bpl; 19028ecbaeeSPaolo Bonzini 19128ecbaeeSPaolo Bonzini bpl = cursor_get_mono_bpl(c); 19228ecbaeeSPaolo Bonzini memset(mask, 0, bpl * c->height); 19328ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 19428ecbaeeSPaolo Bonzini bit = 0x80; 19528ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 19628ecbaeeSPaolo Bonzini if ((*data & 0xff000000) != 0xff000000) { 19728ecbaeeSPaolo Bonzini if (transparent != 0) { 19828ecbaeeSPaolo Bonzini mask[x/8] |= bit; 19928ecbaeeSPaolo Bonzini } 20028ecbaeeSPaolo Bonzini } else { 20128ecbaeeSPaolo Bonzini if (transparent == 0) { 20228ecbaeeSPaolo Bonzini mask[x/8] |= bit; 20328ecbaeeSPaolo Bonzini } 20428ecbaeeSPaolo Bonzini } 20528ecbaeeSPaolo Bonzini bit >>= 1; 20628ecbaeeSPaolo Bonzini if (bit == 0) { 20728ecbaeeSPaolo Bonzini bit = 0x80; 20828ecbaeeSPaolo Bonzini } 20928ecbaeeSPaolo Bonzini } 21028ecbaeeSPaolo Bonzini mask += bpl; 21128ecbaeeSPaolo Bonzini } 21228ecbaeeSPaolo Bonzini } 213