[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