[virt-tools-list] [PATCH v2 04/16] Add a VirtViewerDisplayVte display kind
Victor Toso
victortoso at redhat.com
Thu Dec 20 16:13:55 UTC 2018
On Wed, Sep 26, 2018 at 07:26:27PM +0400, marcandre.lureau at redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau at redhat.com>
>
> 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 at redhat.com>
Looks fine,
Acked-by: Victor Toso <victortoso at redhat.com>
> ---
> 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 at redhat.com>
> + */
> +
> +#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 at redhat.com>
> + */
> +#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
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20181220/d5877286/attachment.sig>
More information about the virt-tools-list
mailing list