Adds two functions: red_dispatcher_use_client_monitors_config: - checks the guest for the QXL_GUEST_CAP_CLIENT_MONITORS_CONFIG_ISR cap, and that QXLInterface is new enough to support cap checking and client_monitors_config callback, returns TRUE if so. - red_dispatcher_client_monitors_config: send the client monitors configuration to the guest. main_channel function added to avoid exposing MainChannelClient out of main_channel.c --- server/main_channel.c | 7 +++++ server/main_channel.h | 2 ++ server/red_dispatcher.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ server/red_dispatcher.h | 5 ++++ 4 files changed, 88 insertions(+) diff --git a/server/main_channel.c b/server/main_channel.c index 0fd5ab6..37ed423 100644 --- a/server/main_channel.c +++ b/server/main_channel.c @@ -46,6 +46,7 @@ #include "red_common.h" #include "reds.h" #include "migration_protocol.h" +#include "red_dispatcher.h" #define ZERO_BUF_SIZE 4096 @@ -1335,3 +1336,9 @@ int main_channel_migrate_src_complete(MainChannel *main_chan, int success) } return semi_seamless_count; } + +void main_channel_client_client_monitors_config(MainChannelClient *mcc, + VDAgentMonitorsConfig *monitors_config) +{ + red_dispatcher_client_monitors_config(&mcc->base, monitors_config); +} diff --git a/server/main_channel.h b/server/main_channel.h index 285a009..4ea907a 100644 --- a/server/main_channel.h +++ b/server/main_channel.h @@ -86,5 +86,7 @@ int main_channel_migrate_src_complete(MainChannel *main_chan, int success); void main_channel_migrate_dst_complete(MainChannelClient *mcc); void main_channel_push_name(MainChannelClient *mcc, const char *name); void main_channel_push_uuid(MainChannelClient *mcc, const uint8_t uuid[16]); +void main_channel_client_client_monitors_config(MainChannelClient *mcc, + VDAgentMonitorsConfig *monitors_config); #endif diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index 8e44674..2495efe 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -85,6 +85,41 @@ extern spice_wan_compression_t zlib_glz_state; static RedDispatcher *dispatchers = NULL; +static int red_dispatcher_version_check(int major, int minor) +{ + if (num_active_workers > 0) { + RedDispatcher *now = dispatchers; + while (now) { + if (now->base.major_version != major || + now->base.minor_version < minor) { + return FALSE; + } + now = now->next; + } + return TRUE; + } + return FALSE; +} + +static int red_dispatcher_test_guest_cap(unsigned cap) +{ + RedDispatcher *now = dispatchers; + unsigned ind = cap / 8; + unsigned cap_mask = 1 << (cap & 7); + + if (num_active_workers == 0) { + return FALSE; + } + + for (; now; now = now->next) { + if (now->guest_capabilities_size < ind + 1 || + !(now->guest_capabilities[ind] & cap_mask)) { + return FALSE; + } + } + return TRUE; +} + static void red_dispatcher_set_display_peer(RedChannel *channel, RedClient *client, RedsStream *stream, int migration, int num_common_caps, uint32_t *common_caps, int num_caps, @@ -297,6 +332,45 @@ static void red_dispatcher_update_area(RedDispatcher *dispatcher, uint32_t surfa &payload); } +int red_dispatcher_use_client_monitors_config(void) +{ + RedDispatcher *now = dispatchers; + + if (num_active_workers == 0) { + return FALSE; + } + + for (; now ; now = now->next) { + if (!red_dispatcher_version_check(3, 2) || + !now->qxl->st->qif->client_monitors_config || + !red_dispatcher_test_guest_cap(QXL_GUEST_CAP_CLIENT_MONITORS_CONFIG_ISR)) { + return FALSE; + } + } + return TRUE; +} + +void red_dispatcher_client_monitors_config(RedChannelClient *rcc, + VDAgentMonitorsConfig *monitors_config) +{ + RedDispatcher *now = dispatchers; + + if (!rcc->channel) { + return; + } + + while (now) { + if (now->qxl->st->qif->client_monitors_config) { + now->qxl->st->qif->client_monitors_config(now->qxl, + monitors_config); + } else { + spice_warning("spice bug: red_dispatcher_client_monitors_config called\n" + "with QXLInterface missing client_monitors_config callback\n"); + } + now = now->next; + } +} + static AsyncCommand *async_command_alloc(RedDispatcher *dispatcher, RedWorkerMessage message, uint64_t cookie) diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h index 7e9ffe6..ccab323 100644 --- a/server/red_dispatcher.h +++ b/server/red_dispatcher.h @@ -18,6 +18,8 @@ #ifndef _H_RED_DISPATCHER #define _H_RED_DISPATCHER +#include "red_channel.h" + struct RedChannelClient; typedef struct AsyncCommand AsyncCommand; @@ -35,6 +37,9 @@ uint32_t red_dispatcher_qxl_ram_size(void); int red_dispatcher_qxl_count(void); void red_dispatcher_async_complete(struct RedDispatcher *, AsyncCommand *); struct Dispatcher *red_dispatcher_get_dispatcher(struct RedDispatcher *); +int red_dispatcher_use_client_monitors_config(void); +void red_dispatcher_client_monitors_config(RedChannelClient *rcc, + VDAgentMonitorsConfig *monitors_config); typedef struct RedWorkerMessageDisplayConnect { RedClient * client; -- 1.7.12 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel