diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2011-07-01 11:18:36 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2011-07-01 12:56:57 +0100 |
commit | 27d7500e03197226c8a29d229772b48e9cec07ba (patch) | |
tree | 37ffeb17cb499a6dd276e4a1af87b84b362836e3 | |
parent | e37190e75497794d188d3547515cccc9376e5111 (diff) | |
download | virt-viewer-27d7500e03197226c8a29d229772b48e9cec07ba.tar.gz virt-viewer-27d7500e03197226c8a29d229772b48e9cec07ba.tar.xz virt-viewer-27d7500e03197226c8a29d229772b48e9cec07ba.zip |
Enable use of scaling from spice >= 0.6
Make the SPICE widget operate in the same way as the VNC widget
with display scaling, and auto-resize, but preserving guest
aspect ratio
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/display-spice.c | 99 | ||||
-rw-r--r-- | src/display-vnc.c | 1 | ||||
-rw-r--r-- | src/display.h | 1 | ||||
-rw-r--r-- | src/viewer.c | 12 | ||||
-rw-r--r-- | virt-viewer.spec.in | 11 |
7 files changed, 110 insertions, 24 deletions
@@ -3,9 +3,9 @@ Virt Viewer provides a graphical viewer for the guest OS display. At this time is supports guest OS using the VNC -protocol. Further protocols may be supported in the future -as user demand dicatates. The viewer can connect directly -to both local and remotely hosted guest OS, optionally +or SPICE protocols. Further protocols may be supported in +the future as user demand dicatates. The viewer can connect +directly to both local and remotely hosted guest OS, optionally using SSL/TLS encryption. Virt Viewer uses the GTK-VNC widget to provide a display @@ -14,7 +14,7 @@ of the VNC protocol. This is available from http://gtk-vnc.sourceforge.net/ Optionally Virt Viewer can also provide a SPICE client -using the SPICE-GTK widget (>= 0.5) available from +using the SPICE-GTK widget (>= 0.6) available from http://spice-space.org/page/Spice-Gtk diff --git a/configure.ac b/configure.ac index 3110d45..8b4d8cd 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ AC_ARG_WITH([spice-gtk], AS_HELP_STRING([--without-spice-gtk], [Ignore presence of spice-gtk and disable it])) AS_IF([test "x$with_spice_gtk" != "xno"], - [PKG_CHECK_MODULES(SPICEGTK, spice-client-gtk-2.0 >= 0.5, [have_spice_gtk=yes], [have_spice_gtk=no])], + [PKG_CHECK_MODULES(SPICEGTK, spice-client-gtk-2.0 >= 0.6, [have_spice_gtk=yes], [have_spice_gtk=no])], [have_spice_gtk=no]) AS_IF([test "x$have_spice_gtk" = "xyes"], diff --git a/src/display-spice.c b/src/display-spice.c index 9ef0b2d..6ff764e 100644 --- a/src/display-spice.c +++ b/src/display-spice.c @@ -184,6 +184,93 @@ static void _spice_main_channel_event(G_GNUC_UNUSED SpiceChannel *channel, g_free(password); } + +/* + * Triggers a resize of the main container to indirectly cause + * the display widget to be resized to fit the available space + */ +static void +viewer_resize_display_widget(VirtViewer *viewer) +{ + gtk_widget_queue_resize(viewer->align); +} + + +/* + * Called when desktop size changes. + * + * It either tries to resize the main window, or it triggers + * recalculation of the display within existing window size + */ +static void viewer_resize_desktop(SpiceChannel *channel G_GNUC_UNUSED, gint format G_GNUC_UNUSED, + gint width, gint height, gint stride G_GNUC_UNUSED, + gint shmid G_GNUC_UNUSED, gpointer imgdata G_GNUC_UNUSED, + VirtViewer *viewer) +{ + DEBUG_LOG("desktop resize %dx%d", width, height); + viewer->desktopWidth = width; + viewer->desktopHeight = height; + + if (viewer->autoResize && viewer->window && !viewer->fullscreen) { + viewer_resize_main_window(viewer); + } else { + viewer_resize_display_widget(viewer); + } +} + + +/* + * Called when the main container widget's size has been set. + * It attempts to fit the display widget into this space while + * maintaining aspect ratio + */ +static gboolean viewer_resize_align(GtkWidget *widget, + GtkAllocation *alloc, + VirtViewer *viewer) +{ + double desktopAspect; + double scrollAspect; + int height, width; + GtkAllocation child; + int dx = 0, dy = 0; + + if (!viewer->active) { + DEBUG_LOG("Skipping inactive resize"); + return TRUE; + } + + if (viewer->desktopWidth == 0 || viewer->desktopHeight == 0) + desktopAspect = 1; + else + desktopAspect = (double)viewer->desktopWidth / (double)viewer->desktopHeight; + scrollAspect = (double)alloc->width / (double)alloc->height; + + if (scrollAspect > desktopAspect) { + width = alloc->height * desktopAspect; + dx = (alloc->width - width) / 2; + height = alloc->height; + } else { + width = alloc->width; + height = alloc->width / desktopAspect; + dy = (alloc->height - height) / 2; + } + + DEBUG_LOG("Align widget=%p is %dx%d, desktop is %dx%d, setting display to %dx%d", + widget, + alloc->width, alloc->height, + viewer->desktopWidth, viewer->desktopHeight, + width, height); + + child.x = alloc->x + dx; + child.y = alloc->y + dy; + child.width = width; + child.height = height; + if (viewer->display && viewer->display->widget) + gtk_widget_size_allocate(viewer->display->widget, &child); + + return FALSE; +} + static void _spice_channel_new(SpiceSession *s, SpiceChannel *channel, VirtViewerDisplay *display) { @@ -206,15 +293,24 @@ static void _spice_channel_new(SpiceSession *s, SpiceChannel *channel, DEBUG_LOG("new display channel (#%d)", id); if (display->widget != NULL) return; + + g_signal_connect(channel, "display-primary-create", + G_CALLBACK(viewer_resize_desktop), display->viewer); + self->display = spice_display_new(s, id); display->widget = GTK_WIDGET(self->display); g_object_set(self->display, "grab-keyboard", TRUE, "grab-mouse", TRUE, - "resize-guest", TRUE, + "resize-guest", FALSE, + "scaling", TRUE, "auto-clipboard", TRUE, NULL); viewer_add_display_and_realize(display->viewer); + + g_signal_connect(display->viewer->align, "size-allocate", + G_CALLBACK(viewer_resize_align), display->viewer); + viewer_initialized(display->viewer); } @@ -264,7 +360,6 @@ VirtViewerDisplaySpice* virt_viewer_display_spice_new(VirtViewer *viewer) self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_SPICE, NULL); d = VIRT_VIEWER_DISPLAY(self); d->viewer = viewer; - d->need_align = FALSE; self->session = spice_session_new(); g_signal_connect(self->session, "channel-new", diff --git a/src/display-vnc.c b/src/display-vnc.c index 0a7edbf..f3afd46 100644 --- a/src/display-vnc.c +++ b/src/display-vnc.c @@ -261,7 +261,6 @@ VirtViewerDisplayVNC* virt_viewer_display_vnc_new(VirtViewer *viewer) d->viewer = viewer; viewer->display = d; - d->need_align = TRUE; d->widget = vnc_display_new(); self->vnc = VNC_DISPLAY(d->widget); vnc_display_set_keyboard_grab(self->vnc, TRUE); diff --git a/src/display.h b/src/display.h index 8a23741..45931b4 100644 --- a/src/display.h +++ b/src/display.h @@ -49,7 +49,6 @@ G_BEGIN_DECLS /* perhaps this become an interface, and be pushed in gtkvnc and spice? */ struct _VirtViewerDisplay { GObject parent; - gboolean need_align; VirtViewer *viewer; GtkWidget *widget; }; diff --git a/src/viewer.c b/src/viewer.c index 7ad395a..bf2a4d5 100644 --- a/src/viewer.c +++ b/src/viewer.c @@ -132,14 +132,7 @@ void viewer_add_display_and_realize(VirtViewer *viewer) g_return_if_fail(viewer->display != NULL); g_return_if_fail(viewer->display->widget != NULL); - if (viewer->display->need_align) { - gtk_container_add(GTK_CONTAINER(viewer->align), viewer->display->widget); - } else { - gtk_notebook_remove_page(GTK_NOTEBOOK(viewer->notebook), 2); - if (gtk_notebook_insert_page(GTK_NOTEBOOK(viewer->notebook), viewer->display->widget, - NULL, 2) == -1) - g_warning("failed to insert a notebook page"); - } + gtk_container_add(GTK_CONTAINER(viewer->align), viewer->display->widget); if (!viewer->window) { gtk_container_add(GTK_CONTAINER(viewer->container), GTK_WIDGET(viewer->notebook)); @@ -839,8 +832,7 @@ static void viewer_show_display(VirtViewer *viewer) gtk_widget_show(viewer->display->widget); gtk_widget_grab_focus(viewer->display->widget); - gtk_notebook_set_current_page(GTK_NOTEBOOK(viewer->notebook), - viewer->display->need_align ? 1 : 2); + gtk_notebook_set_current_page(GTK_NOTEBOOK(viewer->notebook), 1); } static void viewer_connect_info_free(VirtViewer *viewer) diff --git a/virt-viewer.spec.in b/virt-viewer.spec.in index ff667da..64eb595 100644 --- a/virt-viewer.spec.in +++ b/virt-viewer.spec.in @@ -26,7 +26,7 @@ BuildRequires: libxml2-devel BuildRequires: libglade2-devel BuildRequires: gtk-vnc-devel >= 0.3.8 %if %{with_spice} -BuildRequires: spice-gtk-devel >= 0.5 +BuildRequires: spice-gtk-devel >= 0.6 %endif BuildRequires: /usr/bin/pod2man BuildRequires: intltool @@ -40,8 +40,8 @@ BuildRequires: firefox-devel %description Virtual Machine Viewer provides a graphical console client for connecting -to virtual machines. It uses the GTK-VNC widget to provide the display, -and libvirt for looking up VNC server details. +to virtual machines. It uses the GTK-VNC or SPICE-GTK widgets to provide +the display, and libvirt for looking up VNC/SPICE server details. %if %{_with_plugin} %package plugin @@ -50,8 +50,9 @@ Group: Development/Libraries Requires: %{name} = %{version} %description plugin -gtk-vnc is a VNC viewer widget for GTK. It is built using coroutines -allowing it to be completely asynchronous while remaining single threaded. +Virtual Machine Viewer provides a graphical console client for connecting +to virtual machines. It uses the GTK-VNC or SPICE-GTK widgets to provide +the display, and libvirt for looking up VNC/SPICE server details. This package provides a web browser plugin for Mozilla compatible browsers. |