On Tue, Jul 17, 2012 at 09:24:58PM +0200, Marc-André Lureau wrote: > Rely on spice-gtk display channel monitors property to manage > displays. The same display channel may now provide several monitors, > the SpiceDisplay widget must be told which monitor to display > --- > src/virt-viewer-display-spice.c | 20 +++++---- > src/virt-viewer-display-spice.h | 2 +- > src/virt-viewer-session-spice.c | 89 ++++++++++++++++++++++++++++++++++----- > 3 files changed, 92 insertions(+), 19 deletions(-) > > diff --git a/src/virt-viewer-display-spice.c b/src/virt-viewer-display-spice.c > index 53430dd..d06e5cf 100644 > --- a/src/virt-viewer-display-spice.c > +++ b/src/virt-viewer-display-spice.c > @@ -172,7 +172,7 @@ virt_viewer_display_spice_size_allocate(VirtViewerDisplaySpice *self, > { > gdouble dw = allocation->width, dh = allocation->height; > guint zoom = 100; > - guint channelid; > + guint nth; > > if (virt_viewer_display_get_auto_resize(VIRT_VIEWER_DISPLAY(self)) == FALSE) > return; > @@ -187,13 +187,11 @@ virt_viewer_display_spice_size_allocate(VirtViewerDisplaySpice *self, > dh /= ((double)zoom / 100.0); > } > > - g_object_get(self->priv->channel, "channel-id", &channelid, NULL); > + g_object_get(self, "nth-display", &nth, NULL); > > SpiceMainChannel *main_channel = virt_viewer_session_spice_get_main_channel( > VIRT_VIEWER_SESSION_SPICE(virt_viewer_display_get_session(VIRT_VIEWER_DISPLAY(self)))); > - spice_main_set_display(main_channel, > - channelid, > - 0, 0, dw, dh); > + spice_main_set_display(main_channel, nth, 0, 0, dw, dh); > } > > static void > @@ -212,7 +210,8 @@ enable_accel_changed(VirtViewerApp *app, > > GtkWidget * > virt_viewer_display_spice_new(VirtViewerSessionSpice *session, > - SpiceChannel *channel) > + SpiceChannel *channel, > + gint monitorid) > { > VirtViewerDisplaySpice *self; > VirtViewerApp *app; > @@ -222,15 +221,20 @@ virt_viewer_display_spice_new(VirtViewerSessionSpice *session, > g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), NULL); > > g_object_get(channel, "channel-id", &channelid, NULL); > + // We don't allow monitorid != 0 && channelid != 0 > + g_return_val_if_fail(channelid == 0 || monitorid == 0, NULL); > > self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_SPICE, > "session", session, > - "nth-display", channelid, > + // either monitorid is always 0 or channelid > + // is, we can't have display (0, 2) and (2, 0) > + // for example I would have put the comment together with the comment above the g_return_val_if_fail, but that's not important ;) Christophe > + "nth-display", channelid + monitorid, > NULL); > self->priv->channel = channel; > > g_object_get(session, "spice-session", &s, NULL); > - self->priv->display = spice_display_new(s, channelid); > + self->priv->display = spice_display_new_with_monitor(s, channelid, monitorid); > g_object_unref(s); > > virt_viewer_signal_connect_object(self->priv->display, "notify::ready", > diff --git a/src/virt-viewer-display-spice.h b/src/virt-viewer-display-spice.h > index 701ed85..c2013ec 100644 > --- a/src/virt-viewer-display-spice.h > +++ b/src/virt-viewer-display-spice.h > @@ -66,7 +66,7 @@ struct _VirtViewerDisplaySpiceClass { > > GType virt_viewer_display_spice_get_type(void); > > -GtkWidget* virt_viewer_display_spice_new(VirtViewerSessionSpice *session, SpiceChannel *channel); > +GtkWidget* virt_viewer_display_spice_new(VirtViewerSessionSpice *session, SpiceChannel *channel, gint monitorid); > > G_END_DECLS > > diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c > index 6577237..a728cb1 100644 > --- a/src/virt-viewer-session-spice.c > +++ b/src/virt-viewer-session-spice.c > @@ -33,6 +33,7 @@ > #include "virt-viewer-session-spice.h" > #include "virt-viewer-display-spice.h" > #include "virt-viewer-auth.h" > +#include "virt-glib-compat.h" > > #if !GLIB_CHECK_VERSION(2, 26, 0) > #include "gbinding.h" > @@ -414,6 +415,78 @@ agent_connected_changed(SpiceChannel *cmain, > } > > static void > +destroy_display(gpointer data) > +{ > + VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(data); > + VirtViewerSession *session = virt_viewer_display_get_session(display); > + > + DEBUG_LOG("Destroying spice display %p", display); > + virt_viewer_session_remove_display(session, display); > + g_object_unref(display); > +} > + > +static void > +virt_viewer_session_spice_display_monitors(SpiceChannel *channel, > + GParamSpec *pspec G_GNUC_UNUSED, > + VirtViewerSessionSpice *self) > +{ > + GArray *monitors = NULL; > + GPtrArray *displays = NULL; > + GtkWidget *display; > + guint i, monitors_max; > + > + g_object_get(channel, > + "monitors", &monitors, > + "monitors-max", &monitors_max, > + NULL); > + g_return_if_fail(monitors != NULL); > + g_return_if_fail(monitors->len <= monitors_max); > + > + displays = g_object_get_data(G_OBJECT(channel), "virt-viewer-displays"); > + if (displays == NULL) { > + displays = g_ptr_array_new(); > + g_ptr_array_set_free_func(displays, destroy_display); > + g_object_set_data_full(G_OBJECT(channel), "virt-viewer-displays", > + displays, (GDestroyNotify)g_ptr_array_unref); > + } > + > + g_ptr_array_set_size(displays, monitors_max); > + > + for (i = 0; i < monitors_max; i++) { > + display = g_ptr_array_index(displays, i); > + if (display == NULL) { > + display = virt_viewer_display_spice_new(self, channel, i); > + DEBUG_LOG("creating spice display (#:%d)", i); > + g_ptr_array_index(displays, i) = g_object_ref(display); > + } > + > + g_object_freeze_notify(G_OBJECT(display)); > + virt_viewer_display_set_enabled(VIRT_VIEWER_DISPLAY(display), FALSE); > + virt_viewer_session_add_display(VIRT_VIEWER_SESSION(self), > + VIRT_VIEWER_DISPLAY(display)); > + } > + > + for (i = 0; i < monitors->len; i++) { > + SpiceDisplayMonitorConfig *monitor = &g_array_index(monitors, SpiceDisplayMonitorConfig, i); > + display = g_ptr_array_index(displays, monitor->id); > + g_return_if_fail(display != NULL); > + > + if (monitor->width == 0 || monitor->width == 0) > + continue; > + > + virt_viewer_display_set_enabled(VIRT_VIEWER_DISPLAY(display), TRUE); > + virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(display), > + monitor->width, monitor->height); > + } > + > + for (i = 0; i < monitors_max; i++) > + g_object_thaw_notify(g_ptr_array_index(displays, i)); > + > + g_clear_pointer(&monitors, g_array_unref); > + > +} > + > +static void > virt_viewer_session_spice_channel_new(SpiceSession *s, > SpiceChannel *channel, > VirtViewerSession *session) > @@ -441,20 +514,17 @@ virt_viewer_session_spice_channel_new(SpiceSession *s, > > g_signal_connect(channel, "notify::agent-connected", G_CALLBACK(agent_connected_changed), self); > agent_connected_changed(channel, NULL, self); > + > + g_signal_emit_by_name(session, "session-connected"); > } > > if (SPICE_IS_DISPLAY_CHANNEL(channel)) { > - GtkWidget *display; > - > - g_signal_emit_by_name(session, "session-connected"); > + g_signal_emit_by_name(session, "session-initialized"); > > - DEBUG_LOG("new display channel (#%d)", id); > - display = virt_viewer_display_spice_new(self, channel); > - g_object_set_data(G_OBJECT(channel), "virt-viewer-display", display); > - virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session), > - VIRT_VIEWER_DISPLAY(display)); > + g_signal_connect(channel, "notify::monitors", > + G_CALLBACK(virt_viewer_session_spice_display_monitors), self); > > - g_signal_emit_by_name(session, "session-initialized"); > + spice_channel_connect(channel); > } > > if (SPICE_IS_INPUTS_CHANNEL(channel)) { > @@ -538,7 +608,6 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s, > if (SPICE_IS_DISPLAY_CHANNEL(channel)) { > VirtViewerDisplay *display = g_object_get_data(G_OBJECT(channel), "virt-viewer-display"); > DEBUG_LOG("zap display channel (#%d, %p)", id, display); > - virt_viewer_session_remove_display(session, display); > } > > if (SPICE_IS_PLAYBACK_CHANNEL(channel) && self->priv->audio) { > -- > 1.7.10.4 > > _______________________________________________ > virt-tools-list mailing list > virt-tools-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/virt-tools-list
Attachment:
pgpxny_HVXzW4.pgp
Description: PGP signature