[gtk-vnc] src: add support for zoom level
- From: Daniel P. Berrange <dberrange src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk-vnc] src: add support for zoom level
- Date: Wed, 7 Apr 2021 17:09:46 +0000 (UTC)
commit 06d790b04191f739207593cd6339e0ebf68caa73
Author: Daniel P. Berrangé <dan berrange com>
Date: Wed Apr 7 17:33:27 2021 +0100
src: add support for zoom level
This allows the remote desktop be to kept at a fixed scaling
factor between 10% and 400%.
Signed-off-by: Daniel P. Berrangé <berrange redhat com>
examples/gvncviewer.c | 9 +++--
meson.build | 2 +-
src/libgtk-vnc_sym.version | 3 ++
src/meson.build | 1 +
src/vncdisplay.c | 84 +++++++++++++++++++++++++++++++++++++++++++---
src/vncdisplay.h | 3 ++
6 files changed, 94 insertions(+), 8 deletions(-)
---
diff --git a/examples/gvncviewer.c b/examples/gvncviewer.c
index 50e111f..e1794b5 100644
--- a/examples/gvncviewer.c
+++ b/examples/gvncviewer.c
@@ -82,11 +82,13 @@
static gchar **args = NULL;
+int opt_zoom = 100;
static const GOptionEntry options [] =
{
- {
- G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &args,
- NULL, "[hostname][:display]" },
+ { "zoom", 'z', 0, G_OPTION_ARG_INT, &opt_zoom,
+ "Zoom level of window, in percentage", "ZOOM" },
+ { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &args,
+ NULL, "[hostname][:display]" },
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, 0 }
};
@@ -891,6 +893,7 @@ int main(int argc, char **argv)
vnc_display_set_scaling(VNC_DISPLAY(vnc), TRUE);
vnc_display_set_allow_resize(VNC_DISPLAY(vnc), TRUE);
vnc_display_set_lossy_encoding(VNC_DISPLAY(vnc), TRUE);
+ vnc_display_set_zoom_level(VNC_DISPLAY(vnc), opt_zoom);
g_signal_connect(window, "delete-event",
G_CALLBACK(gtk_main_quit), NULL);
diff --git a/meson.build b/meson.build
index d48db12..e2b31d1 100644
--- a/meson.build
+++ b/meson.build
@@ -74,7 +74,7 @@ libpulse_min_version = '11.0'
# common
gobject_introspection_min_version = '1.56.0'
-
+libm_dep = cc.find_library('m', required : true)
gobject_dep = dependency('gobject-2.0', version: '>= ' + glib_min_version)
gio_dep = dependency('gio-2.0', version: '>= ' + glib_min_version)
gio_unix_dep = dependency('gio-unix-2.0', version: '>= ' + glib_min_version, required: false)
diff --git a/src/libgtk-vnc_sym.version b/src/libgtk-vnc_sym.version
index a235e02..4446b20 100644
--- a/src/libgtk-vnc_sym.version
+++ b/src/libgtk-vnc_sym.version
@@ -97,6 +97,9 @@
vnc_display_get_keep_aspect_ratio;
vnc_display_set_keep_aspect_ratio;
+ vnc_display_get_zoom_level;
+ vnc_display_set_zoom_level;
+
local:
*;
};
diff --git a/src/meson.build b/src/meson.build
index d3ff69b..5306fb9 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -360,6 +360,7 @@ if host_machine.system() == 'linux'
endif
gtk_vnc_deps = [
+ libm_dep,
gtk_dep,
gvnc_dep,
gtk_vnc_enum_headers_dep,
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 6e98630..f67448a 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -39,6 +39,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <math.h>
#ifdef G_OS_WIN32
#include <windows.h>
@@ -86,6 +87,7 @@ struct _VncDisplayPrivate
gboolean allow_resize;
gboolean smoothing;
gboolean keep_aspect_ratio;
+ guint zoom_level;
GSList *preferable_auths;
GSList *preferable_vencrypt_subauths;
@@ -122,6 +124,7 @@ enum
PROP_SMOOTHING,
PROP_KEEP_ASPECT_RATIO,
PROP_DEPTH,
+ PROP_ZOOM_LEVEL,
PROP_GRAB_KEYS,
PROP_CONNECTION,
};
@@ -232,6 +235,9 @@ vnc_display_get_property (GObject *object,
case PROP_DEPTH:
g_value_set_enum (value, vnc->priv->depth);
break;
+ case PROP_ZOOM_LEVEL:
+ g_value_set_uint (value, vnc->priv->zoom_level);
+ break;
case PROP_GRAB_KEYS:
g_value_set_boxed(value, vnc->priv->vncgrabseq);
break;
@@ -290,6 +296,9 @@ vnc_display_set_property (GObject *object,
case PROP_DEPTH:
vnc_display_set_depth (vnc, g_value_get_enum (value));
break;
+ case PROP_ZOOM_LEVEL:
+ vnc_display_set_zoom_level (vnc, g_value_get_uint (value));
+ break;
case PROP_GRAB_KEYS:
vnc_display_set_grab_keys(vnc, g_value_get_boxed(value));
break;
@@ -449,8 +458,8 @@ get_render_region_info(GtkWidget *widget,
*offsety = 0;
*height = *winheight;
}
- *scalex = 1;
- *scaley = 1;
+ *scalex = round((double)priv->zoom_level / 100.0);
+ *scaley = round((double)priv->zoom_level / 100.0);
}
}
@@ -1200,6 +1209,10 @@ static gboolean configure_event(GtkWidget *widget,
fbw = vnc_framebuffer_get_width(VNC_FRAMEBUFFER(priv->fb));
fbh = vnc_framebuffer_get_height(VNC_FRAMEBUFFER(priv->fb));
+
+ fbw = round(fbw * (double)priv->zoom_level / 100.0);
+ fbh = round(fbh * (double)priv->zoom_level / 100.0);
+
if (cfg->width == fbw &&
cfg->height == fbh) {
VNC_DEBUG("Framebuffer already matches widget size %dx%d", fbw, fbh);
@@ -1213,8 +1226,8 @@ static gboolean configure_event(GtkWidget *widget,
}
VNC_DEBUG("Need to try resize to %dx%d", cfg->width, cfg->height);
- priv->last_resize_reqw = cfg->width;
- priv->last_resize_reqh = cfg->height;
+ priv->last_resize_reqw = round(cfg->width * 100.0 / (double)priv->zoom_level);
+ priv->last_resize_reqh = round(cfg->height * 100.0 / (double)priv->zoom_level);
if (priv->pending_resize_id) {
VNC_DEBUG("Cancel pending resize timer %lu", priv->pending_resize_id);
@@ -1260,6 +1273,8 @@ static void get_preferred_width(GtkWidget *widget,
else
*defwidth = 0;
+ *defwidth = round(*defwidth * (double)priv->zoom_level / 100.0);
+
if (priv->force_size && !priv->allow_scaling)
*minwidth = *defwidth;
}
@@ -1279,6 +1294,8 @@ static void get_preferred_height(GtkWidget *widget,
else
*defheight = 0;
+ *defheight = round(*defheight * (double)priv->zoom_level / 100.0);
+
if (priv->force_size && !priv->allow_scaling)
*minheight = *defheight;
}
@@ -2466,6 +2483,19 @@ static void vnc_display_class_init(VncDisplayClass *klass)
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
+ g_object_class_install_property (object_class,
+ PROP_ZOOM_LEVEL,
+ g_param_spec_uint ( "zoom-level",
+ "Zoom level",
+ "Zoom percentage level",
+ 10,
+ 400,
+ 100,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
g_object_class_install_property (object_class,
PROP_GRAB_KEYS,
g_param_spec_boxed( "grab-keys",
@@ -2723,6 +2753,7 @@ static void vnc_display_init(VncDisplay *display)
priv->allow_resize = FALSE;
priv->smoothing = TRUE;
priv->keep_aspect_ratio = FALSE;
+ priv->zoom_level = 100;
priv->vncgrabseq = vnc_grab_sequence_new_from_string("Control_L+Alt_L");
priv->vncactiveseq = g_new0(gboolean, priv->vncgrabseq->nkeysyms);
@@ -3483,6 +3514,51 @@ gboolean vnc_display_get_read_only(VncDisplay *obj)
}
+/**
+ * vnc_display_set_zoom_level:
+ * @obj: (transfer none): the VNC display widget
+ * @zoom: the zoom percentage level
+ *
+ * Requests a constant scaling factor to be applied to the remote
+ * desktop. The @zoom value is a percentage in the range 10-400.
+ *
+ * If scaling mode is not active, then this results in the remote
+ * desktop always being rendered at the requested zoom level.
+ *
+ * If scaling mode is active, then the remote desktop will be
+ * scaled to fit the widget regardless of the zoom level.
+ *
+ * In both cases, when the remote desktop size changes, the
+ * widget preferred size will reflect the zoom level.
+ */
+void vnc_display_set_zoom_level(VncDisplay *obj, guint zoom)
+{
+ g_return_if_fail (VNC_IS_DISPLAY (obj));
+
+ if (zoom < 10)
+ zoom = 10;
+ if (zoom > 400)
+ zoom = 400;
+
+ obj->priv->zoom_level = zoom;
+}
+
+/**
+ * vnc_display_get_zoom_level:
+ * @obj: (transfer none): the VNC display widget
+ *
+ * Determine the current constant scaling factor.
+ *
+ * Returns: the zoom percentage level between 10-400
+ */
+guint vnc_display_get_zoom_level(VncDisplay *obj)
+{
+ g_return_val_if_fail (VNC_IS_DISPLAY (obj), 100);
+
+ return obj->priv->zoom_level;
+}
+
+
/**
* vnc_display_is_pointer_absolute:
* @obj: (transfer none): the VNC display widget
diff --git a/src/vncdisplay.h b/src/vncdisplay.h
index b6aff2d..0f1120e 100644
--- a/src/vncdisplay.h
+++ b/src/vncdisplay.h
@@ -149,6 +149,9 @@ gboolean vnc_display_get_shared_flag(VncDisplay *obj);
void vnc_display_set_depth(VncDisplay *obj, VncDisplayDepthColor depth);
VncDisplayDepthColor vnc_display_get_depth(VncDisplay *obj);
+void vnc_display_set_zoom_level(VncDisplay *obj, guint zoom);
+guint vnc_display_get_zoom_level(VncDisplay *obj);
+
void vnc_display_force_grab(VncDisplay *obj, gboolean enable);
gboolean vnc_display_is_pointer_absolute(VncDisplay *obj);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]