1e16f4c87SPeter 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", 22*a89f364aSAlistair Francis __func__, xpm[line]); 2328ecbaeeSPaolo Bonzini return NULL; 2428ecbaeeSPaolo Bonzini } 2528ecbaeeSPaolo Bonzini if (chars != 1) { 26*a89f364aSAlistair Francis fprintf(stderr, "%s: chars != 1 not supported\n", __func__); 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", 44*a89f364aSAlistair Francis __func__, 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 { 849be38598SEduardo Habkost return cursor_parse_xpm(cursor_hidden_xpm); 8528ecbaeeSPaolo Bonzini } 8628ecbaeeSPaolo Bonzini 8728ecbaeeSPaolo Bonzini QEMUCursor *cursor_builtin_left_ptr(void) 8828ecbaeeSPaolo Bonzini { 899be38598SEduardo Habkost return cursor_parse_xpm(cursor_left_ptr_xpm); 9028ecbaeeSPaolo Bonzini } 9128ecbaeeSPaolo Bonzini 9228ecbaeeSPaolo Bonzini QEMUCursor *cursor_alloc(int width, int height) 9328ecbaeeSPaolo Bonzini { 9428ecbaeeSPaolo Bonzini QEMUCursor *c; 9528ecbaeeSPaolo Bonzini int datasize = width * height * sizeof(uint32_t); 9628ecbaeeSPaolo Bonzini 9728ecbaeeSPaolo Bonzini c = g_malloc0(sizeof(QEMUCursor) + datasize); 9828ecbaeeSPaolo Bonzini c->width = width; 9928ecbaeeSPaolo Bonzini c->height = height; 10028ecbaeeSPaolo Bonzini c->refcount = 1; 10128ecbaeeSPaolo Bonzini return c; 10228ecbaeeSPaolo Bonzini } 10328ecbaeeSPaolo Bonzini 10428ecbaeeSPaolo Bonzini void cursor_get(QEMUCursor *c) 10528ecbaeeSPaolo Bonzini { 10628ecbaeeSPaolo Bonzini c->refcount++; 10728ecbaeeSPaolo Bonzini } 10828ecbaeeSPaolo Bonzini 10928ecbaeeSPaolo Bonzini void cursor_put(QEMUCursor *c) 11028ecbaeeSPaolo Bonzini { 11128ecbaeeSPaolo Bonzini if (c == NULL) 11228ecbaeeSPaolo Bonzini return; 11328ecbaeeSPaolo Bonzini c->refcount--; 11428ecbaeeSPaolo Bonzini if (c->refcount) 11528ecbaeeSPaolo Bonzini return; 11628ecbaeeSPaolo Bonzini g_free(c); 11728ecbaeeSPaolo Bonzini } 11828ecbaeeSPaolo Bonzini 11928ecbaeeSPaolo Bonzini int cursor_get_mono_bpl(QEMUCursor *c) 12028ecbaeeSPaolo Bonzini { 121935b3332SMarc-André Lureau return DIV_ROUND_UP(c->width, 8); 12228ecbaeeSPaolo Bonzini } 12328ecbaeeSPaolo Bonzini 12428ecbaeeSPaolo Bonzini void cursor_set_mono(QEMUCursor *c, 12528ecbaeeSPaolo Bonzini uint32_t foreground, uint32_t background, uint8_t *image, 12628ecbaeeSPaolo Bonzini int transparent, uint8_t *mask) 12728ecbaeeSPaolo Bonzini { 12828ecbaeeSPaolo Bonzini uint32_t *data = c->data; 12928ecbaeeSPaolo Bonzini uint8_t bit; 13028ecbaeeSPaolo Bonzini int x,y,bpl; 13128ecbaeeSPaolo Bonzini 13228ecbaeeSPaolo Bonzini bpl = cursor_get_mono_bpl(c); 13328ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 13428ecbaeeSPaolo Bonzini bit = 0x80; 13528ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 13628ecbaeeSPaolo Bonzini if (transparent && mask[x/8] & bit) { 13728ecbaeeSPaolo Bonzini *data = 0x00000000; 13828ecbaeeSPaolo Bonzini } else if (!transparent && !(mask[x/8] & bit)) { 13928ecbaeeSPaolo Bonzini *data = 0x00000000; 14028ecbaeeSPaolo Bonzini } else if (image[x/8] & bit) { 14128ecbaeeSPaolo Bonzini *data = 0xff000000 | foreground; 14228ecbaeeSPaolo Bonzini } else { 14328ecbaeeSPaolo Bonzini *data = 0xff000000 | background; 14428ecbaeeSPaolo Bonzini } 14528ecbaeeSPaolo Bonzini bit >>= 1; 14628ecbaeeSPaolo Bonzini if (bit == 0) { 14728ecbaeeSPaolo Bonzini bit = 0x80; 14828ecbaeeSPaolo Bonzini } 14928ecbaeeSPaolo Bonzini } 15028ecbaeeSPaolo Bonzini mask += bpl; 15128ecbaeeSPaolo Bonzini image += bpl; 15228ecbaeeSPaolo Bonzini } 15328ecbaeeSPaolo Bonzini } 15428ecbaeeSPaolo Bonzini 15528ecbaeeSPaolo Bonzini void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image) 15628ecbaeeSPaolo Bonzini { 15728ecbaeeSPaolo Bonzini uint32_t *data = c->data; 15828ecbaeeSPaolo Bonzini uint8_t bit; 15928ecbaeeSPaolo Bonzini int x,y,bpl; 16028ecbaeeSPaolo Bonzini 16128ecbaeeSPaolo Bonzini bpl = cursor_get_mono_bpl(c); 16228ecbaeeSPaolo Bonzini memset(image, 0, bpl * c->height); 16328ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 16428ecbaeeSPaolo Bonzini bit = 0x80; 16528ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 16628ecbaeeSPaolo Bonzini if (((*data & 0xff000000) == 0xff000000) && 16728ecbaeeSPaolo Bonzini ((*data & 0x00ffffff) == foreground)) { 16828ecbaeeSPaolo Bonzini image[x/8] |= bit; 16928ecbaeeSPaolo Bonzini } 17028ecbaeeSPaolo Bonzini bit >>= 1; 17128ecbaeeSPaolo Bonzini if (bit == 0) { 17228ecbaeeSPaolo Bonzini bit = 0x80; 17328ecbaeeSPaolo Bonzini } 17428ecbaeeSPaolo Bonzini } 17528ecbaeeSPaolo Bonzini image += bpl; 17628ecbaeeSPaolo Bonzini } 17728ecbaeeSPaolo Bonzini } 17828ecbaeeSPaolo Bonzini 17928ecbaeeSPaolo Bonzini void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask) 18028ecbaeeSPaolo Bonzini { 18128ecbaeeSPaolo Bonzini uint32_t *data = c->data; 18228ecbaeeSPaolo Bonzini uint8_t bit; 18328ecbaeeSPaolo Bonzini int x,y,bpl; 18428ecbaeeSPaolo Bonzini 18528ecbaeeSPaolo Bonzini bpl = cursor_get_mono_bpl(c); 18628ecbaeeSPaolo Bonzini memset(mask, 0, bpl * c->height); 18728ecbaeeSPaolo Bonzini for (y = 0; y < c->height; y++) { 18828ecbaeeSPaolo Bonzini bit = 0x80; 18928ecbaeeSPaolo Bonzini for (x = 0; x < c->width; x++, data++) { 19028ecbaeeSPaolo Bonzini if ((*data & 0xff000000) != 0xff000000) { 19128ecbaeeSPaolo Bonzini if (transparent != 0) { 19228ecbaeeSPaolo Bonzini mask[x/8] |= bit; 19328ecbaeeSPaolo Bonzini } 19428ecbaeeSPaolo Bonzini } else { 19528ecbaeeSPaolo Bonzini if (transparent == 0) { 19628ecbaeeSPaolo Bonzini mask[x/8] |= bit; 19728ecbaeeSPaolo Bonzini } 19828ecbaeeSPaolo Bonzini } 19928ecbaeeSPaolo Bonzini bit >>= 1; 20028ecbaeeSPaolo Bonzini if (bit == 0) { 20128ecbaeeSPaolo Bonzini bit = 0x80; 20228ecbaeeSPaolo Bonzini } 20328ecbaeeSPaolo Bonzini } 20428ecbaeeSPaolo Bonzini mask += bpl; 20528ecbaeeSPaolo Bonzini } 20628ecbaeeSPaolo Bonzini } 207