diff options
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/virt-viewer-align.c | 395 | ||||
-rw-r--r-- | src/virt-viewer-align.h | 86 | ||||
-rw-r--r-- | src/virt-viewer-display-spice.c | 87 | ||||
-rw-r--r-- | src/virt-viewer-display-spice.h | 2 | ||||
-rw-r--r-- | src/virt-viewer-display-vnc.c | 84 | ||||
-rw-r--r-- | src/virt-viewer-display-vnc.h | 2 | ||||
-rw-r--r-- | src/virt-viewer-display.c | 392 | ||||
-rw-r--r-- | src/virt-viewer-display.h | 31 | ||||
-rw-r--r-- | src/virt-viewer-priv.h | 8 | ||||
-rw-r--r-- | src/virt-viewer-util.h | 2 | ||||
-rw-r--r-- | src/virt-viewer.c | 100 |
12 files changed, 463 insertions, 727 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a9e433f..3cf965c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,6 @@ virt_viewer_SOURCES = \ virt-viewer-events.h virt-viewer-events.c \ virt-viewer.h virt-viewer.c \ virt-viewer-priv.h \ - virt-viewer-align.h virt-viewer-align.c \ virt-viewer-display.h virt-viewer-display.c \ virt-viewer-display-vnc.h virt-viewer-display-vnc.c \ view/autoDrawer.c \ diff --git a/src/virt-viewer-align.c b/src/virt-viewer-align.c deleted file mode 100644 index e1e056d..0000000 --- a/src/virt-viewer-align.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Virt Viewer: A virtual machine console viewer - * - * Copyright (C) 2007-2011 Red Hat, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Daniel P. Berrange <berrange@redhat.com> - */ - -#include <config.h> - -#include <locale.h> - -#include "virt-viewer-align.h" -#include "virt-viewer-util.h" - - -#define VIRT_VIEWER_ALIGN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), VIRT_VIEWER_TYPE_ALIGN, VirtViewerAlignPrivate)) - -struct _VirtViewerAlignPrivate -{ - gboolean dirty; - guint preferred_width; - guint preferred_height; - guint zoom_level; - gboolean zoom; -}; - -static void virt_viewer_align_size_request(GtkWidget *widget, - GtkRequisition *requisition); -#if GTK_CHECK_VERSION(3, 0, 0) -static void virt_viewer_align_get_preferred_width(GtkWidget *widget, - int *minwidth, - int *defwidth); -static void virt_viewer_align_get_preferred_height(GtkWidget *widget, - int *minheight, - int *defheight); -#endif -static void virt_viewer_align_size_allocate(GtkWidget *widget, - GtkAllocation *allocation); -static void virt_viewer_align_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void virt_viewer_align_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -G_DEFINE_TYPE(VirtViewerAlign, virt_viewer_align, GTK_TYPE_BIN) - -enum { - PROP_0, - - PROP_PREFERRED_WIDTH, - PROP_PREFERRED_HEIGHT, - PROP_ZOOM, - PROP_ZOOM_LEVEL, -}; - -static void -virt_viewer_align_class_init(VirtViewerAlignClass *class) -{ - GObjectClass *gobject_class; - GtkWidgetClass *widget_class; - - gobject_class = (GObjectClass*) class; - widget_class = (GtkWidgetClass*) class; - - gobject_class->set_property = virt_viewer_align_set_property; - gobject_class->get_property = virt_viewer_align_get_property; - -#if GTK_CHECK_VERSION(3, 0, 0) - widget_class->get_preferred_width = virt_viewer_align_get_preferred_width; - widget_class->get_preferred_height = virt_viewer_align_get_preferred_height; -#else - widget_class->size_request = virt_viewer_align_size_request; -#endif - widget_class->size_allocate = virt_viewer_align_size_allocate; - - g_object_class_install_property(gobject_class, - PROP_PREFERRED_WIDTH, - g_param_spec_int("preferred-width", - "Width", - "Preferred width", - 100, - G_MAXINT32, - 100, - G_PARAM_READWRITE)); - g_object_class_install_property(gobject_class, - PROP_PREFERRED_HEIGHT, - g_param_spec_int("preferred-height", - "Height", - "Preferred height", - 100, - G_MAXINT32, - 100, - G_PARAM_READWRITE)); - g_object_class_install_property(gobject_class, - PROP_ZOOM, - g_param_spec_boolean("zoom", - "Zoom", - "Zoom", - TRUE, - G_PARAM_READWRITE)); - g_object_class_install_property(gobject_class, - PROP_ZOOM_LEVEL, - g_param_spec_int("zoom-level", - "Zoom", - "Zoom level", - 10, - 400, - 100, - G_PARAM_READWRITE)); - - g_type_class_add_private(gobject_class, sizeof(VirtViewerAlignPrivate)); -} - -static void -virt_viewer_align_init(VirtViewerAlign *align) -{ - gtk_widget_set_has_window(GTK_WIDGET(align), FALSE); - gtk_widget_set_redraw_on_allocate(GTK_WIDGET(align), FALSE); - - align->priv = VIRT_VIEWER_ALIGN_GET_PRIVATE(align); - - align->priv->preferred_width = 100; - align->priv->preferred_height = 100; - align->priv->zoom_level = 100; - align->priv->zoom = TRUE; -} - -GtkWidget* -virt_viewer_align_new(void) -{ - return g_object_new (VIRT_VIEWER_TYPE_ALIGN, NULL); -} - -static void -virt_viewer_align_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - VirtViewerAlign *align = VIRT_VIEWER_ALIGN(object); - VirtViewerAlignPrivate *priv = align->priv; - - switch (prop_id) { - case PROP_PREFERRED_WIDTH: - virt_viewer_align_set_preferred_size(align, - g_value_get_int(value), - priv->preferred_height); - break; - case PROP_PREFERRED_HEIGHT: - virt_viewer_align_set_preferred_size(align, - priv->preferred_width, - g_value_get_int(value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -virt_viewer_align_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - VirtViewerAlign *align = VIRT_VIEWER_ALIGN(object); - VirtViewerAlignPrivate *priv = align->priv; - - switch (prop_id) { - case PROP_PREFERRED_WIDTH: - g_value_set_int(value, priv->preferred_width); - break; - case PROP_PREFERRED_HEIGHT: - g_value_set_int(value, priv->preferred_height); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -static gboolean -virt_viewer_align_idle(gpointer opaque) -{ - VirtViewerAlign *align = opaque; - VirtViewerAlignPrivate *priv = align->priv; - if (!priv->dirty) - gtk_widget_queue_resize_no_redraw(GTK_WIDGET(align)); - return FALSE; -} - - -static void -virt_viewer_align_size_request(GtkWidget *widget, - GtkRequisition *requisition) -{ - VirtViewerAlign *align = VIRT_VIEWER_ALIGN(widget); - VirtViewerAlignPrivate *priv = align->priv; - int border_width = gtk_container_get_border_width(GTK_CONTAINER(widget)); - - requisition->width = border_width * 2; - requisition->height = border_width * 2; - - if (priv->dirty) { - if (priv->zoom) - requisition->width += priv->preferred_width * priv->zoom_level / 100; - else - requisition->width += priv->preferred_width; - } else { - requisition->width += 50; - } - if (priv->dirty) { - if (priv->zoom) - requisition->height += priv->preferred_height * priv->zoom_level / 100; - else - requisition->height += priv->preferred_height; - } else { - requisition->height += 50; - } - - DEBUG_LOG("Align size request %dx%d (preferred %dx%d)", - requisition->width, requisition->height, - priv->preferred_width, priv->preferred_height); -} - - -#if GTK_CHECK_VERSION(3, 0, 0) -static void virt_viewer_align_get_preferred_width(GtkWidget *widget, - int *minwidth, - int *defwidth) -{ - GtkRequisition req; - - virt_viewer_align_size_request(widget, &req); - - *minwidth = *defwidth = req.width; -} - - -static void virt_viewer_align_get_preferred_height(GtkWidget *widget, - int *minheight, - int *defheight) -{ - GtkRequisition req; - - virt_viewer_align_size_request(widget, &req); - - *minheight = *defheight = req.height; -} -#endif - - -static void -virt_viewer_align_size_allocate(GtkWidget *widget, - GtkAllocation *allocation) -{ - GtkBin *bin = GTK_BIN(widget); - VirtViewerAlign *align = VIRT_VIEWER_ALIGN(widget); - VirtViewerAlignPrivate *priv = align->priv; - GtkAllocation child_allocation; - gint width, height; - gint border_width; - double preferredAspect; - double actualAspect; - GtkWidget *child = gtk_bin_get_child(bin); - - DEBUG_LOG("Allocated %dx%d", allocation->width, allocation->height); - gtk_widget_set_allocation(widget, allocation); - - preferredAspect = (double)priv->preferred_width / (double)priv->preferred_height; - - if (child && gtk_widget_get_visible(child)) { - border_width = gtk_container_get_border_width(GTK_CONTAINER(align)); - - width = MAX(1, allocation->width - 2 * border_width); - height = MAX(1, allocation->height - 2 * border_width); - actualAspect = (double)width / (double)height; - - if (actualAspect > preferredAspect) { - child_allocation.width = height * preferredAspect; - child_allocation.height = height; - } else { - child_allocation.width = width; - child_allocation.height = width / preferredAspect; - } - - child_allocation.x = 0.5 * (width - child_allocation.width) + allocation->x + border_width; - child_allocation.y = 0.5 * (height - child_allocation.height) + allocation->y + border_width; - - DEBUG_LOG("Child allocate %dx%d", child_allocation.width, child_allocation.height); - gtk_widget_size_allocate(child, &child_allocation); - } - - - /* This unsets the size request, so that the user can - * manually resize the window smaller again - */ - if (priv->dirty) { - g_idle_add(virt_viewer_align_idle, widget); - priv->dirty = FALSE; - } -} - - -void virt_viewer_align_set_preferred_size(VirtViewerAlign *align, - guint width, - guint height) -{ - VirtViewerAlignPrivate *priv = align->priv; - - priv->preferred_width = width; - priv->preferred_height = height; - priv->dirty = TRUE; - - gtk_widget_queue_resize(GTK_WIDGET(align)); -} - -void virt_viewer_align_set_zoom_level(VirtViewerAlign *align, - guint zoom) -{ - VirtViewerAlignPrivate *priv = align->priv; - GtkWidget *child = gtk_bin_get_child(GTK_BIN(align)); - - if (zoom < 10) - zoom = 10; - if (zoom > 400) - zoom = 400; - priv->zoom_level = zoom; - - if (child && gtk_widget_get_visible(child)) { - priv->dirty = TRUE; - gtk_widget_queue_resize(GTK_WIDGET(align)); - } -} - - -void virt_viewer_align_zoom_in(VirtViewerAlign *align) -{ - VirtViewerAlignPrivate *priv = align->priv; - virt_viewer_align_set_zoom_level(align, priv->zoom_level + 10); -} - -void virt_viewer_align_zoom_out(VirtViewerAlign *align) -{ - VirtViewerAlignPrivate *priv = align->priv; - virt_viewer_align_set_zoom_level(align, priv->zoom_level - 10); -} - -void virt_viewer_align_zoom_normal(VirtViewerAlign *align) -{ - virt_viewer_align_set_zoom_level(align, 100); -} - - -void virt_viewer_align_set_zoom(VirtViewerAlign *align, - gboolean zoom) -{ - VirtViewerAlignPrivate *priv = align->priv; - GtkWidget *child = gtk_bin_get_child(GTK_BIN(align)); - - priv->zoom = zoom; - if (child && gtk_widget_get_visible(child)) { - priv->dirty = TRUE; - gtk_widget_queue_resize(GTK_WIDGET(align)); - } -} - -/* - * Local variables: - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ diff --git a/src/virt-viewer-align.h b/src/virt-viewer-align.h deleted file mode 100644 index db1194c..0000000 --- a/src/virt-viewer-align.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Virt Viewer: A virtual machine console viewer - * - * Copyright (C) 2007-2011 Red Hat, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Daniel P. Berrange <berrange@redhat.com> - */ -#ifndef _VIRT_VIEWER_ALIGN_H -#define _VIRT_VIEWER_ALIGN_H - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define VIRT_VIEWER_TYPE_ALIGN virt_viewer_align_get_type() - -#define VIRT_VIEWER_ALIGN(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_ALIGN, VirtViewerAlign)) - -#define VIRT_VIEWER_ALIGN_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_ALIGN, VirtViewerAlignClass)) - -#define VIRT_VIEWER_IS_ALIGN(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_ALIGN)) - -#define VIRT_VIEWER_IS_ALIGN_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_ALIGN)) - -#define VIRT_VIEWER_ALIGN_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_ALIGN, VirtViewerAlignClass)) - -typedef struct _VirtViewerAlign VirtViewerAlign; -typedef struct _VirtViewerAlignClass VirtViewerAlignClass; -typedef struct _VirtViewerAlignPrivate VirtViewerAlignPrivate; - - -struct _VirtViewerAlign { - GtkBin parent; - - VirtViewerAlignPrivate *priv; -}; - -struct _VirtViewerAlignClass { - GtkBinClass parent_class; -}; - -GType virt_viewer_align_get_type(void); - -GtkWidget *virt_viewer_align_new(void); - -void virt_viewer_align_set_preferred_size(VirtViewerAlign *align, - guint width, - guint height); - -void virt_viewer_align_zoom_in(VirtViewerAlign *align); -void virt_viewer_align_zoom_out(VirtViewerAlign *align); -void virt_viewer_align_zoom_normal(VirtViewerAlign *align); -void virt_viewer_align_set_zoom_level(VirtViewerAlign *align, - guint zoom); -void virt_viewer_align_set_zoom(VirtViewerAlign *align, - gboolean zoom); - -G_END_DECLS - -#endif /* _VIRT_VIEWER_ALIGN_H */ -/* - * Local variables: - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ diff --git a/src/virt-viewer-display-spice.c b/src/virt-viewer-display-spice.c index 88d64d1..1bc4c97 100644 --- a/src/virt-viewer-display-spice.c +++ b/src/virt-viewer-display-spice.c @@ -201,17 +201,6 @@ virt_viewer_display_spice_main_channel_event(SpiceChannel *channel G_GNUC_UNUSED /* - * Triggers a resize of the main container to indirectly cause - * the display widget to be resized to fit the available space - */ -static void -virt_viewer_display_spice_resize_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 @@ -228,70 +217,14 @@ virt_viewer_display_spice_resize_desktop(SpiceChannel *channel 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) { + virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(viewer->display), width, height); + + if (viewer->autoResize && viewer->window && !viewer->fullscreen) virt_viewer_resize_main_window(viewer); - } else { - virt_viewer_display_spice_resize_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 -virt_viewer_display_spice_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 virt_viewer_display_spice_channel_new(SpiceSession *s, SpiceChannel *channel, @@ -314,14 +247,12 @@ virt_viewer_display_spice_channel_new(SpiceSession *s, if (SPICE_IS_DISPLAY_CHANNEL(channel)) { DEBUG_LOG("new display channel (#%d)", id); - if (display->widget != NULL) - return; - g_signal_connect(channel, "display-primary-create", G_CALLBACK(virt_viewer_display_spice_resize_desktop), display->viewer); self->display = spice_display_new(s, id); - display->widget = GTK_WIDGET(self->display); + gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->display)); + gtk_widget_show(GTK_WIDGET(self->display)); g_object_set(self->display, "grab-keyboard", TRUE, "grab-mouse", TRUE, @@ -329,10 +260,6 @@ virt_viewer_display_spice_channel_new(SpiceSession *s, "scaling", TRUE, "auto-clipboard", TRUE, NULL); - virt_viewer_add_display_and_realize(display->viewer); - - g_signal_connect(display->viewer->align, "size-allocate", - G_CALLBACK(virt_viewer_display_spice_resize_align), display->viewer); virt_viewer_initialized(display->viewer); } @@ -375,7 +302,7 @@ virt_viewer_display_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s, } } -VirtViewerDisplaySpice * +GtkWidget * virt_viewer_display_spice_new(VirtViewer *viewer) { VirtViewerDisplaySpice *self; @@ -393,7 +320,7 @@ virt_viewer_display_spice_new(VirtViewer *viewer) g_signal_connect(self->session, "channel-destroy", G_CALLBACK(virt_viewer_display_spice_channel_destroy), self); - return self; + return GTK_WIDGET(self); } /* diff --git a/src/virt-viewer-display-spice.h b/src/virt-viewer-display-spice.h index c375822..642581c 100644 --- a/src/virt-viewer-display-spice.h +++ b/src/virt-viewer-display-spice.h @@ -63,7 +63,7 @@ typedef struct { GType virt_viewer_display_spice_get_type(void); -VirtViewerDisplaySpice* virt_viewer_display_spice_new(VirtViewer *viewer); +GtkWidget* virt_viewer_display_spice_new(VirtViewer *viewer); G_END_DECLS diff --git a/src/virt-viewer-display-vnc.c b/src/virt-viewer-display-vnc.c index 41f8c89..032aa87 100644 --- a/src/virt-viewer-display-vnc.c +++ b/src/virt-viewer-display-vnc.c @@ -197,17 +197,6 @@ virt_viewer_display_vnc_auth_failure(VirtViewer *viewer, } /* - * Triggers a resize of the main container to indirectly cause - * the display widget to be resized to fit the available space - */ -static void -virt_viewer_display_vnc_resize_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 @@ -217,68 +206,15 @@ static void virt_viewer_display_vnc_resize_desktop(VirtViewer *viewer, gint width, gint height) { DEBUG_LOG("desktop resize %dx%d", width, height); - viewer->desktopWidth = width; - viewer->desktopHeight = height; - if (viewer->autoResize && viewer->window && !viewer->fullscreen) { + virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(viewer->display), width, height); + + if (viewer->autoResize && viewer->window && !viewer->fullscreen) virt_viewer_resize_main_window(viewer); - } else { - virt_viewer_display_vnc_resize_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 -virt_viewer_display_vnc_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; - } - - 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; -} - -VirtViewerDisplayVNC* +GtkWidget * virt_viewer_display_vnc_new(VirtViewer *viewer) { VirtViewerDisplayVNC *self; @@ -289,10 +225,9 @@ virt_viewer_display_vnc_new(VirtViewer *viewer) self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_VNC, NULL); d = VIRT_VIEWER_DISPLAY(self); d->viewer = viewer; - viewer->display = d; - d->widget = vnc_display_new(); - self->vnc = VNC_DISPLAY(d->widget); + self->vnc = VNC_DISPLAY(vnc_display_new()); + gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->vnc)); vnc_display_set_keyboard_grab(self->vnc, TRUE); vnc_display_set_pointer_grab(self->vnc, TRUE); @@ -339,12 +274,7 @@ virt_viewer_display_vnc_new(VirtViewer *viewer) g_signal_connect(self->vnc, "vnc-auth-credential", G_CALLBACK(virt_viewer_auth_vnc_credentials), &viewer->pretty_address); - virt_viewer_add_display_and_realize(viewer); - - g_signal_connect(viewer->align, "size-allocate", - G_CALLBACK(virt_viewer_display_vnc_resize_align), viewer); - - return self; + return GTK_WIDGET(self); } diff --git a/src/virt-viewer-display-vnc.h b/src/virt-viewer-display-vnc.h index c0d776f..f2373b1 100644 --- a/src/virt-viewer-display-vnc.h +++ b/src/virt-viewer-display-vnc.h @@ -60,7 +60,7 @@ typedef struct { GType virt_viewer_display_vnc_get_type(void); -VirtViewerDisplayVNC* virt_viewer_display_vnc_new(VirtViewer *viewer); +GtkWidget* virt_viewer_display_vnc_new(VirtViewer *viewer); G_END_DECLS diff --git a/src/virt-viewer-display.c b/src/virt-viewer-display.c index b2a1347..f2d4b24 100644 --- a/src/virt-viewer-display.c +++ b/src/virt-viewer-display.c @@ -21,64 +21,412 @@ * * Author: Daniel P. Berrange <berrange@redhat.com> */ + +#include <config.h> + +#include <locale.h> + #include "virt-viewer-display.h" +#include "virt-viewer-util.h" + +#define VIRT_VIEWER_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), VIRT_VIEWER_TYPE_DISPLAY, VirtViewerDisplayPrivate)) + +struct _VirtViewerDisplayPrivate +{ + gboolean dirty; + guint desktopWidth; + guint desktopHeight; + guint zoom_level; + gboolean zoom; +}; + +static void virt_viewer_display_size_request(GtkWidget *widget, + GtkRequisition *requisition); +#if GTK_CHECK_VERSION(3, 0, 0) +static void virt_viewer_display_get_preferred_width(GtkWidget *widget, + int *minwidth, + int *defwidth); +static void virt_viewer_display_get_preferred_height(GtkWidget *widget, + int *minheight, + int *defheight); +#endif +static void virt_viewer_display_size_allocate(GtkWidget *widget, + GtkAllocation *allocation); +static void virt_viewer_display_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void virt_viewer_display_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +G_DEFINE_ABSTRACT_TYPE(VirtViewerDisplay, virt_viewer_display, GTK_TYPE_BIN) + +enum { + PROP_0, + + PROP_DESKTOP_WIDTH, + PROP_DESKTOP_HEIGHT, + PROP_ZOOM, + PROP_ZOOM_LEVEL, +}; + +static void +virt_viewer_display_class_init(VirtViewerDisplayClass *class) +{ + GObjectClass *gobject_class; + GtkWidgetClass *widget_class; + + gobject_class = (GObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + + gobject_class->set_property = virt_viewer_display_set_property; + gobject_class->get_property = virt_viewer_display_get_property; + +#if GTK_CHECK_VERSION(3, 0, 0) + widget_class->get_preferred_width = virt_viewer_display_get_preferred_width; + widget_class->get_preferred_height = virt_viewer_display_get_preferred_height; +#else + widget_class->size_request = virt_viewer_display_size_request; +#endif + widget_class->size_allocate = virt_viewer_display_size_allocate; + + g_object_class_install_property(gobject_class, + PROP_DESKTOP_WIDTH, + g_param_spec_int("desktop-width", + "Width", + "Desktop width", + 100, + G_MAXINT32, + 100, + G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_DESKTOP_HEIGHT, + g_param_spec_int("desktop-height", + "Height", + "Desktop height", + 100, + G_MAXINT32, + 100, + G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_ZOOM, + g_param_spec_boolean("zoom", + "Zoom", + "Zoom", + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, + PROP_ZOOM_LEVEL, + g_param_spec_int("zoom-level", + "Zoom", + "Zoom level", + 10, + 400, + 100, + G_PARAM_READWRITE)); + + g_type_class_add_private(gobject_class, sizeof(VirtViewerDisplayPrivate)); +} + +static void +virt_viewer_display_init(VirtViewerDisplay *display) +{ + gtk_widget_set_has_window(GTK_WIDGET(display), FALSE); + gtk_widget_set_redraw_on_allocate(GTK_WIDGET(display), FALSE); + + display->priv = VIRT_VIEWER_DISPLAY_GET_PRIVATE(display); -G_DEFINE_ABSTRACT_TYPE(VirtViewerDisplay, virt_viewer_display, G_TYPE_OBJECT) + display->priv->desktopWidth = 100; + display->priv->desktopHeight = 100; + display->priv->zoom_level = 100; + display->priv->zoom = TRUE; +} +GtkWidget* +virt_viewer_display_new(void) +{ + return g_object_new (VIRT_VIEWER_TYPE_DISPLAY, NULL); +} -static void virt_viewer_display_class_init(VirtViewerDisplayClass *klass G_GNUC_UNUSED) +static void +virt_viewer_display_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { + VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(object); + VirtViewerDisplayPrivate *priv = display->priv; + + switch (prop_id) { + case PROP_DESKTOP_WIDTH: + virt_viewer_display_set_desktop_size(display, + g_value_get_int(value), + priv->desktopHeight); + break; + case PROP_DESKTOP_HEIGHT: + virt_viewer_display_set_desktop_size(display, + priv->desktopWidth, + g_value_get_int(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } -static void virt_viewer_display_init(VirtViewerDisplay *self G_GNUC_UNUSED) +static void +virt_viewer_display_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { + VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(object); + VirtViewerDisplayPrivate *priv = display->priv; + + switch (prop_id) { + case PROP_DESKTOP_WIDTH: + g_value_set_int(value, priv->desktopWidth); + break; + case PROP_DESKTOP_HEIGHT: + g_value_set_int(value, priv->desktopHeight); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } -void virt_viewer_display_close(VirtViewerDisplay *self) + +static gboolean +virt_viewer_display_idle(gpointer opaque) +{ + VirtViewerDisplay *display = opaque; + VirtViewerDisplayPrivate *priv = display->priv; + if (!priv->dirty) + gtk_widget_queue_resize_no_redraw(GTK_WIDGET(display)); + return FALSE; +} + + +static void +virt_viewer_display_size_request(GtkWidget *widget, + GtkRequisition *requisition) +{ + VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(widget); + VirtViewerDisplayPrivate *priv = display->priv; + int border_width = gtk_container_get_border_width(GTK_CONTAINER(widget)); + + requisition->width = border_width * 2; + requisition->height = border_width * 2; + + if (priv->dirty) { + if (priv->zoom) + requisition->width += priv->desktopWidth * priv->zoom_level / 100; + else + requisition->width += priv->desktopWidth; + } else { + requisition->width += 50; + } + if (priv->dirty) { + if (priv->zoom) + requisition->height += priv->desktopHeight * priv->zoom_level / 100; + else + requisition->height += priv->desktopHeight; + } else { + requisition->height += 50; + } + + DEBUG_LOG("Display size request %dx%d (desktop %dx%d)", + requisition->width, requisition->height, + priv->desktopWidth, priv->desktopHeight); +} + + +#if GTK_CHECK_VERSION(3, 0, 0) +static void virt_viewer_display_get_preferred_width(GtkWidget *widget, + int *minwidth, + int *defwidth) +{ + GtkRequisition req; + + virt_viewer_display_size_request(widget, &req); + + *minwidth = *defwidth = req.width; +} + + +static void virt_viewer_display_get_preferred_height(GtkWidget *widget, + int *minheight, + int *defheight) +{ + GtkRequisition req; + + virt_viewer_display_size_request(widget, &req); + + *minheight = *defheight = req.height; +} +#endif + + +static void +virt_viewer_display_size_allocate(GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkBin *bin = GTK_BIN(widget); + VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(widget); + VirtViewerDisplayPrivate *priv = display->priv; + GtkAllocation child_allocation; + gint width, height; + gint border_width; + double desktopAspect; + double actualAspect; + GtkWidget *child = gtk_bin_get_child(bin); + + DEBUG_LOG("Allocated %dx%d", allocation->width, allocation->height); + gtk_widget_set_allocation(widget, allocation); + + desktopAspect = (double)priv->desktopWidth / (double)priv->desktopHeight; + + if (child && gtk_widget_get_visible(child)) { + border_width = gtk_container_get_border_width(GTK_CONTAINER(display)); + + width = MAX(1, allocation->width - 2 * border_width); + height = MAX(1, allocation->height - 2 * border_width); + actualAspect = (double)width / (double)height; + + if (actualAspect > desktopAspect) { + child_allocation.width = height * desktopAspect; + child_allocation.height = height; + } else { + child_allocation.width = width; + child_allocation.height = width / desktopAspect; + } + + child_allocation.x = 0.5 * (width - child_allocation.width) + allocation->x + border_width; + child_allocation.y = 0.5 * (height - child_allocation.height) + allocation->y + border_width; + + DEBUG_LOG("Child allocate %dx%d", child_allocation.width, child_allocation.height); + gtk_widget_size_allocate(child, &child_allocation); + } + + + /* This unsets the size request, so that the user can + * manually resize the window smaller again + */ + if (priv->dirty) { + g_idle_add(virt_viewer_display_idle, widget); + priv->dirty = FALSE; + } +} + + +void virt_viewer_display_set_desktop_size(VirtViewerDisplay *display, + guint width, + guint height) +{ + VirtViewerDisplayPrivate *priv = display->priv; + + priv->desktopWidth = width; + priv->desktopHeight = height; + priv->dirty = TRUE; + + gtk_widget_queue_resize(GTK_WIDGET(display)); +} + + +void virt_viewer_display_get_desktop_size(VirtViewerDisplay *display, + guint *width, + guint *height) +{ + VirtViewerDisplayPrivate *priv = display->priv; + + *width = priv->desktopWidth; + *height = priv->desktopHeight; +} + + +void virt_viewer_display_set_zoom_level(VirtViewerDisplay *display, + guint zoom) +{ + VirtViewerDisplayPrivate *priv = display->priv; + GtkWidget *child = gtk_bin_get_child(GTK_BIN(display)); + + if (zoom < 10) + zoom = 10; + if (zoom > 400) + zoom = 400; + priv->zoom_level = zoom; + + if (child && gtk_widget_get_visible(child)) { + priv->dirty = TRUE; + gtk_widget_queue_resize(GTK_WIDGET(display)); + } +} + + +void virt_viewer_display_set_zoom(VirtViewerDisplay *display, + gboolean zoom) +{ + VirtViewerDisplayPrivate *priv = display->priv; + GtkWidget *child = gtk_bin_get_child(GTK_BIN(display)); + + priv->zoom = zoom; + if (child && gtk_widget_get_visible(child)) { + priv->dirty = TRUE; + gtk_widget_queue_resize(GTK_WIDGET(display)); + } +} + + +void virt_viewer_display_close(VirtViewerDisplay *display) { - g_return_if_fail(VIRT_VIEWER_IS_DISPLAY(self)); + g_return_if_fail(VIRT_VIEWER_IS_DISPLAY(display)); - VIRT_VIEWER_DISPLAY_GET_CLASS(self)->close(self); + VIRT_VIEWER_DISPLAY_GET_CLASS(display)->close(display); } -void virt_viewer_display_send_keys(VirtViewerDisplay *self, +void virt_viewer_display_send_keys(VirtViewerDisplay *display, const guint *keyvals, int nkeyvals) { - g_return_if_fail(VIRT_VIEWER_IS_DISPLAY(self)); + g_return_if_fail(VIRT_VIEWER_IS_DISPLAY(display)); - VIRT_VIEWER_DISPLAY_GET_CLASS(self)->send_keys(self, keyvals, nkeyvals); + VIRT_VIEWER_DISPLAY_GET_CLASS(display)->send_keys(display, keyvals, nkeyvals); } -GdkPixbuf* virt_viewer_display_get_pixbuf(VirtViewerDisplay *self) +GdkPixbuf* virt_viewer_display_get_pixbuf(VirtViewerDisplay *display) { - g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(self), NULL); + g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(display), NULL); - return VIRT_VIEWER_DISPLAY_GET_CLASS(self)->get_pixbuf(self); + return VIRT_VIEWER_DISPLAY_GET_CLASS(display)->get_pixbuf(display); } -gboolean virt_viewer_display_open_fd(VirtViewerDisplay *self, int fd) +gboolean virt_viewer_display_open_fd(VirtViewerDisplay *display, int fd) { - g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(self), FALSE); + g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(display), FALSE); - return VIRT_VIEWER_DISPLAY_GET_CLASS(self)->open_fd(self, fd); + return VIRT_VIEWER_DISPLAY_GET_CLASS(display)->open_fd(display, fd); } -gboolean virt_viewer_display_open_host(VirtViewerDisplay *self, char *host, char *port) +gboolean virt_viewer_display_open_host(VirtViewerDisplay *display, char *host, char *port) { VirtViewerDisplayClass *klass; - g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(self), FALSE); + g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(display), FALSE); - klass = VIRT_VIEWER_DISPLAY_GET_CLASS(self); - return klass->open_host(self, host, port); + klass = VIRT_VIEWER_DISPLAY_GET_CLASS(display); + return klass->open_host(display, host, port); } -gboolean virt_viewer_display_channel_open_fd(VirtViewerDisplay *self, +gboolean virt_viewer_display_channel_open_fd(VirtViewerDisplay *display, VirtViewerDisplayChannel *channel, int fd) { - g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(self), FALSE); + g_return_val_if_fail(VIRT_VIEWER_IS_DISPLAY(display), FALSE); - return VIRT_VIEWER_DISPLAY_GET_CLASS(self)->channel_open_fd(self, channel, fd); + return VIRT_VIEWER_DISPLAY_GET_CLASS(display)->channel_open_fd(display, channel, fd); } /* diff --git a/src/virt-viewer-display.h b/src/virt-viewer-display.h index 6e8057a..c60e62e 100644 --- a/src/virt-viewer-display.h +++ b/src/virt-viewer-display.h @@ -24,7 +24,7 @@ #ifndef _VIRT_VIEWER_DISPLAY_H #define _VIRT_VIEWER_DISPLAY_H -#include <glib-object.h> +#include <gtk/gtk.h> #include "virt-viewer-priv.h" @@ -47,15 +47,22 @@ G_BEGIN_DECLS #define VIRT_VIEWER_DISPLAY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_DISPLAY, VirtViewerDisplayClass)) +typedef struct _VirtViewerDisplay VirtViewerDisplay; +typedef struct _VirtViewerDisplayClass VirtViewerDisplayClass; +typedef struct _VirtViewerDisplayPrivate VirtViewerDisplayPrivate; + + /* perhaps this become an interface, and be pushed in gtkvnc and spice? */ struct _VirtViewerDisplay { - GObject parent; + GtkBin parent; + VirtViewer *viewer; - GtkWidget *widget; + + VirtViewerDisplayPrivate *priv; }; struct _VirtViewerDisplayClass { - GObjectClass parent_class; + GtkBinClass parent_class; /* virtual methods */ void (* close) (VirtViewerDisplay* display); @@ -70,6 +77,22 @@ struct _VirtViewerDisplayClass { GType virt_viewer_display_get_type(void); +GtkWidget *virt_viewer_display_new(void); + +void virt_viewer_display_set_desktop_size(VirtViewerDisplay *display, + guint width, + guint height); + +void virt_viewer_display_get_desktop_size(VirtViewerDisplay *display, + guint *width, + guint *height); + +void virt_viewer_display_set_zoom_level(VirtViewerDisplay *display, + guint zoom); +void virt_viewer_display_set_zoom(VirtViewerDisplay *display, + gboolean zoom); + + void virt_viewer_display_close(VirtViewerDisplay* display); void virt_viewer_display_send_keys(VirtViewerDisplay* display, const guint *keyvals, int nkeyvals); diff --git a/src/virt-viewer-priv.h b/src/virt-viewer-priv.h index 0cc16af..b3053c2 100644 --- a/src/virt-viewer-priv.h +++ b/src/virt-viewer-priv.h @@ -57,7 +57,6 @@ struct _VirtViewer { GtkWidget *container; GtkWidget *notebook; - GtkWidget *align; GtkWidget *status; GtkWidget *toolbar; @@ -65,8 +64,6 @@ struct _VirtViewer { char *pretty_address; - int desktopWidth; - int desktopHeight; gboolean autoResize; gboolean fullscreen; gboolean withEvents; @@ -87,7 +84,9 @@ struct _VirtViewer { gchar *clipboard; - VirtViewerDisplay *display; + GtkWidget *display; + + gint zoomlevel; char *unixsock; char *ghost; @@ -113,7 +112,6 @@ void virt_viewer_set_status(VirtViewer *viewer, const char *text); void virt_viewer_set_title(VirtViewer *viewer, gboolean grabbed); void virt_viewer_enable_modifiers(VirtViewer *viewer); void virt_viewer_disable_modifiers(VirtViewer *viewer); -void virt_viewer_add_display_and_realize(VirtViewer *viewer); void virt_viewer_server_cut_text(VirtViewer *viewer, const gchar *text); void virt_viewer_resize_main_window(VirtViewer *viewer); void virt_viewer_channel_open_fd(VirtViewer *viewer, VirtViewerDisplayChannel *channel); diff --git a/src/virt-viewer-util.h b/src/virt-viewer-util.h index 2c067ad..f2fec29 100644 --- a/src/virt-viewer-util.h +++ b/src/virt-viewer-util.h @@ -28,7 +28,7 @@ extern gboolean doDebug; -#define DEBUG_LOG(s, ...) do { if (doDebug) g_debug((s), ## __VA_ARGS__); } while (0) +#define DEBUG_LOG(s, ...) do { if (doDebug) g_debug(s, ## __VA_ARGS__); } while (0) #define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) diff --git a/src/virt-viewer.c b/src/virt-viewer.c index 87efa62..3f1f589 100644 --- a/src/virt-viewer.c +++ b/src/virt-viewer.c @@ -47,7 +47,6 @@ #include "virt-viewer.h" #include "virt-viewer-priv.h" -#include "virt-viewer-align.h" #include "virt-viewer-events.h" #include "virt-viewer-auth.h" #include "virt-viewer-display-vnc.h" @@ -163,24 +162,6 @@ virt_viewer_simple_message_dialog(GtkWidget *window, } -void -virt_viewer_add_display_and_realize(VirtViewer *viewer) -{ - g_return_if_fail(viewer != NULL); - g_return_if_fail(viewer->display != NULL); - g_return_if_fail(viewer->display->widget != NULL); - - gtk_container_add(GTK_CONTAINER(viewer->align), viewer->display->widget); - - if (!viewer->window) { - gtk_container_add(GTK_CONTAINER(viewer->container), GTK_WIDGET(viewer->notebook)); - gtk_widget_show_all(viewer->container); - } - - gtk_widget_realize(viewer->display->widget); -} - - /* * This code attempts to resize the top level window to be large enough * to contain the entire display desktop at 1:1 ratio. If the local desktop @@ -195,6 +176,8 @@ virt_viewer_resize_main_window(VirtViewer *viewer) int width, height; double desktopAspect; double screenAspect; + guint desktopWidth; + guint desktopHeight; DEBUG_LOG("Preparing main window resize"); if (!viewer->active) { @@ -202,7 +185,10 @@ virt_viewer_resize_main_window(VirtViewer *viewer) return; } - gtk_window_resize(GTK_WINDOW (viewer->window), 1, 1); + gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); + + virt_viewer_display_get_desktop_size(VIRT_VIEWER_DISPLAY(viewer->display), + &desktopWidth, &desktopHeight); screen = gtk_widget_get_screen(viewer->window); gdk_screen_get_monitor_geometry(screen, @@ -210,30 +196,30 @@ virt_viewer_resize_main_window(VirtViewer *viewer) (screen, gtk_widget_get_window(viewer->window)), &fullscreen); - desktopAspect = (double)viewer->desktopWidth / (double)viewer->desktopHeight; + desktopAspect = (double)desktopWidth / (double)desktopHeight; screenAspect = (double)(fullscreen.width - 128) / (double)(fullscreen.height - 128); - if ((viewer->desktopWidth > (fullscreen.width - 128)) || - (viewer->desktopHeight > (fullscreen.height - 128))) { + if ((desktopWidth > (fullscreen.width - 128)) || + (desktopHeight > (fullscreen.height - 128))) { /* Doesn't fit native res, so go as large as possible maintaining aspect ratio */ if (screenAspect > desktopAspect) { - width = viewer->desktopHeight * desktopAspect; - height = viewer->desktopHeight; + width = desktopHeight * desktopAspect; + height = desktopHeight; } else { - width = viewer->desktopWidth; - height = viewer->desktopWidth / desktopAspect; + width = desktopWidth; + height = desktopWidth / desktopAspect; } } else { - width = viewer->desktopWidth; - height = viewer->desktopHeight; + width = desktopWidth; + height = desktopHeight; } DEBUG_LOG("Decided todo %dx%d (desktop is %dx%d, fullscreen is %dx%d", - width, height, viewer->desktopWidth, viewer->desktopHeight, + width, height, desktopWidth, desktopHeight, fullscreen.width, fullscreen.height); - virt_viewer_align_set_preferred_size(VIRT_VIEWER_ALIGN(viewer->align), + virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(viewer->display), width, height); } @@ -242,7 +228,11 @@ virt_viewer_menu_view_zoom_out(GtkWidget *menu G_GNUC_UNUSED, VirtViewer *viewer) { gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); - virt_viewer_align_zoom_out(VIRT_VIEWER_ALIGN(viewer->align)); + if (viewer->zoomlevel > 10) + viewer->zoomlevel -= 10; + + if (viewer->display) + virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(viewer->display), viewer->zoomlevel); } void @@ -250,7 +240,11 @@ virt_viewer_menu_view_zoom_in(GtkWidget *menu G_GNUC_UNUSED, VirtViewer *viewer) { gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); - virt_viewer_align_zoom_in(VIRT_VIEWER_ALIGN(viewer->align)); + if (viewer->zoomlevel < 400) + viewer->zoomlevel += 10; + + if (viewer->display) + virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(viewer->display), viewer->zoomlevel); } void @@ -258,7 +252,10 @@ virt_viewer_menu_view_zoom_reset(GtkWidget *menu G_GNUC_UNUSED, VirtViewer *viewer) { gtk_window_resize(GTK_WINDOW(viewer->window), 1, 1); - virt_viewer_align_zoom_normal(VIRT_VIEWER_ALIGN(viewer->align)); + viewer->zoomlevel = 100; + + if (viewer->display) + virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(viewer->display), viewer->zoomlevel); } void @@ -366,7 +363,7 @@ virt_viewer_quit(VirtViewer *viewer) g_return_if_fail(viewer != NULL); if (viewer->display) - virt_viewer_display_close(viewer->display); + virt_viewer_display_close(VIRT_VIEWER_DISPLAY(viewer->display)); gtk_main_quit(); } @@ -464,7 +461,7 @@ virt_viewer_menu_send(GtkWidget *menu G_GNUC_UNUSED, for (i = 0 ; i < G_N_ELEMENTS(keyCombos) ; i++) { if (!strcmp(text, keyCombos[i].label)) { DEBUG_LOG("Sending key combo %s", gtk_label_get_text(GTK_LABEL(label))); - virt_viewer_display_send_keys(viewer->display, + virt_viewer_display_send_keys(VIRT_VIEWER_DISPLAY(viewer->display), keyCombos[i].keys, keyCombos[i].nkeys); return; @@ -478,7 +475,7 @@ static void virt_viewer_save_screenshot(VirtViewer *viewer, const char *file) { - GdkPixbuf *pix = virt_viewer_display_get_pixbuf(viewer->display); + GdkPixbuf *pix = virt_viewer_display_get_pixbuf(VIRT_VIEWER_DISPLAY(viewer->display)); gdk_pixbuf_save(pix, file, "png", NULL, "tEXt::Generator App", PACKAGE, NULL); gdk_pixbuf_unref(pix); @@ -853,10 +850,8 @@ virt_viewer_show_display(VirtViewer *viewer) { g_return_if_fail(viewer != NULL); g_return_if_fail(viewer->display != NULL); - g_return_if_fail(viewer->display->widget != NULL); - gtk_widget_show(viewer->display->widget); - gtk_widget_grab_focus(viewer->display->widget); + gtk_widget_grab_focus(gtk_bin_get_child(GTK_BIN(viewer->display))); gtk_notebook_set_current_page(GTK_NOTEBOOK(viewer->notebook), 1); } @@ -899,12 +894,12 @@ virt_viewer_extract_connect_info(VirtViewer *viewer, if (g_strcasecmp(type, "vnc") == 0) { virt_viewer_trace(viewer, "Guest %s has a %s display\n", viewer->domkey, type); - viewer->display = VIRT_VIEWER_DISPLAY(virt_viewer_display_vnc_new(viewer)); + viewer->display = virt_viewer_display_vnc_new(viewer); #ifdef HAVE_SPICE_GTK } else if (g_strcasecmp(type, "spice") == 0) { virt_viewer_trace(viewer, "Guest %s has a %s display\n", viewer->domkey, type); - viewer->display = VIRT_VIEWER_DISPLAY(virt_viewer_display_spice_new(viewer)); + viewer->display = virt_viewer_display_spice_new(viewer); #endif } else { virt_viewer_trace(viewer, "Guest %s has unsupported %s display type\n", @@ -913,6 +908,10 @@ virt_viewer_extract_connect_info(VirtViewer *viewer, viewer->domkey); goto cleanup; } + gtk_notebook_append_page(GTK_NOTEBOOK(viewer->notebook), viewer->display, NULL); + if (gtk_bin_get_child(GTK_BIN(viewer->display))) + gtk_widget_realize(GTK_WIDGET(gtk_bin_get_child(GTK_BIN(viewer->display)))); + gtk_widget_show_all(viewer->display); xpath = g_strdup_printf("string(/domain/devices/graphics[@type='%s']/@port)", type); if ((viewer->gport = virt_viewer_extract_xpath_string(xmldesc, xpath)) == NULL) { @@ -969,7 +968,7 @@ virt_viewer_channel_open_fd(VirtViewer *viewer, virt_viewer_simple_message_dialog(viewer->window, _("Can't connect to channel, SSH only supported.")); if (fd >= 0) - virt_viewer_display_channel_open_fd(viewer->display, channel, fd); + virt_viewer_display_channel_open_fd(VIRT_VIEWER_DISPLAY(viewer->display), channel, fd); } #else void @@ -1029,11 +1028,11 @@ virt_viewer_activate(VirtViewer *viewer, #endif if (fd >= 0) { - ret = virt_viewer_display_open_fd(viewer->display, fd); + ret = virt_viewer_display_open_fd(VIRT_VIEWER_DISPLAY(viewer->display), fd); } else { virt_viewer_trace(viewer, "Opening direct TCP connection to display at %s:%s\n", viewer->ghost, viewer->gport); - ret = virt_viewer_display_open_host(viewer->display, + ret = virt_viewer_display_open_host(VIRT_VIEWER_DISPLAY(viewer->display), viewer->ghost, viewer->gport); } @@ -1107,7 +1106,7 @@ virt_viewer_deactivate(VirtViewer *viewer) return; if (viewer->display) - virt_viewer_display_close(viewer->display); + virt_viewer_display_close(VIRT_VIEWER_DISPLAY(viewer->display)); free(viewer->domtitle); viewer->domtitle = NULL; @@ -1346,8 +1345,6 @@ virt_viewer_start(const char *uri, viewer->domkey = g_strdup(name); viewer->uri = g_strdup(uri); - viewer->desktopWidth = viewer->desktopHeight = 400; - g_value_init(&viewer->accelSetting, G_TYPE_STRING); virt_viewer_events_register(); @@ -1376,16 +1373,14 @@ virt_viewer_start(const char *uri, } viewer->status = gtk_label_new(""); - viewer->align = virt_viewer_align_new(); - virt_viewer_align_set_zoom_level(VIRT_VIEWER_ALIGN(viewer->align), zoom); + viewer->zoomlevel = zoom; viewer->notebook = gtk_notebook_new(); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(viewer->notebook), FALSE); gtk_notebook_set_show_border(GTK_NOTEBOOK(viewer->notebook), FALSE); gtk_notebook_append_page(GTK_NOTEBOOK(viewer->notebook), viewer->status, NULL); - gtk_notebook_append_page(GTK_NOTEBOOK(viewer->notebook), viewer->align, NULL); if (container) { viewer->container = container; @@ -1396,10 +1391,7 @@ virt_viewer_start(const char *uri, GtkWidget *vbox = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "viewer-box")); virt_viewer_toolbar_setup(viewer); - //gtk_box_pack_end(GTK_BOX(vbox), viewer->toolbar, TRUE, TRUE, 0); - //gtk_box_pack_end(GTK_BOX(vbox), viewer->notebook, TRUE, TRUE, 0); gtk_box_pack_end(GTK_BOX(vbox), viewer->layout, TRUE, TRUE, 0); - gtk_widget_show_all(GTK_WIDGET(vbox)); GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(viewer->builder, "viewer")); GSList *accels; |