On Wed, Sep 26, 2018 at 07:26:27PM +0400, marcandre.lureau@xxxxxxxxxx wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > > This is not a graphical display, so the application will have to deal > with it with care. > > You may argue that we need a large refactoring to introduce a more > generic "console" object, that could be either graphical or textual. > For now, this does work well enough for me. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> Looks fine, Acked-by: Victor Toso <victortoso@xxxxxxxxxx> > --- > src/Makefile.am | 4 + > src/virt-viewer-display-vte.c | 319 ++++++++++++++++++++++++++++++++++ > src/virt-viewer-display-vte.h | 81 +++++++++ > 3 files changed, 404 insertions(+) > create mode 100644 src/virt-viewer-display-vte.c > create mode 100644 src/virt-viewer-display-vte.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index 0a3cbbf..3a5d90d 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -72,6 +72,8 @@ libvirt_viewer_la_SOURCES = \ > virt-viewer-window.c \ > virt-viewer-vm-connection.h \ > virt-viewer-vm-connection.c \ > + virt-viewer-display-vte.h \ > + virt-viewer-display-vte.c \ > virt-viewer-timed-revealer.c \ > virt-viewer-timed-revealer.h \ > $(NULL) > @@ -110,6 +112,7 @@ COMMON_LIBS = \ > $(GLIB2_LIBS) \ > $(GTK_LIBS) \ > $(GTK_VNC_LIBS) \ > + $(VTE_LIBS) \ > $(SPICE_GTK_LIBS) \ > $(LIBXML2_LIBS) \ > $(OVIRT_LIBS) \ > @@ -121,6 +124,7 @@ COMMON_CFLAGS = \ > $(GLIB2_CFLAGS) \ > $(GTK_CFLAGS) \ > $(GTK_VNC_CFLAGS) \ > + $(VTE_CFLAGS) \ > $(SPICE_GTK_CFLAGS) \ > $(LIBXML2_CFLAGS) \ > $(OVIRT_CFLAGS) \ > diff --git a/src/virt-viewer-display-vte.c b/src/virt-viewer-display-vte.c > new file mode 100644 > index 0000000..bd7ac7d > --- /dev/null > +++ b/src/virt-viewer-display-vte.c > @@ -0,0 +1,319 @@ > +/* > + * Virt Viewer: A virtual machine console viewer > + * > + * Copyright (C) 2018 Red Hat, Inc. > + * > + * 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: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > + */ > + > +#include <config.h> > +#include <glib/gi18n.h> > + > +#ifdef HAVE_VTE > +#include <vte/vte.h> > +#endif > + > +#include "virt-viewer-auth.h" > +#include "virt-viewer-display-vte.h" > +#include "virt-viewer-util.h" > + > +G_DEFINE_TYPE(VirtViewerDisplayVte, virt_viewer_display_vte, VIRT_VIEWER_TYPE_DISPLAY) > + > +struct _VirtViewerDisplayVtePrivate { > +#ifdef HAVE_VTE > + VteTerminal *vte; > +#endif > + GtkWidget *scroll; > + gchar *name; > +}; > + > +#define VIRT_VIEWER_DISPLAY_VTE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), VIRT_VIEWER_TYPE_DISPLAY_VTE, VirtViewerDisplayVtePrivate)) > + > +enum { > + PROP_0, > + > + PROP_NAME, > +}; > + > +static void > +virt_viewer_display_vte_finalize(GObject *obj) > +{ > + G_OBJECT_CLASS(virt_viewer_display_vte_parent_class)->finalize(obj); > +} > + > +static void > +virt_viewer_display_vte_set_property(GObject *object, > + guint prop_id, > + const GValue *value, > + GParamSpec *pspec) > +{ > + VirtViewerDisplayVte *self = VIRT_VIEWER_DISPLAY_VTE(object); > + > + switch (prop_id) { > + case PROP_NAME: > + g_free(self->priv->name); > + self->priv->name = g_value_dup_string(value); > + break; > + default: > + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > + break; > + } > +} > + > +static void > +virt_viewer_display_vte_get_property(GObject *object, > + guint prop_id, > + GValue *value, > + GParamSpec *pspec) > +{ > + VirtViewerDisplayVte *self = VIRT_VIEWER_DISPLAY_VTE(object); > + > + switch (prop_id) { > + case PROP_NAME: > + g_value_set_string(value, self->priv->name); > + break; > + default: > + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); > + break; > + } > +} > + > +static void > +virt_viewer_display_vte_size_allocate(GtkWidget *widget G_GNUC_UNUSED, > + GtkAllocation *allocation G_GNUC_UNUSED) > +{ > + GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); > + > + if (child && gtk_widget_get_visible(child)) > + gtk_widget_size_allocate(child, allocation); > +} > + > +static void > +virt_viewer_display_vte_class_init(VirtViewerDisplayVteClass *klass) > +{ > + GObjectClass *oclass = G_OBJECT_CLASS(klass); > + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); > + > + oclass->set_property = virt_viewer_display_vte_set_property; > + oclass->get_property = virt_viewer_display_vte_get_property; > + oclass->finalize = virt_viewer_display_vte_finalize; > + /* override display desktop aspect-ratio behaviour */ > + widget_class->size_allocate = virt_viewer_display_vte_size_allocate; > + > + g_object_class_install_property(oclass, > + PROP_NAME, > + g_param_spec_string("name", > + "Name", > + "Console name", > + NULL, > + G_PARAM_READWRITE| > + G_PARAM_CONSTRUCT_ONLY| > + G_PARAM_STATIC_STRINGS)); > + g_signal_new("commit", > + G_OBJECT_CLASS_TYPE(oclass), > + G_SIGNAL_RUN_FIRST, > + 0, > + NULL, NULL, > + NULL, > + G_TYPE_NONE, > + 2, > + G_TYPE_POINTER, G_TYPE_INT); > + > + g_type_class_add_private(klass, sizeof(VirtViewerDisplayVtePrivate)); > +} > + > +static void > +virt_viewer_display_vte_init(VirtViewerDisplayVte *self G_GNUC_UNUSED) > +{ > + self->priv = VIRT_VIEWER_DISPLAY_VTE_GET_PRIVATE(self); > +} > + > +#ifdef HAVE_VTE > +static void > +virt_viewer_display_vte_commit(VirtViewerDisplayVte *self, > + const gchar *text, > + guint size, > + gpointer user_data G_GNUC_UNUSED) > +{ > + g_signal_emit_by_name(self, "commit", text, size); > +} > +#endif > + > +static void > +virt_viewer_display_vte_adj_changed(VirtViewerDisplayVte *self, > + GtkAdjustment *adjustment) > +{ > + gtk_widget_set_visible(self->priv->scroll, > + gtk_adjustment_get_upper(adjustment) > gtk_adjustment_get_page_size(adjustment)); > +} > + > +GtkWidget * > +virt_viewer_display_vte_new(VirtViewerSession *session, const char *name) > +{ > + VirtViewerDisplayVte *self; > + GtkWidget *grid, *scroll = NULL, *vte; > + > + self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_VTE, > + "session", session, > + "nth-display", -1, > + "name", name, > + NULL); > +#ifdef HAVE_VTE > + vte = vte_terminal_new(); > + self->priv->vte = VTE_TERMINAL(g_object_ref(vte)); > + virt_viewer_signal_connect_object(vte, "commit", > + G_CALLBACK(virt_viewer_display_vte_commit), > + self, G_CONNECT_SWAPPED); > + scroll = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, > + gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vte))); > + self->priv->scroll = scroll; > +#else > + vte = gtk_label_new(_("Console support is compiled out!")); > +#endif > + g_object_set(vte, "hexpand", TRUE, "vexpand", TRUE, NULL); > + > + grid = gtk_grid_new(); > + > + gtk_container_add(GTK_CONTAINER(grid), vte); > + if (scroll) { > + gtk_container_add(GTK_CONTAINER(grid), scroll); > + gtk_widget_hide(scroll); > + virt_viewer_signal_connect_object(gtk_range_get_adjustment(GTK_RANGE(scroll)), > + "changed", G_CALLBACK(virt_viewer_display_vte_adj_changed), > + self, G_CONNECT_SWAPPED); > + } > + > + gtk_container_add(GTK_CONTAINER(self), grid); > + > + return GTK_WIDGET(self); > +} > + > +/* adapted from gnome-terminal */ > +/* Allow scales a bit smaller and a bit larger than the usual pango ranges */ > +#define TERMINAL_SCALE_XXX_SMALL (PANGO_SCALE_XX_SMALL/1.2) > +#define TERMINAL_SCALE_XXXX_SMALL (TERMINAL_SCALE_XXX_SMALL/1.2) > +#define TERMINAL_SCALE_XXXXX_SMALL (TERMINAL_SCALE_XXXX_SMALL/1.2) > +#define TERMINAL_SCALE_XXX_LARGE (PANGO_SCALE_XX_LARGE*1.2) > +#define TERMINAL_SCALE_XXXX_LARGE (TERMINAL_SCALE_XXX_LARGE*1.2) > +#define TERMINAL_SCALE_XXXXX_LARGE (TERMINAL_SCALE_XXXX_LARGE*1.2) > +#define TERMINAL_SCALE_MINIMUM (TERMINAL_SCALE_XXXXX_SMALL/1.2) > +#define TERMINAL_SCALE_MAXIMUM (TERMINAL_SCALE_XXXXX_LARGE*1.2) > + > +#ifdef HAVE_VTE > +static const double zoom_factors[] = { > + TERMINAL_SCALE_MINIMUM, > + TERMINAL_SCALE_XXXXX_SMALL, > + TERMINAL_SCALE_XXXX_SMALL, > + TERMINAL_SCALE_XXX_SMALL, > + PANGO_SCALE_XX_SMALL, > + PANGO_SCALE_X_SMALL, > + PANGO_SCALE_SMALL, > + PANGO_SCALE_MEDIUM, > + PANGO_SCALE_LARGE, > + PANGO_SCALE_X_LARGE, > + PANGO_SCALE_XX_LARGE, > + TERMINAL_SCALE_XXX_LARGE, > + TERMINAL_SCALE_XXXX_LARGE, > + TERMINAL_SCALE_XXXXX_LARGE, > + TERMINAL_SCALE_MAXIMUM > +}; > + > +static gboolean > +find_larger_zoom_factor (double *zoom) > +{ > + double current = *zoom; > + guint i; > + > + for (i = 0; i < G_N_ELEMENTS (zoom_factors); ++i) > + { > + /* Find a font that's larger than this one */ > + if ((zoom_factors[i] - current) > 1e-6) > + { > + *zoom = zoom_factors[i]; > + return TRUE; > + } > + } > + > + return FALSE; > +} > + > +static gboolean > +find_smaller_zoom_factor (double *zoom) > +{ > + double current = *zoom; > + int i; > + > + i = (int) G_N_ELEMENTS (zoom_factors) - 1; > + while (i >= 0) > + { > + /* Find a font that's smaller than this one */ > + if ((current - zoom_factors[i]) > 1e-6) > + { > + *zoom = zoom_factors[i]; > + return TRUE; > + } > + > + --i; > + } > + > + return FALSE; > +} > + > +void virt_viewer_display_vte_feed(VirtViewerDisplayVte *display, gpointer data, int size) > +{ > + vte_terminal_feed(display->priv->vte, data, size); > +} > + > +void virt_viewer_display_vte_zoom_in(VirtViewerDisplayVte *self) > +{ > + double zoom = vte_terminal_get_font_scale(self->priv->vte); > + > + if (!find_larger_zoom_factor(&zoom)) > + return; > + > + vte_terminal_set_font_scale(self->priv->vte, zoom); > +} > + > +void virt_viewer_display_vte_zoom_out(VirtViewerDisplayVte *self) > +{ > + double zoom = vte_terminal_get_font_scale(self->priv->vte); > + > + if (!find_smaller_zoom_factor(&zoom)) > + return; > + > + vte_terminal_set_font_scale(self->priv->vte, zoom); > +} > + > +void virt_viewer_display_vte_zoom_reset(VirtViewerDisplayVte *self) > +{ > + vte_terminal_set_font_scale(self->priv->vte, PANGO_SCALE_MEDIUM); > +} > +#else > +void virt_viewer_display_vte_feed(VirtViewerDisplayVte *self G_GNUC_UNUSED, > + gpointer data G_GNUC_UNUSED, int size G_GNUC_UNUSED) > +{ > +} > +void virt_viewer_display_vte_zoom_in(VirtViewerDisplayVte *self G_GNUC_UNUSED) > +{ > +} > +void virt_viewer_display_vte_zoom_out(VirtViewerDisplayVte *self G_GNUC_UNUSED) > +{ > +} > +void virt_viewer_display_vte_zoom_reset(VirtViewerDisplayVte *self G_GNUC_UNUSED) > +{ > +} > +#endif > diff --git a/src/virt-viewer-display-vte.h b/src/virt-viewer-display-vte.h > new file mode 100644 > index 0000000..8d111b7 > --- /dev/null > +++ b/src/virt-viewer-display-vte.h > @@ -0,0 +1,81 @@ > +/* > + * Virt Viewer: A virtual machine console viewer > + * > + * Copyright (C) 2018 Red Hat, Inc. > + * > + * 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: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > + */ > +#ifndef _VIRT_VIEWER_DISPLAY_VTE_H > +#define _VIRT_VIEWER_DISPLAY_VTE_H > + > +#include <glib-object.h> > + > +#include "virt-viewer-display.h" > + > +G_BEGIN_DECLS > + > +#define VIRT_VIEWER_TYPE_DISPLAY_VTE virt_viewer_display_vte_get_type() > + > +#define VIRT_VIEWER_DISPLAY_VTE(obj) \ > + (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_DISPLAY_VTE, VirtViewerDisplayVte)) > + > +#define VIRT_VIEWER_DISPLAY_VTE_CLASS(klass) \ > + (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_DISPLAY_VTE, VirtViewerDisplayVteClass)) > + > +#define VIRT_VIEWER_IS_DISPLAY_VTE(obj) \ > + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_DISPLAY_VTE)) > + > +#define VIRT_VIEWER_IS_DISPLAY_VTE_CLASS(klass) \ > + (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_DISPLAY_VTE)) > + > +#define VIRT_VIEWER_DISPLAY_VTE_GET_CLASS(obj) \ > + (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_DISPLAY_VTE, VirtViewerDisplayVteClass)) > + > +typedef struct _VirtViewerDisplayVte VirtViewerDisplayVte; > +typedef struct _VirtViewerDisplayVteClass VirtViewerDisplayVteClass; > +typedef struct _VirtViewerDisplayVtePrivate VirtViewerDisplayVtePrivate; > + > +struct _VirtViewerDisplayVte { > + VirtViewerDisplay parent; > + > + VirtViewerDisplayVtePrivate *priv; > +}; > + > +struct _VirtViewerDisplayVteClass { > + VirtViewerDisplayClass parent_class; > +}; > + > +GType virt_viewer_display_vte_get_type(void); > + > +GtkWidget* virt_viewer_display_vte_new(VirtViewerSession *session, const char *name); > + > +void virt_viewer_display_vte_feed(VirtViewerDisplayVte *vte, gpointer data, int size); > + > +void virt_viewer_display_vte_zoom_reset(VirtViewerDisplayVte *vte); > +void virt_viewer_display_vte_zoom_in(VirtViewerDisplayVte *vte); > +void virt_viewer_display_vte_zoom_out(VirtViewerDisplayVte *vte); > + > +G_END_DECLS > + > +#endif /* _VIRT_VIEWER_DISPLAY_VTE_H */ > +/* > + * Local variables: > + * c-indent-level: 4 > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > -- > 2.19.0.271.gfe8321ec05 >
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list