2 * qxl command logging -- for debug purposes
4 * Copyright (C) 2010 Red Hat, Inc.
6 * maintained by Gerd Hoffmann <kraxel@redhat.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 or
11 * (at your option) version 3 of the License.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 static const char *qxl_type
[] = {
25 [ QXL_CMD_NOP
] = "nop",
26 [ QXL_CMD_DRAW
] = "draw",
27 [ QXL_CMD_UPDATE
] = "update",
28 [ QXL_CMD_CURSOR
] = "cursor",
29 [ QXL_CMD_MESSAGE
] = "message",
30 [ QXL_CMD_SURFACE
] = "surface",
33 static const char *qxl_draw_type
[] = {
34 [ QXL_DRAW_NOP
] = "nop",
35 [ QXL_DRAW_FILL
] = "fill",
36 [ QXL_DRAW_OPAQUE
] = "opaque",
37 [ QXL_DRAW_COPY
] = "copy",
38 [ QXL_COPY_BITS
] = "copy-bits",
39 [ QXL_DRAW_BLEND
] = "blend",
40 [ QXL_DRAW_BLACKNESS
] = "blackness",
41 [ QXL_DRAW_WHITENESS
] = "whitemess",
42 [ QXL_DRAW_INVERS
] = "invers",
43 [ QXL_DRAW_ROP3
] = "rop3",
44 [ QXL_DRAW_STROKE
] = "stroke",
45 [ QXL_DRAW_TEXT
] = "text",
46 [ QXL_DRAW_TRANSPARENT
] = "transparent",
47 [ QXL_DRAW_ALPHA_BLEND
] = "alpha-blend",
50 static const char *qxl_draw_effect
[] = {
51 [ QXL_EFFECT_BLEND
] = "blend",
52 [ QXL_EFFECT_OPAQUE
] = "opaque",
53 [ QXL_EFFECT_REVERT_ON_DUP
] = "revert-on-dup",
54 [ QXL_EFFECT_BLACKNESS_ON_DUP
] = "blackness-on-dup",
55 [ QXL_EFFECT_WHITENESS_ON_DUP
] = "whiteness-on-dup",
56 [ QXL_EFFECT_NOP_ON_DUP
] = "nop-on-dup",
57 [ QXL_EFFECT_NOP
] = "nop",
58 [ QXL_EFFECT_OPAQUE_BRUSH
] = "opaque-brush",
61 static const char *qxl_surface_cmd
[] = {
62 [ QXL_SURFACE_CMD_CREATE
] = "create",
63 [ QXL_SURFACE_CMD_DESTROY
] = "destroy",
66 static const char *spice_surface_fmt
[] = {
67 [ SPICE_SURFACE_FMT_INVALID
] = "invalid",
68 [ SPICE_SURFACE_FMT_1_A
] = "alpha/1",
69 [ SPICE_SURFACE_FMT_8_A
] = "alpha/8",
70 [ SPICE_SURFACE_FMT_16_555
] = "555/16",
71 [ SPICE_SURFACE_FMT_16_565
] = "565/16",
72 [ SPICE_SURFACE_FMT_32_xRGB
] = "xRGB/32",
73 [ SPICE_SURFACE_FMT_32_ARGB
] = "ARGB/32",
76 static const char *qxl_cursor_cmd
[] = {
77 [ QXL_CURSOR_SET
] = "set",
78 [ QXL_CURSOR_MOVE
] = "move",
79 [ QXL_CURSOR_HIDE
] = "hide",
80 [ QXL_CURSOR_TRAIL
] = "trail",
83 static const char *spice_cursor_type
[] = {
84 [ SPICE_CURSOR_TYPE_ALPHA
] = "alpha",
85 [ SPICE_CURSOR_TYPE_MONO
] = "mono",
86 [ SPICE_CURSOR_TYPE_COLOR4
] = "color4",
87 [ SPICE_CURSOR_TYPE_COLOR8
] = "color8",
88 [ SPICE_CURSOR_TYPE_COLOR16
] = "color16",
89 [ SPICE_CURSOR_TYPE_COLOR24
] = "color24",
90 [ SPICE_CURSOR_TYPE_COLOR32
] = "color32",
93 static const char *qxl_v2n(const char *n
[], size_t l
, int v
)
95 if (v
>= l
|| !n
[v
]) {
100 #define qxl_name(_list, _value) qxl_v2n(_list, ARRAY_SIZE(_list), _value)
102 static void qxl_log_image(PCIQXLDevice
*qxl
, QXLPHYSICAL addr
, int group_id
)
105 QXLImageDescriptor
*desc
;
107 image
= qxl_phys2virt(qxl
, addr
, group_id
);
108 desc
= &image
->descriptor
;
109 fprintf(stderr
, " (id %" PRIx64
" type %d flags %d width %d height %d",
110 desc
->id
, desc
->type
, desc
->flags
, desc
->width
, desc
->height
);
111 switch (desc
->type
) {
112 case SPICE_IMAGE_TYPE_BITMAP
:
113 fprintf(stderr
, ", fmt %d flags %d x %d y %d stride %d"
114 " palette %" PRIx64
" data %" PRIx64
,
115 image
->bitmap
.format
, image
->bitmap
.flags
,
116 image
->bitmap
.x
, image
->bitmap
.y
,
117 image
->bitmap
.stride
,
118 image
->bitmap
.palette
, image
->bitmap
.data
);
121 fprintf(stderr
, ")");
124 static void qxl_log_rect(QXLRect
*rect
)
126 fprintf(stderr
, " %dx%d+%d+%d",
127 rect
->right
- rect
->left
,
128 rect
->bottom
- rect
->top
,
129 rect
->left
, rect
->top
);
132 static void qxl_log_cmd_draw_copy(PCIQXLDevice
*qxl
, QXLCopy
*copy
, int group_id
)
134 fprintf(stderr
, " src %" PRIx64
,
136 qxl_log_image(qxl
, copy
->src_bitmap
, group_id
);
137 fprintf(stderr
, " area");
138 qxl_log_rect(©
->src_area
);
139 fprintf(stderr
, " rop %d", copy
->rop_descriptor
);
142 static void qxl_log_cmd_draw(PCIQXLDevice
*qxl
, QXLDrawable
*draw
, int group_id
)
144 fprintf(stderr
, ": surface_id %d type %s effect %s",
146 qxl_name(qxl_draw_type
, draw
->type
),
147 qxl_name(qxl_draw_effect
, draw
->effect
));
148 switch (draw
->type
) {
150 qxl_log_cmd_draw_copy(qxl
, &draw
->u
.copy
, group_id
);
155 static void qxl_log_cmd_draw_compat(PCIQXLDevice
*qxl
, QXLCompatDrawable
*draw
,
158 fprintf(stderr
, ": type %s effect %s",
159 qxl_name(qxl_draw_type
, draw
->type
),
160 qxl_name(qxl_draw_effect
, draw
->effect
));
161 if (draw
->bitmap_offset
) {
162 fprintf(stderr
, ": bitmap %d",
163 draw
->bitmap_offset
);
164 qxl_log_rect(&draw
->bitmap_area
);
166 switch (draw
->type
) {
168 qxl_log_cmd_draw_copy(qxl
, &draw
->u
.copy
, group_id
);
173 static void qxl_log_cmd_surface(PCIQXLDevice
*qxl
, QXLSurfaceCmd
*cmd
)
175 fprintf(stderr
, ": %s id %d",
176 qxl_name(qxl_surface_cmd
, cmd
->type
),
178 if (cmd
->type
== QXL_SURFACE_CMD_CREATE
) {
179 fprintf(stderr
, " size %dx%d stride %d format %s (count %d, max %d)",
180 cmd
->u
.surface_create
.width
,
181 cmd
->u
.surface_create
.height
,
182 cmd
->u
.surface_create
.stride
,
183 qxl_name(spice_surface_fmt
, cmd
->u
.surface_create
.format
),
184 qxl
->guest_surfaces
.count
, qxl
->guest_surfaces
.max
);
186 if (cmd
->type
== QXL_SURFACE_CMD_DESTROY
) {
187 fprintf(stderr
, " (count %d)", qxl
->guest_surfaces
.count
);
191 void qxl_log_cmd_cursor(PCIQXLDevice
*qxl
, QXLCursorCmd
*cmd
, int group_id
)
195 fprintf(stderr
, ": %s",
196 qxl_name(qxl_cursor_cmd
, cmd
->type
));
199 fprintf(stderr
, " +%d+%d visible %s, shape @ 0x%" PRIx64
,
200 cmd
->u
.set
.position
.x
,
201 cmd
->u
.set
.position
.y
,
202 cmd
->u
.set
.visible
? "yes" : "no",
204 cursor
= qxl_phys2virt(qxl
, cmd
->u
.set
.shape
, group_id
);
205 fprintf(stderr
, " type %s size %dx%d hot-spot +%d+%d"
206 " unique 0x%" PRIx64
" data-size %d",
207 qxl_name(spice_cursor_type
, cursor
->header
.type
),
208 cursor
->header
.width
, cursor
->header
.height
,
209 cursor
->header
.hot_spot_x
, cursor
->header
.hot_spot_y
,
210 cursor
->header
.unique
, cursor
->data_size
);
212 case QXL_CURSOR_MOVE
:
213 fprintf(stderr
, " +%d+%d", cmd
->u
.position
.x
, cmd
->u
.position
.y
);
218 void qxl_log_command(PCIQXLDevice
*qxl
, const char *ring
, QXLCommandExt
*ext
)
220 bool compat
= ext
->flags
& QXL_COMMAND_FLAG_COMPAT
;
226 fprintf(stderr
, "qxl-%d/%s:", qxl
->id
, ring
);
227 fprintf(stderr
, " cmd @ 0x%" PRIx64
" %s%s", ext
->cmd
.data
,
228 qxl_name(qxl_type
, ext
->cmd
.type
),
229 compat
? "(compat)" : "");
231 data
= qxl_phys2virt(qxl
, ext
->cmd
.data
, ext
->group_id
);
232 switch (ext
->cmd
.type
) {
235 qxl_log_cmd_draw(qxl
, data
, ext
->group_id
);
237 qxl_log_cmd_draw_compat(qxl
, data
, ext
->group_id
);
240 case QXL_CMD_SURFACE
:
241 qxl_log_cmd_surface(qxl
, data
);
244 qxl_log_cmd_cursor(qxl
, data
, ext
->group_id
);
247 fprintf(stderr
, "\n");