summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathon Jongsma <jjongsma@redhat.com>2015-02-06 11:53:36 -0600
committerFabiano FidĂȘncio <fidencio@redhat.com>2015-02-23 23:00:46 +0100
commit1c7cf80e55776fd1e4b60d972c309390660587dc (patch)
tree0b9ed7f0249ed4b3f0726c1a4232f035ff376abd
parente1dc7ed57855695fd7750e0725f80973f075a1ce (diff)
downloadspice-1c7cf80e55776fd1e4b60d972c309390660587dc.tar.gz
spice-1c7cf80e55776fd1e4b60d972c309390660587dc.tar.xz
spice-1c7cf80e55776fd1e4b60d972c309390660587dc.zip
Remove global 'dispatchers', 'num_active_workers' variables
Since these are server-level variables, move them into RedsState. However, num_active_workers was removed because: - each dispatcher always has 1 active worker, so we can determine the number of active workers by counting the dispatchers - it was never actually set correctly. Even if there was more than one worker, this variable was always only set to either 0 or 1. This change required moving a bunch of helper code into RedsState as well, an providing some RedDispatcher interfaces to access dispatcher information from RedsState.
-rw-r--r--server/agent-msg-filter.c3
-rw-r--r--server/red-dispatcher.c238
-rw-r--r--server/red-dispatcher.h27
-rw-r--r--server/reds-private.h2
-rw-r--r--server/reds.c170
-rw-r--r--server/reds.h4
6 files changed, 243 insertions, 201 deletions
diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c
index 13654f1e..1ddeb814 100644
--- a/server/agent-msg-filter.c
+++ b/server/agent-msg-filter.c
@@ -24,6 +24,7 @@
#include <string.h>
#include "common.h"
#include "agent-msg-filter.h"
+#include "reds.h"
#include "red-dispatcher.h"
void agent_msg_filter_init(struct AgentMsgFilter *filter,
@@ -92,7 +93,7 @@ data_to_read:
}
break;
case VD_AGENT_MONITORS_CONFIG:
- if (red_dispatcher_use_client_monitors_config()) {
+ if (reds_use_client_monitors_config(reds)) {
filter->result = AGENT_MSG_FILTER_MONITORS_CONFIG;
} else {
filter->result = AGENT_MSG_FILTER_OK;
diff --git a/server/red-dispatcher.c b/server/red-dispatcher.c
index ea23b101..43d6a2ff 100644
--- a/server/red-dispatcher.c
+++ b/server/red-dispatcher.c
@@ -41,7 +41,6 @@
#include "red-dispatcher.h"
-static int num_active_workers = 0;
struct AsyncCommand {
RingItem link;
@@ -58,7 +57,6 @@ struct RedDispatcher {
int x_res;
int y_res;
int use_hardware_cursor;
- RedDispatcher *next;
Ring async_commands;
pthread_mutex_t async_lock;
QXLDevSurfaceCreate surface_create;
@@ -74,8 +72,6 @@ typedef struct RedWorkeState {
uint32_t stride;
} RedWorkeState;
-static RedDispatcher *dispatchers = NULL;
-
static int red_dispatcher_check_qxl_version(RedDispatcher *rd, int major, int minor)
{
int qxl_major = rd->qxl->st->qif->base.major_version;
@@ -206,42 +202,6 @@ static void red_dispatcher_cursor_migrate(RedChannelClient *rcc)
&payload);
}
-int red_dispatcher_qxl_count(void)
-{
- return num_active_workers;
-}
-
-static void update_client_mouse_allowed(void)
-{
- static int allowed = FALSE;
- int allow_now = FALSE;
- int x_res = 0;
- int y_res = 0;
-
- if (num_active_workers > 0) {
- allow_now = TRUE;
- RedDispatcher *now = dispatchers;
- while (now && allow_now) {
- if (now->primary_active) {
- allow_now = now->use_hardware_cursor;
- if (num_active_workers == 1) {
- if (allow_now) {
- x_res = now->x_res;
- y_res = now->y_res;
- }
- break;
- }
- }
- now = now->next;
- }
- }
-
- if (allow_now || allow_now != allowed) {
- allowed = allow_now;
- reds_set_client_mouse_allowed(reds, allowed, x_res, y_res);
- }
-}
-
static void red_dispatcher_update_area(RedDispatcher *dispatcher, uint32_t surface_id,
QXLRect *qxl_area, QXLRect *qxl_dirty_rects,
uint32_t num_dirty_rects, uint32_t clear_dirty_region)
@@ -258,37 +218,19 @@ static void red_dispatcher_update_area(RedDispatcher *dispatcher, uint32_t surfa
&payload);
}
-int red_dispatcher_use_client_monitors_config(void)
+gboolean red_dispatcher_use_client_monitors_config(RedDispatcher *dispatcher)
{
- RedDispatcher *now = dispatchers;
-
- if (num_active_workers == 0) {
- return FALSE;
- }
-
- for (; now ; now = now->next) {
- if (!red_dispatcher_check_qxl_version(now, 3, 3) ||
- !now->qxl->st->qif->client_monitors_config ||
- !now->qxl->st->qif->client_monitors_config(now->qxl, NULL)) {
- return FALSE;
- }
- }
- return TRUE;
+ return (red_dispatcher_check_qxl_version(dispatcher, 3, 3) &&
+ dispatcher->qxl->st->qif->client_monitors_config &&
+ dispatcher->qxl->st->qif->client_monitors_config(dispatcher->qxl, NULL));
}
-void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig *monitors_config)
+gboolean red_dispatcher_client_monitors_config(RedDispatcher *dispatcher,
+ VDAgentMonitorsConfig *monitors_config)
{
- RedDispatcher *now = dispatchers;
-
- while (now) {
- if (!now->qxl->st->qif->client_monitors_config ||
- !now->qxl->st->qif->client_monitors_config(now->qxl,
- monitors_config)) {
- /* this is a normal condition, some qemu devices might not implement it */
- spice_debug("QXLInterface::client_monitors_config failed\n");
- }
- now = now->next;
- }
+ return (dispatcher->qxl->st->qif->client_monitors_config &&
+ dispatcher->qxl->st->qif->client_monitors_config(dispatcher->qxl,
+ monitors_config));
}
static AsyncCommand *async_command_alloc(RedDispatcher *dispatcher,
@@ -402,7 +344,7 @@ static void red_dispatcher_destroy_primary_surface_complete(RedDispatcher *dispa
dispatcher->use_hardware_cursor = FALSE;
dispatcher->primary_active = FALSE;
- update_client_mouse_allowed();
+ reds_update_client_mouse_allowed(reds);
}
static void
@@ -454,7 +396,7 @@ static void red_dispatcher_create_primary_surface_complete(RedDispatcher *dispat
dispatcher->use_hardware_cursor = surface->mouse_mode;
dispatcher->primary_active = TRUE;
- update_client_mouse_allowed();
+ reds_update_client_mouse_allowed(reds);
memset(&dispatcher->surface_create, 0, sizeof(QXLDevSurfaceCreate));
}
@@ -630,7 +572,7 @@ static void qxl_worker_oom(QXLWorker *qxl_worker)
red_dispatcher_oom((RedDispatcher*)qxl_worker);
}
-static void red_dispatcher_start(RedDispatcher *dispatcher)
+void red_dispatcher_start(RedDispatcher *dispatcher)
{
RedWorkerMessageStart payload;
@@ -677,7 +619,7 @@ static void red_dispatcher_driver_unload(RedDispatcher *dispatcher)
&payload);
}
-static void red_dispatcher_stop(RedDispatcher *dispatcher)
+void red_dispatcher_stop(RedDispatcher *dispatcher)
{
RedWorkerMessageStop payload;
@@ -712,112 +654,20 @@ static void qxl_worker_loadvm_commands(QXLWorker *qxl_worker,
red_dispatcher_loadvm_commands((RedDispatcher*)qxl_worker, ext, count);
}
-void red_dispatcher_set_mm_time(uint32_t mm_time)
+void red_dispatcher_set_mm_time(RedDispatcher *dispatcher, uint32_t mm_time)
{
- RedDispatcher *now = dispatchers;
- while (now) {
- now->qxl->st->qif->set_mm_time(now->qxl, mm_time);
- now = now->next;
- }
+ dispatcher->qxl->st->qif->set_mm_time(dispatcher->qxl, mm_time);
}
-static int calc_compression_level(void)
+void red_dispatcher_set_compression_level(RedDispatcher *dispatcher, int level)
{
- spice_return_val_if_fail(reds_get_streaming_video(reds) != STREAM_VIDEO_INVALID, -1);
-
- if ((reds_get_streaming_video(reds) != STREAM_VIDEO_OFF) ||
- (spice_server_get_image_compression(reds) != SPICE_IMAGE_COMPRESS_QUIC)) {
- return 0;
- } else {
- return 1;
- }
-}
-
-void red_dispatcher_on_ic_change(void)
-{
- RedWorkerMessageSetCompression payload;
- int compression_level = calc_compression_level();
- RedDispatcher *now = dispatchers;
-
- while (now) {
- now->qxl->st->qif->set_compression_level(now->qxl, compression_level);
- payload.image_compression = spice_server_get_image_compression(reds);
- dispatcher_send_message(&now->dispatcher,
- RED_WORKER_MESSAGE_SET_COMPRESSION,
- &payload);
- now = now->next;
- }
+ dispatcher->qxl->st->qif->set_compression_level(dispatcher->qxl, level);
}
-void red_dispatcher_on_sv_change(void)
-{
- RedWorkerMessageSetStreamingVideo payload;
- int compression_level = calc_compression_level();
- RedDispatcher *now = dispatchers;
- while (now) {
- now->qxl->st->qif->set_compression_level(now->qxl, compression_level);
- payload.streaming_video = reds_get_streaming_video(reds);
- dispatcher_send_message(&now->dispatcher,
- RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
- &payload);
- now = now->next;
- }
-}
-
-void red_dispatcher_set_mouse_mode(uint32_t mode)
-{
- RedWorkerMessageSetMouseMode payload;
- RedDispatcher *now = dispatchers;
- while (now) {
- payload.mode = mode;
- dispatcher_send_message(&now->dispatcher,
- RED_WORKER_MESSAGE_SET_MOUSE_MODE,
- &payload);
- now = now->next;
- }
-}
-
-void red_dispatcher_on_vm_stop(void)
-{
- RedDispatcher *now = dispatchers;
-
- spice_debug(NULL);
- while (now) {
- red_dispatcher_stop(now);
- now = now->next;
- }
-}
-
-void red_dispatcher_on_vm_start(void)
-{
- RedDispatcher *now = dispatchers;
-
- spice_debug(NULL);
- while (now) {
- red_dispatcher_start(now);
- now = now->next;
- }
-}
-
-int red_dispatcher_count(void)
-{
- RedDispatcher *now = dispatchers;
- int ret = 0;
-
- while (now) {
- ret++;
- now = now->next;
- }
- return ret;
-}
-
-uint32_t red_dispatcher_qxl_ram_size(void)
+uint32_t red_dispatcher_qxl_ram_size(RedDispatcher *dispatcher)
{
QXLDevInitInfo qxl_info;
- if (!dispatchers) {
- return 0;
- }
- dispatchers->qxl->st->qif->get_init_info(dispatchers->qxl, &qxl_info);
+ dispatcher->qxl->st->qif->get_init_info(dispatcher->qxl, &qxl_info);
return qxl_info.qxl_ram_size;
}
@@ -1010,7 +860,7 @@ void red_dispatcher_async_complete(struct RedDispatcher *dispatcher,
free(async_command);
}
-RedDispatcher *red_dispatcher_new(QXLInstance *qxl)
+RedDispatcher *red_dispatcher_new(QXLInstance *qxl, int compression_level)
{
RedDispatcher *red_dispatcher;
RedChannel *channel;
@@ -1073,14 +923,11 @@ RedDispatcher *red_dispatcher_new(QXLInstance *qxl)
reds_register_channel(reds, channel);
red_worker_run(worker);
- num_active_workers = 1;
qxl->st->dispatcher = red_dispatcher;
- red_dispatcher->next = dispatchers;
- dispatchers = red_dispatcher;
qxl->st->qif->attache_worker(qxl, &red_dispatcher->base);
- qxl->st->qif->set_compression_level(qxl, calc_compression_level());
+ qxl->st->qif->set_compression_level(qxl, compression_level);
return red_dispatcher;
}
@@ -1102,3 +949,46 @@ void red_dispatcher_clear_pending(RedDispatcher *red_dispatcher, int pending)
clear_bit(pending, &red_dispatcher->pending);
}
+
+gboolean red_dispatcher_get_primary_active(RedDispatcher *dispatcher)
+{
+ return dispatcher->primary_active;
+}
+
+gboolean red_dispatcher_get_allow_client_mouse(RedDispatcher *dispatcher, gint *x_res, gint *y_res)
+{
+ if (dispatcher->use_hardware_cursor) {
+ if (x_res)
+ *x_res = dispatcher->x_res;
+ if (y_res)
+ *y_res = dispatcher->y_res;
+ }
+ return dispatcher->use_hardware_cursor;
+}
+
+void red_dispatcher_on_ic_change(RedDispatcher *dispatcher, spice_image_compression_t ic)
+{
+ RedWorkerMessageSetCompression payload;
+ payload.image_compression = ic;
+ dispatcher_send_message(&dispatcher->dispatcher,
+ RED_WORKER_MESSAGE_SET_COMPRESSION,
+ &payload);
+}
+
+void red_dispatcher_on_sv_change(RedDispatcher *dispatcher, int sv)
+{
+ RedWorkerMessageSetStreamingVideo payload;
+ payload.streaming_video = sv;
+ dispatcher_send_message(&dispatcher->dispatcher,
+ RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
+ &payload);
+}
+
+void red_dispatcher_set_mouse_mode(RedDispatcher *dispatcher, uint32_t mode)
+{
+ RedWorkerMessageSetMouseMode payload;
+ payload.mode = mode;
+ dispatcher_send_message(&dispatcher->dispatcher,
+ RED_WORKER_MESSAGE_SET_MOUSE_MODE,
+ &payload);
+}
diff --git a/server/red-dispatcher.h b/server/red-dispatcher.h
index e74ca176..f594ee67 100644
--- a/server/red-dispatcher.h
+++ b/server/red-dispatcher.h
@@ -25,22 +25,23 @@ typedef struct RedChannelClient RedChannelClient;
typedef struct AsyncCommand AsyncCommand;
-RedDispatcher *red_dispatcher_new(QXLInstance *qxl);
-
-void red_dispatcher_set_mm_time(uint32_t);
-void red_dispatcher_on_ic_change(void);
-void red_dispatcher_on_sv_change(void);
-void red_dispatcher_set_mouse_mode(uint32_t mode);
-void red_dispatcher_on_vm_stop(void);
-void red_dispatcher_on_vm_start(void);
-int red_dispatcher_count(void);
+RedDispatcher *red_dispatcher_new(QXLInstance *qxl, int compression_level);
+
+void red_dispatcher_set_mm_time(RedDispatcher *dispatcher, uint32_t);
+void red_dispatcher_on_ic_change(RedDispatcher *dispatcher, spice_image_compression_t ic);
+void red_dispatcher_on_sv_change(RedDispatcher *dispatcher, int sv);
+void red_dispatcher_set_mouse_mode(RedDispatcher *dispatcher, uint32_t mode);
+void red_dispatcher_set_compression_level(RedDispatcher *dispatcher, int level);
+void red_dispatcher_stop(RedDispatcher *dispatcher);
+void red_dispatcher_start(RedDispatcher *dispatcher);
int red_dispatcher_add_renderer(const char *name);
-uint32_t red_dispatcher_qxl_ram_size(void);
-int red_dispatcher_qxl_count(void);
+uint32_t red_dispatcher_qxl_ram_size(RedDispatcher *dispatcher);
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(VDAgentMonitorsConfig *monitors_config);
+gboolean red_dispatcher_use_client_monitors_config(RedDispatcher *dispatcher);
+gboolean red_dispatcher_client_monitors_config(RedDispatcher *dispatcher, VDAgentMonitorsConfig *monitors_config);
+gboolean red_dispatcher_get_primary_active(RedDispatcher *dispatcher);
+gboolean red_dispatcher_get_allow_client_mouse(RedDispatcher *dispatcher, gint *x_res, gint *y_res);
typedef uint32_t RedWorkerMessage;
diff --git a/server/reds-private.h b/server/reds-private.h
index 0fa03ae2..971526bf 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -226,7 +226,7 @@ struct RedsState {
RedSSLParameters ssl_parameters;
SpiceCoreInterface *core;
-
+ GList *dispatchers;
};
#endif
diff --git a/server/reds.c b/server/reds.c
index 7d1f1efc..1bc0a5fe 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -117,6 +117,13 @@ static void reds_mig_remove_wait_disconnect_client(RedsState *reds, RedClient *c
static void reds_char_device_add_state(RedsState *reds, SpiceCharDeviceState *st);
static void reds_char_device_remove_state(RedsState *reds, SpiceCharDeviceState *st);
static void reds_send_mm_time(RedsState *reds);
+static void reds_on_ic_change(RedsState *reds);
+static void reds_on_sv_change(RedsState *reds);
+static void reds_on_vm_stop(RedsState *reds);
+static void reds_on_vm_start(RedsState *reds);
+static void reds_set_mouse_mode(RedsState *reds, uint32_t mode);
+static uint32_t reds_qxl_ram_size(RedsState *reds);
+static int calc_compression_level(RedsState *reds);
static VDIReadBuf *vdi_port_state_get_read_buf(VDIPortState *state);
static VDIReadBuf *vdi_port_read_buf_ref(VDIReadBuf *buf);
@@ -502,11 +509,16 @@ int reds_get_mouse_mode(RedsState *reds)
static void reds_set_mouse_mode(RedsState *reds, uint32_t mode)
{
+ GList *l;
+
if (reds->mouse_mode == mode) {
return;
}
reds->mouse_mode = mode;
- red_dispatcher_set_mouse_mode(reds->mouse_mode);
+
+ for (l = reds->dispatchers; l != NULL; l = l->next)
+ red_dispatcher_set_mouse_mode(l->data, mode);
+
main_channel_push_mouse_mode(reds->main_channel, reds->mouse_mode, reds->is_client_mouse_allowed);
}
@@ -518,7 +530,7 @@ int reds_get_agent_mouse(RedsState *reds)
static void reds_update_mouse_mode(RedsState *reds)
{
int allowed = 0;
- int qxl_count = red_dispatcher_qxl_count();
+ int qxl_count = g_list_length(reds->dispatchers);
if ((reds->agent_mouse && reds->vdagent) ||
((reds->inputs_channel && inputs_channel_has_tablet(reds->inputs_channel)) &&
@@ -972,7 +984,7 @@ static void reds_on_main_agent_monitors_config(RedsState *reds,
}
monitors_config = (VDAgentMonitorsConfig *)(cmc->buffer + sizeof(*msg_header));
spice_debug("%s: %d\n", __func__, monitors_config->num_of_monitors);
- red_dispatcher_client_monitors_config(monitors_config);
+ reds_client_monitors_config(reds, monitors_config);
reds_client_monitors_config_cleanup(reds);
}
@@ -1603,10 +1615,10 @@ static void reds_handle_main_link(RedsState *reds, RedLinkInfo *link)
}
if (!mig_target) {
- main_channel_push_init(mcc, red_dispatcher_count(),
+ main_channel_push_init(mcc, g_list_length(reds->dispatchers),
reds->mouse_mode, reds->is_client_mouse_allowed,
reds_get_mm_time() - MM_TIME_DELTA,
- red_dispatcher_qxl_ram_size());
+ reds_qxl_ram_size(reds));
if (reds->spice_name)
main_channel_push_name(mcc, reds->spice_name);
if (reds->spice_uuid_is_set)
@@ -1747,10 +1759,10 @@ void reds_on_client_semi_seamless_migrate_complete(RedsState *reds, RedClient *c
mcc = red_client_get_main(client);
// TODO: not doing net test. consider doing it on client_migrate_info
- main_channel_push_init(mcc, red_dispatcher_count(),
+ main_channel_push_init(mcc, g_list_length(reds->dispatchers),
reds->mouse_mode, reds->is_client_mouse_allowed,
reds_get_mm_time() - MM_TIME_DELTA,
- red_dispatcher_qxl_ram_size());
+ reds_qxl_ram_size(reds));
reds_link_mig_target_channels(reds, client);
main_channel_migrate_dst_complete(mcc);
}
@@ -2645,7 +2657,7 @@ static void reds_set_image_compression(RedsState *reds, spice_image_compression_
return;
}
reds->image_compression = val;
- red_dispatcher_on_ic_change();
+ reds_on_ic_change(reds);
}
static void reds_set_one_channel_security(RedsState *reds, int id, uint32_t security)
@@ -3081,7 +3093,8 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *s,
qxl = SPICE_CONTAINEROF(sin, QXLInstance, base);
qxl->st = spice_new0(QXLState, 1);
qxl->st->qif = SPICE_CONTAINEROF(interface, QXLInterface, base);
- qxl->st->dispatcher = red_dispatcher_new(qxl);
+ qxl->st->dispatcher = red_dispatcher_new(qxl, calc_compression_level(s));
+ s->dispatchers = g_list_prepend(s->dispatchers, qxl->st->dispatcher);
} else if (strcmp(interface->type, SPICE_INTERFACE_TABLET) == 0) {
SpiceTabletInstance *tablet = SPICE_CONTAINEROF(sin, SpiceTabletInstance, base);
@@ -3665,7 +3678,7 @@ SPICE_GNUC_VISIBLE int spice_server_set_streaming_video(SpiceServer *s, int valu
value != SPICE_STREAM_VIDEO_FILTER)
return -1;
s->streaming_video = value;
- red_dispatcher_on_sv_change();
+ reds_on_sv_change(s);
return 0;
}
@@ -3879,7 +3892,7 @@ SPICE_GNUC_VISIBLE void spice_server_vm_start(SpiceServer *s)
st_item = SPICE_CONTAINEROF(item, SpiceCharDeviceStateItem, link);
spice_char_device_start(st_item->st);
}
- red_dispatcher_on_vm_start();
+ reds_on_vm_start(s);
}
SPICE_GNUC_VISIBLE void spice_server_vm_stop(SpiceServer *s)
@@ -3894,7 +3907,7 @@ SPICE_GNUC_VISIBLE void spice_server_vm_stop(SpiceServer *s)
st_item = SPICE_CONTAINEROF(item, SpiceCharDeviceStateItem, link);
spice_char_device_stop(st_item->st);
}
- red_dispatcher_on_vm_stop();
+ reds_on_vm_stop(s);
}
SPICE_GNUC_VISIBLE void spice_server_set_seamless_migration(SpiceServer *s, int enable)
@@ -3924,3 +3937,136 @@ SpiceCoreInterface* reds_get_core_interface(RedsState *reds)
{
return reds->core;
}
+
+void reds_update_client_mouse_allowed(RedsState *reds)
+{
+ static int allowed = FALSE;
+ int allow_now = FALSE;
+ int x_res = 0;
+ int y_res = 0;
+ GList *l;
+ int num_active_workers = g_list_length(reds->dispatchers);
+
+ if (num_active_workers > 0) {
+ allow_now = TRUE;
+ for (l = reds->dispatchers; l != NULL && allow_now; l = l->next) {
+
+ RedDispatcher *now = l->data;
+ if (red_dispatcher_get_primary_active(now)) {
+ allow_now = red_dispatcher_get_allow_client_mouse(now, &x_res, &y_res);
+ break;
+ }
+ }
+ }
+
+ if (allow_now || allow_now != allowed) {
+ allowed = allow_now;
+ reds_set_client_mouse_allowed(reds, allowed, x_res, y_res);
+ }
+}
+
+gboolean reds_use_client_monitors_config(RedsState *reds)
+{
+ GList *l;
+
+ if (reds->dispatchers == NULL) {
+ return FALSE;
+ }
+
+ for (l = reds->dispatchers; l != NULL ; l = l->next) {
+ RedDispatcher *now = l->data;
+
+ if (!red_dispatcher_use_client_monitors_config(now))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig *monitors_config)
+{
+ GList *l;
+
+ for (l = reds->dispatchers; l != NULL; l = l->next) {
+ RedDispatcher *now = l->data;
+ if (!red_dispatcher_client_monitors_config(now, monitors_config)) {
+ /* this is a normal condition, some qemu devices might not implement it */
+ spice_debug("QXLInterface::client_monitors_config failed\n");
+ }
+ }
+}
+
+void reds_set_mm_time(RedsState *reds, uint32_t mm_time)
+{
+ GList *l;
+
+ for (l = reds->dispatchers; l != NULL; l = l->next) {
+ RedDispatcher *now = l->data;
+ red_dispatcher_set_mm_time(now, mm_time);
+ }
+}
+
+static int calc_compression_level(RedsState *reds)
+{
+ spice_return_val_if_fail(reds_get_streaming_video(reds) != STREAM_VIDEO_INVALID, -1);
+
+ if ((reds_get_streaming_video(reds) != STREAM_VIDEO_OFF) ||
+ (spice_server_get_image_compression(reds) != SPICE_IMAGE_COMPRESS_QUIC)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+void reds_on_ic_change(RedsState *reds)
+{
+ int compression_level = calc_compression_level(reds);
+ GList *l;
+
+ for (l = reds->dispatchers; l != NULL; l = l->next) {
+ RedDispatcher *d = l->data;
+ red_dispatcher_set_compression_level(d, compression_level);
+ red_dispatcher_on_ic_change(d, spice_server_get_image_compression(reds));
+ }
+}
+
+void reds_on_sv_change(RedsState *reds)
+{
+ int compression_level = calc_compression_level(reds);
+ GList *l;
+
+ for (l = reds->dispatchers; l != NULL; l = l->next) {
+ RedDispatcher *d = l->data;
+ red_dispatcher_set_compression_level(d, compression_level);
+ red_dispatcher_on_sv_change(d, reds_get_streaming_video(reds));
+ }
+}
+
+void reds_on_vm_stop(RedsState *reds)
+{
+ GList *l;
+
+ spice_debug(NULL);
+ for (l = reds->dispatchers; l != NULL; l = l->next)
+ red_dispatcher_stop(l->data);
+}
+
+void reds_on_vm_start(RedsState *reds)
+{
+ GList *l;
+
+ spice_debug(NULL);
+ for (l = reds->dispatchers; l != NULL; l = l->next)
+ red_dispatcher_start(l->data);
+}
+
+uint32_t reds_qxl_ram_size(RedsState *reds)
+{
+ RedDispatcher *first;
+ if (!reds->dispatchers) {
+ return 0;
+ }
+
+ first = reds->dispatchers->data;
+ return red_dispatcher_qxl_ram_size(first);
+}
+
diff --git a/server/reds.h b/server/reds.h
index 936ef642..e89c0533 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -110,5 +110,9 @@ uint32_t reds_get_streaming_video(RedsState *reds);
spice_wan_compression_t reds_get_jpeg_state(RedsState *reds);
spice_wan_compression_t reds_get_zlib_glz_state(RedsState *reds);
SpiceCoreInterface* reds_get_core_interface(RedsState *reds);
+void reds_update_client_mouse_allowed(RedsState *reds);
+gboolean reds_use_client_monitors_config(RedsState *reds);
+void reds_client_monitors_config(RedsState *reds, VDAgentMonitorsConfig *monitors_config);
+void reds_set_mm_time(RedsState *reds, uint32_t mm_time);
#endif