1 /*
2    Copyright (C) 2009 Red Hat, Inc.
3 
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions are
6    met:
7 
8        * Redistributions of source code must retain the above copyright
9          notice, this list of conditions and the following disclaimer.
10        * Redistributions in binary form must reproduce the above copyright
11          notice, this list of conditions and the following disclaimer in
12          the documentation and/or other materials provided with the
13          distribution.
14        * Neither the name of the copyright holder nor the names of its
15          contributors may be used to endorse or promote products derived
16          from this software without specific prior written permission.
17 
18    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
19    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 
32 #ifndef _H_QXL_DEV
33 #define _H_QXL_DEV
34 
35 #include <spice/types.h>
36 #include <spice/barrier.h>
37 #include <spice/ipc_ring.h>
38 #include <spice/enums.h>
39 #include <spice/macros.h>
40 
41 #include <spice/start-packed.h>
42 
43 #define REDHAT_PCI_VENDOR_ID 0x1b36
44 
45 /* 0x100-0x11f reserved for spice, 0x1ff used for unstable work */
46 #define QXL_DEVICE_ID_STABLE 0x0100
47 
48 enum {
49     QXL_REVISION_STABLE_V04=0x01,
50     QXL_REVISION_STABLE_V06=0x02,
51     QXL_REVISION_STABLE_V10=0x03,
52     QXL_REVISION_STABLE_V12=0x04,
53 };
54 
55 #define QXL_DEVICE_ID_DEVEL 0x01ff
56 #define QXL_REVISION_DEVEL 0x01
57 
58 #define QXL_ROM_MAGIC SPICE_MAGIC_CONST("QXRO")
59 #define QXL_RAM_MAGIC SPICE_MAGIC_CONST("QXRA")
60 
61 enum {
62     QXL_RAM_RANGE_INDEX,
63     QXL_VRAM_RANGE_INDEX,
64     QXL_ROM_RANGE_INDEX,
65     QXL_IO_RANGE_INDEX,
66 
67     QXL_PCI_RANGES
68 };
69 
70 /* qxl-1 compat: append only */
71 enum {
72     QXL_IO_NOTIFY_CMD,
73     QXL_IO_NOTIFY_CURSOR,
74     QXL_IO_UPDATE_AREA,
75     QXL_IO_UPDATE_IRQ,
76     QXL_IO_NOTIFY_OOM,
77     QXL_IO_RESET,
78     QXL_IO_SET_MODE,                  /* qxl-1 */
79     QXL_IO_LOG,
80     /* appended for qxl-2 */
81     QXL_IO_MEMSLOT_ADD,
82     QXL_IO_MEMSLOT_DEL,
83     QXL_IO_DETACH_PRIMARY,
84     QXL_IO_ATTACH_PRIMARY,
85     QXL_IO_CREATE_PRIMARY,
86     QXL_IO_DESTROY_PRIMARY,
87     QXL_IO_DESTROY_SURFACE_WAIT,
88     QXL_IO_DESTROY_ALL_SURFACES,
89     /* appended for qxl-3 */
90     QXL_IO_UPDATE_AREA_ASYNC,
91     QXL_IO_MEMSLOT_ADD_ASYNC,
92     QXL_IO_CREATE_PRIMARY_ASYNC,
93     QXL_IO_DESTROY_PRIMARY_ASYNC,
94     QXL_IO_DESTROY_SURFACE_ASYNC,
95     QXL_IO_DESTROY_ALL_SURFACES_ASYNC,
96     QXL_IO_FLUSH_SURFACES_ASYNC,
97     QXL_IO_FLUSH_RELEASE,
98     /* appended for qxl-4 */
99     QXL_IO_MONITORS_CONFIG_ASYNC,
100 
101     QXL_IO_RANGE_SIZE
102 };
103 
104 typedef uint64_t QXLPHYSICAL;
105 typedef int32_t QXLFIXED; //fixed 28.4
106 
107 typedef struct SPICE_ATTR_PACKED QXLPointFix {
108     QXLFIXED x;
109     QXLFIXED y;
110 } QXLPointFix;
111 
112 typedef struct SPICE_ATTR_PACKED QXLPoint {
113     int32_t x;
114     int32_t y;
115 } QXLPoint;
116 
117 typedef struct SPICE_ATTR_PACKED QXLPoint16 {
118     int16_t x;
119     int16_t y;
120 } QXLPoint16;
121 
122 typedef struct SPICE_ATTR_PACKED QXLRect {
123     int32_t top;
124     int32_t left;
125     int32_t bottom;
126     int32_t right;
127 } QXLRect;
128 
129 typedef struct SPICE_ATTR_PACKED QXLURect {
130     uint32_t top;
131     uint32_t left;
132     uint32_t bottom;
133     uint32_t right;
134 } QXLURect;
135 
136 /* qxl-1 compat: append only */
137 typedef struct SPICE_ATTR_PACKED QXLRom {
138     uint32_t magic;
139     uint32_t id;
140     uint32_t update_id;
141     uint32_t compression_level;
142     uint32_t log_level;
143     uint32_t mode;                    /* qxl-1 */
144     uint32_t modes_offset;
145     uint32_t num_pages;
146     uint32_t pages_offset;            /* qxl-1 */
147     uint32_t draw_area_offset;        /* qxl-1 */
148     uint32_t surface0_area_size;      /* qxl-1 name: draw_area_size */
149     uint32_t ram_header_offset;
150     uint32_t mm_clock;
151     /* appended for qxl-2 */
152     uint32_t n_surfaces;
153     uint64_t flags;
154     uint8_t slots_start;
155     uint8_t slots_end;
156     uint8_t slot_gen_bits;
157     uint8_t slot_id_bits;
158     uint8_t slot_generation;
159     /* appended for qxl-4 */
160     uint8_t client_present;
161     uint8_t client_capabilities[58];
162     uint32_t client_monitors_config_crc;
163     struct {
164         uint16_t count;
165         uint16_t padding;
166         QXLURect heads[64];
167     } client_monitors_config;
168 } QXLRom;
169 
170 #define CLIENT_MONITORS_CONFIG_CRC32_POLY 0xedb88320
171 
172 /* qxl-1 compat: fixed */
173 typedef struct SPICE_ATTR_PACKED QXLMode {
174     uint32_t id;
175     uint32_t x_res;
176     uint32_t y_res;
177     uint32_t bits;
178     uint32_t stride;
179     uint32_t x_mili;
180     uint32_t y_mili;
181     uint32_t orientation;
182 } QXLMode;
183 
184 /* qxl-1 compat: fixed */
185 typedef struct SPICE_ATTR_PACKED QXLModes {
186     uint32_t n_modes;
187     QXLMode modes[0];
188 } QXLModes;
189 
190 /* qxl-1 compat: append only */
191 typedef enum QXLCmdType {
192     QXL_CMD_NOP,
193     QXL_CMD_DRAW,
194     QXL_CMD_UPDATE,
195     QXL_CMD_CURSOR,
196     QXL_CMD_MESSAGE,
197     QXL_CMD_SURFACE,
198 } QXLCmdType;
199 
200 /* qxl-1 compat: fixed */
201 typedef struct SPICE_ATTR_PACKED QXLCommand {
202     QXLPHYSICAL data;
203     uint32_t type;
204     uint32_t padding;
205 } QXLCommand;
206 
207 #define QXL_COMMAND_FLAG_COMPAT          (1<<0)
208 #define QXL_COMMAND_FLAG_COMPAT_16BPP    (2<<0)
209 
210 typedef struct SPICE_ATTR_PACKED QXLCommandExt {
211     QXLCommand cmd;
212     uint32_t group_id;
213     uint32_t flags;
214 } QXLCommandExt;
215 
216 typedef struct SPICE_ATTR_PACKED QXLMemSlot {
217     uint64_t mem_start;
218     uint64_t mem_end;
219 } QXLMemSlot;
220 
221 #define QXL_SURF_TYPE_PRIMARY      0
222 
223 #define QXL_SURF_FLAG_KEEP_DATA    (1 << 0)
224 
225 typedef struct SPICE_ATTR_PACKED QXLSurfaceCreate {
226     uint32_t width;
227     uint32_t height;
228     int32_t stride;
229     uint32_t format;
230     uint32_t position;
231     uint32_t mouse_mode;
232     uint32_t flags;
233     uint32_t type;
234     QXLPHYSICAL mem;
235 } QXLSurfaceCreate;
236 
237 #define QXL_COMMAND_RING_SIZE 32
238 #define QXL_CURSOR_RING_SIZE 32
239 #define QXL_RELEASE_RING_SIZE 8
240 
241 SPICE_RING_DECLARE(QXLCommandRing, QXLCommand, QXL_COMMAND_RING_SIZE);
242 SPICE_RING_DECLARE(QXLCursorRing, QXLCommand, QXL_CURSOR_RING_SIZE);
243 
244 SPICE_RING_DECLARE(QXLReleaseRing, uint64_t, QXL_RELEASE_RING_SIZE);
245 
246 #define QXL_LOG_BUF_SIZE 4096
247 
248 #define QXL_INTERRUPT_DISPLAY (1 << 0)
249 #define QXL_INTERRUPT_CURSOR (1 << 1)
250 #define QXL_INTERRUPT_IO_CMD (1 << 2)
251 #define QXL_INTERRUPT_ERROR  (1 << 3)
252 #define QXL_INTERRUPT_CLIENT (1 << 4)
253 #define QXL_INTERRUPT_CLIENT_MONITORS_CONFIG  (1 << 5)
254 
255 /* qxl-1 compat: append only */
256 typedef struct SPICE_ATTR_ALIGNED(4) SPICE_ATTR_PACKED QXLRam {
257     uint32_t magic;
258     uint32_t int_pending;
259     uint32_t int_mask;
260     uint8_t log_buf[QXL_LOG_BUF_SIZE];
261     QXLCommandRing cmd_ring;
262     QXLCursorRing cursor_ring;
263     QXLReleaseRing release_ring;
264     QXLRect update_area;
265     /* appended for qxl-2 */
266     uint32_t update_surface;
267     QXLMemSlot mem_slot;
268     QXLSurfaceCreate create_surface;
269     uint64_t flags;
270 
271     /* appended for qxl-4 */
272 
273     /* used by QXL_IO_MONITORS_CONFIG_ASYNC */
274     QXLPHYSICAL monitors_config;
275 
276 } QXLRam;
277 
278 typedef union SPICE_ATTR_PACKED QXLReleaseInfo {
279     uint64_t id;      // in
280     uint64_t next;    // out
281 } QXLReleaseInfo;
282 
283 typedef struct  SPICE_ATTR_PACKED QXLDataChunk {
284     uint32_t data_size;
285     QXLPHYSICAL prev_chunk;
286     QXLPHYSICAL next_chunk;
287     uint8_t data[0];
288 } QXLDataChunk;
289 
290 typedef struct SPICE_ATTR_PACKED QXLMessage {
291     QXLReleaseInfo release_info;
292     uint8_t data[0];
293 } QXLMessage;
294 
295 typedef struct SPICE_ATTR_PACKED QXLCompatUpdateCmd {
296     QXLReleaseInfo release_info;
297     QXLRect area;
298     uint32_t update_id;
299 } QXLCompatUpdateCmd;
300 
301 typedef struct SPICE_ATTR_PACKED QXLUpdateCmd {
302     QXLReleaseInfo release_info;
303     QXLRect area;
304     uint32_t update_id;
305     uint32_t surface_id;
306 } QXLUpdateCmd;
307 
308 typedef struct SPICE_ATTR_PACKED QXLCursorHeader {
309     uint64_t unique;
310     uint16_t type;
311     uint16_t width;
312     uint16_t height;
313     uint16_t hot_spot_x;
314     uint16_t hot_spot_y;
315 } QXLCursorHeader;
316 
317 typedef struct SPICE_ATTR_PACKED QXLCursor {
318     QXLCursorHeader header;
319     uint32_t data_size;
320     QXLDataChunk chunk;
321 } QXLCursor;
322 
323 enum {
324     QXL_CURSOR_SET,
325     QXL_CURSOR_MOVE,
326     QXL_CURSOR_HIDE,
327     QXL_CURSOR_TRAIL,
328 };
329 
330 #define QXL_CURSUR_DEVICE_DATA_SIZE 128
331 
332 typedef struct SPICE_ATTR_PACKED QXLCursorCmd {
333     QXLReleaseInfo release_info;
334     uint8_t type;
335     union {
336         struct SPICE_ATTR_PACKED {
337             QXLPoint16 position;
338             uint8_t visible;
339             QXLPHYSICAL shape;
340         } set;
341         struct SPICE_ATTR_PACKED {
342             uint16_t length;
343             uint16_t frequency;
344         } trail;
345         QXLPoint16 position;
346     } u;
347     uint8_t device_data[QXL_CURSUR_DEVICE_DATA_SIZE]; //todo: dynamic size from rom
348 } QXLCursorCmd;
349 
350 enum {
351     QXL_DRAW_NOP,
352     QXL_DRAW_FILL,
353     QXL_DRAW_OPAQUE,
354     QXL_DRAW_COPY,
355     QXL_COPY_BITS,
356     QXL_DRAW_BLEND,
357     QXL_DRAW_BLACKNESS,
358     QXL_DRAW_WHITENESS,
359     QXL_DRAW_INVERS,
360     QXL_DRAW_ROP3,
361     QXL_DRAW_STROKE,
362     QXL_DRAW_TEXT,
363     QXL_DRAW_TRANSPARENT,
364     QXL_DRAW_ALPHA_BLEND,
365     QXL_DRAW_COMPOSITE
366 };
367 
368 typedef struct SPICE_ATTR_PACKED QXLRasterGlyph {
369     QXLPoint render_pos;
370     QXLPoint glyph_origin;
371     uint16_t width;
372     uint16_t height;
373     uint8_t data[0];
374 } QXLRasterGlyph;
375 
376 typedef struct SPICE_ATTR_PACKED QXLString {
377     uint32_t data_size;
378     uint16_t length;
379     uint16_t flags;
380     QXLDataChunk chunk;
381 } QXLString;
382 
383 typedef struct SPICE_ATTR_PACKED QXLCopyBits {
384     QXLPoint src_pos;
385 } QXLCopyBits;
386 
387 typedef enum QXLEffectType
388 {
389     QXL_EFFECT_BLEND = 0,
390     QXL_EFFECT_OPAQUE = 1,
391     QXL_EFFECT_REVERT_ON_DUP = 2,
392     QXL_EFFECT_BLACKNESS_ON_DUP = 3,
393     QXL_EFFECT_WHITENESS_ON_DUP = 4,
394     QXL_EFFECT_NOP_ON_DUP = 5,
395     QXL_EFFECT_NOP = 6,
396     QXL_EFFECT_OPAQUE_BRUSH = 7
397 } QXLEffectType;
398 
399 typedef struct SPICE_ATTR_PACKED QXLPattern {
400     QXLPHYSICAL pat;
401     QXLPoint pos;
402 } QXLPattern;
403 
404 typedef struct SPICE_ATTR_PACKED QXLBrush {
405     uint32_t type;
406     union {
407         uint32_t color;
408         QXLPattern pattern;
409     } u;
410 } QXLBrush;
411 
412 typedef struct SPICE_ATTR_PACKED QXLQMask {
413     uint8_t flags;
414     QXLPoint pos;
415     QXLPHYSICAL bitmap;
416 } QXLQMask;
417 
418 typedef struct SPICE_ATTR_PACKED QXLFill {
419     QXLBrush brush;
420     uint16_t rop_descriptor;
421     QXLQMask mask;
422 } QXLFill;
423 
424 typedef struct SPICE_ATTR_PACKED QXLOpaque {
425     QXLPHYSICAL src_bitmap;
426     QXLRect src_area;
427     QXLBrush brush;
428     uint16_t rop_descriptor;
429     uint8_t scale_mode;
430     QXLQMask mask;
431 } QXLOpaque;
432 
433 typedef struct SPICE_ATTR_PACKED QXLCopy {
434     QXLPHYSICAL src_bitmap;
435     QXLRect src_area;
436     uint16_t rop_descriptor;
437     uint8_t scale_mode;
438     QXLQMask mask;
439 } QXLCopy, QXLBlend;
440 
441 typedef struct SPICE_ATTR_PACKED QXLTransparent {
442     QXLPHYSICAL src_bitmap;
443     QXLRect src_area;
444     uint32_t src_color;
445     uint32_t true_color;
446 } QXLTransparent;
447 
448 typedef struct SPICE_ATTR_PACKED QXLAlphaBlend {
449     uint16_t alpha_flags;
450     uint8_t alpha;
451     QXLPHYSICAL src_bitmap;
452     QXLRect src_area;
453 } QXLAlphaBlend;
454 
455 typedef struct SPICE_ATTR_PACKED QXLCompatAlphaBlend {
456     uint8_t alpha;
457     QXLPHYSICAL src_bitmap;
458     QXLRect src_area;
459 } QXLCompatAlphaBlend;
460 
461 typedef struct SPICE_ATTR_PACKED QXLRop3 {
462     QXLPHYSICAL src_bitmap;
463     QXLRect src_area;
464     QXLBrush brush;
465     uint8_t rop3;
466     uint8_t scale_mode;
467     QXLQMask mask;
468 } QXLRop3;
469 
470 typedef struct SPICE_ATTR_PACKED QXLLineAttr {
471     uint8_t flags;
472     uint8_t join_style;
473     uint8_t end_style;
474     uint8_t style_nseg;
475     QXLFIXED width;
476     QXLFIXED miter_limit;
477     QXLPHYSICAL style;
478 } QXLLineAttr;
479 
480 typedef struct SPICE_ATTR_PACKED QXLStroke {
481     QXLPHYSICAL path;
482     QXLLineAttr attr;
483     QXLBrush brush;
484     uint16_t fore_mode;
485     uint16_t back_mode;
486 } QXLStroke;
487 
488 typedef struct SPICE_ATTR_PACKED QXLText {
489     QXLPHYSICAL str;
490     QXLRect back_area;
491     QXLBrush fore_brush;
492     QXLBrush back_brush;
493     uint16_t fore_mode;
494     uint16_t back_mode;
495 } QXLText;
496 
497 typedef struct SPICE_ATTR_PACKED QXLBlackness {
498     QXLQMask mask;
499 } QXLBlackness, QXLInvers, QXLWhiteness;
500 
501 typedef struct SPICE_ATTR_PACKED QXLClip {
502     uint32_t type;
503     QXLPHYSICAL data;
504 } QXLClip;
505 
506 typedef enum {
507     QXL_OP_CLEAR                     = 0x00,
508     QXL_OP_SOURCE		     = 0x01,
509     QXL_OP_DST                       = 0x02,
510     QXL_OP_OVER                      = 0x03,
511     QXL_OP_OVER_REVERSE              = 0x04,
512     QXL_OP_IN                        = 0x05,
513     QXL_OP_IN_REVERSE                = 0x06,
514     QXL_OP_OUT                       = 0x07,
515     QXL_OP_OUT_REVERSE               = 0x08,
516     QXL_OP_ATOP                      = 0x09,
517     QXL_OP_ATOP_REVERSE              = 0x0a,
518     QXL_OP_XOR                       = 0x0b,
519     QXL_OP_ADD                       = 0x0c,
520     QXL_OP_SATURATE                  = 0x0d,
521     /* Note the jump here from 0x0d to 0x30 */
522     QXL_OP_MULTIPLY                  = 0x30,
523     QXL_OP_SCREEN                    = 0x31,
524     QXL_OP_OVERLAY                   = 0x32,
525     QXL_OP_DARKEN                    = 0x33,
526     QXL_OP_LIGHTEN                   = 0x34,
527     QXL_OP_COLOR_DODGE               = 0x35,
528     QXL_OP_COLOR_BURN                = 0x36,
529     QXL_OP_HARD_LIGHT                = 0x37,
530     QXL_OP_SOFT_LIGHT                = 0x38,
531     QXL_OP_DIFFERENCE                = 0x39,
532     QXL_OP_EXCLUSION                 = 0x3a,
533     QXL_OP_HSL_HUE                   = 0x3b,
534     QXL_OP_HSL_SATURATION            = 0x3c,
535     QXL_OP_HSL_COLOR                 = 0x3d,
536     QXL_OP_HSL_LUMINOSITY            = 0x3e
537 } QXLOperator;
538 
539 typedef struct {
540     uint32_t	t00;
541     uint32_t	t01;
542     uint32_t	t02;
543     uint32_t	t10;
544     uint32_t	t11;
545     uint32_t	t12;
546 } QXLTransform;
547 
548 /* The flags field has the following bit fields:
549  *
550  *     operator:		[  0 -  7 ]
551  *     src_filter:		[  8 - 10 ]
552  *     mask_filter:		[ 11 - 13 ]
553  *     src_repeat:		[ 14 - 15 ]
554  *     mask_repeat:		[ 16 - 17 ]
555  *     component_alpha:		[ 18 - 18 ]
556  *     reserved:		[ 19 - 31 ]
557  *
558  * The repeat and filter values are those of pixman:
559  *		REPEAT_NONE =		0
560  *              REPEAT_NORMAL =		1
561  *		REPEAT_PAD =		2
562  *		REPEAT_REFLECT =	3
563  *
564  * The filter values are:
565  *		FILTER_NEAREST =	0
566  *		FILTER_BILINEAR	=	1
567  */
568 typedef struct SPICE_ATTR_PACKED QXLComposite {
569     uint32_t		flags;
570 
571     QXLPHYSICAL		src;
572     QXLPHYSICAL		src_transform;		/* May be NULL */
573     QXLPHYSICAL		mask;			/* May be NULL */
574     QXLPHYSICAL		mask_transform;		/* May be NULL */
575     QXLPoint16		src_origin;
576     QXLPoint16		mask_origin;
577 } QXLComposite;
578 
579 typedef struct SPICE_ATTR_PACKED QXLCompatDrawable {
580     QXLReleaseInfo release_info;
581     uint8_t effect;
582     uint8_t type;
583     uint16_t bitmap_offset;
584     QXLRect bitmap_area;
585     QXLRect bbox;
586     QXLClip clip;
587     uint32_t mm_time;
588     union {
589         QXLFill fill;
590         QXLOpaque opaque;
591         QXLCopy copy;
592         QXLTransparent transparent;
593         QXLCompatAlphaBlend alpha_blend;
594         QXLCopyBits copy_bits;
595         QXLBlend blend;
596         QXLRop3 rop3;
597         QXLStroke stroke;
598         QXLText text;
599         QXLBlackness blackness;
600         QXLInvers invers;
601         QXLWhiteness whiteness;
602     } u;
603 } QXLCompatDrawable;
604 
605 typedef struct SPICE_ATTR_PACKED QXLDrawable {
606     QXLReleaseInfo release_info;
607     uint32_t surface_id;
608     uint8_t effect;
609     uint8_t type;
610     uint8_t self_bitmap;
611     QXLRect self_bitmap_area;
612     QXLRect bbox;
613     QXLClip clip;
614     uint32_t mm_time;
615     int32_t surfaces_dest[3];
616     QXLRect surfaces_rects[3];
617     union {
618         QXLFill fill;
619         QXLOpaque opaque;
620         QXLCopy copy;
621         QXLTransparent transparent;
622         QXLAlphaBlend alpha_blend;
623         QXLCopyBits copy_bits;
624         QXLBlend blend;
625         QXLRop3 rop3;
626         QXLStroke stroke;
627         QXLText text;
628         QXLBlackness blackness;
629         QXLInvers invers;
630         QXLWhiteness whiteness;
631 	QXLComposite composite;
632     } u;
633 } QXLDrawable;
634 
635 typedef enum QXLSurfaceCmdType {
636     QXL_SURFACE_CMD_CREATE,
637     QXL_SURFACE_CMD_DESTROY,
638 } QXLSurfaceCmdType;
639 
640 typedef struct SPICE_ATTR_PACKED QXLSurface {
641     uint32_t format;
642     uint32_t width;
643     uint32_t height;
644     int32_t stride;
645     QXLPHYSICAL data;
646 } QXLSurface;
647 
648 typedef struct SPICE_ATTR_PACKED QXLSurfaceCmd {
649     QXLReleaseInfo release_info;
650     uint32_t surface_id;
651     uint8_t type;
652     uint32_t flags;
653     union {
654         QXLSurface surface_create;
655     } u;
656 } QXLSurfaceCmd;
657 
658 typedef struct SPICE_ATTR_PACKED QXLClipRects {
659     uint32_t num_rects;
660     QXLDataChunk chunk;
661 } QXLClipRects;
662 
663 enum {
664     QXL_PATH_BEGIN = (1 << 0),
665     QXL_PATH_END = (1 << 1),
666     QXL_PATH_CLOSE = (1 << 3),
667     QXL_PATH_BEZIER = (1 << 4),
668 };
669 
670 typedef struct SPICE_ATTR_PACKED QXLPathSeg {
671     uint32_t flags;
672     uint32_t count;
673     QXLPointFix points[0];
674 } QXLPathSeg;
675 
676 typedef struct SPICE_ATTR_PACKED QXLPath {
677     uint32_t data_size;
678     QXLDataChunk chunk;
679 } QXLPath;
680 
681 enum {
682     QXL_IMAGE_GROUP_DRIVER,
683     QXL_IMAGE_GROUP_DEVICE,
684     QXL_IMAGE_GROUP_RED,
685     QXL_IMAGE_GROUP_DRIVER_DONT_CACHE,
686 };
687 
688 typedef struct SPICE_ATTR_PACKED QXLImageID {
689     uint32_t group;
690     uint32_t unique;
691 } QXLImageID;
692 
693 typedef union {
694   QXLImageID id;
695   uint64_t value;
696 } QXLImageIDUnion;
697 
698 typedef enum QXLImageFlags {
699     QXL_IMAGE_CACHE = (1 << 0),
700     QXL_IMAGE_HIGH_BITS_SET = (1 << 1),
701 } QXLImageFlags;
702 
703 typedef enum QXLBitmapFlags {
704     QXL_BITMAP_DIRECT = (1 << 0),
705     QXL_BITMAP_UNSTABLE = (1 << 1),
706     QXL_BITMAP_TOP_DOWN = (1 << 2), // == SPICE_BITMAP_FLAGS_TOP_DOWN
707 } QXLBitmapFlags;
708 
709 #define QXL_SET_IMAGE_ID(image, _group, _unique) {              \
710     (image)->descriptor.id = (((uint64_t)_unique) << 32) | _group;	\
711 }
712 
713 typedef struct SPICE_ATTR_PACKED QXLImageDescriptor {
714     uint64_t id;
715     uint8_t type;
716     uint8_t flags;
717     uint32_t width;
718     uint32_t height;
719 } QXLImageDescriptor;
720 
721 typedef struct SPICE_ATTR_PACKED QXLPalette {
722     uint64_t unique;
723     uint16_t num_ents;
724     uint32_t ents[0];
725 } QXLPalette;
726 
727 typedef struct SPICE_ATTR_PACKED QXLBitmap {
728     uint8_t format;
729     uint8_t flags;
730     uint32_t x;
731     uint32_t y;
732     uint32_t stride;
733     QXLPHYSICAL palette;
734     QXLPHYSICAL data; //data[0] ?
735 } QXLBitmap;
736 
737 typedef struct SPICE_ATTR_PACKED QXLSurfaceId {
738     uint32_t surface_id;
739 } QXLSurfaceId;
740 
741 typedef struct SPICE_ATTR_PACKED QXLQUICData {
742     uint32_t data_size;
743     /* This data for QUIC is a QXLDataChunk.
744      * This differs from QXLBitmap where it's a reference to bitmap data or
745      * a reference to QXLDataChunk */
746     uint8_t data[0];
747 } QXLQUICData, QXLLZRGBData, QXLJPEGData;
748 
749 typedef struct SPICE_ATTR_PACKED QXLImage {
750     QXLImageDescriptor descriptor;
751     union { // variable length
752         QXLBitmap bitmap;
753         QXLQUICData quic;
754         QXLSurfaceId surface_image;
755     };
756 } QXLImage;
757 
758 /* A QXLHead is a single monitor output backed by a QXLSurface.
759  * x and y offsets are unsigned since they are used in relation to
760  * the given surface, not the same as the x, y coordinates in the guest
761  * screen reference frame. */
762 typedef struct SPICE_ATTR_PACKED QXLHead {
763     uint32_t id;
764     uint32_t surface_id;
765     uint32_t width;
766     uint32_t height;
767     uint32_t x;
768     uint32_t y;
769     uint32_t flags;
770 } QXLHead;
771 
772 typedef struct SPICE_ATTR_PACKED QXLMonitorsConfig {
773     uint16_t count;
774     uint16_t max_allowed; /* If it is 0 no fixed limit is given by the driver */
775     QXLHead heads[0];
776 } QXLMonitorsConfig;
777 
778 #include <spice/end-packed.h>
779 
780 typedef struct QXLReleaseInfoExt {
781     QXLReleaseInfo *info;
782     uint32_t group_id;
783 } QXLReleaseInfoExt;
784 
785 #endif /* _H_QXL_DEV */
786