> > From: Jonathon Jongsma <jjongsma@xxxxxxxxxx> > > 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. This patch has two main problems: 1- is really big; 2- code is broken. Due to 1 I cannot understand why 2, I'll try to split the patch. Frediano > --- > server/agent-msg-filter.c | 3 +- > server/red-dispatcher.c | 229 > +++++++++++++--------------------------------- > server/red-dispatcher.h | 26 +++--- > server/reds-private.h | 2 +- > server/reds.c | 170 +++++++++++++++++++++++++++++++--- > server/reds.h | 4 + > 6 files changed, 243 insertions(+), 191 deletions(-) > > diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c > index 1c1c01f..069822b 100644 > --- a/server/agent-msg-filter.c > +++ b/server/agent-msg-filter.c > @@ -24,6 +24,7 @@ > #include <string.h> > #include "red-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 dce20c4..ead598d 100644 > --- a/server/red-dispatcher.c > +++ b/server/red-dispatcher.c > @@ -39,7 +39,6 @@ > > #include "red-dispatcher.h" > > -static int num_active_workers = 0; > > struct AsyncCommand { > RingItem link; > @@ -56,15 +55,12 @@ 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; > unsigned int max_monitors; > }; > > -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; > @@ -194,42 +190,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) > @@ -246,37 +206,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"); > - } > - 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, > @@ -391,7 +333,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 > @@ -443,7 +385,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)); > } > > @@ -619,7 +561,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; > > @@ -667,7 +609,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; > > @@ -702,103 +644,20 @@ static void qxl_worker_loadvm_commands(QXLWorker > *qxl_worker, > red_dispatcher_loadvm_commands((RedDispatcher*)qxl_worker, ext, count); > } > > -static inline int calc_compression_level(void) > +void red_dispatcher_set_mm_time(RedDispatcher *dispatcher, uint32_t mm_time) > { > - spice_assert(reds_get_streaming_video(reds) != > SPICE_STREAM_VIDEO_INVALID); > - > - if ((reds_get_streaming_video(reds) != SPICE_STREAM_VIDEO_OFF) || > - (spice_server_get_image_compression(reds) != > SPICE_IMAGE_COMPRESSION_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; > - } > -} > - > -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; > - } > + dispatcher->qxl->st->qif->set_mm_time(dispatcher->qxl, mm_time); > } > > -void red_dispatcher_set_mouse_mode(uint32_t mode) > +void red_dispatcher_set_compression_level(RedDispatcher *dispatcher, int > level) > { > - 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; > - } > + dispatcher->qxl->st->qif->set_compression_level(dispatcher->qxl, level); > } > > -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; > } > > @@ -1049,7 +908,7 @@ void red_dispatcher_async_complete(struct RedDispatcher > *dispatcher, > free(async_command); > } > > -void red_dispatcher_init(QXLInstance *qxl) > +void red_dispatcher_init(QXLInstance *qxl, int compression_level) > { > RedDispatcher *red_dispatcher; > RedChannel *channel; > @@ -1116,14 +975,11 @@ void red_dispatcher_init(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); > } > > struct Dispatcher *red_dispatcher_get_dispatcher(RedDispatcher > *red_dispatcher) > @@ -1143,3 +999,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, > SpiceImageCompression 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 11a4f2a..e62092f 100644 > --- a/server/red-dispatcher.h > +++ b/server/red-dispatcher.h > @@ -24,20 +24,22 @@ typedef struct RedDispatcher RedDispatcher; > > typedef struct AsyncCommand AsyncCommand; > > -void red_dispatcher_init(QXLInstance *qxl); > - > -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); > -uint32_t red_dispatcher_qxl_ram_size(void); > -int red_dispatcher_qxl_count(void); > +void red_dispatcher_init(QXLInstance *qxl, int compression_level); > + > +void red_dispatcher_set_mm_time(RedDispatcher *dispatcher, uint32_t); > +void red_dispatcher_on_ic_change(RedDispatcher *dispatcher, > SpiceImageCompression 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); > +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 2272d4c..c214091 100644 > --- a/server/reds-private.h > +++ b/server/reds-private.h > @@ -241,7 +241,7 @@ struct RedsState { > > RedSSLParameters ssl_parameters; > SpiceCoreInterfaceInternal *core; > - > + GList *dispatchers; > }; > > #endif > diff --git a/server/reds.c b/server/reds.c > index 81a9220..eec8086 100644 > --- a/server/reds.c > +++ b/server/reds.c > @@ -172,6 +172,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); > @@ -556,11 +563,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); > } > > @@ -572,7 +584,7 @@ gboolean reds_get_agent_mouse(const 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) || > (inputs_channel_has_tablet(reds->inputs_channel) && qxl_count == 1)) > { > @@ -1025,7 +1037,7 @@ static void > reds_on_main_agent_monitors_config(RedsState *reds, > } > monitors_config = (VDAgentMonitorsConfig *)(cmc->buffer + > sizeof(*msg_header)); > spice_debug("%s: %d", __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); > } > > @@ -1669,10 +1681,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) > @@ -1815,10 +1827,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); > } > @@ -2769,7 +2781,7 @@ static void reds_set_image_compression(RedsState *reds, > SpiceImageCompression va > 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) > @@ -3196,7 +3208,8 @@ SPICE_GNUC_VISIBLE int > spice_server_add_interface(SpiceServer *s, > pthread_mutex_init(&qxl->st->scanout_mutex, NULL); > qxl->st->scanout.drm_dma_buf_fd = -1; > qxl->st->qif = SPICE_CONTAINEROF(interface, QXLInterface, base); > - red_dispatcher_init(qxl); > + red_dispatcher_init(qxl, calc_compression_level(reds)); > + reds->dispatchers = g_list_prepend(reds->dispatchers, > qxl->st->dispatcher); > > } else if (strcmp(interface->type, SPICE_INTERFACE_TABLET) == 0) { > SpiceTabletInstance *tablet = SPICE_CONTAINEROF(sin, > SpiceTabletInstance, base); > @@ -3791,7 +3804,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(reds); > return 0; > } > > @@ -3991,7 +4004,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(reds); > } > > SPICE_GNUC_VISIBLE void spice_server_vm_stop(SpiceServer *s) > @@ -4006,7 +4019,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(reds); > } > > SPICE_GNUC_VISIBLE void spice_server_set_seamless_migration(SpiceServer *s, > int enable) > @@ -4043,3 +4056,136 @@ SpiceCoreInterfaceInternal* > 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_assert(reds_get_streaming_video(reds) != > SPICE_STREAM_VIDEO_INVALID); > + > + if ((reds_get_streaming_video(reds) != SPICE_STREAM_VIDEO_OFF) || > + (spice_server_get_image_compression(reds) != > SPICE_IMAGE_COMPRESSION_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 6caed73..686aaac 100644 > --- a/server/reds.h > +++ b/server/reds.h > @@ -111,5 +111,9 @@ uint32_t reds_get_streaming_video(const RedsState *reds); > spice_wan_compression_t reds_get_jpeg_state(const RedsState *reds); > spice_wan_compression_t reds_get_zlib_glz_state(const RedsState *reds); > SpiceCoreInterfaceInternal* 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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel