static void virtio_gpu_set_scanout(VirtIOGPU *g,

                                   struct virtio_gpu_ctrl_command *cmd)

{

    struct virtio_gpu_simple_resource *res;

    struct virtio_gpu_scanout *scanout;

    pixman_format_code_t format;

    uint32_t offset;

    int bpp;

    struct virtio_gpu_set_scanout ss;



    VIRTIO_GPU_FILL_CMD(ss);

    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,

                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);



    if (ss.scanout_id >= g->conf.max_outputs) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",

                      __func__, ss.scanout_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

        return;

    }



    g->enable = 1;

    if (ss.resource_id == 0) {

        scanout = &g->scanout[ss.scanout_id];

        if (scanout->resource_id) {

            res = virtio_gpu_find_resource(g, scanout->resource_id);

            if (res) {

                res->scanout_bitmask &= ~(1 << ss.scanout_id);

            }

        }

        if (ss.scanout_id == 0) {

            qemu_log_mask(LOG_GUEST_ERROR,

                          "%s: illegal scanout id specified %d",

                          __func__, ss.scanout_id);

            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

            return;

        }

        dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);

        scanout->ds = NULL;

        scanout->width = 0;

        scanout->height = 0;

        return;

    }



    /* create a surface for this scanout */

    res = virtio_gpu_find_resource(g, ss.resource_id);

    if (!res) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",

                      __func__, ss.resource_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

        return;

    }



    if (ss.r.x > res->width ||

        ss.r.y > res->height ||

        ss.r.width > res->width ||

        ss.r.height > res->height ||

        ss.r.x + ss.r.width > res->width ||

        ss.r.y + ss.r.height > res->height) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"

                      " resource %d, (%d,%d)+%d,%d vs %d %d\n",

                      __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,

                      ss.r.width, ss.r.height, res->width, res->height);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;

        return;

    }



    scanout = &g->scanout[ss.scanout_id];



    format = pixman_image_get_format(res->image);

    bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;

    offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);

    if (!scanout->ds || surface_data(scanout->ds)

        != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||

        scanout->width != ss.r.width ||

        scanout->height != ss.r.height) {

        pixman_image_t *rect;

        void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;

        rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,

                                        pixman_image_get_stride(res->image));

        pixman_image_ref(res->image);

        pixman_image_set_destroy_function(rect, virtio_unref_resource,

                                          res->image);

        /* realloc the surface ptr */

        scanout->ds = qemu_create_displaysurface_pixman(rect);

        if (!scanout->ds) {

            cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;

            return;

        }


        dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds);

    }



    res->scanout_bitmask |= (1 << ss.scanout_id);

    scanout->resource_id = ss.resource_id;

    scanout->x = ss.r.x;

    scanout->y = ss.r.y;

    scanout->width = ss.r.width;

    scanout->height = ss.r.height;

}
static void virtio_gpu_set_scanout(VirtIOGPU *g,

                                   struct virtio_gpu_ctrl_command *cmd)

{

    struct virtio_gpu_simple_resource *res;

    struct virtio_gpu_scanout *scanout;

    pixman_format_code_t format;

    uint32_t offset;

    int bpp;

    struct virtio_gpu_set_scanout ss;



    VIRTIO_GPU_FILL_CMD(ss);

    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,

                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);



    if (ss.scanout_id >= g->conf.max_outputs) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",

                      __func__, ss.scanout_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

        return;

    }



    g->enable = 1;

    if (ss.resource_id == 0) {

        scanout = &g->scanout[ss.scanout_id];

        if (scanout->resource_id) {

            res = virtio_gpu_find_resource(g, scanout->resource_id);

            if (res) {

                res->scanout_bitmask &= ~(1 << ss.scanout_id);

            }

        }

        if (ss.scanout_id == 0) {

            qemu_log_mask(LOG_GUEST_ERROR,

                          "%s: illegal scanout id specified %d",

                          __func__, ss.scanout_id);

            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

            return;

        }

        dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);

        scanout->ds = NULL;

        scanout->width = 0;

        scanout->height = 0;

        return;

    }



    

    res = virtio_gpu_find_resource(g, ss.resource_id);

    if (!res) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",

                      __func__, ss.resource_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

        return;

    }



    if (ss.r.x > res->width ||

        ss.r.y > res->height ||

        ss.r.width > res->width ||

        ss.r.height > res->height ||

        ss.r.x + ss.r.width > res->width ||

        ss.r.y + ss.r.height > res->height) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"

                      " resource %d, (%d,%d)+%d,%d vs %d %d\n",

                      __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,

                      ss.r.width, ss.r.height, res->width, res->height);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;

        return;

    }



    scanout = &g->scanout[ss.scanout_id];



    format = pixman_image_get_format(res->image);

    bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;

    offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);

    if (!scanout->ds || surface_data(scanout->ds)

        != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||

        scanout->width != ss.r.width ||

        scanout->height != ss.r.height) {

        pixman_image_t *rect;

        void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;

        rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,

                                        pixman_image_get_stride(res->image));

        pixman_image_ref(res->image);

        pixman_image_set_destroy_function(rect, virtio_unref_resource,

                                          res->image);

        

        scanout->ds = qemu_create_displaysurface_pixman(rect);

        if (!scanout->ds) {

            cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;

            return;

        }


        dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds);

    }



    res->scanout_bitmask |= (1 << ss.scanout_id);

    scanout->resource_id = ss.resource_id;

    scanout->x = ss.r.x;

    scanout->y = ss.r.y;

    scanout->width = ss.r.width;

    scanout->height = ss.r.height;

}
static void FUNC_0(VirtIOGPU *VAR_0,

                                   struct virtio_gpu_ctrl_command *VAR_1)

{

    struct virtio_gpu_simple_resource *VAR_2;

    struct virtio_gpu_scanout *VAR_3;

    pixman_format_code_t format;

    uint32_t offset;

    int VAR_4;

    struct FUNC_0 VAR_5;



    VIRTIO_GPU_FILL_CMD(VAR_5);

    trace_virtio_gpu_cmd_set_scanout(VAR_5.scanout_id, VAR_5.resource_id,

                                     VAR_5.r.width, VAR_5.r.height, VAR_5.r.x, VAR_5.r.y);



    if (VAR_5.scanout_id >= VAR_0->conf.max_outputs) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal VAR_3 id specified %d",

                      __func__, VAR_5.scanout_id);

        VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

        return;

    }



    VAR_0->enable = 1;

    if (VAR_5.resource_id == 0) {

        VAR_3 = &VAR_0->VAR_3[VAR_5.scanout_id];

        if (VAR_3->resource_id) {

            VAR_2 = virtio_gpu_find_resource(VAR_0, VAR_3->resource_id);

            if (VAR_2) {

                VAR_2->scanout_bitmask &= ~(1 << VAR_5.scanout_id);

            }

        }

        if (VAR_5.scanout_id == 0) {

            qemu_log_mask(LOG_GUEST_ERROR,

                          "%s: illegal VAR_3 id specified %d",

                          __func__, VAR_5.scanout_id);

            VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

            return;

        }

        dpy_gfx_replace_surface(VAR_0->VAR_3[VAR_5.scanout_id].con, NULL);

        VAR_3->ds = NULL;

        VAR_3->width = 0;

        VAR_3->height = 0;

        return;

    }



    

    VAR_2 = virtio_gpu_find_resource(VAR_0, VAR_5.resource_id);

    if (!VAR_2) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",

                      __func__, VAR_5.resource_id);

        VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

        return;

    }



    if (VAR_5.r.x > VAR_2->width ||

        VAR_5.r.y > VAR_2->height ||

        VAR_5.r.width > VAR_2->width ||

        VAR_5.r.height > VAR_2->height ||

        VAR_5.r.x + VAR_5.r.width > VAR_2->width ||

        VAR_5.r.y + VAR_5.r.height > VAR_2->height) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal VAR_3 %d bounds for"

                      " resource %d, (%d,%d)+%d,%d vs %d %d\n",

                      __func__, VAR_5.scanout_id, VAR_5.resource_id, VAR_5.r.x, VAR_5.r.y,

                      VAR_5.r.width, VAR_5.r.height, VAR_2->width, VAR_2->height);

        VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;

        return;

    }



    VAR_3 = &VAR_0->VAR_3[VAR_5.scanout_id];



    format = pixman_image_get_format(VAR_2->image);

    VAR_4 = (PIXMAN_FORMAT_BPP(format) + 7) / 8;

    offset = (VAR_5.r.x * VAR_4) + VAR_5.r.y * pixman_image_get_stride(VAR_2->image);

    if (!VAR_3->ds || surface_data(VAR_3->ds)

        != ((uint8_t *)pixman_image_get_data(VAR_2->image) + offset) ||

        VAR_3->width != VAR_5.r.width ||

        VAR_3->height != VAR_5.r.height) {

        pixman_image_t *rect;

        void *VAR_6 = (uint8_t *)pixman_image_get_data(VAR_2->image) + offset;

        rect = pixman_image_create_bits(format, VAR_5.r.width, VAR_5.r.height, VAR_6,

                                        pixman_image_get_stride(VAR_2->image));

        pixman_image_ref(VAR_2->image);

        pixman_image_set_destroy_function(rect, virtio_unref_resource,

                                          VAR_2->image);

        

        VAR_3->ds = qemu_create_displaysurface_pixman(rect);

        if (!VAR_3->ds) {

            VAR_1->error = VIRTIO_GPU_RESP_ERR_UNSPEC;

            return;

        }


        dpy_gfx_replace_surface(VAR_0->VAR_3[VAR_5.scanout_id].con, VAR_3->ds);

    }



    VAR_2->scanout_bitmask |= (1 << VAR_5.scanout_id);

    VAR_3->resource_id = VAR_5.resource_id;

    VAR_3->x = VAR_5.r.x;

    VAR_3->y = VAR_5.r.y;

    VAR_3->width = VAR_5.r.width;

    VAR_3->height = VAR_5.r.height;

}
static void FUNC_0(VirtIOGPU *VAR_0,
struct virtio_gpu_ctrl_command *VAR_1)
{ struct virtio_gpu_simple_resource *VAR_2; struct virtio_gpu_scanout *VAR_3; pixman_format_code_t format; uint32_t offset; int VAR_4; struct FUNC_0 VAR_5; VIRTIO_GPU_FILL_CMD(VAR_5); trace_virtio_gpu_cmd_set_scanout(VAR_5.scanout_id, VAR_5.resource_id,
VAR_5.r.width, VAR_5.r.height, VAR_5.r.x, VAR_5.r.y); if (VAR_5.scanout_id >= VAR_0->conf.max_outputs) { qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal VAR_3 id specified %d",
__func__, VAR_5.scanout_id); VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; return; } VAR_0->enable = 1; if (VAR_5.resource_id == 0) { VAR_3 = &VAR_0->VAR_3[VAR_5.scanout_id]; if (VAR_3->resource_id) { VAR_2 = virtio_gpu_find_resource(VAR_0, VAR_3->resource_id); if (VAR_2) { VAR_2->scanout_bitmask &= ~(1 << VAR_5.scanout_id); } } if (VAR_5.scanout_id == 0) { qemu_log_mask(LOG_GUEST_ERROR,
"%s: illegal VAR_3 id specified %d",
__func__, VAR_5.scanout_id); VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; return; } dpy_gfx_replace_surface(VAR_0->VAR_3[VAR_5.scanout_id].con, NULL); VAR_3->ds = NULL; VAR_3->width = 0; VAR_3->height = 0; return; } VAR_2 = virtio_gpu_find_resource(VAR_0, VAR_5.resource_id); if (!VAR_2) { qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",
__func__, VAR_5.resource_id); VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; return; } if (VAR_5.r.x > VAR_2->width ||
VAR_5.r.y > VAR_2->height ||
VAR_5.r.width > VAR_2->width ||
VAR_5.r.height > VAR_2->height ||
VAR_5.r.x + VAR_5.r.width > VAR_2->width ||
VAR_5.r.y + VAR_5.r.height > VAR_2->height) { qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal VAR_3 %d bounds for"
" resource %d, (%d,%d)+%d,%d vs %d %d\n",
__func__, VAR_5.scanout_id, VAR_5.resource_id, VAR_5.r.x, VAR_5.r.y,
VAR_5.r.width, VAR_5.r.height, VAR_2->width, VAR_2->height); VAR_1->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; return; } VAR_3 = &VAR_0->VAR_3[VAR_5.scanout_id]; format = pixman_image_get_format(VAR_2->image); VAR_4 = (PIXMAN_FORMAT_BPP(format) + 7) / 8; offset = (VAR_5.r.x * VAR_4) + VAR_5.r.y * pixman_image_get_stride(VAR_2->image); if (!VAR_3->ds || surface_data(VAR_3->ds)
!= ((uint8_t *)pixman_image_get_data(VAR_2->image) + offset) ||
VAR_3->width != VAR_5.r.width ||
VAR_3->height != VAR_5.r.height) { pixman_image_t *rect; void *VAR_6 = (uint8_t *)pixman_image_get_data(VAR_2->image) + offset; rect = pixman_image_create_bits(format, VAR_5.r.width, VAR_5.r.height, VAR_6,
pixman_image_get_stride(VAR_2->image)); pixman_image_ref(VAR_2->image); pixman_image_set_destroy_function(rect, virtio_unref_resource,
VAR_2->image); VAR_3->ds = qemu_create_displaysurface_pixman(rect); if (!VAR_3->ds) { VAR_1->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; } dpy_gfx_replace_surface(VAR_0->VAR_3[VAR_5.scanout_id].con, VAR_3->ds); } VAR_2->scanout_bitmask |= (1 << VAR_5.scanout_id); VAR_3->resource_id = VAR_5.resource_id; VAR_3->x = VAR_5.r.x; VAR_3->y = VAR_5.r.y; VAR_3->width = VAR_5.r.width; VAR_3->height = VAR_5.r.height; }