/*
 * Copyright (C) 2010 Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "ui/qemu-spice.h"
#include "qemu/timer.h"
#include "qemu/main-loop.h"
#include "qemu/option.h"
#include "qemu/queue.h"
#include "ui/console.h"
#include "trace.h"

#include "ui/spice-display.h"

bool spice_opengl;

int qemu_spice_rect_is_empty(const QXLRect* r)
{
    return r->top == r->bottom || r->left == r->right;
}

void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
{
    if (qemu_spice_rect_is_empty(r)) {
        return;
    }

    if (qemu_spice_rect_is_empty(dest)) {
        *dest = *r;
        return;
    }

    dest->top = MIN(dest->top, r->top);
    dest->left = MIN(dest->left, r->left);
    dest->bottom = MAX(dest->bottom, r->bottom);
    dest->right = MAX(dest->right, r->right);
}

QXLCookie *qxl_cookie_new(int type, uint64_t io)
{
    QXLCookie *cookie;

    cookie = g_malloc0(sizeof(*cookie));
    cookie->type = type;
    cookie->io = io;
    return cookie;
}

void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
                            qxl_async_io async)
{
    trace_qemu_spice_add_memslot(ssd->qxl.id, memslot->slot_id,
                                memslot->virt_start, memslot->virt_end,
                                async);

    if (async != QXL_SYNC) {
        spice_qxl_add_memslot_async(&ssd->qxl, memslot,
                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                          QXL_IO_MEMSLOT_ADD_ASYNC));
    } else {
        spice_qxl_add_memslot(&ssd->qxl, memslot);
    }
}

void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
{
    trace_qemu_spice_del_memslot(ssd->qxl.id, gid, sid);
    spice_qxl_del_memslot(&ssd->qxl, gid, sid);
}

void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
                                       QXLDevSurfaceCreate *surface,
                                       qxl_async_io async)
{
    trace_qemu_spice_create_primary_surface(ssd->qxl.id, id, surface, async);
    if (async != QXL_SYNC) {
        spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface,
                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                          QXL_IO_CREATE_PRIMARY_ASYNC));
    } else {
        spice_qxl_create_primary_surface(&ssd->qxl, id, surface);
    }
}

void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
                                        uint32_t id, qxl_async_io async)
{
    trace_qemu_spice_destroy_primary_surface(ssd->qxl.id, id, async);
    if (async != QXL_SYNC) {
        spice_qxl_destroy_primary_surface_async(&ssd->qxl, id,
                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                          QXL_IO_DESTROY_PRIMARY_ASYNC));
    } else {
        spice_qxl_destroy_primary_surface(&ssd->qxl, id);
    }
}

void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
{
    trace_qemu_spice_wakeup(ssd->qxl.id);
    spice_qxl_wakeup(&ssd->qxl);
}

static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
                                         QXLRect *rect)
{
    SimpleSpiceUpdate *update;
    QXLDrawable *drawable;
    QXLImage *image;
    QXLCommand *cmd;
    int bw, bh;
    struct timespec time_space;
    pixman_image_t *dest;

    trace_qemu_spice_create_update(
           rect->left, rect->right,
           rect->top, rect->bottom);

    update   = g_malloc0(sizeof(*update));
    drawable = &update->drawable;
    image    = &update->image;
    cmd      = &update->ext.cmd;

    bw       = rect->right - rect->left;
    bh       = rect->bottom - rect->top;
    update->bitmap = g_malloc(bw * bh * 4);

    drawable->bbox            = *rect;
    drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
    drawable->effect          = QXL_EFFECT_OPAQUE;
    drawable->release_info.id = (uintptr_t)(&update->ext);
    drawable->type            = QXL_DRAW_COPY;
    drawable->surfaces_dest[0] = -1;
    drawable->surfaces_dest[1] = -1;
    drawable->surfaces_dest[2] = -1;
    clock_gettime(CLOCK_MONOTONIC, &time_space);
    /* time in milliseconds from epoch. */
    drawable->mm_time = time_space.tv_sec * 1000
                      + time_space.tv_nsec / 1000 / 1000;

    drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
    drawable->u.copy.src_bitmap      = (uintptr_t)image;
    drawable->u.copy.src_area.right  = bw;
    drawable->u.copy.src_area.bottom = bh;

    QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
    image->descriptor.type   = SPICE_IMAGE_TYPE_BITMAP;
    image->bitmap.flags      = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
    image->bitmap.stride     = bw * 4;
    image->descriptor.width  = image->bitmap.x = bw;
    image->descriptor.height = image->bitmap.y = bh;
    image->bitmap.data = (uintptr_t)(update->bitmap);
    image->bitmap.palette = 0;
    image->bitmap.format = SPICE_BITMAP_FMT_32BIT;

    dest = pixman_image_create_bits(PIXMAN_LE_x8r8g8b8, bw, bh,
                                    (void *)update->bitmap, bw * 4);
    pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror,
                           rect->left, rect->top, 0, 0,
                           rect->left, rect->top, bw, bh);
    pixman_image_composite(PIXMAN_OP_SRC, ssd->mirror, NULL, dest,
                           rect->left, rect->top, 0, 0,
                           0, 0, bw, bh);
    pixman_image_unref(dest);

    cmd->type = QXL_CMD_DRAW;
    cmd->data = (uintptr_t)drawable;

    QTAILQ_INSERT_TAIL(&ssd->updates, update, next);
}

static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
{
    static const int blksize = 32;
    int blocks = DIV_ROUND_UP(surface_width(ssd->ds), blksize);
    int dirty_top[blocks];
    int y, yoff1, yoff2, x, xoff, blk, bw;
    int bpp = surface_bytes_per_pixel(ssd->ds);
    uint8_t *guest, *mirror;

    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
        return;
    };

    for (blk = 0; blk < blocks; blk++) {
        dirty_top[blk] = -1;
    }

    guest = surface_data(ssd->ds);
    mirror = (void *)pixman_image_get_data(ssd->mirror);
    for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
        yoff1 = y * surface_stride(ssd->ds);
        yoff2 = y * pixman_image_get_stride(ssd->mirror);
        for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
            xoff = x * bpp;
            blk = x / blksize;
            bw = MIN(blksize, ssd->dirty.right - x);
            if (memcmp(guest + yoff1 + xoff,
                       mirror + yoff2 + xoff,
                       bw * bpp) == 0) {
                if (dirty_top[blk] != -1) {
                    QXLRect update = {
                        .top    = dirty_top[blk],
                        .bottom = y,
                        .left   = x,
                        .right  = x + bw,
                    };
                    qemu_spice_create_one_update(ssd, &update);
                    dirty_top[blk] = -1;
                }
            } else {
                if (dirty_top[blk] == -1) {
                    dirty_top[blk] = y;
                }
            }
        }
    }

    for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
        blk = x / blksize;
        bw = MIN(blksize, ssd->dirty.right - x);
        if (dirty_top[blk] != -1) {
            QXLRect update = {
                .top    = dirty_top[blk],
                .bottom = ssd->dirty.bottom,
                .left   = x,
                .right  = x + bw,
            };
            qemu_spice_create_one_update(ssd, &update);
            dirty_top[blk] = -1;
        }
    }

    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
}

static SimpleSpiceCursor*
qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd,
                                QEMUCursor *c,
                                int on)
{
    size_t size = c ? c->width * c->height * 4 : 0;
    SimpleSpiceCursor *update;
    QXLCursorCmd *ccmd;
    QXLCursor *cursor;
    QXLCommand *cmd;

    update   = g_malloc0(sizeof(*update) + size);
    ccmd     = &update->cmd;
    cursor   = &update->cursor;
    cmd      = &update->ext.cmd;

    if (c) {
        ccmd->type = QXL_CURSOR_SET;
        ccmd->u.set.position.x = ssd->ptr_x + ssd->hot_x;
        ccmd->u.set.position.y = ssd->ptr_y + ssd->hot_y;
        ccmd->u.set.visible    = true;
        ccmd->u.set.shape      = (uintptr_t)cursor;
        cursor->header.unique     = ssd->unique++;
        cursor->header.type       = SPICE_CURSOR_TYPE_ALPHA;
        cursor->header.width      = c->width;
        cursor->header.height     = c->height;
        cursor->header.hot_spot_x = c->hot_x;
        cursor->header.hot_spot_y = c->hot_y;
        cursor->data_size         = size;
        cursor->chunk.data_size   = size;
        memcpy(cursor->chunk.data, c->data, size);
    } else if (!on) {
        ccmd->type = QXL_CURSOR_HIDE;
    } else {
        ccmd->type = QXL_CURSOR_MOVE;
        ccmd->u.position.x = ssd->ptr_x + ssd->hot_x;
        ccmd->u.position.y = ssd->ptr_y + ssd->hot_y;
    }
    ccmd->release_info.id = (uintptr_t)(&update->ext);

    cmd->type = QXL_CMD_CURSOR;
    cmd->data = (uintptr_t)ccmd;

    return update;
}

/*
 * Called from spice server thread context (via interface_release_resource)
 * We do *not* hold the global qemu mutex here, so extra care is needed
 * when calling qemu functions.  QEMU interfaces used:
 *    - g_free (underlying glibc free is re-entrant).
 */
void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
{
    g_free(update->bitmap);
    g_free(update);
}

void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
{
    QXLDevMemSlot memslot;

    memset(&memslot, 0, sizeof(memslot));
    memslot.slot_group_id = MEMSLOT_GROUP_HOST;
    memslot.virt_end = ~0;
    qemu_spice_add_memslot(ssd, &memslot, QXL_SYNC);
}

void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
{
    QXLDevSurfaceCreate surface;
    uint64_t surface_size;

    memset(&surface, 0, sizeof(surface));

    surface_size = (uint64_t) surface_width(ssd->ds) *
        surface_height(ssd->ds) * 4;
    assert(surface_size > 0);
    assert(surface_size < INT_MAX);
    if (ssd->bufsize < surface_size) {
        ssd->bufsize = surface_size;
        g_free(ssd->buf);
        ssd->buf = g_malloc(ssd->bufsize);
    }

    surface.format     = SPICE_SURFACE_FMT_32_xRGB;
    surface.width      = surface_width(ssd->ds);
    surface.height     = surface_height(ssd->ds);
    surface.stride     = -surface.width * 4;
    surface.mouse_mode = true;
    surface.flags      = 0;
    surface.type       = 0;
    surface.mem        = (uintptr_t)ssd->buf;
    surface.group_id   = MEMSLOT_GROUP_HOST;

    qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
}

void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
{
    qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
}

void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd)
{
    qemu_mutex_init(&ssd->lock);
    QTAILQ_INIT(&ssd->updates);
    ssd->mouse_x = -1;
    ssd->mouse_y = -1;
    if (ssd->num_surfaces == 0) {
        ssd->num_surfaces = 1024;
    }
}

/* display listener callbacks */

void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
                               int x, int y, int w, int h)
{
    QXLRect update_area;

    trace_qemu_spice_display_update(ssd->qxl.id, x, y, w, h);
    update_area.left = x,
    update_area.right = x + w;
    update_area.top = y;
    update_area.bottom = y + h;

    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
        ssd->notify++;
    }
    qemu_spice_rect_union(&ssd->dirty, &update_area);
}

void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
                               DisplaySurface *surface)
{
    SimpleSpiceUpdate *update;
    bool need_destroy;

    if (surface && ssd->surface &&
        surface_width(surface) == pixman_image_get_width(ssd->surface) &&
        surface_height(surface) == pixman_image_get_height(ssd->surface) &&
        surface_format(surface) == pixman_image_get_format(ssd->surface)) {
        /* no-resize fast path: just swap backing store */
        trace_qemu_spice_display_surface(ssd->qxl.id,
                                         surface_width(surface),
                                         surface_height(surface),
                                         true);
        qemu_mutex_lock(&ssd->lock);
        ssd->ds = surface;
        pixman_image_unref(ssd->surface);
        ssd->surface = pixman_image_ref(ssd->ds->image);
        qemu_mutex_unlock(&ssd->lock);
        qemu_spice_display_update(ssd, 0, 0,
                                  surface_width(surface),
                                  surface_height(surface));
        return;
    }

    /* full mode switch */
    trace_qemu_spice_display_surface(ssd->qxl.id,
                                     surface ? surface_width(surface)  : 0,
                                     surface ? surface_height(surface) : 0,
                                     false);

    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
    if (ssd->surface) {
        pixman_image_unref(ssd->surface);
        ssd->surface = NULL;
        pixman_image_unref(ssd->mirror);
        ssd->mirror = NULL;
    }

    qemu_mutex_lock(&ssd->lock);
    need_destroy = (ssd->ds != NULL);
    ssd->ds = surface;
    while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) {
        QTAILQ_REMOVE(&ssd->updates, update, next);
        qemu_spice_destroy_update(ssd, update);
    }
    qemu_mutex_unlock(&ssd->lock);
    if (need_destroy) {
        qemu_spice_destroy_host_primary(ssd);
    }
    if (ssd->ds) {
        ssd->surface = pixman_image_ref(ssd->ds->image);
        ssd->mirror  = qemu_pixman_mirror_create(ssd->ds->format,
                                                 ssd->ds->image);
        qemu_spice_create_host_primary(ssd);
    }

    memset(&ssd->dirty, 0, sizeof(ssd->dirty));
    ssd->notify++;

    qemu_mutex_lock(&ssd->lock);
    if (ssd->cursor) {
        g_free(ssd->ptr_define);
        ssd->ptr_define = qemu_spice_create_cursor_update(ssd, ssd->cursor, 0);
    }
    qemu_mutex_unlock(&ssd->lock);
}

void qemu_spice_cursor_refresh_bh(void *opaque)
{
    SimpleSpiceDisplay *ssd = opaque;

    qemu_mutex_lock(&ssd->lock);
    if (ssd->cursor) {
        QEMUCursor *c = ssd->cursor;
        assert(ssd->dcl.con);
        cursor_get(c);
        qemu_mutex_unlock(&ssd->lock);
        dpy_cursor_define(ssd->dcl.con, c);
        qemu_mutex_lock(&ssd->lock);
        cursor_put(c);
    }

    if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
        int x, y;
        assert(ssd->dcl.con);
        x = ssd->mouse_x;
        y = ssd->mouse_y;
        ssd->mouse_x = -1;
        ssd->mouse_y = -1;
        qemu_mutex_unlock(&ssd->lock);
        dpy_mouse_set(ssd->dcl.con, x, y, 1);
    } else {
        qemu_mutex_unlock(&ssd->lock);
    }
}

void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
{
    graphic_hw_update(ssd->dcl.con);

    qemu_mutex_lock(&ssd->lock);
    if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) {
        qemu_spice_create_update(ssd);
        ssd->notify++;
    }
    qemu_mutex_unlock(&ssd->lock);

    trace_qemu_spice_display_refresh(ssd->qxl.id, ssd->notify);
    if (ssd->notify) {
        ssd->notify = 0;
        qemu_spice_wakeup(ssd);
    }
}

/* spice display interface callbacks */

static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
{
    /* nothing to do */
}

static void interface_set_compression_level(QXLInstance *sin, int level)
{
    /* nothing to do */
}

#if SPICE_NEEDS_SET_MM_TIME
static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
{
    /* nothing to do */
}
#endif

static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
{
    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);

    info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
    info->memslot_id_bits  = MEMSLOT_SLOT_BITS;
    info->num_memslots = NUM_MEMSLOTS;
    info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
    info->internal_groupslot_id = 0;
    info->qxl_ram_size = 16 * 1024 * 1024;
    info->n_surfaces = ssd->num_surfaces;
}

static int interface_get_command(QXLInstance *sin, QXLCommandExt *ext)
{
    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
    SimpleSpiceUpdate *update;
    int ret = false;

    qemu_mutex_lock(&ssd->lock);
    update = QTAILQ_FIRST(&ssd->updates);
    if (update != NULL) {
        QTAILQ_REMOVE(&ssd->updates, update, next);
        *ext = update->ext;
        ret = true;
    }
    qemu_mutex_unlock(&ssd->lock);

    return ret;
}

static int interface_req_cmd_notification(QXLInstance *sin)
{
    return 1;
}

static void interface_release_resource(QXLInstance *sin,
                                       QXLReleaseInfoExt rext)
{
    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
    SimpleSpiceUpdate *update;
    SimpleSpiceCursor *cursor;
    QXLCommandExt *ext;

    ext = (void *)(intptr_t)(rext.info->id);
    switch (ext->cmd.type) {
    case QXL_CMD_DRAW:
        update = container_of(ext, SimpleSpiceUpdate, ext);
        qemu_spice_destroy_update(ssd, update);
        break;
    case QXL_CMD_CURSOR:
        cursor = container_of(ext, SimpleSpiceCursor, ext);
        g_free(cursor);
        break;
    default:
        g_assert_not_reached();
    }
}

static int interface_get_cursor_command(QXLInstance *sin, QXLCommandExt *ext)
{
    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
    int ret;

    qemu_mutex_lock(&ssd->lock);
    if (ssd->ptr_define) {
        *ext = ssd->ptr_define->ext;
        ssd->ptr_define = NULL;
        ret = true;
    } else if (ssd->ptr_move) {
        *ext = ssd->ptr_move->ext;
        ssd->ptr_move = NULL;
        ret = true;
    } else {
        ret = false;
    }
    qemu_mutex_unlock(&ssd->lock);
    return ret;
}

static int interface_req_cursor_notification(QXLInstance *sin)
{
    return 1;
}

static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
{
    fprintf(stderr, "%s: abort()\n", __func__);
    abort();
}

static int interface_flush_resources(QXLInstance *sin)
{
    fprintf(stderr, "%s: abort()\n", __func__);
    abort();
    return 0;
}

static void interface_update_area_complete(QXLInstance *sin,
        uint32_t surface_id,
        QXLRect *dirty, uint32_t num_updated_rects)
{
    /* should never be called, used in qxl native mode only */
    fprintf(stderr, "%s: abort()\n", __func__);
    abort();
}

/* called from spice server thread context only */
static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
{
    QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;

    switch (cookie->type) {
#ifdef HAVE_SPICE_GL
    case QXL_COOKIE_TYPE_GL_DRAW_DONE:
    {
        SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
        qemu_bh_schedule(ssd->gl_unblock_bh);
        break;
    }
    case QXL_COOKIE_TYPE_IO:
        if (cookie->io == QXL_IO_MONITORS_CONFIG_ASYNC) {
            g_free(cookie->u.data);
        }
        break;
#endif
    default:
        /* should never be called, used in qxl native mode only */
        fprintf(stderr, "%s: abort()\n", __func__);
        abort();
    }
    g_free(cookie);
}

static void interface_set_client_capabilities(QXLInstance *sin,
                                              uint8_t client_present,
                                              uint8_t caps[58])
{
    /* nothing to do */
}

static int interface_client_monitors_config(QXLInstance *sin,
                                            VDAgentMonitorsConfig *mc)
{
    SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
    QemuUIInfo info;
    int head;

    if (!dpy_ui_info_supported(ssd->dcl.con)) {
        return 0; /* == not supported by guest */
    }

    if (!mc) {
        return 1;
    }

    memset(&info, 0, sizeof(info));

    if (mc->num_of_monitors == 1) {
        /*
         * New spice-server version which filters the list of monitors
         * to only include those that belong to our display channel.
         *
         * single-head configuration (where filtering doesn't matter)
         * takes this code path too.
         */
        info.width  = mc->monitors[0].width;
        info.height = mc->monitors[0].height;
    } else {
        /*
         * Old spice-server which gives us all monitors, so we have to
         * figure ourself which entry we need.  Array index is the
         * channel_id, which is the qemu console index, see
         * qemu_spice_add_display_interface().
         */
        head = qemu_console_get_index(ssd->dcl.con);
        if (mc->num_of_monitors > head) {
            info.width  = mc->monitors[head].width;
            info.height = mc->monitors[head].height;
        }
    }

    trace_qemu_spice_ui_info(ssd->qxl.id, info.width, info.height);
    dpy_set_ui_info(ssd->dcl.con, &info);
    return 1;
}

static const QXLInterface dpy_interface = {
    .base.type               = SPICE_INTERFACE_QXL,
    .base.description        = "qemu simple display",
    .base.major_version      = SPICE_INTERFACE_QXL_MAJOR,
    .base.minor_version      = SPICE_INTERFACE_QXL_MINOR,

    .attache_worker          = interface_attach_worker,
    .set_compression_level   = interface_set_compression_level,
#if SPICE_NEEDS_SET_MM_TIME
    .set_mm_time             = interface_set_mm_time,
#endif
    .get_init_info           = interface_get_init_info,

    /* the callbacks below are called from spice server thread context */
    .get_command             = interface_get_command,
    .req_cmd_notification    = interface_req_cmd_notification,
    .release_resource        = interface_release_resource,
    .get_cursor_command      = interface_get_cursor_command,
    .req_cursor_notification = interface_req_cursor_notification,
    .notify_update           = interface_notify_update,
    .flush_resources         = interface_flush_resources,
    .async_complete          = interface_async_complete,
    .update_area_complete    = interface_update_area_complete,
    .set_client_capabilities = interface_set_client_capabilities,
    .client_monitors_config  = interface_client_monitors_config,
};

static void display_update(DisplayChangeListener *dcl,
                           int x, int y, int w, int h)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    qemu_spice_display_update(ssd, x, y, w, h);
}

static void display_switch(DisplayChangeListener *dcl,
                           DisplaySurface *surface)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    qemu_spice_display_switch(ssd, surface);
}

static void display_refresh(DisplayChangeListener *dcl)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    qemu_spice_display_refresh(ssd);
}

static void display_mouse_set(DisplayChangeListener *dcl,
                              int x, int y, int on)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    qemu_mutex_lock(&ssd->lock);
    ssd->ptr_x = x;
    ssd->ptr_y = y;
    g_free(ssd->ptr_move);
    ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL, on);
    qemu_mutex_unlock(&ssd->lock);
    qemu_spice_wakeup(ssd);
}

static void display_mouse_define(DisplayChangeListener *dcl,
                                 QEMUCursor *c)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    qemu_mutex_lock(&ssd->lock);
    cursor_get(c);
    cursor_put(ssd->cursor);
    ssd->cursor = c;
    ssd->hot_x = c->hot_x;
    ssd->hot_y = c->hot_y;
    g_free(ssd->ptr_move);
    ssd->ptr_move = NULL;
    g_free(ssd->ptr_define);
    ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0);
    qemu_mutex_unlock(&ssd->lock);
    qemu_spice_wakeup(ssd);
}

static const DisplayChangeListenerOps display_listener_ops = {
    .dpy_name             = "spice",
    .dpy_gfx_update       = display_update,
    .dpy_gfx_switch       = display_switch,
    .dpy_gfx_check_format = qemu_pixman_check_format,
    .dpy_refresh          = display_refresh,
    .dpy_mouse_set        = display_mouse_set,
    .dpy_cursor_define    = display_mouse_define,
};

#ifdef HAVE_SPICE_GL

static void qemu_spice_gl_monitor_config(SimpleSpiceDisplay *ssd,
                                         int x, int y, int w, int h)
{
    QXLMonitorsConfig *config;
    QXLCookie *cookie;

    config = g_malloc0(sizeof(QXLMonitorsConfig) + sizeof(QXLHead));
    config->count = 1;
    config->max_allowed = 1;
    config->heads[0].x = x;
    config->heads[0].y = y;
    config->heads[0].width = w;
    config->heads[0].height = h;
    cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                            QXL_IO_MONITORS_CONFIG_ASYNC);
    cookie->u.data = config;

    spice_qxl_monitors_config_async(&ssd->qxl,
                                    (uintptr_t)config,
                                    MEMSLOT_GROUP_HOST,
                                    (uintptr_t)cookie);
}

static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block)
{
    uint64_t timeout;

    if (block) {
        timeout = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
        timeout += 1000; /* one sec */
        timer_mod(ssd->gl_unblock_timer, timeout);
    } else {
        timer_del(ssd->gl_unblock_timer);
    }
    graphic_hw_gl_block(ssd->dcl.con, block);
}

static void qemu_spice_gl_unblock_bh(void *opaque)
{
    SimpleSpiceDisplay *ssd = opaque;

    qemu_spice_gl_block(ssd, false);
}

static void qemu_spice_gl_block_timer(void *opaque)
{
    warn_report("spice: no gl-draw-done within one second");
}

static void spice_gl_refresh(DisplayChangeListener *dcl)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    uint64_t cookie;

    if (!ssd->ds || qemu_console_is_gl_blocked(ssd->dcl.con)) {
        return;
    }

    graphic_hw_update(dcl->con);
    if (ssd->gl_updates && ssd->have_surface) {
        qemu_spice_gl_block(ssd, true);
        cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
        spice_qxl_gl_draw_async(&ssd->qxl, 0, 0,
                                surface_width(ssd->ds),
                                surface_height(ssd->ds),
                                cookie);
        ssd->gl_updates = 0;
    }
}

static void spice_gl_update(DisplayChangeListener *dcl,
                            int x, int y, int w, int h)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    surface_gl_update_texture(ssd->gls, ssd->ds, x, y, w, h);
    ssd->gl_updates++;
}

static void spice_gl_switch(DisplayChangeListener *dcl,
                            struct DisplaySurface *new_surface)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    EGLint stride, fourcc;
    int fd;

    if (ssd->ds) {
        surface_gl_destroy_texture(ssd->gls, ssd->ds);
    }
    ssd->ds = new_surface;
    if (ssd->ds) {
        surface_gl_create_texture(ssd->gls, ssd->ds);
        fd = egl_get_fd_for_texture(ssd->ds->texture,
                                    &stride, &fourcc,
                                    NULL);
        if (fd < 0) {
            surface_gl_destroy_texture(ssd->gls, ssd->ds);
            return;
        }

        trace_qemu_spice_gl_surface(ssd->qxl.id,
                                    surface_width(ssd->ds),
                                    surface_height(ssd->ds),
                                    fourcc);

        /* note: spice server will close the fd */
        spice_qxl_gl_scanout(&ssd->qxl, fd,
                             surface_width(ssd->ds),
                             surface_height(ssd->ds),
                             stride, fourcc, false);
        ssd->have_surface = true;
        ssd->have_scanout = false;

        qemu_spice_gl_monitor_config(ssd, 0, 0,
                                     surface_width(ssd->ds),
                                     surface_height(ssd->ds));
    }
}

static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
                                                  QEMUGLParams *params)
{
    eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                   qemu_egl_rn_ctx);
    return qemu_egl_create_context(dcl, params);
}

static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    trace_qemu_spice_gl_scanout_disable(ssd->qxl.id);
    spice_qxl_gl_scanout(&ssd->qxl, -1, 0, 0, 0, 0, false);
    qemu_spice_gl_monitor_config(ssd, 0, 0, 0, 0);
    ssd->have_surface = false;
    ssd->have_scanout = false;
}

static void qemu_spice_gl_scanout_texture(DisplayChangeListener *dcl,
                                          uint32_t tex_id,
                                          bool y_0_top,
                                          uint32_t backing_width,
                                          uint32_t backing_height,
                                          uint32_t x, uint32_t y,
                                          uint32_t w, uint32_t h)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    EGLint stride = 0, fourcc = 0;
    int fd = -1;

    assert(tex_id);
    fd = egl_get_fd_for_texture(tex_id, &stride, &fourcc, NULL);
    if (fd < 0) {
        fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
        return;
    }
    trace_qemu_spice_gl_scanout_texture(ssd->qxl.id, w, h, fourcc);

    /* note: spice server will close the fd */
    spice_qxl_gl_scanout(&ssd->qxl, fd, backing_width, backing_height,
                         stride, fourcc, y_0_top);
    qemu_spice_gl_monitor_config(ssd, x, y, w, h);
    ssd->have_surface = false;
    ssd->have_scanout = true;
}

static void qemu_spice_gl_scanout_dmabuf(DisplayChangeListener *dcl,
                                         QemuDmaBuf *dmabuf)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    ssd->guest_dmabuf = dmabuf;
    ssd->guest_dmabuf_refresh = true;

    ssd->have_surface = false;
    ssd->have_scanout = true;
}

static void qemu_spice_gl_cursor_dmabuf(DisplayChangeListener *dcl,
                                        QemuDmaBuf *dmabuf, bool have_hot,
                                        uint32_t hot_x, uint32_t hot_y)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    ssd->have_hot = have_hot;
    ssd->hot_x = hot_x;
    ssd->hot_y = hot_y;

    trace_qemu_spice_gl_cursor(ssd->qxl.id, dmabuf != NULL, have_hot);
    if (dmabuf) {
        egl_dmabuf_import_texture(dmabuf);
        if (!dmabuf->texture) {
            return;
        }
        egl_fb_setup_for_tex(&ssd->cursor_fb, dmabuf->width, dmabuf->height,
                             dmabuf->texture, false);
    } else {
        egl_fb_destroy(&ssd->cursor_fb);
    }
}

static void qemu_spice_gl_cursor_position(DisplayChangeListener *dcl,
                                          uint32_t pos_x, uint32_t pos_y)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    qemu_mutex_lock(&ssd->lock);
    ssd->ptr_x = pos_x;
    ssd->ptr_y = pos_y;
    qemu_mutex_unlock(&ssd->lock);
}

static void qemu_spice_gl_release_dmabuf(DisplayChangeListener *dcl,
                                         QemuDmaBuf *dmabuf)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    if (ssd->guest_dmabuf == dmabuf) {
        ssd->guest_dmabuf = NULL;
        ssd->guest_dmabuf_refresh = false;
    }
    egl_dmabuf_release_texture(dmabuf);
}

static void qemu_spice_gl_update(DisplayChangeListener *dcl,
                                 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
    EGLint stride = 0, fourcc = 0;
    bool render_cursor = false;
    bool y_0_top = false; /* FIXME */
    uint64_t cookie;
    int fd;

    if (!ssd->have_scanout) {
        return;
    }

    if (ssd->cursor_fb.texture) {
        render_cursor = true;
    }
    if (ssd->render_cursor != render_cursor) {
        ssd->render_cursor = render_cursor;
        ssd->guest_dmabuf_refresh = true;
        egl_fb_destroy(&ssd->blit_fb);
    }

    if (ssd->guest_dmabuf_refresh) {
        QemuDmaBuf *dmabuf = ssd->guest_dmabuf;
        if (render_cursor) {
            egl_dmabuf_import_texture(dmabuf);
            if (!dmabuf->texture) {
                return;
            }

            /* source framebuffer */
            egl_fb_setup_for_tex(&ssd->guest_fb,
                                 dmabuf->width, dmabuf->height,
                                 dmabuf->texture, false);

            /* dest framebuffer */
            if (ssd->blit_fb.width  != dmabuf->width ||
                ssd->blit_fb.height != dmabuf->height) {
                trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, dmabuf->width,
                                                  dmabuf->height);
                egl_fb_destroy(&ssd->blit_fb);
                egl_fb_setup_new_tex(&ssd->blit_fb,
                                     dmabuf->width, dmabuf->height);
                fd = egl_get_fd_for_texture(ssd->blit_fb.texture,
                                            &stride, &fourcc, NULL);
                spice_qxl_gl_scanout(&ssd->qxl, fd,
                                     dmabuf->width, dmabuf->height,
                                     stride, fourcc, false);
            }
        } else {
            trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id,
                                               dmabuf->width, dmabuf->height);
            /* note: spice server will close the fd, so hand over a dup */
            spice_qxl_gl_scanout(&ssd->qxl, dup(dmabuf->fd),
                                 dmabuf->width, dmabuf->height,
                                 dmabuf->stride, dmabuf->fourcc,
                                 dmabuf->y0_top);
        }
        qemu_spice_gl_monitor_config(ssd, 0, 0, dmabuf->width, dmabuf->height);
        ssd->guest_dmabuf_refresh = false;
    }

    if (render_cursor) {
        int x, y;
        qemu_mutex_lock(&ssd->lock);
        x = ssd->ptr_x;
        y = ssd->ptr_y;
        qemu_mutex_unlock(&ssd->lock);
        egl_texture_blit(ssd->gls, &ssd->blit_fb, &ssd->guest_fb,
                         !y_0_top);
        egl_texture_blend(ssd->gls, &ssd->blit_fb, &ssd->cursor_fb,
                          !y_0_top, x, y, 1.0, 1.0);
        glFlush();
    }

    trace_qemu_spice_gl_update(ssd->qxl.id, w, h, x, y);
    qemu_spice_gl_block(ssd, true);
    cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
    spice_qxl_gl_draw_async(&ssd->qxl, x, y, w, h, cookie);
}

static const DisplayChangeListenerOps display_listener_gl_ops = {
    .dpy_name                = "spice-egl",
    .dpy_gfx_update          = spice_gl_update,
    .dpy_gfx_switch          = spice_gl_switch,
    .dpy_gfx_check_format    = console_gl_check_format,
    .dpy_refresh             = spice_gl_refresh,
    .dpy_mouse_set           = display_mouse_set,
    .dpy_cursor_define       = display_mouse_define,

    .dpy_gl_ctx_create       = qemu_spice_gl_create_context,
    .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
    .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
    .dpy_gl_ctx_get_current  = qemu_egl_get_current_context,

    .dpy_gl_scanout_disable  = qemu_spice_gl_scanout_disable,
    .dpy_gl_scanout_texture  = qemu_spice_gl_scanout_texture,
    .dpy_gl_scanout_dmabuf   = qemu_spice_gl_scanout_dmabuf,
    .dpy_gl_cursor_dmabuf    = qemu_spice_gl_cursor_dmabuf,
    .dpy_gl_cursor_position  = qemu_spice_gl_cursor_position,
    .dpy_gl_release_dmabuf   = qemu_spice_gl_release_dmabuf,
    .dpy_gl_update           = qemu_spice_gl_update,
};

#endif /* HAVE_SPICE_GL */

static void qemu_spice_display_init_one(QemuConsole *con)
{
    SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);

    qemu_spice_display_init_common(ssd);

    ssd->dcl.ops = &display_listener_ops;
#ifdef HAVE_SPICE_GL
    if (spice_opengl) {
        ssd->dcl.ops = &display_listener_gl_ops;
        ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
        ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
                                             qemu_spice_gl_block_timer, ssd);
        ssd->gls = qemu_gl_init_shader();
        ssd->have_surface = false;
        ssd->have_scanout = false;
    }
#endif
    ssd->dcl.con = con;

    ssd->qxl.base.sif = &dpy_interface.base;
    qemu_spice_add_display_interface(&ssd->qxl, con);

#if SPICE_SERVER_VERSION >= 0x000e02 /* release 0.14.2 */
    char device_address[256] = "";
    if (qemu_spice_fill_device_address(con, device_address, 256)) {
        spice_qxl_set_device_info(&ssd->qxl,
                                  device_address,
                                  qemu_console_get_head(con),
                                  1);
    }
#endif

    qemu_spice_create_host_memslot(ssd);

    register_displaychangelistener(&ssd->dcl);
}

void qemu_spice_display_init(void)
{
    QemuOptsList *olist = qemu_find_opts("spice");
    QemuOpts *opts = QTAILQ_FIRST(&olist->head);
    QemuConsole *spice_con, *con;
    const char *str;
    int i;

    str = qemu_opt_get(opts, "display");
    if (str) {
        int head = qemu_opt_get_number(opts, "head", 0);
        Error *err = NULL;

        spice_con = qemu_console_lookup_by_device_name(str, head, &err);
        if (err) {
            error_report("Failed to lookup display/head");
            exit(1);
        }
    } else {
        spice_con = NULL;
    }

    for (i = 0;; i++) {
        con = qemu_console_lookup_by_index(i);
        if (!con || !qemu_console_is_graphic(con)) {
            break;
        }
        if (qemu_spice_have_display_interface(con)) {
            continue;
        }
        if (spice_con != NULL && spice_con != con) {
            continue;
        }
        qemu_spice_display_init_one(con);
    }
}
