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. --- 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 -- 2.5.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel