spice: fix multihead support

This patch fixes spice display initialization to handle
multihead properly.

spice-core now keeps track of which QemuConsole has a spice
display channel attached to it and which has not.  It also
manages display channel ids.

spice-display looks at all QemuConsoles and will pick up any
graphic console not yet bound to a spice channel (which in practice
are all non-qxl graphic devices).

Result is that
 (a) you'll get a spice client window for each graphical device
     now (first only without this patch), and
 (b) mixing qxl and non-qxl vga cards works properly.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2013-10-11 22:39:59 +02:00
parent 35b2122db4
commit 9fa032866d
5 changed files with 47 additions and 14 deletions

View file

@ -48,7 +48,6 @@ static char *auth_passwd;
static time_t auth_expires = TIME_MAX;
static int spice_migration_completed;
int using_spice = 0;
int spice_displays;
static QemuThread me;
@ -837,13 +836,30 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
}
if (strcmp(sin->sif->type, SPICE_INTERFACE_QXL) == 0) {
spice_displays++;
}
return spice_server_add_interface(spice_server, sin);
}
static GSList *spice_consoles;
static int display_id;
bool qemu_spice_have_display_interface(QemuConsole *con)
{
if (g_slist_find(spice_consoles, con)) {
return true;
}
return false;
}
int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con)
{
if (g_slist_find(spice_consoles, con)) {
return -1;
}
qxlin->id = display_id++;
spice_consoles = g_slist_append(spice_consoles, con);
return qemu_spice_add_interface(&qxlin->base);
}
static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn)
{
time_t lifetime, now = time(NULL);

View file

@ -612,21 +612,38 @@ static const DisplayChangeListenerOps display_listener_ops = {
.dpy_refresh = display_refresh,
};
void qemu_spice_display_init(DisplayState *ds)
static void qemu_spice_display_init_one(QemuConsole *con)
{
SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
qemu_spice_display_init_common(ssd);
ssd->qxl.base.sif = &dpy_interface.base;
qemu_spice_add_interface(&ssd->qxl.base);
qemu_spice_add_display_interface(&ssd->qxl, con);
assert(ssd->worker);
qemu_spice_create_host_memslot(ssd);
ssd->dcl.ops = &display_listener_ops;
ssd->dcl.con = qemu_console_lookup_by_index(0);
ssd->dcl.con = con;
register_displaychangelistener(&ssd->dcl);
qemu_spice_create_host_primary(ssd);
}
void qemu_spice_display_init(void)
{
QemuConsole *con;
int i;
for (i = 0;; i++) {
con = qemu_console_lookup_by_index(i);
if (!con || !qemu_console_is_graphic(con)) {
break;
}
if (qemu_spice_have_display_interface(con)) {
continue;
}
qemu_spice_display_init_one(con);
}
}