[Spice-devel] [PATCH 4/7] server/red_dispatcher: client_monitors_config support
Alon Levy
alevy at redhat.com
Mon Sep 10 08:43:59 PDT 2012
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
More information about the Spice-devel
mailing list