> With a SPICE_DISPLAY_CAP_MONITORS_CONFIG capable client, the client needs to > know what part of the primary to use for each monitor. If the guest driver > does not support this, the server sends messages to the client for a > single monitor spanning the entire primary. > > As soon as the guest calls spice_qxl_monitors_config_async once, we set > the red_worker driver_has_monitors_config flag and stop doing this. > > This is a problem when the driver gets unloaded, for example after a reboot > or when switching to a text vc with usermode mode-setting under Linux. > > To reproduce this start a multi-mon capable Linux guest which uses > usermode mode-setting and then once X has started switch to a text vc. Note > how the client window does not only not resize, if you try to resize it > manually you always keep blackborders since the aspect is wrong. > > This patch is the spice-server side of fixing this, it adds a new > spice_qxl_driver_unload method which clears the driver_has_monitors_config > flag. > > The other patch needed to fix this is in qemu, and will calls this new method > from qxl_enter_vga_mode. ACK, good catch. > > Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> > --- > server/red_dispatcher.c | 15 +++++++++++++++ > server/red_dispatcher.h | 3 +++ > server/red_worker.c | 12 ++++++++++++ > server/red_worker.h | 1 + > server/spice-server.syms | 5 +++++ > server/spice.h | 4 +++- > 6 files changed, 39 insertions(+), 1 deletion(-) > > diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c > index 97e9737..e58d693 100644 > --- a/server/red_dispatcher.c > +++ b/server/red_dispatcher.c > @@ -705,6 +705,15 @@ static void > red_dispatcher_monitors_config_async(RedDispatcher *dispatcher, > dispatcher_send_message(&dispatcher->dispatcher, message, &payload); > } > > +static void red_dispatcher_driver_unload(RedDispatcher *dispatcher) > +{ > + RedWorkerMessageDriverUnload payload; > + > + dispatcher_send_message(&dispatcher->dispatcher, > + RED_WORKER_MESSAGE_DRIVER_UNLOAD, > + &payload); > +} > + > static void red_dispatcher_stop(RedDispatcher *dispatcher) > { > RedWorkerMessageStop payload; > @@ -994,6 +1003,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_driver_unload(QXLInstance *instance) > +{ > + red_dispatcher_driver_unload(instance->st->dispatcher); > +} > + > void red_dispatcher_async_complete(struct RedDispatcher *dispatcher, > AsyncCommand *async_command) > { > diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h > index 17eeb29..4d0d2a8 100644 > --- a/server/red_dispatcher.h > +++ b/server/red_dispatcher.h > @@ -201,4 +201,7 @@ typedef struct RedWorkerMessageMonitorsConfigAsync { > int group_id; > } RedWorkerMessageMonitorsConfigAsync; > > +typedef struct RedWorkerMessageDriverUnload { > +} RedWorkerMessageDriverUnload; > + > #endif > diff --git a/server/red_worker.c b/server/red_worker.c > index 4842ad6..a127ca7 100644 > --- a/server/red_worker.c > +++ b/server/red_worker.c > @@ -11535,6 +11535,13 @@ void handle_dev_reset_memslots(void *opaque, void > *payload) > red_memslot_info_reset(&worker->mem_slots); > } > > +void handle_dev_driver_unload(void *opaque, void *payload) > +{ > + RedWorker *worker = opaque; > + > + worker->driver_has_monitors_config = 0; > +} > + > void handle_dev_loadvm_commands(void *opaque, void *payload) > { > RedWorkerMessageLoadvmCommands *msg = payload; > @@ -11758,6 +11765,11 @@ static void register_callbacks(Dispatcher > *dispatcher) > handle_dev_monitors_config_async, > sizeof(RedWorkerMessageMonitorsConfigAsync), > DISPATCHER_ASYNC); > + dispatcher_register_handler(dispatcher, > + RED_WORKER_MESSAGE_DRIVER_UNLOAD, > + handle_dev_driver_unload, > + sizeof(RedWorkerMessageDriverUnload), > + DISPATCHER_NONE); > } > > > diff --git a/server/red_worker.h b/server/red_worker.h > index 6c5b839..796b090 100644 > --- a/server/red_worker.h > +++ b/server/red_worker.h > @@ -86,6 +86,7 @@ enum { > RED_WORKER_MESSAGE_CURSOR_CHANNEL_CREATE, > > RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC, > + RED_WORKER_MESSAGE_DRIVER_UNLOAD, > > RED_WORKER_MESSAGE_COUNT // LAST > }; > diff --git a/server/spice-server.syms b/server/spice-server.syms > index 2091fe0..53edd17 100644 > --- a/server/spice-server.syms > +++ b/server/spice-server.syms > @@ -135,3 +135,8 @@ SPICE_SERVER_0.12.2 { > global: > spice_server_port_event; > } SPICE_SERVER_0.11.4; > + > +SPICE_SERVER_0.12.3 { > +global: > + spice_qxl_driver_unload; > +} SPICE_SERVER_0.12.2; > diff --git a/server/spice.h b/server/spice.h > index 45b7408..18bd11a 100644 > --- a/server/spice.h > +++ b/server/spice.h > @@ -23,7 +23,7 @@ > #include <spice/qxl_dev.h> > #include <spice/vd_agent.h> > > -#define SPICE_SERVER_VERSION 0x000c02 /* release 0.12.2 */ > +#define SPICE_SERVER_VERSION 0x000c03 /* release 0.12.3 */ > > /* interface base type */ > > @@ -167,6 +167,8 @@ void spice_qxl_flush_surfaces_async(QXLInstance > *instance, uint64_t cookie); > /* since spice 0.12.0 */ > void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL > monitors_config, > int group_id, uint64_t cookie); > +/* since spice 0.12.3 */ > +void spice_qxl_driver_unload(QXLInstance *instance); > > typedef struct QXLDrawArea { > uint8_t *buf; > -- > 1.8.2 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel