提交 9fa03286 编写于 作者: G Gerd Hoffmann

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: NGerd Hoffmann <kraxel@redhat.com>
上级 35b2122d
...@@ -2037,8 +2037,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) ...@@ -2037,8 +2037,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]"); qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
qxl->ssd.qxl.base.sif = &qxl_interface.base; qxl->ssd.qxl.base.sif = &qxl_interface.base;
qxl->ssd.qxl.id = qxl->id; if (qemu_spice_add_display_interface(&qxl->ssd.qxl, qxl->vga.con) != 0) {
if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) {
error_report("qxl interface %d.%d not supported by spice-server", error_report("qxl interface %d.%d not supported by spice-server",
SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR); SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
return -1; return -1;
......
...@@ -27,14 +27,15 @@ ...@@ -27,14 +27,15 @@
#include "monitor/monitor.h" #include "monitor/monitor.h"
extern int using_spice; extern int using_spice;
extern int spice_displays;
void qemu_spice_init(void); void qemu_spice_init(void);
void qemu_spice_input_init(void); void qemu_spice_input_init(void);
void qemu_spice_audio_init(void); void qemu_spice_audio_init(void);
void qemu_spice_display_init(DisplayState *ds); void qemu_spice_display_init(void);
int qemu_spice_display_add_client(int csock, int skipauth, int tls); int qemu_spice_display_add_client(int csock, int skipauth, int tls);
int qemu_spice_add_interface(SpiceBaseInstance *sin); int qemu_spice_add_interface(SpiceBaseInstance *sin);
bool qemu_spice_have_display_interface(QemuConsole *con);
int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con);
int qemu_spice_set_passwd(const char *passwd, int qemu_spice_set_passwd(const char *passwd,
bool fail_if_connected, bool disconnect_if_connected); bool fail_if_connected, bool disconnect_if_connected);
int qemu_spice_set_pw_expire(time_t expires); int qemu_spice_set_pw_expire(time_t expires);
......
...@@ -48,7 +48,6 @@ static char *auth_passwd; ...@@ -48,7 +48,6 @@ static char *auth_passwd;
static time_t auth_expires = TIME_MAX; static time_t auth_expires = TIME_MAX;
static int spice_migration_completed; static int spice_migration_completed;
int using_spice = 0; int using_spice = 0;
int spice_displays;
static QemuThread me; static QemuThread me;
...@@ -837,11 +836,28 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin) ...@@ -837,11 +836,28 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
qemu_add_vm_change_state_handler(vm_change_state_handler, NULL); qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
} }
if (strcmp(sin->sif->type, SPICE_INTERFACE_QXL) == 0) { return spice_server_add_interface(spice_server, sin);
spice_displays++; }
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;
}
return spice_server_add_interface(spice_server, sin); 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) static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn)
......
...@@ -612,21 +612,38 @@ static const DisplayChangeListenerOps display_listener_ops = { ...@@ -612,21 +612,38 @@ static const DisplayChangeListenerOps display_listener_ops = {
.dpy_refresh = display_refresh, .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); SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
qemu_spice_display_init_common(ssd); qemu_spice_display_init_common(ssd);
ssd->qxl.base.sif = &dpy_interface.base; 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); assert(ssd->worker);
qemu_spice_create_host_memslot(ssd); qemu_spice_create_host_memslot(ssd);
ssd->dcl.ops = &display_listener_ops; ssd->dcl.ops = &display_listener_ops;
ssd->dcl.con = qemu_console_lookup_by_index(0); ssd->dcl.con = con;
register_displaychangelistener(&ssd->dcl); register_displaychangelistener(&ssd->dcl);
qemu_spice_create_host_primary(ssd); 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);
}
}
...@@ -4315,8 +4315,8 @@ int main(int argc, char **argv, char **envp) ...@@ -4315,8 +4315,8 @@ int main(int argc, char **argv, char **envp)
} }
#endif #endif
#ifdef CONFIG_SPICE #ifdef CONFIG_SPICE
if (using_spice && !spice_displays) { if (using_spice) {
qemu_spice_display_init(ds); qemu_spice_display_init();
} }
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册