We try to inject an interrupt to the vm in this case, which we cannot do if it is stopped. Instead log this and update when vm restarts. RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=870972 (that bz is on qemu, it will be cloned or just changed, not sure yet) --- server/red_worker.c | 64 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/server/red_worker.c b/server/red_worker.c index ec1c284..9edd5d4 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -997,6 +997,7 @@ typedef struct RedWorker { #endif int driver_has_monitors_config; + int set_client_capabilities_pending; } RedWorker; typedef enum { @@ -10327,6 +10328,48 @@ static void display_channel_create(RedWorker *worker, int migrate) stat_compress_init(&display_channel->jpeg_alpha_stat, jpeg_alpha_stat_name); } +static void guest_set_client_capabilities(RedWorker *worker) +{ + int i; + DisplayChannelClient *dcc; + RedChannelClient *rcc; + RingItem *link; + uint8_t caps[58] = { 0 }; + int caps_available[] = { + SPICE_DISPLAY_CAP_SIZED_STREAM, + SPICE_DISPLAY_CAP_MONITORS_CONFIG, + SPICE_DISPLAY_CAP_COMPOSITE, + SPICE_DISPLAY_CAP_A8_SURFACE, + }; + +#define SET_CAP(a,c) \ + ((a)[(c) / 8] |= (1 << ((c) % 8))) + +#define CLEAR_CAP(a,c) \ + ((a)[(c) / 8] &= ~(1 << ((c) % 8))) + + if (!worker->running) { + worker->set_client_capabilities_pending = 1; + return; + } + if (worker->display_channel->common.base.clients_num == 0) { + worker->qxl->st->qif->set_client_capabilities(worker->qxl, FALSE, caps); + } else { + // Take least common denominator + for (i = 0 ; i < sizeof(caps_available) / sizeof(caps_available[0]); ++i) { + SET_CAP(caps, caps_available[i]); + } + DCC_FOREACH(link, dcc, &worker->display_channel->common.base) { + rcc = (RedChannelClient *)dcc; + for (i = 0 ; i < sizeof(caps_available) / sizeof(caps_available[0]); ++i) { + if (!red_channel_client_test_remote_cap(rcc, caps_available[i])) + CLEAR_CAP(caps, caps_available[i]); + } + } + worker->qxl->st->qif->set_client_capabilities(worker->qxl, TRUE, caps); + } + worker->set_client_capabilities_pending = 0; +} static void handle_new_display_channel(RedWorker *worker, RedClient *client, RedsStream *stream, int migrate, @@ -10384,22 +10427,7 @@ static void handle_new_display_channel(RedWorker *worker, RedClient *client, Red if (worker->qxl->st->qif->base.major_version == 3 && worker->qxl->st->qif->base.minor_version >= 2 && worker->qxl->st->qif->set_client_capabilities) { - RedChannelClient *rcc = (RedChannelClient *)dcc; - uint8_t caps[58] = { 0 }; - -#define SET_CAP(a,c) \ - ((a)[(c) / 8] |= (1 << ((c) % 8))) - - if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_SIZED_STREAM)) - SET_CAP(caps, SPICE_DISPLAY_CAP_SIZED_STREAM); - if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) - SET_CAP(caps, SPICE_DISPLAY_CAP_MONITORS_CONFIG); - if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_COMPOSITE)) - SET_CAP(caps, SPICE_DISPLAY_CAP_COMPOSITE); - if (red_channel_client_test_remote_cap(rcc, SPICE_DISPLAY_CAP_A8_SURFACE)) - SET_CAP(caps, SPICE_DISPLAY_CAP_A8_SURFACE); - - worker->qxl->st->qif->set_client_capabilities(worker->qxl, TRUE, caps); + guest_set_client_capabilities(worker); } // todo: tune level according to bandwidth @@ -11146,6 +11174,7 @@ void handle_dev_start(void *opaque, void *payload) worker->display_channel->common.during_target_migrate = FALSE; } worker->running = TRUE; + guest_set_client_capabilities(worker); } void handle_dev_wakeup(void *opaque, void *payload) @@ -11267,8 +11296,7 @@ void handle_dev_display_disconnect(void *opaque, void *payload) if (worker->qxl->st->qif->base.major_version == 3 && worker->qxl->st->qif->base.minor_version >= 2 && worker->qxl->st->qif->set_client_capabilities) { - uint8_t caps[58] = { 0 }; - worker->qxl->st->qif->set_client_capabilities(worker->qxl, FALSE, caps); + guest_set_client_capabilities(worker); } red_channel_client_disconnect(rcc); -- 1.7.12.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel