mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-common
synced 2025-12-26 14:18:36 +00:00
Properly parse QXLImage to the new-world SpiceImage
SpiceImage now replaces RedImage and has all image types in it. All image data are now chunked (and as such not copied when demarshalling).
This commit is contained in:
parent
4b6605fc42
commit
e37ce72809
@ -69,18 +69,6 @@
|
||||
(((descriptor)->type == SPICE_IMAGE_TYPE_JPEG) || \
|
||||
((descriptor)->type == SPICE_IMAGE_TYPE_JPEG_ALPHA))
|
||||
|
||||
#ifdef WIN32
|
||||
typedef struct __declspec (align(1)) LZImage {
|
||||
#else
|
||||
typedef struct __attribute__ ((__packed__)) LZImage {
|
||||
#endif
|
||||
SpiceImageDescriptor descriptor;
|
||||
union {
|
||||
SpiceLZRGBData lz_rgb;
|
||||
SpiceLZPLTData lz_plt;
|
||||
};
|
||||
} LZImage;
|
||||
|
||||
static inline int fix_to_int(SPICE_FIXED28_4 fixed)
|
||||
{
|
||||
int val, rem;
|
||||
@ -157,11 +145,9 @@ typedef struct QuicData {
|
||||
QuicUsrContext usr;
|
||||
QuicContext *quic;
|
||||
jmp_buf jmp_env;
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
SPICE_ADDRESS next;
|
||||
SpiceVirtMapping *virt_mapping;
|
||||
#endif
|
||||
char message_buf[512];
|
||||
SpiceChunks *chunks;
|
||||
int current_chunk;
|
||||
} QuicData;
|
||||
|
||||
typedef struct CanvasBase {
|
||||
@ -196,32 +182,6 @@ typedef struct CanvasBase {
|
||||
spice_destroy_fn_t usr_data_destroy;
|
||||
} CanvasBase;
|
||||
|
||||
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define ATTR_PACKED __attribute__ ((__packed__))
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
#define ATTR_PACKED
|
||||
#endif
|
||||
|
||||
typedef struct ATTR_PACKED DataChunk {
|
||||
uint32_t size;
|
||||
SPICE_ADDRESS prev;
|
||||
SPICE_ADDRESS next;
|
||||
uint8_t data[0];
|
||||
} DataChunk;
|
||||
|
||||
#undef ATTR_PACKED
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ROP_INPUT_SRC,
|
||||
ROP_INPUT_BRUSH,
|
||||
@ -434,7 +394,7 @@ static pixman_format_code_t canvas_get_target_format(CanvasBase *canvas,
|
||||
return format;
|
||||
}
|
||||
|
||||
static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image,
|
||||
static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceImage *image,
|
||||
int invers, int want_original)
|
||||
{
|
||||
pixman_image_t *surface = NULL;
|
||||
@ -445,30 +405,21 @@ static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image
|
||||
int stride;
|
||||
int width;
|
||||
int height;
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
DataChunk **tmp;
|
||||
DataChunk *chunk;
|
||||
#endif
|
||||
|
||||
if (setjmp(quic_data->jmp_env)) {
|
||||
pixman_image_unref(surface);
|
||||
CANVAS_ERROR("quic error, %s", quic_data->message_buf);
|
||||
}
|
||||
|
||||
#ifdef SW_CANVAS_NO_CHUNKS
|
||||
if (quic_decode_begin(quic_data->quic, (uint32_t *)image->quic.data,
|
||||
image->quic.data_size >> 2, &type, &width, &height) == QUIC_ERROR) {
|
||||
CANVAS_ERROR("quic decode begin failed");
|
||||
}
|
||||
#else
|
||||
tmp = (DataChunk **)image->quic.data;
|
||||
chunk = *tmp;
|
||||
quic_data->next = chunk->next;
|
||||
if (quic_decode_begin(quic_data->quic, (uint32_t *)chunk->data, chunk->size >> 2,
|
||||
quic_data->chunks = image->u.quic.data;
|
||||
quic_data->current_chunk = 0;
|
||||
|
||||
if (quic_decode_begin(quic_data->quic,
|
||||
(uint32_t *)image->u.quic.data->chunk[0].data,
|
||||
image->u.quic.data->chunk[0].len >> 2,
|
||||
&type, &width, &height) == QUIC_ERROR) {
|
||||
CANVAS_ERROR("quic decode begin failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (type) {
|
||||
case QUIC_IMAGE_TYPE_RGBA:
|
||||
@ -564,7 +515,7 @@ static void dump_jpeg(uint8_t* data, int data_size)
|
||||
}
|
||||
#endif
|
||||
|
||||
static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceJPEGImage *image, int invers)
|
||||
static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceImage *image, int invers)
|
||||
{
|
||||
pixman_image_t *surface = NULL;
|
||||
int stride;
|
||||
@ -572,7 +523,8 @@ static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceJPEGImage *image
|
||||
int height;
|
||||
uint8_t *dest;
|
||||
|
||||
canvas->jpeg->ops->begin_decode(canvas->jpeg, image->jpeg.data, image->jpeg.data_size,
|
||||
ASSERT(image->u.jpeg.data->num_chunks == 1); /* TODO: Handle chunks */
|
||||
canvas->jpeg->ops->begin_decode(canvas->jpeg, image->u.jpeg.data->chunk[0].data, image->u.jpeg.data->chunk[0].len,
|
||||
&width, &height);
|
||||
ASSERT((uint32_t)width == image->descriptor.width);
|
||||
ASSERT((uint32_t)height == image->descriptor.height);
|
||||
@ -606,13 +558,13 @@ static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceJPEGImage *image
|
||||
}
|
||||
}
|
||||
#ifdef DUMP_JPEG
|
||||
dump_jpeg(image->jpeg.data, image->jpeg.data_size);
|
||||
dump_jpeg(image->u.jpeg.data, image->u.jpeg.data_size);
|
||||
#endif
|
||||
return surface;
|
||||
}
|
||||
|
||||
static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
|
||||
SpiceJPEGAlphaImage *image, int invers)
|
||||
SpiceImage *image, int invers)
|
||||
{
|
||||
pixman_image_t *surface = NULL;
|
||||
int stride;
|
||||
@ -627,13 +579,15 @@ static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
|
||||
int alpha_size;
|
||||
int lz_alpha_width, lz_alpha_height, n_comp_pixels, lz_alpha_top_down;
|
||||
|
||||
canvas->jpeg->ops->begin_decode(canvas->jpeg, image->jpeg_alpha.data,
|
||||
image->jpeg_alpha.jpeg_size,
|
||||
ASSERT(image->u.jpeg_alpha.data->num_chunks == 1);
|
||||
canvas->jpeg->ops->begin_decode(canvas->jpeg,
|
||||
image->u.jpeg_alpha.data->chunk[0].data,
|
||||
image->u.jpeg_alpha.data->chunk[0].len,
|
||||
&width, &height);
|
||||
ASSERT((uint32_t)width == image->descriptor.width);
|
||||
ASSERT((uint32_t)height == image->descriptor.height);
|
||||
|
||||
if (image->jpeg_alpha.flags & SPICE_JPEG_ALPHA_FLAGS_TOP_DOWN) {
|
||||
if (image->u.jpeg_alpha.flags & SPICE_JPEG_ALPHA_FLAGS_TOP_DOWN) {
|
||||
alpha_top_down = TRUE;
|
||||
}
|
||||
|
||||
@ -642,7 +596,7 @@ static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
|
||||
#endif
|
||||
surface = alloc_lz_image_surface(&lz_data->decode_data, PIXMAN_a8r8g8b8,
|
||||
width, height, width*height, alpha_top_down);
|
||||
|
||||
|
||||
if (surface == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
@ -651,9 +605,9 @@ static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
|
||||
stride = pixman_image_get_stride(surface);
|
||||
|
||||
canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
|
||||
|
||||
comp_alpha_buf = image->jpeg_alpha.data + image->jpeg_alpha.jpeg_size;
|
||||
alpha_size = image->jpeg_alpha.data_size - image->jpeg_alpha.jpeg_size;
|
||||
|
||||
comp_alpha_buf = image->u.jpeg_alpha.data->chunk[0].data + image->u.jpeg_alpha.jpeg_size;
|
||||
alpha_size = image->u.jpeg_alpha.data_size - image->u.jpeg_alpha.jpeg_size;
|
||||
|
||||
lz_decode_begin(lz_data->lz, comp_alpha_buf, alpha_size, &lz_alpha_type,
|
||||
&lz_alpha_width, &lz_alpha_height, &n_comp_pixels,
|
||||
@ -685,7 +639,7 @@ static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas,
|
||||
}
|
||||
}
|
||||
#ifdef DUMP_JPEG
|
||||
dump_jpeg(image->jpeg_alpha.data, image->jpeg_alpha.jpeg_size);
|
||||
dump_jpeg(image->u.jpeg_alpha.data, image->u.jpeg_alpha.jpeg_size);
|
||||
#endif
|
||||
return surface;
|
||||
}
|
||||
@ -698,7 +652,9 @@ static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap*
|
||||
pixman_image_t *image;
|
||||
pixman_format_code_t format;
|
||||
|
||||
src = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
|
||||
spice_chunks_linearize(bitmap->data);
|
||||
|
||||
src = bitmap->data->chunk[0].data;
|
||||
src_stride = bitmap->stride;
|
||||
|
||||
if (want_original) {
|
||||
@ -730,27 +686,24 @@ static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap*
|
||||
|
||||
#ifdef SW_CANVAS_CACHE
|
||||
|
||||
static inline SpicePalette *canvas_get_palette(CanvasBase *canvas, SPICE_ADDRESS base_palette, uint8_t flags)
|
||||
static inline SpicePalette *canvas_get_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags)
|
||||
{
|
||||
SpicePalette *palette;
|
||||
if (!base_palette) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE) {
|
||||
palette = canvas->palette_cache->ops->get(canvas->palette_cache, base_palette);
|
||||
} else if (flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME) {
|
||||
palette = (SpicePalette *)SPICE_GET_ADDRESS(base_palette);
|
||||
canvas->palette_cache->ops->put(canvas->palette_cache, palette);
|
||||
palette = canvas->palette_cache->ops->get(canvas->palette_cache, palette_id);
|
||||
} else {
|
||||
palette = (SpicePalette *)SPICE_GET_ADDRESS(base_palette);
|
||||
palette = base_palette;
|
||||
if (palette != NULL && flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME) {
|
||||
canvas->palette_cache->ops->put(canvas->palette_cache, palette);
|
||||
}
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
static inline SpicePalette *canvas_get_localized_palette(CanvasBase *canvas, SPICE_ADDRESS base_palette, uint8_t flags, int *free_palette)
|
||||
static inline SpicePalette *canvas_get_localized_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags, int *free_palette)
|
||||
{
|
||||
SpicePalette *palette = canvas_get_palette(canvas, base_palette, flags);
|
||||
SpicePalette *palette = canvas_get_palette(canvas, base_palette, palette_id, flags);
|
||||
SpicePalette *copy;
|
||||
uint32_t *now, *end;
|
||||
size_t size;
|
||||
@ -784,7 +737,7 @@ static inline SpicePalette *canvas_get_localized_palette(CanvasBase *canvas, SPI
|
||||
return copy;
|
||||
}
|
||||
|
||||
static pixman_image_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int invers,
|
||||
static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image, int invers,
|
||||
int want_original)
|
||||
{
|
||||
LzData *lz_data = &canvas->lz_data;
|
||||
@ -811,13 +764,15 @@ static pixman_image_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int inv
|
||||
|
||||
free_palette = FALSE;
|
||||
if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB) {
|
||||
comp_buf = image->lz_rgb.data;
|
||||
comp_size = image->lz_rgb.data_size;
|
||||
ASSERT(image->u.lz_rgb.data->num_chunks == 1); /* TODO: Handle chunks */
|
||||
comp_buf = image->u.lz_rgb.data->chunk[0].data;
|
||||
comp_size = image->u.lz_rgb.data->chunk[0].len;
|
||||
palette = NULL;
|
||||
} else if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
|
||||
comp_buf = image->lz_plt.data;
|
||||
comp_size = image->lz_plt.data_size;
|
||||
palette = canvas_get_localized_palette(canvas, image->lz_plt.palette, image->lz_plt.flags, &free_palette);
|
||||
ASSERT(image->u.lz_plt.data->num_chunks == 1); /* TODO: Handle chunks */
|
||||
comp_buf = image->u.lz_plt.data->chunk[0].data;
|
||||
comp_size = image->u.lz_plt.data->chunk[0].len;
|
||||
palette = canvas_get_localized_palette(canvas, image->u.lz_plt.palette, image->u.lz_plt.palette_id, image->u.lz_plt.flags, &free_palette);
|
||||
} else {
|
||||
CANVAS_ERROR("unexpected image type");
|
||||
}
|
||||
@ -918,7 +873,7 @@ static pixman_image_t *canvas_get_glz_rgb_common(CanvasBase *canvas, uint8_t *da
|
||||
|
||||
// don't handle plts since bitmaps with plt can be decoded globally to RGB32 (because
|
||||
// same byte sequence can be transformed to different RGB pixels by different plts)
|
||||
static pixman_image_t *canvas_get_glz(CanvasBase *canvas, LZImage *image,
|
||||
static pixman_image_t *canvas_get_glz(CanvasBase *canvas, SpiceImage *image,
|
||||
int want_original)
|
||||
{
|
||||
ASSERT(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB);
|
||||
@ -926,10 +881,11 @@ static pixman_image_t *canvas_get_glz(CanvasBase *canvas, LZImage *image,
|
||||
canvas->glz_data.decode_data.dc = canvas->dc;
|
||||
#endif
|
||||
|
||||
return canvas_get_glz_rgb_common(canvas, image->lz_rgb.data, want_original);
|
||||
ASSERT(image->u.lz_rgb.data->num_chunks == 1); /* TODO: Handle chunks */
|
||||
return canvas_get_glz_rgb_common(canvas, image->u.lz_rgb.data->chunk[0].data, want_original);
|
||||
}
|
||||
|
||||
static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceZlibGlzRGBImage *image,
|
||||
static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceImage *image,
|
||||
int want_original)
|
||||
{
|
||||
uint8_t *glz_data;
|
||||
@ -939,9 +895,11 @@ static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceZlibGlzR
|
||||
CANVAS_ERROR("zlib not supported");
|
||||
}
|
||||
|
||||
glz_data = (uint8_t*)spice_malloc(image->zlib_glz.glz_data_size);
|
||||
canvas->zlib->ops->decode(canvas->zlib, image->zlib_glz.data, image->zlib_glz.data_size,
|
||||
glz_data, image->zlib_glz.glz_data_size);
|
||||
ASSERT(image->u.zlib_glz.data->num_chunks == 1); /* TODO: Handle chunks */
|
||||
glz_data = (uint8_t*)spice_malloc(image->u.zlib_glz.glz_data_size);
|
||||
canvas->zlib->ops->decode(canvas->zlib, image->u.zlib_glz.data->chunk[0].data,
|
||||
image->u.zlib_glz.data->chunk[0].len,
|
||||
glz_data, image->u.zlib_glz.glz_data_size);
|
||||
surface = canvas_get_glz_rgb_common(canvas, glz_data, want_original);
|
||||
free(glz_data);
|
||||
return surface;
|
||||
@ -993,7 +951,7 @@ static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
|
||||
pixman_image_t* surface;
|
||||
SpicePalette *palette;
|
||||
|
||||
palette = canvas_get_palette(canvas, bitmap->palette, bitmap->flags);
|
||||
palette = canvas_get_palette(canvas, bitmap->palette, bitmap->palette_id, bitmap->flags);
|
||||
#ifdef DEBUG_DUMP_BITMAP
|
||||
if (palette) {
|
||||
dump_bitmap(bitmap, palette);
|
||||
@ -1079,26 +1037,20 @@ static void dump_surface(pixman_image_t *surface, int cache)
|
||||
|
||||
#endif
|
||||
|
||||
static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SpiceImage *image)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
|
||||
if (descriptor->type == SPICE_IMAGE_TYPE_SURFACE) {
|
||||
SpiceSurfaceImage *surface = (SpiceSurfaceImage *)descriptor;
|
||||
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface.surface_id);
|
||||
if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
|
||||
SpiceSurface *surface = &image->u.surface;
|
||||
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SpiceImage *image)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor;
|
||||
|
||||
descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
|
||||
if (descriptor->type == SPICE_IMAGE_TYPE_SURFACE) {
|
||||
SpiceSurfaceImage *surface = (SpiceSurfaceImage *)descriptor;
|
||||
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface.surface_id);
|
||||
if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
|
||||
SpiceSurface *surface = &image->u.surface;
|
||||
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1115,10 +1067,10 @@ static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SPICE_A
|
||||
* you have to be able to handle any image format. This is useful to avoid
|
||||
* e.g. losing alpha when blending a argb32 image on a rgb16 surface.
|
||||
*/
|
||||
static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRESS addr,
|
||||
static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
|
||||
int want_original, int real_get)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
SpiceImageDescriptor *descriptor = &image->descriptor;
|
||||
pixman_image_t *surface, *converted;
|
||||
pixman_format_code_t wanted_format, surface_format;
|
||||
int saved_want_original;
|
||||
@ -1150,40 +1102,33 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
|
||||
|
||||
switch (descriptor->type) {
|
||||
case SPICE_IMAGE_TYPE_QUIC: {
|
||||
SpiceQUICImage *image = (SpiceQUICImage *)descriptor;
|
||||
surface = canvas_get_quic(canvas, image, 0, want_original);
|
||||
break;
|
||||
}
|
||||
#ifdef SW_CANVAS_NO_CHUNKS
|
||||
#if defined(SW_CANVAS_CACHE)
|
||||
case SPICE_IMAGE_TYPE_LZ_PLT: {
|
||||
LZImage *image = (LZImage *)descriptor;
|
||||
surface = canvas_get_lz(canvas, image, 0, want_original);
|
||||
break;
|
||||
}
|
||||
case SPICE_IMAGE_TYPE_LZ_RGB: {
|
||||
LZImage *image = (LZImage *)descriptor;
|
||||
surface = canvas_get_lz(canvas, image, 0, want_original);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SPICE_IMAGE_TYPE_JPEG: {
|
||||
SpiceJPEGImage *image = (SpiceJPEGImage *)descriptor;
|
||||
surface = canvas_get_jpeg(canvas, image, 0);
|
||||
break;
|
||||
}
|
||||
case SPICE_IMAGE_TYPE_JPEG_ALPHA: {
|
||||
SpiceJPEGAlphaImage *image = (SpiceJPEGAlphaImage *)descriptor;
|
||||
surface = canvas_get_jpeg_alpha(canvas, image, 0);
|
||||
break;
|
||||
}
|
||||
#if defined(SW_CANVAS_CACHE)
|
||||
case SPICE_IMAGE_TYPE_GLZ_RGB: {
|
||||
LZImage *image = (LZImage *)descriptor;
|
||||
surface = canvas_get_glz(canvas, image, want_original);
|
||||
break;
|
||||
}
|
||||
case SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB: {
|
||||
SpiceZlibGlzRGBImage *image = (SpiceZlibGlzRGBImage *)descriptor;
|
||||
surface = canvas_get_zlib_glz_rgb(canvas, image, want_original);
|
||||
break;
|
||||
}
|
||||
@ -1197,8 +1142,7 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
|
||||
break;
|
||||
#endif
|
||||
case SPICE_IMAGE_TYPE_BITMAP: {
|
||||
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor;
|
||||
surface = canvas_get_bits(canvas, &bitmap->bitmap, want_original);
|
||||
surface = canvas_get_bits(canvas, &image->u.bitmap, want_original);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1298,10 +1242,10 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
|
||||
|
||||
#else
|
||||
|
||||
static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRESS addr,
|
||||
static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
|
||||
int want_original, int real_get)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
SpiceImageDescriptor *descriptor = &image->descriptor;
|
||||
pixman_format_code_t format;
|
||||
|
||||
/* When touching, never load image. */
|
||||
@ -1311,12 +1255,10 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
|
||||
|
||||
switch (descriptor->type) {
|
||||
case SPICE_IMAGE_TYPE_QUIC: {
|
||||
SpiceQUICImage *image = (SpiceQUICImage *)descriptor;
|
||||
return canvas_get_quic(canvas, image, 0);
|
||||
}
|
||||
case SPICE_IMAGE_TYPE_BITMAP: {
|
||||
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor;
|
||||
return canvas_get_bits(canvas, &bitmap->bitmap, want_original, &format);
|
||||
return canvas_get_bits(canvas, &image->u.bitmap, want_original, &format);
|
||||
}
|
||||
default:
|
||||
CANVAS_ERROR("invalid image type");
|
||||
@ -1325,25 +1267,25 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
|
||||
|
||||
#endif
|
||||
|
||||
static SpiceCanvas *canvas_get_surface_mask(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
static SpiceCanvas *canvas_get_surface_mask(CanvasBase *canvas, SpiceImage *image)
|
||||
{
|
||||
return canvas_get_surface_mask_internal(canvas, addr);
|
||||
return canvas_get_surface_mask_internal(canvas, image);
|
||||
}
|
||||
|
||||
static SpiceCanvas *canvas_get_surface(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
static SpiceCanvas *canvas_get_surface(CanvasBase *canvas, SpiceImage *image)
|
||||
{
|
||||
return canvas_get_surface_internal(canvas, addr);
|
||||
return canvas_get_surface_internal(canvas, image);
|
||||
}
|
||||
|
||||
static pixman_image_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr,
|
||||
static pixman_image_t *canvas_get_image(CanvasBase *canvas, SpiceImage *image,
|
||||
int want_original)
|
||||
{
|
||||
return canvas_get_image_internal(canvas, addr, want_original, TRUE);
|
||||
return canvas_get_image_internal(canvas, image, want_original, TRUE);
|
||||
}
|
||||
|
||||
static void canvas_touch_image(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
static void canvas_touch_image(CanvasBase *canvas, SpiceImage *image)
|
||||
{
|
||||
canvas_get_image_internal(canvas, addr, TRUE, FALSE);
|
||||
canvas_get_image_internal(canvas, image, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static pixman_image_t* canvas_get_image_from_self(SpiceCanvas *canvas,
|
||||
@ -1407,7 +1349,8 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
src_line = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
|
||||
spice_chunks_linearize(bitmap->data);
|
||||
src_line = bitmap->data->chunk[0].data;
|
||||
src_stride = bitmap->stride;
|
||||
end_line = src_line + (bitmap->y * src_stride);
|
||||
line_size = SPICE_ALIGN(bitmap->x, 8) >> 3;
|
||||
@ -1530,7 +1473,7 @@ static inline pixman_image_t *canvas_A1_invers(pixman_image_t *src_surf)
|
||||
|
||||
static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int *needs_invert_out)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor;
|
||||
SpiceImage *image;
|
||||
pixman_image_t *surface;
|
||||
int need_invers;
|
||||
int is_invers;
|
||||
@ -1540,31 +1483,30 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int
|
||||
*needs_invert_out = 0;
|
||||
}
|
||||
|
||||
descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(mask->bitmap);
|
||||
image = mask->bitmap;
|
||||
need_invers = mask->flags & SPICE_MASK_FLAGS_INVERS;
|
||||
|
||||
#ifdef SW_CANVAS_CACHE
|
||||
cache_me = descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME;
|
||||
cache_me = image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME;
|
||||
#else
|
||||
cache_me = 0;
|
||||
#endif
|
||||
|
||||
switch (descriptor->type) {
|
||||
switch (image->descriptor.type) {
|
||||
case SPICE_IMAGE_TYPE_BITMAP: {
|
||||
SpiceBitmapImage *bitmap = (SpiceBitmapImage *)descriptor;
|
||||
is_invers = need_invers && !cache_me;
|
||||
surface = canvas_get_bitmap_mask(canvas, &bitmap->bitmap, is_invers);
|
||||
surface = canvas_get_bitmap_mask(canvas, &image->u.bitmap, is_invers);
|
||||
break;
|
||||
}
|
||||
#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
|
||||
case SPICE_IMAGE_TYPE_FROM_CACHE:
|
||||
surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id);
|
||||
surface = canvas->bits_cache->ops->get(canvas->bits_cache, image->descriptor.id);
|
||||
is_invers = 0;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SW_CANVAS_CACHE
|
||||
case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
|
||||
surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, descriptor->id);
|
||||
surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, image->descriptor.id);
|
||||
is_invers = 0;
|
||||
break;
|
||||
#endif
|
||||
@ -1574,7 +1516,7 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int
|
||||
|
||||
#if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
|
||||
if (cache_me) {
|
||||
canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
|
||||
canvas->bits_cache->ops->put(canvas->bits_cache, image->descriptor.id, surface);
|
||||
}
|
||||
|
||||
if (need_invers && !is_invers) { // surface is in cache
|
||||
@ -1847,13 +1789,6 @@ static void quic_usr_free(QuicUsrContext *usr, void *ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#ifdef SW_CANVAS_NO_CHUNKS
|
||||
|
||||
static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
|
||||
{
|
||||
LzData *usr_data = (LzData *)usr;
|
||||
@ -1896,29 +1831,19 @@ static int lz_usr_more_lines(LzUsrContext *usr, uint8_t **lines)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed)
|
||||
{
|
||||
QuicData *quic_data = (QuicData *)usr;
|
||||
DataChunk *chunk;
|
||||
uint32_t size;
|
||||
|
||||
if (!quic_data->next) {
|
||||
if (quic_data->current_chunk == quic_data->chunks->num_chunks -1) {
|
||||
return 0;
|
||||
}
|
||||
chunk = (DataChunk *)quic_data->virt_mapping->ops->get_virt(quic_data->virt_mapping, quic_data->next,
|
||||
sizeof(DataChunk));
|
||||
size = chunk->size;
|
||||
quic_data->virt_mapping->ops->validate_virt(quic_data->virt_mapping, (unsigned long)chunk->data,
|
||||
quic_data->next, size);
|
||||
quic_data->current_chunk++;
|
||||
|
||||
quic_data->next = chunk->next;
|
||||
*io_ptr = (uint32_t *)chunk->data;
|
||||
return size >> 2;
|
||||
*io_ptr = (uint32_t *)quic_data->chunks->chunk[quic_data->current_chunk].data;
|
||||
return quic_data->chunks->chunk[quic_data->current_chunk].len >> 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
|
||||
{
|
||||
@ -1928,9 +1853,7 @@ static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
|
||||
static void canvas_base_destroy(CanvasBase *canvas)
|
||||
{
|
||||
quic_destroy(canvas->quic_data.quic);
|
||||
#ifdef SW_CANVAS_NO_CHUNKS
|
||||
lz_destroy(canvas->lz_data.lz);
|
||||
#endif
|
||||
#ifdef GDI_CANVAS
|
||||
DeleteDC(canvas->dc);
|
||||
#endif
|
||||
@ -3398,9 +3321,6 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
)
|
||||
{
|
||||
canvas->parent.ops = ops;
|
||||
@ -3411,13 +3331,10 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
|
||||
canvas->quic_data.usr.free = quic_usr_free;
|
||||
canvas->quic_data.usr.more_space = quic_usr_more_space;
|
||||
canvas->quic_data.usr.more_lines = quic_usr_more_lines;
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
canvas->quic_data.virt_mapping = virt_mapping;
|
||||
#endif
|
||||
if (!(canvas->quic_data.quic = quic_create(&canvas->quic_data.usr))) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef SW_CANVAS_NO_CHUNKS
|
||||
|
||||
canvas->lz_data.usr.error = lz_usr_error;
|
||||
canvas->lz_data.usr.warn = lz_usr_warn;
|
||||
canvas->lz_data.usr.info = lz_usr_warn;
|
||||
@ -3428,7 +3345,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
|
||||
if (!(canvas->lz_data.lz = lz_create(&canvas->lz_data.usr))) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
canvas->surfaces = surfaces;
|
||||
canvas->glz_data.decoder = glz_decoder;
|
||||
canvas->jpeg = jpeg_decoder;
|
||||
|
||||
@ -33,7 +33,6 @@ typedef struct _SpicePaletteCache SpicePaletteCache;
|
||||
typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
|
||||
typedef struct _SpiceJpegDecoder SpiceJpegDecoder;
|
||||
typedef struct _SpiceZlibDecoder SpiceZlibDecoder;
|
||||
typedef struct _SpiceVirtMapping SpiceVirtMapping;
|
||||
typedef struct _SpiceCanvas SpiceCanvas;
|
||||
|
||||
typedef struct {
|
||||
@ -120,16 +119,6 @@ struct _SpiceZlibDecoder {
|
||||
SpiceZlibDecoderOps *ops;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *(*get_virt)(SpiceVirtMapping *mapping, unsigned long addr, uint32_t add_size);
|
||||
void (*validate_virt)(SpiceVirtMapping *mapping, unsigned long virt,
|
||||
unsigned long from_addr, uint32_t add_size);
|
||||
} SpiceVirtMappingOps;
|
||||
|
||||
struct _SpiceVirtMapping {
|
||||
SpiceVirtMappingOps *ops;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void (*draw_fill)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
|
||||
void (*draw_copy)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
|
||||
|
||||
@ -806,9 +806,6 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
)
|
||||
{
|
||||
GLCanvas *canvas;
|
||||
@ -835,9 +832,6 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
|
||||
, glz_decoder
|
||||
, jpeg_decoder
|
||||
, zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, virt_mapping
|
||||
#endif
|
||||
);
|
||||
if (!init_ok) {
|
||||
goto error_2;
|
||||
|
||||
@ -32,9 +32,6 @@ SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
);
|
||||
void gl_canvas_set_textures_lost(SpiceCanvas *canvas, int textures_lost);
|
||||
void gl_canvas_init();
|
||||
|
||||
@ -1173,9 +1173,6 @@ static SpiceCanvas *canvas_create_common(pixman_image_t *image,
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
)
|
||||
{
|
||||
SwCanvas *canvas;
|
||||
@ -1202,9 +1199,6 @@ static SpiceCanvas *canvas_create_common(pixman_image_t *image,
|
||||
, glz_decoder
|
||||
, jpeg_decoder
|
||||
, zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, virt_mapping
|
||||
#endif
|
||||
);
|
||||
canvas->private_data = NULL;
|
||||
canvas->private_data_size = 0;
|
||||
@ -1225,9 +1219,6 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
@ -1246,9 +1237,6 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format
|
||||
, glz_decoder
|
||||
, jpeg_decoder
|
||||
, zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, virt_mapping
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
@ -1264,9 +1252,6 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
@ -1285,9 +1270,6 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
|
||||
, glz_decoder
|
||||
, jpeg_decoder
|
||||
, zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, virt_mapping
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -37,9 +37,6 @@ SpiceCanvas *canvas_create(int width, int height, uint32_t format
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
);
|
||||
|
||||
SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint8_t *data, size_t stride
|
||||
@ -53,9 +50,6 @@ SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
, SpiceJpegDecoder *jpeg_decoder
|
||||
, SpiceZlibDecoder *zlib_decoder
|
||||
#ifndef SW_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ def write_read_primitive(writer, start, container, name, scope):
|
||||
writer.assign("pos", start + " + " + container.get_nw_offset(m, "", "__nw_size"))
|
||||
writer.error_check("pos + %s > message_end" % m.member_type.get_fixed_nw_size())
|
||||
|
||||
var = "%s__value" % (name)
|
||||
var = "%s__value" % (name.replace(".", "_"))
|
||||
if not scope.variable_defined(var):
|
||||
scope.variable_def(m.member_type.c_type(), var)
|
||||
writer.assign(var, "read_%s(pos)" % (m.member_type.primitive_type()))
|
||||
@ -112,7 +112,7 @@ def write_read_primitive_item(writer, item, scope):
|
||||
assert(item.type.is_primitive())
|
||||
writer.assign("pos", item.get_position())
|
||||
writer.error_check("pos + %s > message_end" % item.type.get_fixed_nw_size())
|
||||
var = "%s__value" % (item.subprefix)
|
||||
var = "%s__value" % (item.subprefix.replace(".", "_"))
|
||||
scope.variable_def(item.type.c_type(), var)
|
||||
writer.assign(var, "read_%s(pos)" % (item.type.primitive_type()))
|
||||
return var
|
||||
|
||||
@ -811,14 +811,31 @@ class ContainerType(Type):
|
||||
return str(fixed)
|
||||
|
||||
def lookup_member(self, name):
|
||||
dot = name.find('.')
|
||||
rest = None
|
||||
if dot >= 0:
|
||||
rest = name[dot+1:]
|
||||
name = name[:dot]
|
||||
|
||||
member = None
|
||||
if self.members_by_name.has_key(name):
|
||||
return self.members_by_name[name]
|
||||
for m in self.members:
|
||||
if m.is_switch():
|
||||
member = m.lookup_case_member(name)
|
||||
if member:
|
||||
return member
|
||||
raise Exception, "No member called %s found" % name
|
||||
member = self.members_by_name[name]
|
||||
else:
|
||||
for m in self.members:
|
||||
if m.is_switch():
|
||||
member = m.lookup_case_member(name)
|
||||
if member != None:
|
||||
break
|
||||
if member != None:
|
||||
break
|
||||
|
||||
if member == None:
|
||||
raise Exception, "No member called %s found" % name
|
||||
|
||||
if rest != None:
|
||||
return member.member_type.lookup_member(rest)
|
||||
|
||||
return member
|
||||
|
||||
class StructType(ContainerType):
|
||||
def __init__(self, name, members, attribute_list):
|
||||
|
||||
@ -95,7 +95,7 @@ def SPICE_BNF():
|
||||
|
||||
switchCase = Group(Group(OneOrMore(default_.setParseAction(replaceWith(None)) + colon | case_.suppress() + identifier + colon)) + variableDef) \
|
||||
.setParseAction(lambda toks: ptypes.SwitchCase(toks[0][0], toks[0][1]))
|
||||
switchBody = Group(switch_ + lparen + identifier + rparen + lbrace + Group(OneOrMore(switchCase)) + rbrace + identifier + attributes - semi) \
|
||||
switchBody = Group(switch_ + lparen + delimitedList(identifier,delim='.', combine=True) + rparen + lbrace + Group(OneOrMore(switchCase)) + rbrace + identifier + attributes - semi) \
|
||||
.setParseAction(lambda toks: ptypes.Switch(toks[0][1], toks[0][2], toks[0][3], toks[0][4]))
|
||||
messageBody = structBody = Group(lbrace + ZeroOrMore(variableDef | switchBody) + rbrace)
|
||||
structSpec = Group(struct_ + identifier + structBody + attributes).setParseAction(lambda toks: ptypes.StructType(toks[0][1], toks[0][2], toks[0][3]))
|
||||
|
||||
81
spice.proto
81
spice.proto
@ -111,7 +111,7 @@ channel BaseChannel {
|
||||
message {
|
||||
uint32 id;
|
||||
uint64 timestamp;
|
||||
uint8 data[] @end @ctype(uint8_t) @as_ptr(data_len);
|
||||
uint8 data[] @ctype(uint8_t) @as_ptr(data_len);
|
||||
} ping;
|
||||
|
||||
message {
|
||||
@ -435,16 +435,16 @@ struct BitmapData {
|
||||
uint32 stride;
|
||||
switch (flags) {
|
||||
case PAL_FROM_CACHE:
|
||||
uint64 palette;
|
||||
uint64 palette_id;
|
||||
default:
|
||||
Palette *palette @outvar(bitmap);
|
||||
Palette *palette @outvar(bitmap) @c_ptr;
|
||||
} pal @anon;
|
||||
uint8 *data[image_size(8, stride, y)] @nocopy; /* pointer to array, not array of pointers as in C */
|
||||
uint8 *data[image_size(8, stride, y)] @chunk; /* pointer to array, not array of pointers as in C */
|
||||
} @ctype(SpiceBitmap);
|
||||
|
||||
struct BinaryData {
|
||||
uint32 data_size;
|
||||
uint8 data[data_size] @end @nomarshal;
|
||||
uint8 data[data_size] @nomarshal @chunk;
|
||||
} @ctype(SpiceQUICData);
|
||||
|
||||
struct LZPLTData {
|
||||
@ -452,58 +452,63 @@ struct LZPLTData {
|
||||
uint32 data_size;
|
||||
switch (flags) {
|
||||
case PAL_FROM_CACHE:
|
||||
uint64 palette;
|
||||
uint64 palette_id;
|
||||
default:
|
||||
Palette *palette @nonnull @outvar(lzplt);
|
||||
Palette *palette @nonnull @outvar(lzplt) @c_ptr;
|
||||
} pal @anon;
|
||||
uint8 data[data_size] @end @nomarshal;
|
||||
uint8 data[data_size] @nomarshal @chunk;
|
||||
};
|
||||
|
||||
struct ZlibGlzRGBData {
|
||||
uint32 glz_data_size;
|
||||
uint32 data_size;
|
||||
uint8 data[data_size] @end @nomarshal;
|
||||
uint8 data[data_size] @nomarshal @chunk;
|
||||
} @ctype(SpiceZlibGlzRGBData);
|
||||
|
||||
struct JPEGAlphaData {
|
||||
jpeg_alpha_flags flags;
|
||||
uint32 jpeg_size;
|
||||
uint32 data_size;
|
||||
uint8 data[data_size] @end @nomarshal;
|
||||
uint8 data[data_size] @nomarshal @chunk;
|
||||
} @ctype(SpiceJPEGAlphaData);
|
||||
|
||||
struct Surface {
|
||||
uint32 surface_id;
|
||||
};
|
||||
|
||||
struct Image {
|
||||
uint64 id;
|
||||
image_type type;
|
||||
image_flags flags;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
|
||||
switch (type) {
|
||||
struct Image {
|
||||
struct ImageDescriptor {
|
||||
uint64 id;
|
||||
image_type type;
|
||||
image_flags flags;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
} descriptor;
|
||||
|
||||
switch (descriptor.type) {
|
||||
case BITMAP:
|
||||
BitmapData bitmap_data @ctype(SpiceBitmap);
|
||||
BitmapData bitmap;
|
||||
case QUIC:
|
||||
BinaryData quic;
|
||||
case LZ_RGB:
|
||||
case GLZ_RGB:
|
||||
BinaryData lz_rgb;
|
||||
case JPEG:
|
||||
BinaryData binary_data @ctype(SpiceQUICData);
|
||||
BinaryData jpeg;
|
||||
case LZ_PLT:
|
||||
LZPLTData lzplt_data @ctype(SpiceLZPLTData);
|
||||
LZPLTData lz_plt;
|
||||
case ZLIB_GLZ_RGB:
|
||||
ZlibGlzRGBData zlib_glz_data @ctype(SpiceZlibGlzRGBData);
|
||||
ZlibGlzRGBData zlib_glz;
|
||||
case JPEG_ALPHA:
|
||||
JPEGAlphaData jpeg_alpha_data @ctype(SpiceJPEGAlphaData);
|
||||
JPEGAlphaData jpeg_alpha;
|
||||
case SURFACE:
|
||||
Surface surface_data;
|
||||
} u @end;
|
||||
} @ctype(SpiceImageDescriptor);
|
||||
Surface surface;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct Pattern {
|
||||
Image *pat @nonnull;
|
||||
Image *pat @nonnull @c_ptr;
|
||||
Point pos;
|
||||
};
|
||||
|
||||
@ -520,7 +525,7 @@ struct Brush {
|
||||
struct QMask {
|
||||
mask_flags flags;
|
||||
Point pos;
|
||||
Image *bitmap;
|
||||
Image *bitmap @c_ptr;
|
||||
};
|
||||
|
||||
struct LineAttr {
|
||||
@ -649,7 +654,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Opaque {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
Brush brush;
|
||||
ropd rop_descriptor;
|
||||
@ -661,7 +666,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Copy {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
ropd rop_descriptor;
|
||||
image_scale_mode scale_mode;
|
||||
@ -672,7 +677,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Blend {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
ropd rop_descriptor;
|
||||
image_scale_mode scale_mode;
|
||||
@ -704,7 +709,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Rop3 {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
Brush brush;
|
||||
uint8 rop3;
|
||||
@ -739,7 +744,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Transparent {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
uint32 src_color;
|
||||
uint32 true_color;
|
||||
@ -751,7 +756,7 @@ channel DisplayChannel : BaseChannel {
|
||||
struct AlphaBlnd {
|
||||
alpha_flags alpha_flags;
|
||||
uint8 alpha;
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
} data;
|
||||
} draw_alpha_blend;
|
||||
@ -875,7 +880,7 @@ struct CursorHeader {
|
||||
struct Cursor {
|
||||
cursor_flags flags;
|
||||
CursorHeader header;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
};
|
||||
|
||||
channel CursorChannel : BaseChannel {
|
||||
@ -929,13 +934,13 @@ channel PlaybackChannel : BaseChannel {
|
||||
server:
|
||||
message {
|
||||
uint32 time;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
} @ctype(SpiceMsgPlaybackPacket) data = 101;
|
||||
|
||||
message {
|
||||
uint32 time;
|
||||
audio_data_mode mode;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
} mode;
|
||||
|
||||
message {
|
||||
@ -960,13 +965,13 @@ channel RecordChannel : BaseChannel {
|
||||
client:
|
||||
message {
|
||||
uint32 time;
|
||||
uint8 data[] @end @nomarshal @as_ptr(data_size);
|
||||
uint8 data[] @nomarshal @as_ptr(data_size);
|
||||
} @ctype(SpiceMsgcRecordPacket) data = 101;
|
||||
|
||||
message {
|
||||
uint32 time;
|
||||
audio_data_mode mode;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
} mode;
|
||||
|
||||
message {
|
||||
|
||||
67
spice1.proto
67
spice1.proto
@ -111,7 +111,7 @@ channel BaseChannel {
|
||||
message {
|
||||
uint32 id;
|
||||
uint64 timestamp;
|
||||
uint8 data[] @end @ctype(uint8_t) @as_ptr(data_len);
|
||||
uint8 data[] @ctype(uint8_t) @as_ptr(data_len);
|
||||
} ping;
|
||||
|
||||
message {
|
||||
@ -419,16 +419,16 @@ struct BitmapData {
|
||||
uint32 stride;
|
||||
switch (flags) {
|
||||
case PAL_FROM_CACHE:
|
||||
uint64 palette;
|
||||
uint64 palette_id;
|
||||
default:
|
||||
Palette *palette @outvar(bitmap);
|
||||
Palette *palette @outvar(bitmap) @c_ptr;
|
||||
} pal @anon;
|
||||
uint8 *data[image_size(8, stride, y)] @nocopy; /* pointer to array, not array of pointers as in C */
|
||||
uint8 *data[image_size(8, stride, y)] @chunk; /* pointer to array, not array of pointers as in C */
|
||||
} @ctype(SpiceBitmap);
|
||||
|
||||
struct BinaryData {
|
||||
uint32 data_size;
|
||||
uint8 data[data_size] @end @nomarshal;
|
||||
uint8 data[data_size] @nomarshal @chunk;
|
||||
} @ctype(SpiceQUICData);
|
||||
|
||||
struct LZPLTData {
|
||||
@ -436,34 +436,37 @@ struct LZPLTData {
|
||||
uint32 data_size;
|
||||
switch (flags) {
|
||||
case PAL_FROM_CACHE:
|
||||
uint64 palette;
|
||||
uint64 palette_id;
|
||||
default:
|
||||
Palette *palette @nonnull @outvar(lzplt);
|
||||
Palette *palette @nonnull @outvar(lzplt) @c_ptr;
|
||||
} pal @anon;
|
||||
uint8 data[data_size] @end @nomarshal;
|
||||
uint8 data[data_size] @nomarshal @chunk;
|
||||
};
|
||||
|
||||
struct Image {
|
||||
uint64 id;
|
||||
image_type type;
|
||||
image_flags flags;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
struct ImageDescriptor {
|
||||
uint64 id;
|
||||
image_type type;
|
||||
image_flags flags;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
} descriptor;
|
||||
|
||||
switch (type) {
|
||||
switch (descriptor.type) {
|
||||
case BITMAP:
|
||||
BitmapData bitmap_data @ctype(SpiceBitmap);
|
||||
BitmapData bitmap;
|
||||
case QUIC:
|
||||
BinaryData quic;
|
||||
case LZ_RGB:
|
||||
case GLZ_RGB:
|
||||
BinaryData binary_data @ctype(SpiceQUICData);
|
||||
BinaryData lz_rgb;
|
||||
case LZ_PLT:
|
||||
LZPLTData lzplt_data @ctype(SpiceLZPLTData);
|
||||
} u @end;
|
||||
} @ctype(SpiceImageDescriptor);
|
||||
LZPLTData lz_plt;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct Pattern {
|
||||
Image *pat @nonnull;
|
||||
Image *pat @nonnull @c_ptr;
|
||||
Point pos;
|
||||
};
|
||||
|
||||
@ -480,7 +483,7 @@ struct Brush {
|
||||
struct QMask {
|
||||
mask_flags flags;
|
||||
Point pos;
|
||||
Image *bitmap;
|
||||
Image *bitmap @c_ptr;
|
||||
};
|
||||
|
||||
struct LineAttr {
|
||||
@ -608,7 +611,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Opaque {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
Brush brush;
|
||||
ropd rop_descriptor;
|
||||
@ -620,7 +623,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Copy {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
ropd rop_descriptor;
|
||||
image_scale_mode scale_mode;
|
||||
@ -631,7 +634,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Blend {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
ropd rop_descriptor;
|
||||
image_scale_mode scale_mode;
|
||||
@ -663,7 +666,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Rop3 {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
Brush brush;
|
||||
uint8 rop3;
|
||||
@ -698,7 +701,7 @@ channel DisplayChannel : BaseChannel {
|
||||
message {
|
||||
DisplayBase base;
|
||||
struct Transparent {
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
uint32 src_color;
|
||||
uint32 true_color;
|
||||
@ -710,7 +713,7 @@ channel DisplayChannel : BaseChannel {
|
||||
struct AlphaBlnd {
|
||||
int8 alpha_flags @virtual(0);
|
||||
uint8 alpha;
|
||||
Image *src_bitmap;
|
||||
Image *src_bitmap @c_ptr;
|
||||
Rect src_area;
|
||||
} data;
|
||||
} draw_alpha_blend;
|
||||
@ -822,7 +825,7 @@ struct CursorHeader {
|
||||
struct Cursor {
|
||||
cursor_flags flags;
|
||||
CursorHeader header;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
};
|
||||
|
||||
channel CursorChannel : BaseChannel {
|
||||
@ -876,13 +879,13 @@ channel PlaybackChannel : BaseChannel {
|
||||
server:
|
||||
message {
|
||||
uint32 time;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
} @ctype(SpiceMsgPlaybackPacket) data = 101;
|
||||
|
||||
message {
|
||||
uint32 time;
|
||||
audio_data_mode mode;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
} mode;
|
||||
|
||||
message {
|
||||
@ -907,13 +910,13 @@ channel RecordChannel : BaseChannel {
|
||||
client:
|
||||
message {
|
||||
uint32 time;
|
||||
uint8 data[] @end @nomarshal @as_ptr(data_size);
|
||||
uint8 data[] @nomarshal @as_ptr(data_size);
|
||||
} @ctype(SpiceMsgcRecordPacket) data = 101;
|
||||
|
||||
message {
|
||||
uint32 time;
|
||||
audio_data_mode mode;
|
||||
uint8 data[] @end @as_ptr(data_size);
|
||||
uint8 data[] @as_ptr(data_size);
|
||||
} mode;
|
||||
|
||||
message {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user