diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c index 74adaa2d..a2ef2263 100644 --- a/server/red_dispatcher.c +++ b/server/red_dispatcher.c @@ -66,6 +66,7 @@ struct RedDispatcher { Ring async_commands; pthread_mutex_t async_lock; QXLDevSurfaceCreate surface_create; + unsigned int max_monitors; }; extern uint32_t streaming_video; @@ -693,6 +694,7 @@ static void red_dispatcher_monitors_config_async(RedDispatcher *dispatcher, payload.base.cmd = async_command_alloc(dispatcher, message, cookie); payload.monitors_config = monitors_config; payload.group_id = group_id; + payload.max_monitors = dispatcher->max_monitors; dispatcher_send_message(&dispatcher->dispatcher, message, &payload); } @@ -986,6 +988,12 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors red_dispatcher_monitors_config_async(instance->st->dispatcher, monitors_config, group_id, cookie); } +SPICE_GNUC_VISIBLE +void spice_qxl_set_max_monitors(QXLInstance *instance, unsigned int max_monitors) +{ + instance->st->dispatcher->max_monitors = MAX(1u, max_monitors); +} + SPICE_GNUC_VISIBLE void spice_qxl_driver_unload(QXLInstance *instance) { @@ -1110,6 +1118,8 @@ void red_dispatcher_init(QXLInstance *qxl) red_dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait; red_dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands; + red_dispatcher->max_monitors = UINT_MAX; + qxl->st->qif->get_init_info(qxl, &init_info); init_data.memslot_id_bits = init_info.memslot_id_bits; diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h index 907b7c7c..70b8a628 100644 --- a/server/red_dispatcher.h +++ b/server/red_dispatcher.h @@ -200,6 +200,7 @@ typedef struct RedWorkerMessageMonitorsConfigAsync { RedWorkerMessageAsync base; QXLPHYSICAL monitors_config; int group_id; + unsigned int max_monitors; } RedWorkerMessageMonitorsConfigAsync; typedef struct RedWorkerMessageDriverUnload { diff --git a/server/red_worker.c b/server/red_worker.c index 515262d6..f3d8ad93 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -11217,11 +11217,13 @@ static inline void red_monitors_config_item_add(DisplayChannelClient *dcc) } static void worker_update_monitors_config(RedWorker *worker, - QXLMonitorsConfig *dev_monitors_config) + QXLMonitorsConfig *dev_monitors_config, + unsigned int max_monitors) { int heads_size; MonitorsConfig *monitors_config; int i; + unsigned int count = MIN(dev_monitors_config->count, max_monitors); monitors_config_decref(worker->monitors_config); @@ -11235,13 +11237,13 @@ static void worker_update_monitors_config(RedWorker *worker, dev_monitors_config->heads[i].width, dev_monitors_config->heads[i].height); } - heads_size = dev_monitors_config->count * sizeof(QXLHead); + heads_size = count * sizeof(QXLHead); worker->monitors_config = monitors_config = spice_malloc(sizeof(*monitors_config) + heads_size); monitors_config->refs = 1; monitors_config->worker = worker; - monitors_config->count = dev_monitors_config->count; - monitors_config->max_allowed = dev_monitors_config->max_allowed; + monitors_config->count = count; + monitors_config->max_allowed = MIN(dev_monitors_config->max_allowed, max_monitors); memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size); } @@ -11651,7 +11653,7 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload) dev_monitors_config->max_allowed); return; } - worker_update_monitors_config(worker, dev_monitors_config); + worker_update_monitors_config(worker, dev_monitors_config, msg->max_monitors); red_worker_push_monitors_config(worker); } diff --git a/server/spice-qxl.h b/server/spice-qxl.h index 31ff742f..dd49a860 100644 --- a/server/spice-qxl.h +++ b/server/spice-qxl.h @@ -97,6 +97,9 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors int group_id, uint64_t cookie); /* since spice 0.12.3 */ void spice_qxl_driver_unload(QXLInstance *instance); +/* since spice 0.12.6 */ +void spice_qxl_set_max_monitors(QXLInstance *instance, + unsigned int max_monitors); typedef struct QXLDrawArea { uint8_t *buf; diff --git a/server/spice-server.syms b/server/spice-server.syms index 21938112..3c7d9456 100644 --- a/server/spice-server.syms +++ b/server/spice-server.syms @@ -153,3 +153,8 @@ global: spice_server_get_best_record_rate; spice_server_set_record_rate; } SPICE_SERVER_0.12.4; + +SPICE_SERVER_0.12.6 { +global: + spice_qxl_set_max_monitors; +} SPICE_SERVER_0.12.5;