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 #ifndef H_QXL_DEV
32 #define H_QXL_DEV
33 
34 #include <linux/types.h>
35 
36 /*
37  * from spice-protocol
38  * Release 0.10.0
39  */
40 
41 /* enums.h */
42 
43 enum SpiceImageType {
44 	SPICE_IMAGE_TYPE_BITMAP,
45 	SPICE_IMAGE_TYPE_QUIC,
46 	SPICE_IMAGE_TYPE_RESERVED,
47 	SPICE_IMAGE_TYPE_LZ_PLT = 100,
48 	SPICE_IMAGE_TYPE_LZ_RGB,
49 	SPICE_IMAGE_TYPE_GLZ_RGB,
50 	SPICE_IMAGE_TYPE_FROM_CACHE,
51 	SPICE_IMAGE_TYPE_SURFACE,
52 	SPICE_IMAGE_TYPE_JPEG,
53 	SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS,
54 	SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB,
55 	SPICE_IMAGE_TYPE_JPEG_ALPHA,
56 
57 	SPICE_IMAGE_TYPE_ENUM_END
58 };
59 
60 enum SpiceBitmapFmt {
61 	SPICE_BITMAP_FMT_INVALID,
62 	SPICE_BITMAP_FMT_1BIT_LE,
63 	SPICE_BITMAP_FMT_1BIT_BE,
64 	SPICE_BITMAP_FMT_4BIT_LE,
65 	SPICE_BITMAP_FMT_4BIT_BE,
66 	SPICE_BITMAP_FMT_8BIT,
67 	SPICE_BITMAP_FMT_16BIT,
68 	SPICE_BITMAP_FMT_24BIT,
69 	SPICE_BITMAP_FMT_32BIT,
70 	SPICE_BITMAP_FMT_RGBA,
71 
72 	SPICE_BITMAP_FMT_ENUM_END
73 };
74 
75 enum SpiceSurfaceFmt {
76 	SPICE_SURFACE_FMT_INVALID,
77 	SPICE_SURFACE_FMT_1_A,
78 	SPICE_SURFACE_FMT_8_A = 8,
79 	SPICE_SURFACE_FMT_16_555 = 16,
80 	SPICE_SURFACE_FMT_32_xRGB = 32,
81 	SPICE_SURFACE_FMT_16_565 = 80,
82 	SPICE_SURFACE_FMT_32_ARGB = 96,
83 
84 	SPICE_SURFACE_FMT_ENUM_END
85 };
86 
87 enum SpiceClipType {
88 	SPICE_CLIP_TYPE_NONE,
89 	SPICE_CLIP_TYPE_RECTS,
90 
91 	SPICE_CLIP_TYPE_ENUM_END
92 };
93 
94 enum SpiceRopd {
95 	SPICE_ROPD_INVERS_SRC = (1 << 0),
96 	SPICE_ROPD_INVERS_BRUSH = (1 << 1),
97 	SPICE_ROPD_INVERS_DEST = (1 << 2),
98 	SPICE_ROPD_OP_PUT = (1 << 3),
99 	SPICE_ROPD_OP_OR = (1 << 4),
100 	SPICE_ROPD_OP_AND = (1 << 5),
101 	SPICE_ROPD_OP_XOR = (1 << 6),
102 	SPICE_ROPD_OP_BLACKNESS = (1 << 7),
103 	SPICE_ROPD_OP_WHITENESS = (1 << 8),
104 	SPICE_ROPD_OP_INVERS = (1 << 9),
105 	SPICE_ROPD_INVERS_RES = (1 << 10),
106 
107 	SPICE_ROPD_MASK = 0x7ff
108 };
109 
110 enum SpiceBrushType {
111 	SPICE_BRUSH_TYPE_NONE,
112 	SPICE_BRUSH_TYPE_SOLID,
113 	SPICE_BRUSH_TYPE_PATTERN,
114 
115 	SPICE_BRUSH_TYPE_ENUM_END
116 };
117 
118 enum SpiceCursorType {
119 	SPICE_CURSOR_TYPE_ALPHA,
120 	SPICE_CURSOR_TYPE_MONO,
121 	SPICE_CURSOR_TYPE_COLOR4,
122 	SPICE_CURSOR_TYPE_COLOR8,
123 	SPICE_CURSOR_TYPE_COLOR16,
124 	SPICE_CURSOR_TYPE_COLOR24,
125 	SPICE_CURSOR_TYPE_COLOR32,
126 
127 	SPICE_CURSOR_TYPE_ENUM_END
128 };
129 
130 /* qxl_dev.h */
131 
132 #pragma pack(push, 1)
133 
134 #define REDHAT_PCI_VENDOR_ID 0x1b36
135 
136 /* 0x100-0x11f reserved for spice, 0x1ff used for unstable work */
137 #define QXL_DEVICE_ID_STABLE 0x0100
138 
139 enum {
140 	QXL_REVISION_STABLE_V04 = 0x01,
141 	QXL_REVISION_STABLE_V06 = 0x02,
142 	QXL_REVISION_STABLE_V10 = 0x03,
143 	QXL_REVISION_STABLE_V12 = 0x04,
144 };
145 
146 #define QXL_DEVICE_ID_DEVEL 0x01ff
147 #define QXL_REVISION_DEVEL 0x01
148 
149 #define QXL_ROM_MAGIC (*(uint32_t *)"QXRO")
150 #define QXL_RAM_MAGIC (*(uint32_t *)"QXRA")
151 
152 enum {
153 	QXL_RAM_RANGE_INDEX,
154 	QXL_VRAM_RANGE_INDEX,
155 	QXL_ROM_RANGE_INDEX,
156 	QXL_IO_RANGE_INDEX,
157 
158 	QXL_PCI_RANGES
159 };
160 
161 /* qxl-1 compat: append only */
162 enum {
163 	QXL_IO_NOTIFY_CMD,
164 	QXL_IO_NOTIFY_CURSOR,
165 	QXL_IO_UPDATE_AREA,
166 	QXL_IO_UPDATE_IRQ,
167 	QXL_IO_NOTIFY_OOM,
168 	QXL_IO_RESET,
169 	QXL_IO_SET_MODE,                  /* qxl-1 */
170 	QXL_IO_LOG,
171 	/* appended for qxl-2 */
172 	QXL_IO_MEMSLOT_ADD,
173 	QXL_IO_MEMSLOT_DEL,
174 	QXL_IO_DETACH_PRIMARY,
175 	QXL_IO_ATTACH_PRIMARY,
176 	QXL_IO_CREATE_PRIMARY,
177 	QXL_IO_DESTROY_PRIMARY,
178 	QXL_IO_DESTROY_SURFACE_WAIT,
179 	QXL_IO_DESTROY_ALL_SURFACES,
180 	/* appended for qxl-3 */
181 	QXL_IO_UPDATE_AREA_ASYNC,
182 	QXL_IO_MEMSLOT_ADD_ASYNC,
183 	QXL_IO_CREATE_PRIMARY_ASYNC,
184 	QXL_IO_DESTROY_PRIMARY_ASYNC,
185 	QXL_IO_DESTROY_SURFACE_ASYNC,
186 	QXL_IO_DESTROY_ALL_SURFACES_ASYNC,
187 	QXL_IO_FLUSH_SURFACES_ASYNC,
188 	QXL_IO_FLUSH_RELEASE,
189 	/* appended for qxl-4 */
190 	QXL_IO_MONITORS_CONFIG_ASYNC,
191 
192 	QXL_IO_RANGE_SIZE
193 };
194 
195 typedef uint64_t QXLPHYSICAL;
196 typedef int32_t QXLFIXED; /* fixed 28.4 */
197 
198 struct qxl_point_fix {
199 	QXLFIXED x;
200 	QXLFIXED y;
201 };
202 
203 struct qxl_point {
204 	int32_t x;
205 	int32_t y;
206 };
207 
208 struct qxl_point_1_6 {
209 	int16_t x;
210 	int16_t y;
211 };
212 
213 struct qxl_rect {
214 	int32_t top;
215 	int32_t left;
216 	int32_t bottom;
217 	int32_t right;
218 };
219 
220 struct qxl_urect {
221 	uint32_t top;
222 	uint32_t left;
223 	uint32_t bottom;
224 	uint32_t right;
225 };
226 
227 /* qxl-1 compat: append only */
228 struct qxl_rom {
229 	uint32_t magic;
230 	uint32_t id;
231 	uint32_t update_id;
232 	uint32_t compression_level;
233 	uint32_t log_level;
234 	uint32_t mode;			  /* qxl-1 */
235 	uint32_t modes_offset;
236 	uint32_t num_io_pages;
237 	uint32_t pages_offset;		  /* qxl-1 */
238 	uint32_t draw_area_offset;	  /* qxl-1 */
239 	uint32_t surface0_area_size;	  /* qxl-1 name: draw_area_size */
240 	uint32_t ram_header_offset;
241 	uint32_t mm_clock;
242 	/* appended for qxl-2 */
243 	uint32_t n_surfaces;
244 	uint64_t flags;
245 	uint8_t slots_start;
246 	uint8_t slots_end;
247 	uint8_t slot_gen_bits;
248 	uint8_t slot_id_bits;
249 	uint8_t slot_generation;
250 	/* appended for qxl-4 */
251 	uint8_t client_present;
252 	uint8_t client_capabilities[58];
253 	uint32_t client_monitors_config_crc;
254 	struct {
255 		uint16_t count;
256 	uint16_t padding;
257 		struct qxl_urect heads[64];
258 	} client_monitors_config;
259 };
260 
261 /* qxl-1 compat: fixed */
262 struct qxl_mode {
263 	uint32_t id;
264 	uint32_t x_res;
265 	uint32_t y_res;
266 	uint32_t bits;
267 	uint32_t stride;
268 	uint32_t x_mili;
269 	uint32_t y_mili;
270 	uint32_t orientation;
271 };
272 
273 /* qxl-1 compat: fixed */
274 struct qxl_modes {
275 	uint32_t n_modes;
276 	struct qxl_mode modes[0];
277 };
278 
279 /* qxl-1 compat: append only */
280 enum qxl_cmd_type {
281 	QXL_CMD_NOP,
282 	QXL_CMD_DRAW,
283 	QXL_CMD_UPDATE,
284 	QXL_CMD_CURSOR,
285 	QXL_CMD_MESSAGE,
286 	QXL_CMD_SURFACE,
287 };
288 
289 /* qxl-1 compat: fixed */
290 struct qxl_command {
291 	QXLPHYSICAL data;
292 	uint32_t type;
293 	uint32_t padding;
294 };
295 
296 #define QXL_COMMAND_FLAG_COMPAT		(1<<0)
297 #define QXL_COMMAND_FLAG_COMPAT_16BPP	(2<<0)
298 
299 struct qxl_command_ext {
300 	struct qxl_command cmd;
301 	uint32_t group_id;
302 	uint32_t flags;
303 };
304 
305 struct qxl_mem_slot {
306 	uint64_t mem_start;
307 	uint64_t mem_end;
308 };
309 
310 #define QXL_SURF_TYPE_PRIMARY	   0
311 
312 #define QXL_SURF_FLAG_KEEP_DATA	   (1 << 0)
313 
314 struct qxl_surface_create {
315 	uint32_t width;
316 	uint32_t height;
317 	int32_t stride;
318 	uint32_t format;
319 	uint32_t position;
320 	uint32_t mouse_mode;
321 	uint32_t flags;
322 	uint32_t type;
323 	QXLPHYSICAL mem;
324 };
325 
326 #define QXL_COMMAND_RING_SIZE 32
327 #define QXL_CURSOR_RING_SIZE 32
328 #define QXL_RELEASE_RING_SIZE 8
329 
330 #define QXL_LOG_BUF_SIZE 4096
331 
332 #define QXL_INTERRUPT_DISPLAY (1 << 0)
333 #define QXL_INTERRUPT_CURSOR (1 << 1)
334 #define QXL_INTERRUPT_IO_CMD (1 << 2)
335 #define QXL_INTERRUPT_ERROR  (1 << 3)
336 #define QXL_INTERRUPT_CLIENT (1 << 4)
337 #define QXL_INTERRUPT_CLIENT_MONITORS_CONFIG  (1 << 5)
338 
339 struct qxl_ring_header {
340 	uint32_t num_items;
341 	uint32_t prod;
342 	uint32_t notify_on_prod;
343 	uint32_t cons;
344 	uint32_t notify_on_cons;
345 };
346 
347 /* qxl-1 compat: append only */
348 struct qxl_ram_header {
349 	uint32_t magic;
350 	uint32_t int_pending;
351 	uint32_t int_mask;
352 	uint8_t log_buf[QXL_LOG_BUF_SIZE];
353 	struct qxl_ring_header  cmd_ring_hdr;
354 	struct qxl_command	cmd_ring[QXL_COMMAND_RING_SIZE];
355 	struct qxl_ring_header  cursor_ring_hdr;
356 	struct qxl_command	cursor_ring[QXL_CURSOR_RING_SIZE];
357 	struct qxl_ring_header  release_ring_hdr;
358 	uint64_t		release_ring[QXL_RELEASE_RING_SIZE];
359 	struct qxl_rect update_area;
360 	/* appended for qxl-2 */
361 	uint32_t update_surface;
362 	struct qxl_mem_slot mem_slot;
363 	struct qxl_surface_create create_surface;
364 	uint64_t flags;
365 
366 	/* appended for qxl-4 */
367 
368 	/* used by QXL_IO_MONITORS_CONFIG_ASYNC */
369 	QXLPHYSICAL monitors_config;
370 	uint8_t guest_capabilities[64];
371 };
372 
373 union qxl_release_info {
374 	uint64_t id;	  /* in  */
375 	uint64_t next;	  /* out */
376 };
377 
378 struct qxl_release_info_ext {
379 	union qxl_release_info *info;
380 	uint32_t group_id;
381 };
382 
383 struct qxl_data_chunk {
384 	uint32_t data_size;
385 	QXLPHYSICAL prev_chunk;
386 	QXLPHYSICAL next_chunk;
387 	uint8_t data[0];
388 };
389 
390 struct qxl_message {
391 	union qxl_release_info release_info;
392 	uint8_t data[0];
393 };
394 
395 struct qxl_compat_update_cmd {
396 	union qxl_release_info release_info;
397 	struct qxl_rect area;
398 	uint32_t update_id;
399 };
400 
401 struct qxl_update_cmd {
402 	union qxl_release_info release_info;
403 	struct qxl_rect area;
404 	uint32_t update_id;
405 	uint32_t surface_id;
406 };
407 
408 struct qxl_cursor_header {
409 	uint64_t unique;
410 	uint16_t type;
411 	uint16_t width;
412 	uint16_t height;
413 	uint16_t hot_spot_x;
414 	uint16_t hot_spot_y;
415 };
416 
417 struct qxl_cursor {
418 	struct qxl_cursor_header header;
419 	uint32_t data_size;
420 	struct qxl_data_chunk chunk;
421 };
422 
423 enum {
424 	QXL_CURSOR_SET,
425 	QXL_CURSOR_MOVE,
426 	QXL_CURSOR_HIDE,
427 	QXL_CURSOR_TRAIL,
428 };
429 
430 #define QXL_CURSOR_DEVICE_DATA_SIZE 128
431 
432 struct qxl_cursor_cmd {
433 	union qxl_release_info release_info;
434 	uint8_t type;
435 	union {
436 		struct {
437 			struct qxl_point_1_6 position;
438 			uint8_t visible;
439 			QXLPHYSICAL shape;
440 		} set;
441 		struct {
442 			uint16_t length;
443 			uint16_t frequency;
444 		} trail;
445 		struct qxl_point_1_6 position;
446 	} u;
447 	/* todo: dynamic size from rom */
448 	uint8_t device_data[QXL_CURSOR_DEVICE_DATA_SIZE];
449 };
450 
451 enum {
452 	QXL_DRAW_NOP,
453 	QXL_DRAW_FILL,
454 	QXL_DRAW_OPAQUE,
455 	QXL_DRAW_COPY,
456 	QXL_COPY_BITS,
457 	QXL_DRAW_BLEND,
458 	QXL_DRAW_BLACKNESS,
459 	QXL_DRAW_WHITENESS,
460 	QXL_DRAW_INVERS,
461 	QXL_DRAW_ROP3,
462 	QXL_DRAW_STROKE,
463 	QXL_DRAW_TEXT,
464 	QXL_DRAW_TRANSPARENT,
465 	QXL_DRAW_ALPHA_BLEND,
466 	QXL_DRAW_COMPOSITE
467 };
468 
469 struct qxl_raster_glyph {
470 	struct qxl_point render_pos;
471 	struct qxl_point glyph_origin;
472 	uint16_t width;
473 	uint16_t height;
474 	uint8_t data[0];
475 };
476 
477 struct qxl_string {
478 	uint32_t data_size;
479 	uint16_t length;
480 	uint16_t flags;
481 	struct qxl_data_chunk chunk;
482 };
483 
484 struct qxl_copy_bits {
485 	struct qxl_point src_pos;
486 };
487 
488 enum qxl_effect_type {
489 	QXL_EFFECT_BLEND = 0,
490 	QXL_EFFECT_OPAQUE = 1,
491 	QXL_EFFECT_REVERT_ON_DUP = 2,
492 	QXL_EFFECT_BLACKNESS_ON_DUP = 3,
493 	QXL_EFFECT_WHITENESS_ON_DUP = 4,
494 	QXL_EFFECT_NOP_ON_DUP = 5,
495 	QXL_EFFECT_NOP = 6,
496 	QXL_EFFECT_OPAQUE_BRUSH = 7
497 };
498 
499 struct qxl_pattern {
500 	QXLPHYSICAL pat;
501 	struct qxl_point pos;
502 };
503 
504 struct qxl_brush {
505 	uint32_t type;
506 	union {
507 		uint32_t color;
508 		struct qxl_pattern pattern;
509 	} u;
510 };
511 
512 struct qxl_q_mask {
513 	uint8_t flags;
514 	struct qxl_point pos;
515 	QXLPHYSICAL bitmap;
516 };
517 
518 struct qxl_fill {
519 	struct qxl_brush brush;
520 	uint16_t rop_descriptor;
521 	struct qxl_q_mask mask;
522 };
523 
524 struct qxl_opaque {
525 	QXLPHYSICAL src_bitmap;
526 	struct qxl_rect src_area;
527 	struct qxl_brush brush;
528 	uint16_t rop_descriptor;
529 	uint8_t scale_mode;
530 	struct qxl_q_mask mask;
531 };
532 
533 struct qxl_copy {
534 	QXLPHYSICAL src_bitmap;
535 	struct qxl_rect src_area;
536 	uint16_t rop_descriptor;
537 	uint8_t scale_mode;
538 	struct qxl_q_mask mask;
539 };
540 
541 struct qxl_transparent {
542 	QXLPHYSICAL src_bitmap;
543 	struct qxl_rect src_area;
544 	uint32_t src_color;
545 	uint32_t true_color;
546 };
547 
548 struct qxl_alpha_blend {
549 	uint16_t alpha_flags;
550 	uint8_t alpha;
551 	QXLPHYSICAL src_bitmap;
552 	struct qxl_rect src_area;
553 };
554 
555 struct qxl_compat_alpha_blend {
556 	uint8_t alpha;
557 	QXLPHYSICAL src_bitmap;
558 	struct qxl_rect src_area;
559 };
560 
561 struct qxl_rop_3 {
562 	QXLPHYSICAL src_bitmap;
563 	struct qxl_rect src_area;
564 	struct qxl_brush brush;
565 	uint8_t rop3;
566 	uint8_t scale_mode;
567 	struct qxl_q_mask mask;
568 };
569 
570 struct qxl_line_attr {
571 	uint8_t flags;
572 	uint8_t join_style;
573 	uint8_t end_style;
574 	uint8_t style_nseg;
575 	QXLFIXED width;
576 	QXLFIXED miter_limit;
577 	QXLPHYSICAL style;
578 };
579 
580 struct qxl_stroke {
581 	QXLPHYSICAL path;
582 	struct qxl_line_attr attr;
583 	struct qxl_brush brush;
584 	uint16_t fore_mode;
585 	uint16_t back_mode;
586 };
587 
588 struct qxl_text {
589 	QXLPHYSICAL str;
590 	struct qxl_rect back_area;
591 	struct qxl_brush fore_brush;
592 	struct qxl_brush back_brush;
593 	uint16_t fore_mode;
594 	uint16_t back_mode;
595 };
596 
597 struct qxl_mask {
598 	struct qxl_q_mask mask;
599 };
600 
601 struct qxl_clip {
602 	uint32_t type;
603 	QXLPHYSICAL data;
604 };
605 
606 enum qxl_operator {
607 	QXL_OP_CLEAR			 = 0x00,
608 	QXL_OP_SOURCE			 = 0x01,
609 	QXL_OP_DST			 = 0x02,
610 	QXL_OP_OVER			 = 0x03,
611 	QXL_OP_OVER_REVERSE		 = 0x04,
612 	QXL_OP_IN			 = 0x05,
613 	QXL_OP_IN_REVERSE		 = 0x06,
614 	QXL_OP_OUT			 = 0x07,
615 	QXL_OP_OUT_REVERSE		 = 0x08,
616 	QXL_OP_ATOP			 = 0x09,
617 	QXL_OP_ATOP_REVERSE		 = 0x0a,
618 	QXL_OP_XOR			 = 0x0b,
619 	QXL_OP_ADD			 = 0x0c,
620 	QXL_OP_SATURATE			 = 0x0d,
621 	/* Note the jump here from 0x0d to 0x30 */
622 	QXL_OP_MULTIPLY			 = 0x30,
623 	QXL_OP_SCREEN			 = 0x31,
624 	QXL_OP_OVERLAY			 = 0x32,
625 	QXL_OP_DARKEN			 = 0x33,
626 	QXL_OP_LIGHTEN			 = 0x34,
627 	QXL_OP_COLOR_DODGE		 = 0x35,
628 	QXL_OP_COLOR_BURN		 = 0x36,
629 	QXL_OP_HARD_LIGHT		 = 0x37,
630 	QXL_OP_SOFT_LIGHT		 = 0x38,
631 	QXL_OP_DIFFERENCE		 = 0x39,
632 	QXL_OP_EXCLUSION		 = 0x3a,
633 	QXL_OP_HSL_HUE			 = 0x3b,
634 	QXL_OP_HSL_SATURATION		 = 0x3c,
635 	QXL_OP_HSL_COLOR		 = 0x3d,
636 	QXL_OP_HSL_LUMINOSITY		 = 0x3e
637 };
638 
639 struct qxl_transform {
640 	uint32_t	t00;
641 	uint32_t	t01;
642 	uint32_t	t02;
643 	uint32_t	t10;
644 	uint32_t	t11;
645 	uint32_t	t12;
646 };
647 
648 /* The flags field has the following bit fields:
649  *
650  *     operator:		[  0 -  7 ]
651  *     src_filter:		[  8 - 10 ]
652  *     mask_filter:		[ 11 - 13 ]
653  *     src_repeat:		[ 14 - 15 ]
654  *     mask_repeat:		[ 16 - 17 ]
655  *     component_alpha:		[ 18 - 18 ]
656  *     reserved:		[ 19 - 31 ]
657  *
658  * The repeat and filter values are those of pixman:
659  *		REPEAT_NONE =		0
660  *              REPEAT_NORMAL =		1
661  *		REPEAT_PAD =		2
662  *		REPEAT_REFLECT =	3
663  *
664  * The filter values are:
665  *		FILTER_NEAREST =	0
666  *		FILTER_BILINEAR	=	1
667  */
668 struct qxl_composite {
669 	uint32_t		flags;
670 
671 	QXLPHYSICAL			src;
672 	QXLPHYSICAL			src_transform;	/* May be NULL */
673 	QXLPHYSICAL			mask;		/* May be NULL */
674 	QXLPHYSICAL			mask_transform;	/* May be NULL */
675 	struct qxl_point_1_6	src_origin;
676 	struct qxl_point_1_6	mask_origin;
677 };
678 
679 struct qxl_compat_drawable {
680 	union qxl_release_info release_info;
681 	uint8_t effect;
682 	uint8_t type;
683 	uint16_t bitmap_offset;
684 	struct qxl_rect bitmap_area;
685 	struct qxl_rect bbox;
686 	struct qxl_clip clip;
687 	uint32_t mm_time;
688 	union {
689 		struct qxl_fill fill;
690 		struct qxl_opaque opaque;
691 		struct qxl_copy copy;
692 		struct qxl_transparent transparent;
693 		struct qxl_compat_alpha_blend alpha_blend;
694 		struct qxl_copy_bits copy_bits;
695 		struct qxl_copy blend;
696 		struct qxl_rop_3 rop3;
697 		struct qxl_stroke stroke;
698 		struct qxl_text text;
699 		struct qxl_mask blackness;
700 		struct qxl_mask invers;
701 		struct qxl_mask whiteness;
702 	} u;
703 };
704 
705 struct qxl_drawable {
706 	union qxl_release_info release_info;
707 	uint32_t surface_id;
708 	uint8_t effect;
709 	uint8_t type;
710 	uint8_t self_bitmap;
711 	struct qxl_rect self_bitmap_area;
712 	struct qxl_rect bbox;
713 	struct qxl_clip clip;
714 	uint32_t mm_time;
715 	int32_t surfaces_dest[3];
716 	struct qxl_rect surfaces_rects[3];
717 	union {
718 		struct qxl_fill fill;
719 		struct qxl_opaque opaque;
720 		struct qxl_copy copy;
721 		struct qxl_transparent transparent;
722 		struct qxl_alpha_blend alpha_blend;
723 		struct qxl_copy_bits copy_bits;
724 		struct qxl_copy blend;
725 		struct qxl_rop_3 rop3;
726 		struct qxl_stroke stroke;
727 		struct qxl_text text;
728 		struct qxl_mask blackness;
729 		struct qxl_mask invers;
730 		struct qxl_mask whiteness;
731 		struct qxl_composite composite;
732 	} u;
733 };
734 
735 enum qxl_surface_cmd_type {
736 	QXL_SURFACE_CMD_CREATE,
737 	QXL_SURFACE_CMD_DESTROY,
738 };
739 
740 struct qxl_surface {
741 	uint32_t format;
742 	uint32_t width;
743 	uint32_t height;
744 	int32_t stride;
745 	QXLPHYSICAL data;
746 };
747 
748 struct qxl_surface_cmd {
749 	union qxl_release_info release_info;
750 	uint32_t surface_id;
751 	uint8_t type;
752 	uint32_t flags;
753 	union {
754 		struct qxl_surface surface_create;
755 	} u;
756 };
757 
758 struct qxl_clip_rects {
759 	uint32_t num_rects;
760 	struct qxl_data_chunk chunk;
761 };
762 
763 enum {
764 	QXL_PATH_BEGIN = (1 << 0),
765 	QXL_PATH_END = (1 << 1),
766 	QXL_PATH_CLOSE = (1 << 3),
767 	QXL_PATH_BEZIER = (1 << 4),
768 };
769 
770 struct qxl_path_seg {
771 	uint32_t flags;
772 	uint32_t count;
773 	struct qxl_point_fix points[0];
774 };
775 
776 struct qxl_path {
777 	uint32_t data_size;
778 	struct qxl_data_chunk chunk;
779 };
780 
781 enum {
782 	QXL_IMAGE_GROUP_DRIVER,
783 	QXL_IMAGE_GROUP_DEVICE,
784 	QXL_IMAGE_GROUP_RED,
785 	QXL_IMAGE_GROUP_DRIVER_DONT_CACHE,
786 };
787 
788 struct qxl_image_id {
789 	uint32_t group;
790 	uint32_t unique;
791 };
792 
793 union qxl_image_id_union {
794 	struct qxl_image_id id;
795 	uint64_t value;
796 };
797 
798 enum qxl_image_flags {
799 	QXL_IMAGE_CACHE = (1 << 0),
800 	QXL_IMAGE_HIGH_BITS_SET = (1 << 1),
801 };
802 
803 enum qxl_bitmap_flags {
804 	QXL_BITMAP_DIRECT = (1 << 0),
805 	QXL_BITMAP_UNSTABLE = (1 << 1),
806 	QXL_BITMAP_TOP_DOWN = (1 << 2), /* == SPICE_BITMAP_FLAGS_TOP_DOWN */
807 };
808 
809 #define QXL_SET_IMAGE_ID(image, _group, _unique) {              \
810 	(image)->descriptor.id = (((uint64_t)_unique) << 32) | _group;	\
811 }
812 
813 struct qxl_image_descriptor {
814 	uint64_t id;
815 	uint8_t type;
816 	uint8_t flags;
817 	uint32_t width;
818 	uint32_t height;
819 };
820 
821 struct qxl_palette {
822 	uint64_t unique;
823 	uint16_t num_ents;
824 	uint32_t ents[0];
825 };
826 
827 struct qxl_bitmap {
828 	uint8_t format;
829 	uint8_t flags;
830 	uint32_t x;
831 	uint32_t y;
832 	uint32_t stride;
833 	QXLPHYSICAL palette;
834 	QXLPHYSICAL data; /* data[0] ? */
835 };
836 
837 struct qxl_surface_id {
838 	uint32_t surface_id;
839 };
840 
841 struct qxl_encoder_data {
842 	uint32_t data_size;
843 	uint8_t data[0];
844 };
845 
846 struct qxl_image {
847 	struct qxl_image_descriptor descriptor;
848 	union { /* variable length */
849 		struct qxl_bitmap bitmap;
850 		struct qxl_encoder_data quic;
851 		struct qxl_surface_id surface_image;
852 	} u;
853 };
854 
855 /* A QXLHead is a single monitor output backed by a QXLSurface.
856  * x and y offsets are unsigned since they are used in relation to
857  * the given surface, not the same as the x, y coordinates in the guest
858  * screen reference frame. */
859 struct qxl_head {
860 	uint32_t id;
861 	uint32_t surface_id;
862 	uint32_t width;
863 	uint32_t height;
864 	uint32_t x;
865 	uint32_t y;
866 	uint32_t flags;
867 };
868 
869 struct qxl_monitors_config {
870 	uint16_t count;
871 	uint16_t max_allowed; /* If it is 0 no fixed limit is given by the
872 				 driver */
873 	struct qxl_head heads[0];
874 };
875 
876 #pragma pack(pop)
877 
878 #endif /* _H_QXL_DEV */
879