#include "qemu/osdep.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "qemu/buffer.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qemu/units.h"
#include "hw/qdev-core.h"
#include "migration/blocker.h"
#include "ui/clipboard.h"
#include "ui/console.h"
#include "ui/input.h"
#include "trace.h"

#include "qapi/qapi-types-char.h"
#include "qapi/qapi-types-ui.h"

#include "spice/vd_agent.h"

#define CHECK_SPICE_PROTOCOL_VERSION(major, minor, micro) \
    (CONFIG_SPICE_PROTOCOL_MAJOR > (major) ||             \
     (CONFIG_SPICE_PROTOCOL_MAJOR == (major) &&           \
      CONFIG_SPICE_PROTOCOL_MINOR > (minor)) ||           \
     (CONFIG_SPICE_PROTOCOL_MAJOR == (major) &&           \
      CONFIG_SPICE_PROTOCOL_MINOR == (minor) &&           \
      CONFIG_SPICE_PROTOCOL_MICRO >= (micro)))

#define VDAGENT_BUFFER_LIMIT (1 * MiB)
#define VDAGENT_MOUSE_DEFAULT true
#define VDAGENT_CLIPBOARD_DEFAULT false

struct VDAgentChardev {
    Chardev parent;

    /* TODO: migration isn't yet supported */
    Error *migration_blocker;

    /* config */
    bool mouse;
    bool clipboard;

    /* guest vdagent */
    uint32_t caps;
    VDIChunkHeader chunk;
    uint32_t chunksize;
    uint8_t *msgbuf;
    uint32_t msgsize;
    uint8_t *xbuf;
    uint32_t xoff, xsize;
    Buffer outbuf;

    /* mouse */
    DeviceState mouse_dev;
    uint32_t mouse_x;
    uint32_t mouse_y;
    uint32_t mouse_btn;
    uint32_t mouse_display;
    QemuInputHandlerState *mouse_hs;

    /* clipboard */
    QemuClipboardPeer cbpeer;
    uint32_t last_serial[QEMU_CLIPBOARD_SELECTION__COUNT];
    uint32_t cbpending[QEMU_CLIPBOARD_SELECTION__COUNT];
};
typedef struct VDAgentChardev VDAgentChardev;

#define TYPE_CHARDEV_QEMU_VDAGENT "chardev-qemu-vdagent"

DECLARE_INSTANCE_CHECKER(VDAgentChardev, QEMU_VDAGENT_CHARDEV,
                         TYPE_CHARDEV_QEMU_VDAGENT);

/* ------------------------------------------------------------------ */
/* names, for debug logging                                           */

static const char *cap_name[] = {
    [VD_AGENT_CAP_MOUSE_STATE]                    = "mouse-state",
    [VD_AGENT_CAP_MONITORS_CONFIG]                = "monitors-config",
    [VD_AGENT_CAP_REPLY]                          = "reply",
    [VD_AGENT_CAP_CLIPBOARD]                      = "clipboard",
    [VD_AGENT_CAP_DISPLAY_CONFIG]                 = "display-config",
    [VD_AGENT_CAP_CLIPBOARD_BY_DEMAND]            = "clipboard-by-demand",
    [VD_AGENT_CAP_CLIPBOARD_SELECTION]            = "clipboard-selection",
    [VD_AGENT_CAP_SPARSE_MONITORS_CONFIG]         = "sparse-monitors-config",
    [VD_AGENT_CAP_GUEST_LINEEND_LF]               = "guest-lineend-lf",
    [VD_AGENT_CAP_GUEST_LINEEND_CRLF]             = "guest-lineend-crlf",
    [VD_AGENT_CAP_MAX_CLIPBOARD]                  = "max-clipboard",
    [VD_AGENT_CAP_AUDIO_VOLUME_SYNC]              = "audio-volume-sync",
    [VD_AGENT_CAP_MONITORS_CONFIG_POSITION]       = "monitors-config-position",
    [VD_AGENT_CAP_FILE_XFER_DISABLED]             = "file-xfer-disabled",
    [VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS]      = "file-xfer-detailed-errors",
    [VD_AGENT_CAP_GRAPHICS_DEVICE_INFO]           = "graphics-device-info",
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
    [VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB] = "clipboard-no-release-on-regrab",
    [VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL]          = "clipboard-grab-serial",
#endif
};

static const char *msg_name[] = {
    [VD_AGENT_MOUSE_STATE]           = "mouse-state",
    [VD_AGENT_MONITORS_CONFIG]       = "monitors-config",
    [VD_AGENT_REPLY]                 = "reply",
    [VD_AGENT_CLIPBOARD]             = "clipboard",
    [VD_AGENT_DISPLAY_CONFIG]        = "display-config",
    [VD_AGENT_ANNOUNCE_CAPABILITIES] = "announce-capabilities",
    [VD_AGENT_CLIPBOARD_GRAB]        = "clipboard-grab",
    [VD_AGENT_CLIPBOARD_REQUEST]     = "clipboard-request",
    [VD_AGENT_CLIPBOARD_RELEASE]     = "clipboard-release",
    [VD_AGENT_FILE_XFER_START]       = "file-xfer-start",
    [VD_AGENT_FILE_XFER_STATUS]      = "file-xfer-status",
    [VD_AGENT_FILE_XFER_DATA]        = "file-xfer-data",
    [VD_AGENT_CLIENT_DISCONNECTED]   = "client-disconnected",
    [VD_AGENT_MAX_CLIPBOARD]         = "max-clipboard",
    [VD_AGENT_AUDIO_VOLUME_SYNC]     = "audio-volume-sync",
    [VD_AGENT_GRAPHICS_DEVICE_INFO]  = "graphics-device-info",
};

static const char *sel_name[] = {
    [VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD] = "clipboard",
    [VD_AGENT_CLIPBOARD_SELECTION_PRIMARY]   = "primary",
    [VD_AGENT_CLIPBOARD_SELECTION_SECONDARY] = "secondary",
};

static const char *type_name[] = {
    [VD_AGENT_CLIPBOARD_NONE]       = "none",
    [VD_AGENT_CLIPBOARD_UTF8_TEXT]  = "text",
    [VD_AGENT_CLIPBOARD_IMAGE_PNG]  = "png",
    [VD_AGENT_CLIPBOARD_IMAGE_BMP]  = "bmp",
    [VD_AGENT_CLIPBOARD_IMAGE_TIFF] = "tiff",
    [VD_AGENT_CLIPBOARD_IMAGE_JPG]  = "jpg",
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 3)
    [VD_AGENT_CLIPBOARD_FILE_LIST]  = "files",
#endif
};

#define GET_NAME(_m, _v) \
    (((_v) < ARRAY_SIZE(_m) && (_m[_v])) ? (_m[_v]) : "???")

/* ------------------------------------------------------------------ */
/* send messages                                                      */

static void vdagent_send_buf(VDAgentChardev *vd)
{
    uint32_t len;

    while (!buffer_empty(&vd->outbuf)) {
        len = qemu_chr_be_can_write(CHARDEV(vd));
        if (len == 0) {
            return;
        }
        if (len > vd->outbuf.offset) {
            len = vd->outbuf.offset;
        }
        qemu_chr_be_write(CHARDEV(vd), vd->outbuf.buffer, len);
        buffer_advance(&vd->outbuf, len);
    }
}

static void vdagent_send_msg(VDAgentChardev *vd, VDAgentMessage *msg)
{
    uint8_t *msgbuf = (void *)msg;
    uint32_t msgsize = sizeof(VDAgentMessage) + msg->size;
    uint32_t msgoff = 0;
    VDIChunkHeader chunk;

    trace_vdagent_send(GET_NAME(msg_name, msg->type));

    msg->protocol = VD_AGENT_PROTOCOL;

    if (vd->outbuf.offset + msgsize > VDAGENT_BUFFER_LIMIT) {
        error_report("buffer full, dropping message");
        return;
    }

    while (msgoff < msgsize) {
        chunk.port = VDP_CLIENT_PORT;
        chunk.size = msgsize - msgoff;
        if (chunk.size > 1024) {
            chunk.size = 1024;
        }
        buffer_reserve(&vd->outbuf, sizeof(chunk) + chunk.size);
        buffer_append(&vd->outbuf, &chunk, sizeof(chunk));
        buffer_append(&vd->outbuf, msgbuf + msgoff, chunk.size);
        msgoff += chunk.size;
    }
    vdagent_send_buf(vd);
}

static void vdagent_send_caps(VDAgentChardev *vd)
{
    g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +
                                               sizeof(VDAgentAnnounceCapabilities) +
                                               sizeof(uint32_t));
    VDAgentAnnounceCapabilities *caps = (void *)msg->data;

    msg->type = VD_AGENT_ANNOUNCE_CAPABILITIES;
    msg->size = sizeof(VDAgentAnnounceCapabilities) + sizeof(uint32_t);
    if (vd->mouse) {
        caps->caps[0] |= (1 << VD_AGENT_CAP_MOUSE_STATE);
    }
    if (vd->clipboard) {
        caps->caps[0] |= (1 << VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
        caps->caps[0] |= (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION);
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
        caps->caps[0] |= (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL);
#endif
    }

    vdagent_send_msg(vd, msg);
}

/* ------------------------------------------------------------------ */
/* mouse events                                                       */

static bool have_mouse(VDAgentChardev *vd)
{
    return vd->mouse &&
        (vd->caps & (1 << VD_AGENT_CAP_MOUSE_STATE));
}

static void vdagent_send_mouse(VDAgentChardev *vd)
{
    g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +
                                               sizeof(VDAgentMouseState));
    VDAgentMouseState *mouse = (void *)msg->data;

    msg->type = VD_AGENT_MOUSE_STATE;
    msg->size = sizeof(VDAgentMouseState);

    mouse->x          = vd->mouse_x;
    mouse->y          = vd->mouse_y;
    mouse->buttons    = vd->mouse_btn;
    mouse->display_id = vd->mouse_display;

    vdagent_send_msg(vd, msg);
}

static void vdagent_pointer_event(DeviceState *dev, QemuConsole *src,
                                  InputEvent *evt)
{
    static const int bmap[INPUT_BUTTON__MAX] = {
        [INPUT_BUTTON_LEFT]        = VD_AGENT_LBUTTON_MASK,
        [INPUT_BUTTON_RIGHT]       = VD_AGENT_RBUTTON_MASK,
        [INPUT_BUTTON_MIDDLE]      = VD_AGENT_MBUTTON_MASK,
        [INPUT_BUTTON_WHEEL_UP]    = VD_AGENT_UBUTTON_MASK,
        [INPUT_BUTTON_WHEEL_DOWN]  = VD_AGENT_DBUTTON_MASK,
#ifdef VD_AGENT_EBUTTON_MASK
        [INPUT_BUTTON_SIDE]        = VD_AGENT_SBUTTON_MASK,
        [INPUT_BUTTON_EXTRA]       = VD_AGENT_EBUTTON_MASK,
#endif
    };

    VDAgentChardev *vd = container_of(dev, struct VDAgentChardev, mouse_dev);
    InputMoveEvent *move;
    InputBtnEvent *btn;
    uint32_t xres, yres;

    switch (evt->type) {
    case INPUT_EVENT_KIND_ABS:
        move = evt->u.abs.data;
        xres = qemu_console_get_width(src, 1024);
        yres = qemu_console_get_height(src, 768);
        if (move->axis == INPUT_AXIS_X) {
            vd->mouse_x = qemu_input_scale_axis(move->value,
                                                INPUT_EVENT_ABS_MIN,
                                                INPUT_EVENT_ABS_MAX,
                                                0, xres);
        } else if (move->axis == INPUT_AXIS_Y) {
            vd->mouse_y = qemu_input_scale_axis(move->value,
                                                INPUT_EVENT_ABS_MIN,
                                                INPUT_EVENT_ABS_MAX,
                                                0, yres);
        }
        vd->mouse_display = qemu_console_get_index(src);
        break;

    case INPUT_EVENT_KIND_BTN:
        btn = evt->u.btn.data;
        if (btn->down) {
            vd->mouse_btn |= bmap[btn->button];
        } else {
            vd->mouse_btn &= ~bmap[btn->button];
        }
        break;

    default:
        /* keep gcc happy */
        break;
    }
}

static void vdagent_pointer_sync(DeviceState *dev)
{
    VDAgentChardev *vd = container_of(dev, struct VDAgentChardev, mouse_dev);

    if (vd->caps & (1 << VD_AGENT_CAP_MOUSE_STATE)) {
        vdagent_send_mouse(vd);
    }
}

static const QemuInputHandler vdagent_mouse_handler = {
    .name  = "vdagent mouse",
    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
    .event = vdagent_pointer_event,
    .sync  = vdagent_pointer_sync,
};

/* ------------------------------------------------------------------ */
/* clipboard                                                          */

static bool have_clipboard(VDAgentChardev *vd)
{
    return vd->clipboard &&
        (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
}

static bool have_selection(VDAgentChardev *vd)
{
    return vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION);
}

static uint32_t type_qemu_to_vdagent(enum QemuClipboardType type)
{
    switch (type) {
    case QEMU_CLIPBOARD_TYPE_TEXT:
        return VD_AGENT_CLIPBOARD_UTF8_TEXT;
    default:
        return VD_AGENT_CLIPBOARD_NONE;
    }
}

static void vdagent_send_clipboard_grab(VDAgentChardev *vd,
                                        QemuClipboardInfo *info)
{
    g_autofree VDAgentMessage *msg =
        g_malloc0(sizeof(VDAgentMessage) +
                  sizeof(uint32_t) * (QEMU_CLIPBOARD_TYPE__COUNT + 1) +
                  sizeof(uint32_t));
    uint8_t *s = msg->data;
    uint32_t *data = (uint32_t *)msg->data;
    uint32_t q, type;

    if (have_selection(vd)) {
        *s = info->selection;
        data++;
        msg->size += sizeof(uint32_t);
    } else if (info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
        return;
    }

#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
    if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
        if (!info->has_serial) {
            /* client should win */
            info->serial = vd->last_serial[info->selection]++;
            info->has_serial = true;
        }
        *data = info->serial;
        data++;
        msg->size += sizeof(uint32_t);
    }
#endif

    for (q = 0; q < QEMU_CLIPBOARD_TYPE__COUNT; q++) {
        type = type_qemu_to_vdagent(q);
        if (type != VD_AGENT_CLIPBOARD_NONE && info->types[q].available) {
            *data = type;
            data++;
            msg->size += sizeof(uint32_t);
        }
    }

    msg->type = VD_AGENT_CLIPBOARD_GRAB;
    vdagent_send_msg(vd, msg);
}

static void vdagent_send_clipboard_release(VDAgentChardev *vd,
                                           QemuClipboardInfo *info)
{
    g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +
                                               sizeof(uint32_t));

    if (have_selection(vd)) {
        uint8_t *s = msg->data;
        *s = info->selection;
        msg->size += sizeof(uint32_t);
    } else if (info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
        return;
    }

    msg->type = VD_AGENT_CLIPBOARD_RELEASE;
    vdagent_send_msg(vd, msg);
}

static void vdagent_send_clipboard_data(VDAgentChardev *vd,
                                        QemuClipboardInfo *info,
                                        QemuClipboardType type)
{
    g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +
                                               sizeof(uint32_t) * 2 +
                                               info->types[type].size);

    uint8_t *s = msg->data;
    uint32_t *data = (uint32_t *)msg->data;

    if (have_selection(vd)) {
        *s = info->selection;
        data++;
        msg->size += sizeof(uint32_t);
    } else if (info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
        return;
    }

    *data = type_qemu_to_vdagent(type);
    data++;
    msg->size += sizeof(uint32_t);

    memcpy(data, info->types[type].data, info->types[type].size);
    msg->size += info->types[type].size;

    msg->type = VD_AGENT_CLIPBOARD;
    vdagent_send_msg(vd, msg);
}

static void vdagent_send_empty_clipboard_data(VDAgentChardev *vd,
                                              QemuClipboardSelection selection,
                                              QemuClipboardType type)
{
    g_autoptr(QemuClipboardInfo) info = qemu_clipboard_info_new(&vd->cbpeer, selection);

    trace_vdagent_send_empty_clipboard();
    vdagent_send_clipboard_data(vd, info, type);
}

static void vdagent_clipboard_update_info(VDAgentChardev *vd,
                                          QemuClipboardInfo *info)
{
    QemuClipboardSelection s = info->selection;
    QemuClipboardType type;
    bool self_update = info->owner == &vd->cbpeer;

    if (info != qemu_clipboard_info(s)) {
        vd->cbpending[s] = 0;
        if (!self_update) {
            if (info->owner) {
                vdagent_send_clipboard_grab(vd, info);
            } else {
                vdagent_send_clipboard_release(vd, info);
            }
        }
        return;
    }

    if (self_update) {
        return;
    }

    for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
        if (vd->cbpending[s] & (1 << type)) {
            vd->cbpending[s] &= ~(1 << type);
            vdagent_send_clipboard_data(vd, info, type);
        }
    }
}

static void vdagent_clipboard_reset_serial(VDAgentChardev *vd)
{
    Chardev *chr = CHARDEV(vd);

    /* reopen the agent connection to reset the serial state */
    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
    /* OPENED again after the guest disconnected, see set_fe_open */
}

static void vdagent_clipboard_notify(Notifier *notifier, void *data)
{
    VDAgentChardev *vd =
        container_of(notifier, VDAgentChardev, cbpeer.notifier);
    QemuClipboardNotify *notify = data;

    switch (notify->type) {
    case QEMU_CLIPBOARD_UPDATE_INFO:
        vdagent_clipboard_update_info(vd, notify->info);
        return;
    case QEMU_CLIPBOARD_RESET_SERIAL:
        vdagent_clipboard_reset_serial(vd);
        return;
    }
}

static void vdagent_clipboard_request(QemuClipboardInfo *info,
                                      QemuClipboardType qtype)
{
    VDAgentChardev *vd = container_of(info->owner, VDAgentChardev, cbpeer);
    g_autofree VDAgentMessage *msg = g_malloc0(sizeof(VDAgentMessage) +
                                               sizeof(uint32_t) * 2);
    uint32_t type = type_qemu_to_vdagent(qtype);
    uint8_t *s = msg->data;
    uint32_t *data = (uint32_t *)msg->data;

    if (type == VD_AGENT_CLIPBOARD_NONE) {
        return;
    }

    if (have_selection(vd)) {
        *s = info->selection;
        data++;
        msg->size += sizeof(uint32_t);
    }

    *data = type;
    msg->size += sizeof(uint32_t);

    msg->type = VD_AGENT_CLIPBOARD_REQUEST;
    vdagent_send_msg(vd, msg);
}

static void vdagent_clipboard_recv_grab(VDAgentChardev *vd, uint8_t s, uint32_t size, void *data)
{
    g_autoptr(QemuClipboardInfo) info = NULL;

    trace_vdagent_cb_grab_selection(GET_NAME(sel_name, s));
    info = qemu_clipboard_info_new(&vd->cbpeer, s);
#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1)
    if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) {
        if (size < sizeof(uint32_t)) {
            /* this shouldn't happen! */
            return;
        }

        info->has_serial = true;
        info->serial = *(uint32_t *)data;
        if (info->serial < vd->last_serial[s]) {
            trace_vdagent_cb_grab_discard(GET_NAME(sel_name, s),
                                          vd->last_serial[s], info->serial);
            /* discard lower-ordering guest grab */
            return;
        }
        vd->last_serial[s] = info->serial;
        data += sizeof(uint32_t);
        size -= sizeof(uint32_t);
    }
#endif
    if (size > sizeof(uint32_t) * 10) {
        /*
         * spice has 6 types as of 2021. Limiting to 10 entries
         * so we have some wiggle room.
         */
        return;
    }
    while (size >= sizeof(uint32_t)) {
        trace_vdagent_cb_grab_type(GET_NAME(type_name, *(uint32_t *)data));
        switch (*(uint32_t *)data) {
        case VD_AGENT_CLIPBOARD_UTF8_TEXT:
            info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
            break;
        default:
            break;
        }
        data += sizeof(uint32_t);
        size -= sizeof(uint32_t);
    }
    qemu_clipboard_update(info);
}

static void vdagent_clipboard_recv_request(VDAgentChardev *vd, uint8_t s, uint32_t size, void *data)
{
    QemuClipboardType type;
    QemuClipboardInfo *info;

    if (size < sizeof(uint32_t)) {
        return;
    }
    switch (*(uint32_t *)data) {
    case VD_AGENT_CLIPBOARD_UTF8_TEXT:
        type = QEMU_CLIPBOARD_TYPE_TEXT;
        break;
    default:
        return;
    }

    info = qemu_clipboard_info(s);
    if (info && info->types[type].available && info->owner != &vd->cbpeer) {
        if (info->types[type].data) {
            vdagent_send_clipboard_data(vd, info, type);
        } else {
            vd->cbpending[s] |= (1 << type);
            qemu_clipboard_request(info, type);
        }
    } else {
        vdagent_send_empty_clipboard_data(vd, s, type);
    }
}

static void vdagent_clipboard_recv_data(VDAgentChardev *vd, uint8_t s, uint32_t size, void *data)
{
    QemuClipboardType type;

    if (size < sizeof(uint32_t)) {
        return;
    }
    switch (*(uint32_t *)data) {
    case VD_AGENT_CLIPBOARD_UTF8_TEXT:
        type = QEMU_CLIPBOARD_TYPE_TEXT;
        break;
    default:
        return;
    }
    data += 4;
    size -= 4;

    if (qemu_clipboard_peer_owns(&vd->cbpeer, s)) {
        qemu_clipboard_set_data(&vd->cbpeer, qemu_clipboard_info(s),
                                type, size, data, true);
    }
}

static void vdagent_clipboard_recv_release(VDAgentChardev *vd, uint8_t s)
{
    qemu_clipboard_peer_release(&vd->cbpeer, s);
}

static void vdagent_chr_recv_clipboard(VDAgentChardev *vd, VDAgentMessage *msg)
{
    uint8_t s = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
    uint32_t size = msg->size;
    void *data = msg->data;

    if (have_selection(vd)) {
        if (size < 4) {
            return;
        }
        s = *(uint8_t *)data;
        if (s >= QEMU_CLIPBOARD_SELECTION__COUNT) {
            return;
        }
        data += 4;
        size -= 4;
    }

    switch (msg->type) {
    case VD_AGENT_CLIPBOARD_GRAB:
        return vdagent_clipboard_recv_grab(vd, s, size, data);
    case VD_AGENT_CLIPBOARD_REQUEST:
        return vdagent_clipboard_recv_request(vd, s, size, data);
    case VD_AGENT_CLIPBOARD: /* data */
        return vdagent_clipboard_recv_data(vd, s, size, data);
    case VD_AGENT_CLIPBOARD_RELEASE:
        return vdagent_clipboard_recv_release(vd, s);
    default:
        g_assert_not_reached();
    }
}

/* ------------------------------------------------------------------ */
/* chardev backend                                                    */

static void vdagent_chr_open(Chardev *chr,
                             ChardevBackend *backend,
                             bool *be_opened,
                             Error **errp)
{
    VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);
    ChardevQemuVDAgent *cfg = backend->u.qemu_vdagent.data;

#if HOST_BIG_ENDIAN
    /*
     * TODO: vdagent protocol is defined to be LE,
     * so we have to byteswap everything on BE hosts.
     */
    error_setg(errp, "vdagent is not supported on bigendian hosts");
    return;
#endif

    if (migrate_add_blocker(&vd->migration_blocker, errp) != 0) {
        return;
    }

    vd->mouse = VDAGENT_MOUSE_DEFAULT;
    if (cfg->has_mouse) {
        vd->mouse = cfg->mouse;
    }

    vd->clipboard = VDAGENT_CLIPBOARD_DEFAULT;
    if (cfg->has_clipboard) {
        vd->clipboard = cfg->clipboard;
    }

    if (vd->mouse) {
        vd->mouse_hs = qemu_input_handler_register(&vd->mouse_dev,
                                                   &vdagent_mouse_handler);
    }

    *be_opened = true;
}

static void vdagent_chr_recv_caps(VDAgentChardev *vd, VDAgentMessage *msg)
{
    VDAgentAnnounceCapabilities *caps = (void *)msg->data;
    int i;

    if (msg->size < (sizeof(VDAgentAnnounceCapabilities) +
                     sizeof(uint32_t))) {
        return;
    }

    for (i = 0; i < ARRAY_SIZE(cap_name); i++) {
        if (caps->caps[0] & (1 << i)) {
            trace_vdagent_peer_cap(GET_NAME(cap_name, i));
        }
    }

    vd->caps = caps->caps[0];
    if (caps->request) {
        vdagent_send_caps(vd);
    }
    if (have_mouse(vd) && vd->mouse_hs) {
        qemu_input_handler_activate(vd->mouse_hs);
    }

    memset(vd->last_serial, 0, sizeof(vd->last_serial));

    if (have_clipboard(vd) && vd->cbpeer.notifier.notify == NULL) {
        vd->cbpeer.name = "vdagent";
        vd->cbpeer.notifier.notify = vdagent_clipboard_notify;
        vd->cbpeer.request = vdagent_clipboard_request;
        qemu_clipboard_peer_register(&vd->cbpeer);
    }
}

static void vdagent_chr_recv_msg(VDAgentChardev *vd, VDAgentMessage *msg)
{
    trace_vdagent_recv_msg(GET_NAME(msg_name, msg->type), msg->size);

    switch (msg->type) {
    case VD_AGENT_ANNOUNCE_CAPABILITIES:
        vdagent_chr_recv_caps(vd, msg);
        break;
    case VD_AGENT_CLIPBOARD:
    case VD_AGENT_CLIPBOARD_GRAB:
    case VD_AGENT_CLIPBOARD_REQUEST:
    case VD_AGENT_CLIPBOARD_RELEASE:
        if (have_clipboard(vd)) {
            vdagent_chr_recv_clipboard(vd, msg);
        }
        break;
    default:
        break;
    }
}

static void vdagent_reset_xbuf(VDAgentChardev *vd)
{
    g_clear_pointer(&vd->xbuf, g_free);
    vd->xoff = 0;
    vd->xsize = 0;
}

static void vdagent_chr_recv_chunk(VDAgentChardev *vd)
{
    VDAgentMessage *msg = (void *)vd->msgbuf;

    if (!vd->xsize) {
        if (vd->msgsize < sizeof(*msg)) {
            error_report("%s: message too small: %d < %zd", __func__,
                         vd->msgsize, sizeof(*msg));
            return;
        }
        if (vd->msgsize == msg->size + sizeof(*msg)) {
            vdagent_chr_recv_msg(vd, msg);
            return;
        }
    }

    if (!vd->xsize) {
        vd->xsize = msg->size + sizeof(*msg);
        vd->xbuf = g_malloc0(vd->xsize);
    }

    if (vd->xoff + vd->msgsize > vd->xsize) {
        error_report("%s: Oops: %d+%d > %d", __func__,
                     vd->xoff, vd->msgsize, vd->xsize);
        vdagent_reset_xbuf(vd);
        return;
    }

    memcpy(vd->xbuf + vd->xoff, vd->msgbuf, vd->msgsize);
    vd->xoff += vd->msgsize;
    if (vd->xoff < vd->xsize) {
        return;
    }

    msg = (void *)vd->xbuf;
    vdagent_chr_recv_msg(vd, msg);
    vdagent_reset_xbuf(vd);
}

static void vdagent_reset_bufs(VDAgentChardev *vd)
{
    memset(&vd->chunk, 0, sizeof(vd->chunk));
    vd->chunksize = 0;
    g_free(vd->msgbuf);
    vd->msgbuf = NULL;
    vd->msgsize = 0;
}

static int vdagent_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
    VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);
    uint32_t copy, ret = len;

    while (len) {
        if (vd->chunksize < sizeof(vd->chunk)) {
            copy = sizeof(vd->chunk) - vd->chunksize;
            if (copy > len) {
                copy = len;
            }
            memcpy((void *)(&vd->chunk) + vd->chunksize, buf, copy);
            vd->chunksize += copy;
            buf += copy;
            len -= copy;
            if (vd->chunksize < sizeof(vd->chunk)) {
                break;
            }

            assert(vd->msgbuf == NULL);
            vd->msgbuf = g_malloc0(vd->chunk.size);
        }

        copy = vd->chunk.size - vd->msgsize;
        if (copy > len) {
            copy = len;
        }
        memcpy(vd->msgbuf + vd->msgsize, buf, copy);
        vd->msgsize += copy;
        buf += copy;
        len -= copy;

        if (vd->msgsize == vd->chunk.size) {
            trace_vdagent_recv_chunk(vd->chunk.size);
            vdagent_chr_recv_chunk(vd);
            vdagent_reset_bufs(vd);
        }
    }

    return ret;
}

static void vdagent_chr_accept_input(Chardev *chr)
{
    VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);

    vdagent_send_buf(vd);
}

static void vdagent_disconnect(VDAgentChardev *vd)
{
    trace_vdagent_disconnect();

    buffer_reset(&vd->outbuf);
    vdagent_reset_bufs(vd);
    vd->caps = 0;
    if (vd->mouse_hs) {
        qemu_input_handler_deactivate(vd->mouse_hs);
    }
    if (vd->cbpeer.notifier.notify) {
        qemu_clipboard_peer_unregister(&vd->cbpeer);
        memset(&vd->cbpeer, 0, sizeof(vd->cbpeer));
    }
}

static void vdagent_chr_set_fe_open(struct Chardev *chr, int fe_open)
{
    VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(chr);

    if (!fe_open) {
        trace_vdagent_close();
        vdagent_disconnect(vd);
        /* To reset_serial, we CLOSED our side. Make sure the other end knows we
         * are ready again. */
        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
        return;
    }

    trace_vdagent_open();
}

static void vdagent_chr_parse(QemuOpts *opts, ChardevBackend *backend,
                              Error **errp)
{
    ChardevQemuVDAgent *cfg;

    backend->type = CHARDEV_BACKEND_KIND_QEMU_VDAGENT;
    cfg = backend->u.qemu_vdagent.data = g_new0(ChardevQemuVDAgent, 1);
    qemu_chr_parse_common(opts, qapi_ChardevQemuVDAgent_base(cfg));
    cfg->has_mouse = true;
    cfg->mouse = qemu_opt_get_bool(opts, "mouse", VDAGENT_MOUSE_DEFAULT);
    cfg->has_clipboard = true;
    cfg->clipboard = qemu_opt_get_bool(opts, "clipboard", VDAGENT_CLIPBOARD_DEFAULT);
}

/* ------------------------------------------------------------------ */

static void vdagent_chr_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->parse            = vdagent_chr_parse;
    cc->open             = vdagent_chr_open;
    cc->chr_write        = vdagent_chr_write;
    cc->chr_set_fe_open  = vdagent_chr_set_fe_open;
    cc->chr_accept_input = vdagent_chr_accept_input;
}

static void vdagent_chr_init(Object *obj)
{
    VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(obj);

    buffer_init(&vd->outbuf, "vdagent-outbuf");
    error_setg(&vd->migration_blocker,
               "The vdagent chardev doesn't yet support migration");
}

static void vdagent_chr_fini(Object *obj)
{
    VDAgentChardev *vd = QEMU_VDAGENT_CHARDEV(obj);

    migrate_del_blocker(&vd->migration_blocker);
    vdagent_disconnect(vd);
    if (vd->mouse_hs) {
        qemu_input_handler_unregister(vd->mouse_hs);
    }
    buffer_free(&vd->outbuf);
}

static const TypeInfo vdagent_chr_type_info = {
    .name = TYPE_CHARDEV_QEMU_VDAGENT,
    .parent = TYPE_CHARDEV,
    .instance_size = sizeof(VDAgentChardev),
    .instance_init = vdagent_chr_init,
    .instance_finalize = vdagent_chr_fini,
    .class_init = vdagent_chr_class_init,
};

static void register_types(void)
{
    type_register_static(&vdagent_chr_type_info);
}

type_init(register_types);
