static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor, uint32_t group_id) { QEMUCursor *c; size_t size; c = cursor_alloc(cursor->header.width, cursor->header.height); c->hot_x = cursor->header.hot_spot_x; c->hot_y = cursor->header.hot_spot_y; switch (cursor->header.type) { case SPICE_CURSOR_TYPE_ALPHA: size = sizeof(uint32_t) * cursor->header.width * cursor->header.height; qxl_unpack_chunks(c->data, size, qxl, &cursor->chunk, group_id); if (qxl->debug > 2) { cursor_print_ascii_art(c, "qxl/alpha"); } break; default: fprintf(stderr, "%s: not implemented: type %d\n", __FUNCTION__, cursor->header.type); goto fail; } return c; fail: cursor_put(c); return NULL; }
/* for creating built-in cursors */ static QEMUCursor *cursor_parse_xpm(const char *xpm[]) { QEMUCursor *c; uint32_t ctab[128]; unsigned int width, height, colors, chars; unsigned int line = 0, i, r, g, b, x, y, pixel; char name[16]; uint8_t idx; /* parse header line: width, height, #colors, #chars */ if (sscanf(xpm[line], "%u %u %u %u", &width, &height, &colors, &chars) != 4) { fprintf(stderr, "%s: header parse error: \"%s\"\n", __FUNCTION__, xpm[line]); return NULL; } if (chars != 1) { fprintf(stderr, "%s: chars != 1 not supported\n", __FUNCTION__); return NULL; } line++; /* parse color table */ for (i = 0; i < colors; i++, line++) { if (sscanf(xpm[line], "%c c %15s", &idx, name) == 2) { if (sscanf(name, "#%02x%02x%02x", &r, &g, &b) == 3) { ctab[idx] = (0xff << 24) | (b << 16) | (g << 8) | r; continue; } if (strcmp(name, "None") == 0) { ctab[idx] = 0x00000000; continue; } } fprintf(stderr, "%s: color parse error: \"%s\"\n", __FUNCTION__, xpm[line]); return NULL; } /* parse pixel data */ c = cursor_alloc(width, height); for (pixel = 0, y = 0; y < height; y++, line++) { for (x = 0; x < height; x++, pixel++) { idx = xpm[line][x]; c->data[pixel] = ctab[idx]; } } return c; }
static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor) { QEMUCursor *c; uint8_t *image, *mask; size_t size; c = cursor_alloc(cursor->header.width, cursor->header.height); c->hot_x = cursor->header.hot_spot_x; c->hot_y = cursor->header.hot_spot_y; switch (cursor->header.type) { case SPICE_CURSOR_TYPE_ALPHA: size = cursor->header.width * cursor->header.height * sizeof(uint32_t); memcpy(c->data, cursor->chunk.data, size); if (qxl->debug > 2) { cursor_print_ascii_art(c, "qxl/alpha"); } break; case SPICE_CURSOR_TYPE_MONO: mask = cursor->chunk.data; image = mask + cursor_get_mono_bpl(c) * c->width; cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask); if (qxl->debug > 2) { cursor_print_ascii_art(c, "qxl/mono"); } break; default: fprintf(stderr, "%s: not implemented: type %d\n", __FUNCTION__, cursor->header.type); goto fail; } return c; fail: cursor_put(c); return NULL; }