[virt-tools-list] [PATCH virt-viewer 16/25] Hook up handling of Monitors

Christophe Fergeau cfergeau at redhat.com
Wed Jul 18 09:38:27 UTC 2012


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 at redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20120718/91c65fb7/attachment.sig>


More information about the virt-tools-list mailing list