[virt-tools-list] [PATCH 2/2] Implement SPICE desktop resizing that takes account of zoom level
Daniel P. Berrange
berrange at redhat.com
Tue Feb 7 17:10:54 UTC 2012
From: "Daniel P. Berrange" <berrange at redhat.com>
The standard SPICE widget guest resize implementation does not
take into account the zoom level settings in virt-viewer, because
it has no knowledge of this functionality. The guest resize can,
however, be done by calling spice_main_set_display() directly.
This allows virt-viewer to resize the guest taking into account
zoom levels.
ie, if virt-viewer is run with --zoom 50 and the window
is resized to 400x300, then the guest agent should
be told to set its resolution to 800x600
---
src/virt-viewer-display-spice.c | 32 ++++++++++++++++++++++++++++++++
src/virt-viewer-display-spice.h | 1 +
src/virt-viewer-display.c | 15 +++++++++++++++
src/virt-viewer-display.h | 2 ++
src/virt-viewer-session-spice.c | 9 +++++++++
5 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/src/virt-viewer-display-spice.c b/src/virt-viewer-display-spice.c
index d3b44b8..2121105 100644
--- a/src/virt-viewer-display-spice.c
+++ b/src/virt-viewer-display-spice.c
@@ -36,6 +36,7 @@ G_DEFINE_TYPE (VirtViewerDisplaySpice, virt_viewer_display_spice, VIRT_VIEWER_TY
struct _VirtViewerDisplaySpicePrivate {
SpiceChannel *channel;
+ SpiceMainChannel *main_channel;
SpiceDisplay *display;
};
@@ -53,6 +54,7 @@ virt_viewer_display_spice_finalize(GObject *obj)
g_object_unref(spice->priv->display);
g_object_unref(spice->priv->channel);
+ g_object_unref(spice->priv->main_channel);
G_OBJECT_CLASS(virt_viewer_display_spice_parent_class)->finalize(obj);
}
@@ -151,8 +153,33 @@ virt_viewer_display_spice_mouse_grab(SpiceDisplay *display G_GNUC_UNUSED,
}
+static void
+virt_viewer_display_spice_size_allocate(SpiceDisplay *display G_GNUC_UNUSED,
+ GtkAllocation *allocation,
+ VirtViewerDisplaySpice *self G_GNUC_UNUSED)
+{
+ gdouble dw = allocation->width, dh = allocation->height;
+ guint zoom = 100;
+ guint channelid;
+
+ if (virt_viewer_display_get_zoom(VIRT_VIEWER_DISPLAY(self))) {
+ zoom = virt_viewer_display_get_zoom_level(VIRT_VIEWER_DISPLAY(self));
+
+ dw /= ((double)zoom / 100.0);
+ dh /= ((double)zoom / 100.0);
+ }
+
+ g_object_get(self->priv->channel, "channel-id", &channelid, NULL);
+
+ spice_main_set_display(self->priv->main_channel,
+ channelid,
+ 0, 0, dw, dh);
+}
+
+
GtkWidget *
virt_viewer_display_spice_new(SpiceChannel *channel,
+ SpiceMainChannel *main_channel,
SpiceDisplay *display)
{
VirtViewerDisplaySpice *self;
@@ -167,6 +194,7 @@ virt_viewer_display_spice_new(SpiceChannel *channel,
"nth-display", channelid,
NULL);
self->priv->channel = g_object_ref(channel);
+ self->priv->main_channel = g_object_ref(main_channel);
self->priv->display = g_object_ref(display);
g_signal_connect(channel, "display-primary-create",
@@ -189,6 +217,10 @@ virt_viewer_display_spice_new(SpiceChannel *channel,
g_signal_connect(self->priv->display,
"mouse-grab",
G_CALLBACK(virt_viewer_display_spice_mouse_grab), self);
+ g_signal_connect(self->priv->display,
+ "size-allocate",
+ G_CALLBACK(virt_viewer_display_spice_size_allocate), self);
+
return GTK_WIDGET(self);
}
diff --git a/src/virt-viewer-display-spice.h b/src/virt-viewer-display-spice.h
index 3b4e8e6..ee412a1 100644
--- a/src/virt-viewer-display-spice.h
+++ b/src/virt-viewer-display-spice.h
@@ -66,6 +66,7 @@ struct _VirtViewerDisplaySpiceClass {
GType virt_viewer_display_spice_get_type(void);
GtkWidget* virt_viewer_display_spice_new(SpiceChannel *channel,
+ SpiceMainChannel *main_channel,
SpiceDisplay *display);
G_END_DECLS
diff --git a/src/virt-viewer-display.c b/src/virt-viewer-display.c
index 1d2ade2..cdddc32 100644
--- a/src/virt-viewer-display.c
+++ b/src/virt-viewer-display.c
@@ -468,6 +468,13 @@ void virt_viewer_display_set_zoom_level(VirtViewerDisplay *display,
}
+guint virt_viewer_display_get_zoom_level(VirtViewerDisplay *display)
+{
+ VirtViewerDisplayPrivate *priv = display->priv;
+ return priv->zoom_level;
+}
+
+
void virt_viewer_display_set_zoom(VirtViewerDisplay *display,
gboolean zoom)
{
@@ -481,6 +488,14 @@ void virt_viewer_display_set_zoom(VirtViewerDisplay *display,
}
}
+
+gboolean virt_viewer_display_get_zoom(VirtViewerDisplay *display)
+{
+ VirtViewerDisplayPrivate *priv = display->priv;
+ return priv->zoom;
+}
+
+
void virt_viewer_display_send_keys(VirtViewerDisplay *display,
const guint *keyvals, int nkeyvals)
{
diff --git a/src/virt-viewer-display.h b/src/virt-viewer-display.h
index 5deb923..f7b61f6 100644
--- a/src/virt-viewer-display.h
+++ b/src/virt-viewer-display.h
@@ -94,8 +94,10 @@ void virt_viewer_display_get_desktop_size(VirtViewerDisplay *display,
void virt_viewer_display_set_zoom_level(VirtViewerDisplay *display,
guint zoom);
+guint virt_viewer_display_get_zoom_level(VirtViewerDisplay *display);
void virt_viewer_display_set_zoom(VirtViewerDisplay *display,
gboolean zoom);
+gboolean virt_viewer_display_get_zoom(VirtViewerDisplay *display);
void virt_viewer_display_send_keys(VirtViewerDisplay *display,
const guint *keyvals, int nkeyvals);
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index 7d8e2b0..200a75c 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -40,6 +40,7 @@ G_DEFINE_TYPE (VirtViewerSessionSpice, virt_viewer_session_spice, VIRT_VIEWER_TY
struct _VirtViewerSessionSpicePrivate {
SpiceSession *session;
SpiceGtkSession *gtk_session;
+ SpiceMainChannel *main_channel;
SpiceAudio *audio;
};
@@ -103,6 +104,8 @@ virt_viewer_session_spice_dispose(GObject *obj)
}
if (spice->priv->audio)
g_object_unref(spice->priv->audio);
+ if (spice->priv->main_channel)
+ g_object_unref(spice->priv->main_channel);
G_OBJECT_CLASS(virt_viewer_session_spice_parent_class)->finalize(obj);
}
@@ -372,6 +375,9 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
if (SPICE_IS_MAIN_CHANNEL(channel)) {
g_signal_connect(channel, "channel-event",
G_CALLBACK(virt_viewer_session_spice_main_channel_event), self);
+ if (self->priv->main_channel != NULL)
+ return;
+ self->priv->main_channel = g_object_ref(channel);
}
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
@@ -381,6 +387,7 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
DEBUG_LOG("new session channel (#%d)", id);
display = virt_viewer_display_spice_new(channel,
+ self->priv->main_channel,
spice_display_new(s, id));
virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session),
@@ -414,6 +421,8 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
g_object_get(channel, "channel-id", &id, NULL);
if (SPICE_IS_MAIN_CHANNEL(channel)) {
DEBUG_LOG("zap main channel");
+ g_object_unref(self->priv->main_channel);
+ self->priv->main_channel = NULL;
}
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
--
1.7.7.6
More information about the virt-tools-list
mailing list