X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=spice-qemu-char.c;h=351fcaa033a5c2bc27f51217b46a9523e76ebb6d;hb=f6f949e9295889fb272698aea763dcea77d616ce;hp=f10970c9dbc80e9fd5fa8029d40199ee889ba13a;hpb=6f8111a16d9cb3744a7b05726df28ee8cb6d8d30;p=mirror_qemu.git diff --git a/spice-qemu-char.c b/spice-qemu-char.c index f10970c9db..351fcaa033 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -1,17 +1,14 @@ -#include "config-host.h" +#include "qemu/osdep.h" #include "trace.h" #include "ui/qemu-spice.h" #include "sysemu/char.h" #include -#include #include -#include "qemu/osdep.h" typedef struct SpiceCharDriver { CharDriverState* chr; SpiceCharDeviceInstance sin; - char *subtype; bool active; bool blocked; const uint8_t *datapos; @@ -112,6 +109,9 @@ static SpiceCharDeviceInterface vmc_interface = { #if SPICE_SERVER_VERSION >= 0x000c02 .event = vmc_event, #endif +#if SPICE_SERVER_VERSION >= 0x000c06 + .flags = SPICE_CHAR_DEVICE_NOTIFY_WRITABLE, +#endif }; @@ -160,7 +160,7 @@ static gboolean spice_char_source_dispatch(GSource *source, return func(NULL, G_IO_OUT, user_data); } -GSourceFuncs SpiceCharSourceFuncs = { +static GSourceFuncs SpiceCharSourceFuncs = { .prepare = spice_char_source_prepare, .check = spice_char_source_check, .dispatch = spice_char_source_dispatch, @@ -171,7 +171,7 @@ static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond) SpiceCharDriver *scd = chr->opaque; SpiceCharSource *src; - assert(cond == G_IO_OUT); + assert(cond & G_IO_OUT); src = (SpiceCharSource *)g_source_new(&SpiceCharSourceFuncs, sizeof(SpiceCharSource)); @@ -213,7 +213,7 @@ static void spice_chr_close(struct CharDriverState *chr) g_free(s); } -static void spice_chr_set_fe_open(struct CharDriverState *chr, int fe_open) +static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open) { SpiceCharDriver *s = chr->opaque; if (fe_open) { @@ -223,6 +223,28 @@ static void spice_chr_set_fe_open(struct CharDriverState *chr, int fe_open) } } +static void spice_port_set_fe_open(struct CharDriverState *chr, int fe_open) +{ +#if SPICE_SERVER_VERSION >= 0x000c02 + SpiceCharDriver *s = chr->opaque; + + if (fe_open) { + spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED); + } else { + spice_server_port_event(&s->sin, SPICE_PORT_EVENT_CLOSED); + } +#endif +} + +static void spice_chr_fe_event(struct CharDriverState *chr, int event) +{ +#if SPICE_SERVER_VERSION >= 0x000c02 + SpiceCharDriver *s = chr->opaque; + + spice_server_port_event(&s->sin, event); +#endif +} + static void print_allowed_subtypes(void) { const char** psubtype; @@ -240,12 +262,26 @@ static void print_allowed_subtypes(void) fprintf(stderr, "\n"); } -static CharDriverState *chr_open(const char *subtype) +static void spice_chr_accept_input(struct CharDriverState *chr) +{ + SpiceCharDriver *s = chr->opaque; + + spice_server_char_device_wakeup(&s->sin); +} + +static CharDriverState *chr_open(const char *subtype, + void (*set_fe_open)(struct CharDriverState *, + int), + ChardevCommon *backend, + Error **errp) { CharDriverState *chr; SpiceCharDriver *s; - chr = g_malloc0(sizeof(CharDriverState)); + chr = qemu_chr_alloc(backend, errp); + if (!chr) { + return NULL; + } s = g_malloc0(sizeof(SpiceCharDriver)); s->chr = chr; s->active = false; @@ -254,22 +290,26 @@ static CharDriverState *chr_open(const char *subtype) chr->chr_write = spice_chr_write; chr->chr_add_watch = spice_chr_add_watch; chr->chr_close = spice_chr_close; - chr->chr_set_fe_open = spice_chr_set_fe_open; + chr->chr_set_fe_open = set_fe_open; + chr->explicit_be_open = true; + chr->chr_fe_event = spice_chr_fe_event; + chr->chr_accept_input = spice_chr_accept_input; QLIST_INSERT_HEAD(&spice_chars, s, next); return chr; } -CharDriverState *qemu_chr_open_spice_vmc(const char *type) +static CharDriverState *qemu_chr_open_spice_vmc(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data; + const char *type = spicevmc->type; const char **psubtype = spice_server_char_device_recognized_subtypes(); + ChardevCommon *common = qapi_ChardevSpiceChannel_base(spicevmc); - if (type == NULL) { - fprintf(stderr, "spice-qemu-char: missing name parameter\n"); - print_allowed_subtypes(); - return NULL; - } for (; *psubtype != NULL; ++psubtype) { if (strcmp(type, *psubtype) == 0) { break; @@ -281,12 +321,18 @@ CharDriverState *qemu_chr_open_spice_vmc(const char *type) return NULL; } - return chr_open(type); + return chr_open(type, spice_vmc_set_fe_open, common, errp); } #if SPICE_SERVER_VERSION >= 0x000c02 -CharDriverState *qemu_chr_open_spice_port(const char *name) +static CharDriverState *qemu_chr_open_spice_port(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevSpicePort *spiceport = backend->u.spiceport.data; + const char *name = spiceport->fqdn; + ChardevCommon *common = qapi_ChardevSpicePort_base(spiceport); CharDriverState *chr; SpiceCharDriver *s; @@ -295,7 +341,10 @@ CharDriverState *qemu_chr_open_spice_port(const char *name) return NULL; } - chr = chr_open("port"); + chr = chr_open("port", spice_port_set_fe_open, common, errp); + if (!chr) { + return NULL; + } s = chr->opaque; s->sin.portname = g_strdup(name); @@ -319,34 +368,38 @@ static void qemu_chr_parse_spice_vmc(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *name = qemu_opt_get(opts, "name"); + ChardevSpiceChannel *spicevmc; if (name == NULL) { error_setg(errp, "chardev: spice channel: no name given"); return; } - backend->spicevmc = g_new0(ChardevSpiceChannel, 1); - backend->spicevmc->type = g_strdup(name); + spicevmc = backend->u.spicevmc.data = g_new0(ChardevSpiceChannel, 1); + qemu_chr_parse_common(opts, qapi_ChardevSpiceChannel_base(spicevmc)); + spicevmc->type = g_strdup(name); } static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *name = qemu_opt_get(opts, "name"); + ChardevSpicePort *spiceport; if (name == NULL) { error_setg(errp, "chardev: spice port: no name given"); return; } - backend->spiceport = g_new0(ChardevSpicePort, 1); - backend->spiceport->fqdn = g_strdup(name); + spiceport = backend->u.spiceport.data = g_new0(ChardevSpicePort, 1); + qemu_chr_parse_common(opts, qapi_ChardevSpicePort_base(spiceport)); + spiceport->fqdn = g_strdup(name); } static void register_types(void) { - register_char_driver_qapi("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC, - qemu_chr_parse_spice_vmc); - register_char_driver_qapi("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT, - qemu_chr_parse_spice_port); + register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC, + qemu_chr_parse_spice_vmc, qemu_chr_open_spice_vmc); + register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT, + qemu_chr_parse_spice_port, qemu_chr_open_spice_port); } type_init(register_types);