[Spice-devel] [spice-server v3 14/14] qxl: Use QXLCommandExt in external red-parse-qxl.h API

Christophe Fergeau cfergeau at redhat.com
Tue Apr 24 10:29:18 UTC 2018


Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
---
 server/red-parse-qxl.c          | 146 +++++++++++++++++++---------------------
 server/red-parse-qxl.h          |  12 ++--
 server/red-worker.c             |  12 ++--
 server/tests/test-qxl-parsing.c |  32 +++++++--
 4 files changed, 107 insertions(+), 95 deletions(-)

diff --git a/server/red-parse-qxl.c b/server/red-parse-qxl.c
index 732eabcab..0f27b8b02 100644
--- a/server/red-parse-qxl.c
+++ b/server/red-parse-qxl.c
@@ -92,19 +92,18 @@ static inline uint32_t color_16_to_32(uint32_t color)
 static void * red_qxl_guest_resources_init(RedQXLGuestResources *guest_resources,
                                            QXLInstance *qxl_instance,
                                            RedMemSlotInfo *slots,
-                                           int group_id,
-                                           QXLPHYSICAL addr,
+                                           const QXLCommandExt *qxl_cmd,
                                            size_t size)
 {
     int error;
     void *red_data;
 
-    red_data = (void *)memslot_get_virt(slots, addr, size, group_id, &error);
+    red_data = (void *)memslot_get_virt(slots, qxl_cmd->cmd.data, size, qxl_cmd->group_id, &error);
     if (error) {
         return NULL;
     }
     guest_resources->qxl = qxl_instance;
-    guest_resources->release_info_ext.group_id = group_id;
+    guest_resources->release_info_ext.group_id = qxl_cmd->group_id;
     /* The 'release_info' field in QXL*Cmd is always the very first field */
     guest_resources->release_info_ext.info = red_data;
 
@@ -1040,21 +1039,21 @@ static void red_put_clip(SpiceClip *red_clip)
     }
 }
 
-static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
-                                    RedDrawable *red_drawable, QXLPHYSICAL addr, uint32_t flags)
+static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd,
+                                    RedDrawable *red_drawable, uint32_t flags)
 {
     QXLDrawable *qxl_drawable;
     int i;
 
     qxl_drawable = red_qxl_guest_resources_init(&red_drawable->guest_resources,
-                                                qxl_instance, slots, group_id,
-                                                addr, sizeof(*qxl_drawable));
+                                                qxl_instance, slots, qxl_cmd,
+                                                sizeof(*qxl_drawable));
     if (qxl_drawable == NULL) {
         return false;
     }
 
     red_get_rect_ptr(&red_drawable->bbox, &qxl_drawable->bbox);
-    red_get_clip_ptr(slots, group_id, &red_drawable->clip, &qxl_drawable->clip);
+    red_get_clip_ptr(slots, qxl_cmd->group_id, &red_drawable->clip, &qxl_drawable->clip);
     red_drawable->effect           = qxl_drawable->effect;
     red_drawable->mm_time          = qxl_drawable->mm_time;
     red_drawable->self_bitmap      = qxl_drawable->self_bitmap;
@@ -1069,48 +1068,48 @@ static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
     red_drawable->type = qxl_drawable->type;
     switch (red_drawable->type) {
     case QXL_DRAW_ALPHA_BLEND:
-        red_get_alpha_blend_ptr(slots, group_id,
+        red_get_alpha_blend_ptr(slots, qxl_cmd->group_id,
                                 &red_drawable->u.alpha_blend, &qxl_drawable->u.alpha_blend, flags);
         break;
     case QXL_DRAW_BLACKNESS:
-        red_get_blackness_ptr(slots, group_id,
+        red_get_blackness_ptr(slots, qxl_cmd->group_id,
                               &red_drawable->u.blackness, &qxl_drawable->u.blackness, flags);
         break;
     case QXL_DRAW_BLEND:
-        return red_get_blend_ptr(slots, group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags);
+        return red_get_blend_ptr(slots, qxl_cmd->group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags);
     case QXL_DRAW_COPY:
-        return red_get_copy_ptr(slots, group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags);
+        return red_get_copy_ptr(slots, qxl_cmd->group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags);
     case QXL_COPY_BITS:
         red_get_point_ptr(&red_drawable->u.copy_bits.src_pos, &qxl_drawable->u.copy_bits.src_pos);
         break;
     case QXL_DRAW_FILL:
-        red_get_fill_ptr(slots, group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags);
+        red_get_fill_ptr(slots, qxl_cmd->group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags);
         break;
     case QXL_DRAW_OPAQUE:
-        red_get_opaque_ptr(slots, group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags);
+        red_get_opaque_ptr(slots, qxl_cmd->group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags);
         break;
     case QXL_DRAW_INVERS:
-        red_get_invers_ptr(slots, group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags);
+        red_get_invers_ptr(slots, qxl_cmd->group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags);
         break;
     case QXL_DRAW_NOP:
         break;
     case QXL_DRAW_ROP3:
-        red_get_rop3_ptr(slots, group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags);
+        red_get_rop3_ptr(slots, qxl_cmd->group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags);
         break;
     case QXL_DRAW_COMPOSITE:
-        red_get_composite_ptr(slots, group_id, &red_drawable->u.composite, &qxl_drawable->u.composite, flags);
+        red_get_composite_ptr(slots, qxl_cmd->group_id, &red_drawable->u.composite, &qxl_drawable->u.composite, flags);
         break;
     case QXL_DRAW_STROKE:
-        return red_get_stroke_ptr(slots, group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags);
+        return red_get_stroke_ptr(slots, qxl_cmd->group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags);
     case QXL_DRAW_TEXT:
-        red_get_text_ptr(slots, group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags);
+        red_get_text_ptr(slots, qxl_cmd->group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags);
         break;
     case QXL_DRAW_TRANSPARENT:
-        red_get_transparent_ptr(slots, group_id,
+        red_get_transparent_ptr(slots, qxl_cmd->group_id,
                                 &red_drawable->u.transparent, &qxl_drawable->u.transparent, flags);
         break;
     case QXL_DRAW_WHITENESS:
-        red_get_whiteness_ptr(slots, group_id,
+        red_get_whiteness_ptr(slots, qxl_cmd->group_id,
                               &red_drawable->u.whiteness, &qxl_drawable->u.whiteness, flags);
         break;
     default:
@@ -1120,20 +1119,20 @@ static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
     return true;
 }
 
-static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
-                                    RedDrawable *red_drawable, QXLPHYSICAL addr, uint32_t flags)
+static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd,
+                                    RedDrawable *red_drawable, uint32_t flags)
 {
     QXLCompatDrawable *qxl_drawable;
 
     qxl_drawable = red_qxl_guest_resources_init(&red_drawable->guest_resources,
-                                                qxl_instance, slots, group_id,
-                                                addr, sizeof(*qxl_drawable));
+                                                qxl_instance, slots, qxl_cmd,
+                                                sizeof(*qxl_drawable));
     if (qxl_drawable == NULL) {
         return false;
     }
 
     red_get_rect_ptr(&red_drawable->bbox, &qxl_drawable->bbox);
-    red_get_clip_ptr(slots, group_id, &red_drawable->clip, &qxl_drawable->clip);
+    red_get_clip_ptr(slots, qxl_cmd->group_id, &red_drawable->clip, &qxl_drawable->clip);
     red_drawable->effect           = qxl_drawable->effect;
     red_drawable->mm_time          = qxl_drawable->mm_time;
 
@@ -1147,17 +1146,17 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
     red_drawable->type = qxl_drawable->type;
     switch (red_drawable->type) {
     case QXL_DRAW_ALPHA_BLEND:
-        red_get_alpha_blend_ptr_compat(slots, group_id,
+        red_get_alpha_blend_ptr_compat(slots, qxl_cmd->group_id,
                                        &red_drawable->u.alpha_blend, &qxl_drawable->u.alpha_blend, flags);
         break;
     case QXL_DRAW_BLACKNESS:
-        red_get_blackness_ptr(slots, group_id,
+        red_get_blackness_ptr(slots, qxl_cmd->group_id,
                               &red_drawable->u.blackness, &qxl_drawable->u.blackness, flags);
         break;
     case QXL_DRAW_BLEND:
-        return red_get_blend_ptr(slots, group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags);
+        return red_get_blend_ptr(slots, qxl_cmd->group_id, &red_drawable->u.blend, &qxl_drawable->u.blend, flags);
     case QXL_DRAW_COPY:
-        return red_get_copy_ptr(slots, group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags);
+        return red_get_copy_ptr(slots, qxl_cmd->group_id, &red_drawable->u.copy, &qxl_drawable->u.copy, flags);
     case QXL_COPY_BITS:
         red_get_point_ptr(&red_drawable->u.copy_bits.src_pos, &qxl_drawable->u.copy_bits.src_pos);
         red_drawable->surface_deps[0] = 0;
@@ -1169,30 +1168,30 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
             (red_drawable->bbox.bottom - red_drawable->bbox.top);
         break;
     case QXL_DRAW_FILL:
-        red_get_fill_ptr(slots, group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags);
+        red_get_fill_ptr(slots, qxl_cmd->group_id, &red_drawable->u.fill, &qxl_drawable->u.fill, flags);
         break;
     case QXL_DRAW_OPAQUE:
-        red_get_opaque_ptr(slots, group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags);
+        red_get_opaque_ptr(slots, qxl_cmd->group_id, &red_drawable->u.opaque, &qxl_drawable->u.opaque, flags);
         break;
     case QXL_DRAW_INVERS:
-        red_get_invers_ptr(slots, group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags);
+        red_get_invers_ptr(slots, qxl_cmd->group_id, &red_drawable->u.invers, &qxl_drawable->u.invers, flags);
         break;
     case QXL_DRAW_NOP:
         break;
     case QXL_DRAW_ROP3:
-        red_get_rop3_ptr(slots, group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags);
+        red_get_rop3_ptr(slots, qxl_cmd->group_id, &red_drawable->u.rop3, &qxl_drawable->u.rop3, flags);
         break;
     case QXL_DRAW_STROKE:
-        return red_get_stroke_ptr(slots, group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags);
+        return red_get_stroke_ptr(slots, qxl_cmd->group_id, &red_drawable->u.stroke, &qxl_drawable->u.stroke, flags);
     case QXL_DRAW_TEXT:
-        red_get_text_ptr(slots, group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags);
+        red_get_text_ptr(slots, qxl_cmd->group_id, &red_drawable->u.text, &qxl_drawable->u.text, flags);
         break;
     case QXL_DRAW_TRANSPARENT:
-        red_get_transparent_ptr(slots, group_id,
+        red_get_transparent_ptr(slots, qxl_cmd->group_id,
                                 &red_drawable->u.transparent, &qxl_drawable->u.transparent, flags);
         break;
     case QXL_DRAW_WHITENESS:
-        red_get_whiteness_ptr(slots, group_id,
+        red_get_whiteness_ptr(slots, qxl_cmd->group_id,
                               &red_drawable->u.whiteness, &qxl_drawable->u.whiteness, flags);
         break;
     default:
@@ -1202,15 +1201,15 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
     return true;
 }
 
-static bool red_get_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
-                             RedDrawable *red_drawable, QXLPHYSICAL addr, uint32_t flags)
+static bool red_get_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd,
+                             RedDrawable *red_drawable, uint32_t flags)
 {
     bool ret;
 
     if (flags & QXL_COMMAND_FLAG_COMPAT) {
-        ret = red_get_compat_drawable(qxl_instance, slots, group_id, red_drawable, addr, flags);
+        ret = red_get_compat_drawable(qxl_instance, slots, qxl_cmd, red_drawable, flags);
     } else {
-        ret = red_get_native_drawable(qxl_instance, slots, group_id, red_drawable, addr, flags);
+        ret = red_get_native_drawable(qxl_instance, slots, qxl_cmd, red_drawable, flags);
     }
     return ret;
 }
@@ -1265,14 +1264,14 @@ static void red_put_drawable(RedDrawable *red_drawable)
     red_qxl_guest_resources_release(&red_drawable->guest_resources);
 }
 
-static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
-                               RedUpdateCmd *red_cmd, QXLPHYSICAL addr)
+static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
+                               const QXLCommandExt *qxl_cmd_ext, RedUpdateCmd *red_cmd)
 {
     QXLUpdateCmd *qxl_cmd;
 
     qxl_cmd = red_qxl_guest_resources_init(&red_cmd->guest_resources,
-                                           qxl_instance, slots, group_id,
-                                           addr, sizeof(*qxl_cmd));
+                                           qxl_instance, slots, qxl_cmd_ext,
+                                           sizeof(*qxl_cmd));
     if (qxl_cmd == NULL) {
         return false;
     }
@@ -1288,7 +1287,7 @@ static void red_put_update_cmd(RedUpdateCmd *red_cmd)
     red_qxl_guest_resources_release(&red_cmd->guest_resources);
 }
 
-RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr)
+RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd_ext)
 {
     RedUpdateCmd *cmd;
 
@@ -1296,7 +1295,7 @@ RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int gr
 
     cmd->refs = 1;
 
-    if (!red_get_update_cmd(qxl, slots, group_id, cmd, addr)) {
+    if (!red_get_update_cmd(qxl, slots, qxl_cmd_ext, cmd)) {
         red_update_cmd_unref(cmd);
         return NULL;
     }
@@ -1319,8 +1318,8 @@ void red_update_cmd_unref(RedUpdateCmd *cmd)
     g_free(cmd);
 }
 
-static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
-                            RedMessage *red_message, QXLPHYSICAL addr)
+static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
+                            const QXLCommandExt *qxl_cmd, RedMessage *red_message)
 {
     QXLMessage *qxl_message;
     int memslot_id;
@@ -1335,14 +1334,14 @@ static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, in
      */
     //qxl_message = (QXLMessage *)memslot_get_virt(slots, addr, sizeof(*qxl_message), group_id, &error);
     qxl_message = red_qxl_guest_resources_init(&red_message->guest_resources,
-                                               qxl_instance, slots, group_id,
-                                               addr, sizeof(*qxl_message));
+                                               qxl_instance, slots, qxl_cmd,
+                                               sizeof(*qxl_message));
     if (qxl_message == NULL) {
         return false;
     }
     red_message->data = qxl_message->data;
-    memslot_id = memslot_get_id(slots, addr+sizeof(*qxl_message));
-    len = memslot_max_size_virt(slots, ((intptr_t) qxl_message)+sizeof(*qxl_message), memslot_id, group_id);
+    memslot_id = memslot_get_id(slots, qxl_cmd->cmd.data+sizeof(*qxl_message));
+    len = memslot_max_size_virt(slots, ((intptr_t) qxl_message)+sizeof(*qxl_message), memslot_id, qxl_cmd->group_id);
     len = MIN(len, 100000);
     end = (uint8_t *)memchr(qxl_message->data, 0, len);
     if (end == NULL) {
@@ -1357,7 +1356,7 @@ static void red_put_message(RedMessage *red_message)
     red_qxl_guest_resources_release(&red_message->guest_resources);
 }
 
-RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr)
+RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd)
 {
     RedMessage *message;
 
@@ -1365,7 +1364,7 @@ RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_i
 
     message->refs = 1;
 
-    if (!red_get_message(qxl, slots, group_id, message, addr)) {
+    if (!red_get_message(qxl, slots, qxl_cmd, message)) {
         red_message_unref(message);
         return NULL;
     }
@@ -1434,17 +1433,16 @@ bool red_validate_surface(uint32_t width, uint32_t height,
     return true;
 }
 
-static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
-                                RedSurfaceCmd *red_cmd, QXLPHYSICAL addr)
-
+static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
+                                const QXLCommandExt *qxl_cmd_ext, RedSurfaceCmd *red_cmd)
 {
     QXLSurfaceCmd *qxl_cmd;
     uint64_t size;
     int error;
 
     qxl_cmd = red_qxl_guest_resources_init(&red_cmd->guest_resources,
-                                           qxl_instance, slots, group_id,
-                                           addr, sizeof(*qxl_cmd));
+                                           qxl_instance, slots, qxl_cmd_ext,
+                                           sizeof(*qxl_cmd));
     if (qxl_cmd == NULL) {
         return false;
     }
@@ -1467,7 +1465,7 @@ static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots
 
         size = red_cmd->u.surface_create.height * abs(red_cmd->u.surface_create.stride);
         red_cmd->u.surface_create.data =
-            (uint8_t*)memslot_get_virt(slots, qxl_cmd->u.surface_create.data, size, group_id, &error);
+            (uint8_t*)memslot_get_virt(slots, qxl_cmd->u.surface_create.data, size, qxl_cmd_ext->group_id, &error);
         if (error) {
             return false;
         }
@@ -1482,7 +1480,7 @@ static void red_put_surface_cmd(RedSurfaceCmd *red_cmd)
 }
 
 RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
-                                   int group_id, QXLPHYSICAL addr)
+                                   const QXLCommandExt *qxl_cmd_ext)
 {
     RedSurfaceCmd *cmd;
 
@@ -1490,7 +1488,7 @@ RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *sl
 
     cmd->refs = 1;
 
-    if (!red_get_surface_cmd(qxl_instance, slots, group_id, cmd, addr)) {
+    if (!red_get_surface_cmd(qxl_instance, slots, qxl_cmd_ext, cmd)) {
         red_surface_cmd_unref(cmd);
         return NULL;
     }
@@ -1560,14 +1558,13 @@ static void red_put_cursor(SpiceCursor *red_cmd)
 }
 
 static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
-                               int group_id, RedCursorCmd *red_cmd,
-                               QXLPHYSICAL addr)
+                               const QXLCommandExt *qxl_cmd_ext, RedCursorCmd *red_cmd)
 {
     QXLCursorCmd *qxl_cmd;
 
     qxl_cmd = red_qxl_guest_resources_init(&red_cmd->guest_resources,
-                                           qxl_instance, slots, group_id,
-                                           addr, sizeof(*qxl_cmd));
+                                           qxl_instance, slots, qxl_cmd_ext,
+                                           sizeof(*qxl_cmd));
     if (qxl_cmd == NULL) {
         return false;
     }
@@ -1577,7 +1574,7 @@ static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
     case QXL_CURSOR_SET:
         red_get_point16_ptr(&red_cmd->u.set.position, &qxl_cmd->u.set.position);
         red_cmd->u.set.visible  = qxl_cmd->u.set.visible;
-        return red_get_cursor(slots, group_id,  &red_cmd->u.set.shape, qxl_cmd->u.set.shape);
+        return red_get_cursor(slots, qxl_cmd_ext->group_id,  &red_cmd->u.set.shape, qxl_cmd->u.set.shape);
     case QXL_CURSOR_MOVE:
         red_get_point16_ptr(&red_cmd->u.position, &qxl_cmd->u.position);
         break;
@@ -1590,7 +1587,7 @@ static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
 }
 
 RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
-                                 int group_id, QXLPHYSICAL addr)
+                                 const QXLCommandExt *qxl_cmd)
 {
     RedCursorCmd *cmd;
 
@@ -1598,7 +1595,7 @@ RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slot
 
     cmd->refs = 1;
 
-    if (!red_get_cursor_cmd(qxl_instance, slots, group_id, cmd, addr)) {
+    if (!red_get_cursor_cmd(qxl_instance, slots, qxl_cmd, cmd)) {
         red_cursor_cmd_unref(cmd);
         return NULL;
     }
@@ -1647,14 +1644,13 @@ void red_drawable_unref(RedDrawable *red_drawable)
 }
 
 RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
-                              int group_id, QXLPHYSICAL addr,
-                              uint32_t flags)
+                              const QXLCommandExt *qxl_cmd, uint32_t flags)
 {
     RedDrawable *red = g_new0(RedDrawable, 1);
 
     red->refs = 1;
 
-    if (!red_get_drawable(qxl, slots, group_id, red, addr, flags)) {
+    if (!red_get_drawable(qxl, slots, qxl_cmd, red, flags)) {
        red_drawable_unref(red);
        return NULL;
     }
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 2f6af584d..624669470 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -118,16 +118,15 @@ typedef struct RedCursorCmd {
 void red_get_rect_ptr(SpiceRect *red, const QXLRect *qxl);
 
 RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
-                              int group_id, QXLPHYSICAL addr,
-                              uint32_t flags);
+                              const QXLCommandExt *qxl_cmd_ext, uint32_t flags);
 RedDrawable *red_drawable_ref(RedDrawable *drawable);
 void red_drawable_unref(RedDrawable *red_drawable);
 
-RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr);
+RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd_ext);
 RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red);
 void red_update_cmd_unref(RedUpdateCmd *red);
 
-RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr);
+RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd);
 RedMessage *red_message_ref(RedMessage *red);
 void red_message_unref(RedMessage *red);
 
@@ -135,12 +134,11 @@ bool red_validate_surface(uint32_t width, uint32_t height,
                           int32_t stride, uint32_t format);
 
 RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
-                                   int group_id, QXLPHYSICAL addr);
+                                   const QXLCommandExt *qxl_cmd_ext);
 RedSurfaceCmd *red_surface_cmd_ref(RedSurfaceCmd *cmd);
 void red_surface_cmd_unref(RedSurfaceCmd *cmd);
 
-RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
-                                 int group_id, QXLPHYSICAL addr);
+RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, const QXLCommandExt *qxl_cmd_ext);
 RedCursorCmd *red_cursor_cmd_ref(RedCursorCmd *cmd);
 void red_cursor_cmd_unref(RedCursorCmd *cmd);
 
diff --git a/server/red-worker.c b/server/red-worker.c
index b0273eee1..1a3416d55 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -103,8 +103,7 @@ static gboolean red_process_cursor_cmd(RedWorker *worker, const QXLCommandExt *e
 {
     RedCursorCmd *cursor_cmd;
 
-    cursor_cmd = red_cursor_cmd_new(worker->qxl, &worker->mem_slots,
-                                    ext->group_id, ext->cmd.data);
+    cursor_cmd = red_cursor_cmd_new(worker->qxl, &worker->mem_slots, ext);
     if (cursor_cmd == NULL) {
         return FALSE;
     }
@@ -161,7 +160,7 @@ static gboolean red_process_surface_cmd(RedWorker *worker, QXLCommandExt *ext, g
 {
     RedSurfaceCmd *surface_cmd;
 
-    surface_cmd = red_surface_cmd_new(worker->qxl, &worker->mem_slots, ext->group_id, ext->cmd.data);
+    surface_cmd = red_surface_cmd_new(worker->qxl, &worker->mem_slots, ext);
     if (surface_cmd == NULL) {
         return false;
     }
@@ -209,8 +208,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
         case QXL_CMD_DRAW: {
             RedDrawable *red_drawable;
             red_drawable = red_drawable_new(worker->qxl, &worker->mem_slots,
-                                            ext_cmd.group_id, ext_cmd.cmd.data,
-                                            ext_cmd.flags); // returns with 1 ref
+                                            &ext_cmd, ext_cmd.flags); // returns with 1 ref
 
             if (red_drawable != NULL) {
                 display_channel_process_draw(worker->display_channel, red_drawable,
@@ -222,7 +220,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
         case QXL_CMD_UPDATE: {
             RedUpdateCmd *update;
 
-            update = red_update_cmd_new(worker->qxl, &worker->mem_slots,  ext_cmd.group_id, ext_cmd.cmd.data);
+            update = red_update_cmd_new(worker->qxl, &worker->mem_slots, &ext_cmd);
             if (update == NULL) {
                 break;
             }
@@ -238,7 +236,7 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
         case QXL_CMD_MESSAGE: {
             RedMessage *message;
 
-            message = red_message_new(worker->qxl, &worker->mem_slots, ext_cmd.group_id, ext_cmd.cmd.data);
+            message = red_message_new(worker->qxl, &worker->mem_slots, &ext_cmd);
             if (message == NULL) {
                 break;
             }
diff --git a/server/tests/test-qxl-parsing.c b/server/tests/test-qxl-parsing.c
index f244379bc..22136a6c9 100644
--- a/server/tests/test-qxl-parsing.c
+++ b/server/tests/test-qxl-parsing.c
@@ -90,12 +90,15 @@ static void test_no_issues(void)
     RedMemSlotInfo mem_info;
     RedSurfaceCmd *cmd;
     QXLSurfaceCmd qxl;
+    QXLCommandExt cmd_ext = { 0, };
 
     init_meminfo(&mem_info);
     init_qxl_surface(&qxl);
 
     /* try to create a surface with no issues, should succeed */
-    cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
+    cmd_ext.group_id = 0;
+    cmd_ext.cmd.data = to_physical(&qxl);
+    cmd = red_surface_cmd_new(NULL, &mem_info, &cmd_ext);
     g_assert_nonnull(cmd);
     red_surface_cmd_unref(cmd);
 
@@ -108,6 +111,7 @@ static void test_stride_too_small(void)
     RedMemSlotInfo mem_info;
     RedSurfaceCmd *cmd;
     QXLSurfaceCmd qxl;
+    QXLCommandExt cmd_ext = { 0, };
 
     init_meminfo(&mem_info);
     init_qxl_surface(&qxl);
@@ -117,7 +121,9 @@ static void test_stride_too_small(void)
      * This can be used to cause buffer overflows so refuse it.
      */
     qxl.u.surface_create.stride = 256;
-    cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
+    cmd_ext.group_id = 0;
+    cmd_ext.cmd.data = to_physical(&qxl);
+    cmd = red_surface_cmd_new(NULL, &mem_info, &cmd_ext);
     g_assert_null(cmd);
 
     deinit_qxl_surface(&qxl);
@@ -129,6 +135,7 @@ static void test_too_big_image(void)
     RedMemSlotInfo mem_info;
     RedSurfaceCmd *cmd;
     QXLSurfaceCmd qxl;
+    QXLCommandExt cmd_ext = { 0, };
 
     init_meminfo(&mem_info);
     init_qxl_surface(&qxl);
@@ -143,7 +150,9 @@ static void test_too_big_image(void)
     qxl.u.surface_create.stride = 0x08000004 * 4;
     qxl.u.surface_create.width = 0x08000004;
     qxl.u.surface_create.height = 0x40000020;
-    cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
+    cmd_ext.group_id = 0;
+    cmd_ext.cmd.data = to_physical(&qxl);
+    cmd = red_surface_cmd_new(NULL, &mem_info, &cmd_ext);
     g_assert_null(cmd);
 
     deinit_qxl_surface(&qxl);
@@ -156,6 +165,7 @@ static void test_cursor_command(void)
     RedCursorCmd *red_cursor_cmd;
     QXLCursorCmd cursor_cmd;
     QXLCursor *cursor;
+    QXLCommandExt cmd_ext = { 0, };
 
     init_meminfo(&mem_info);
 
@@ -171,7 +181,9 @@ static void test_cursor_command(void)
 
     cursor_cmd.u.set.shape = to_physical(cursor);
 
-    red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
+    cmd_ext.group_id = 0;
+    cmd_ext.cmd.data = to_physical(&cursor_cmd);
+    red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, &cmd_ext);
     g_assert_true(red_cursor_cmd != NULL);
     red_cursor_cmd_unref(red_cursor_cmd);
     g_free(cursor);
@@ -185,6 +197,7 @@ static void test_circular_empty_chunks(void)
     QXLCursorCmd cursor_cmd;
     QXLCursor *cursor;
     QXLDataChunk *chunks[2];
+    QXLCommandExt cmd_ext = { 0, };
 
     init_meminfo(&mem_info);
     g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
@@ -205,7 +218,9 @@ static void test_circular_empty_chunks(void)
 
     cursor_cmd.u.set.shape = to_physical(cursor);
 
-    red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
+    cmd_ext.group_id = 0;
+    cmd_ext.cmd.data = to_physical(&cursor_cmd);
+    red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, &cmd_ext);
     if (red_cursor_cmd != NULL) {
         /* function does not return errors so there should be no data */
         g_assert_cmpuint(red_cursor_cmd->type, ==, QXL_CURSOR_SET);
@@ -228,11 +243,14 @@ static void test_circular_small_chunks(void)
     QXLCursorCmd cursor_cmd;
     QXLCursor *cursor;
     QXLDataChunk *chunks[2];
+    QXLCommandExt cmd_ext;
 
     init_meminfo(&mem_info);
     g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
                           "*red_get_data_chunks_ptr: data split in too many chunks, avoiding DoS*");
 
+    memset(&cmd_ext, 0, sizeof(cmd_ext));
+
     /* a circular list of small chunks should not be a problems */
     memset(&cursor_cmd, 0, sizeof(cursor_cmd));
     cursor_cmd.type = QXL_CURSOR_SET;
@@ -248,7 +266,9 @@ static void test_circular_small_chunks(void)
 
     cursor_cmd.u.set.shape = to_physical(cursor);
 
-    red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
+    cmd_ext.group_id = 0;
+    cmd_ext.cmd.data = to_physical(&cursor_cmd);
+    red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, &cmd_ext);
     if (red_cursor_cmd != NULL) {
         /* function does not return errors so there should be no data */
         g_assert_cmpuint(red_cursor_cmd->type, ==, QXL_CURSOR_SET);
-- 
2.14.3



More information about the Spice-devel mailing list