[Spice-devel] [RFC] server/red_parse_qxl: introduce visitor for cursor
Alon Levy
alevy at redhat.com
Wed Nov 14 12:36:44 PST 2012
This is a second attempt at recording commands received from the qxl
device. The visitor allows more code to be shared between the device to
spice struct verifier and copier and the logger.
---
Does this look doable? it's the beginning of a second try at recording qxl
traffic for debugging and development.
server/red_parse_qxl.c | 142 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 104 insertions(+), 38 deletions(-)
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index 82463e1..298a334 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -1251,8 +1251,88 @@ void red_put_surface_cmd(RedSurfaceCmd *red)
/* nothing yet */
}
-static int red_get_cursor(RedMemSlotInfo *slots, int group_id,
- SpiceCursor *red, QXLPHYSICAL addr)
+typedef struct CursorCmdVisitor {
+ RedMemSlotInfo *slots;
+ int group_id;
+ void *opaque;
+ void (*visit_cursor_cmd)(void *opaque, QXLCursorCmd *qxl);
+ void (*visit_cursor_set_1)(void *opaque, QXLPoint16 *position, uint8_t visible);
+ void (*visit_cursor_set_2)(void *opaque, QXLCursorHeader *header,
+ uint32_t data_size, bool free_data, size_t size,
+ uint8_t *data);
+ void (*visit_cursor_move)(void *opaque, QXLPoint16 *position);
+ void (*visit_cursor_trail)(void *opaque, uint16_t length, uint16_t frequency);
+} CursorCmdVisitor;
+
+static void red_put_cursor(SpiceCursor *red)
+{
+ free(red->data);
+}
+
+static void copy_visit_cursor_cmd(void *opaque, QXLCursorCmd *qxl)
+{
+ RedCursorCmd *cmd = opaque;
+
+ cmd->release_info = &qxl->release_info;
+ cmd->type = qxl->type;
+}
+
+void copy_visit_cursor_set_1(void *opaque, QXLPoint16 *position, uint8_t visible)
+{
+ RedCursorCmd *red = opaque;
+
+ red_get_point16_ptr(&red->u.set.position, position);
+ red->u.set.visible = visible;
+}
+
+static void copy_visit_cursor_set_2(void *opaque, QXLCursorHeader *header,
+ uint32_t data_size, bool free_data, size_t size,
+ uint8_t *data)
+{
+ RedCursorCmd *cmd = opaque;
+ SpiceCursor *red = &cmd->u.set.shape;
+
+ red->header.unique = header->unique;
+ red->header.type = header->type;
+ red->header.width = header->width;
+ red->header.height = header->height;
+ red->header.hot_spot_x = header->hot_spot_x;
+ red->header.hot_spot_y = header->hot_spot_y;
+
+ red->flags = 0;
+ red->data_size = data_size;
+ if (free_data) {
+ red->data = data;
+ } else {
+ red->data = spice_malloc(size);
+ memcpy(red->data, data, size);
+ }
+}
+
+void copy_visit_cursor_move(void *opaque, QXLPoint16 *position)
+{
+ RedCursorCmd *red = opaque;
+
+ red_get_point16_ptr(&red->u.position, position);
+}
+
+void copy_visit_cursor_trail(void *opaque, uint16_t length, uint16_t frequency)
+{
+ RedCursorCmd *red = opaque;
+
+ red->u.trail.length = length;
+ red->u.trail.frequency = frequency;
+}
+
+CursorCmdVisitor copy_cursor_visitor = {
+ .visit_cursor_cmd = copy_visit_cursor_cmd,
+ .visit_cursor_set_1 = copy_visit_cursor_set_1,
+ .visit_cursor_set_2 = copy_visit_cursor_set_2,
+ .visit_cursor_move = copy_visit_cursor_move,
+ .visit_cursor_trail = copy_visit_cursor_trail,
+};
+
+static int visit_cursor_cmd_set(CursorCmdVisitor *v, QXLPHYSICAL addr)
{
QXLCursor *qxl;
RedDataChunk chunks;
@@ -1261,69 +1341,55 @@ static int red_get_cursor(RedMemSlotInfo *slots, int group_id,
bool free_data;
int error;
- qxl = (QXLCursor *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+ qxl = (QXLCursor *)get_virt(v->slots, addr, sizeof(*qxl), v->group_id, &error);
if (error) {
return 1;
}
- red->header.unique = qxl->header.unique;
- red->header.type = qxl->header.type;
- red->header.width = qxl->header.width;
- red->header.height = qxl->header.height;
- red->header.hot_spot_x = qxl->header.hot_spot_x;
- red->header.hot_spot_y = qxl->header.hot_spot_y;
-
- red->flags = 0;
- red->data_size = qxl->data_size;
- size = red_get_data_chunks_ptr(slots, group_id,
- get_memslot_id(slots, addr),
+ size = red_get_data_chunks_ptr(v->slots, v->group_id,
+ get_memslot_id(v->slots, addr),
&chunks, &qxl->chunk);
data = red_linearize_chunk(&chunks, size, &free_data);
red_put_data_chunks(&chunks);
- if (free_data) {
- red->data = data;
- } else {
- red->data = spice_malloc(size);
- memcpy(red->data, data, size);
- }
+ v->visit_cursor_set_2(v->opaque, &qxl->header, qxl->data_size,
+ free_data, size, data);
return 0;
}
-static void red_put_cursor(SpiceCursor *red)
-{
- free(red->data);
-}
-
-int red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id,
- RedCursorCmd *red, QXLPHYSICAL addr)
+int visit_cursor_cmd(CursorCmdVisitor *v, QXLPHYSICAL addr)
{
QXLCursorCmd *qxl;
int error;
- qxl = (QXLCursorCmd *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
+ qxl = (QXLCursorCmd *)get_virt(v->slots, addr, sizeof(*qxl), v->group_id, &error);
if (error) {
return error;
}
- red->release_info = &qxl->release_info;
-
- red->type = qxl->type;
- switch (red->type) {
+ v->visit_cursor_cmd(v->opaque, qxl);
+ switch (qxl->type) {
case QXL_CURSOR_SET:
- red_get_point16_ptr(&red->u.set.position, &qxl->u.set.position);
- red->u.set.visible = qxl->u.set.visible;
- error = red_get_cursor(slots, group_id, &red->u.set.shape, qxl->u.set.shape);
+ v->visit_cursor_set_1(v->opaque, &qxl->u.set.position, qxl->u.set.visible);
+ error = visit_cursor_cmd_set(v, qxl->u.set.shape);
break;
case QXL_CURSOR_MOVE:
- red_get_point16_ptr(&red->u.position, &qxl->u.position);
+ v->visit_cursor_move(v->opaque, &qxl->u.position);
break;
case QXL_CURSOR_TRAIL:
- red->u.trail.length = qxl->u.trail.length;
- red->u.trail.frequency = qxl->u.trail.frequency;
+ v->visit_cursor_trail(v->opaque, qxl->u.trail.length, qxl->u.trail.frequency);
break;
}
return error;
}
+int red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id,
+ RedCursorCmd *red, QXLPHYSICAL addr)
+{
+ copy_cursor_visitor.slots = slots;
+ copy_cursor_visitor.group_id = group_id;
+ copy_cursor_visitor.opaque = red;
+ return visit_cursor_cmd(©_cursor_visitor, addr);
+}
+
void red_put_cursor_cmd(RedCursorCmd *red)
{
switch (red->type) {
--
1.8.0
More information about the Spice-devel
mailing list