[vinagre] Allow scaling of RDP sessions
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vinagre] Allow scaling of RDP sessions
- Date: Fri, 4 Sep 2015 14:35:17 +0000 (UTC)
commit 66f91ed8a5c07d17f44990a8f5fb7647df04f60d
Author: Marek Kasik <mkasik redhat com>
Date: Fri Sep 4 16:25:54 2015 +0200
Allow scaling of RDP sessions
Add ability to scale RDP sessions using scaling functionality of cairo library.
Session is placed in the center of the window as in other plugins.
https://bugzilla.gnome.org/show_bug.cgi?id=753766
Makefile.am | 2 +
plugins/rdp/vinagre-rdp-connection.c | 121 ++++++++++++++++++-
plugins/rdp/vinagre-rdp-connection.h | 6 +-
plugins/rdp/vinagre-rdp-plugin.c | 26 +++-
plugins/rdp/vinagre-rdp-tab.c | 226 ++++++++++++++++++++++++++++++++-
5 files changed, 364 insertions(+), 17 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 09ff61e..6c1ba2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,6 +153,8 @@ vinagre_vinagre_SOURCES += \
plugins/rdp/vinagre-rdp-plugin.c \
plugins/rdp/vinagre-rdp-connection.c \
plugins/rdp/vinagre-rdp-tab.c
+
+vinagre_vinagre_LDADD += -lm
endif
if VINAGRE_ENABLE_SPICE
diff --git a/plugins/rdp/vinagre-rdp-connection.c b/plugins/rdp/vinagre-rdp-connection.c
index 99182c7..c5f6ed1 100644
--- a/plugins/rdp/vinagre-rdp-connection.c
+++ b/plugins/rdp/vinagre-rdp-connection.c
@@ -23,9 +23,17 @@
#include <vinagre/vinagre-cache-prefs.h>
#include "vinagre-rdp-connection.h"
+#include "vinagre-vala.h"
+
struct _VinagreRdpConnectionPrivate
{
- gint dummy;
+ gboolean scaling;
+};
+
+enum
+{
+ PROP_0,
+ PROP_SCALING,
};
#define VINAGRE_RDP_CONNECTION_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VINAGRE_TYPE_RDP_CONNECTION,
VinagreRdpConnectionPrivate))
@@ -44,21 +52,83 @@ vinagre_rdp_connection_constructed (GObject *object)
}
static void
+vinagre_rdp_connection_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ VinagreRdpConnection *conn;
+
+ g_return_if_fail (VINAGRE_IS_RDP_CONNECTION (object));
+
+ conn = VINAGRE_RDP_CONNECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_SCALING:
+ vinagre_rdp_connection_set_scaling (conn, g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+vinagre_rdp_connection_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ VinagreRdpConnection *conn;
+
+ g_return_if_fail (VINAGRE_IS_RDP_CONNECTION (object));
+
+ conn = VINAGRE_RDP_CONNECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_SCALING:
+ g_value_set_boolean (value, conn->priv->scaling);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
rdp_fill_writer (VinagreConnection *conn, xmlTextWriter *writer)
{
+ VinagreRdpConnection *rdp_conn = VINAGRE_RDP_CONNECTION (conn);
VINAGRE_CONNECTION_CLASS (vinagre_rdp_connection_parent_class)->impl_fill_writer (conn, writer);
+
+ xmlTextWriterWriteFormatElement (writer, BAD_CAST "scaling", "%d", rdp_conn->priv->scaling);
}
static void
rdp_parse_item (VinagreConnection *conn, xmlNode *root)
{
+ xmlNode *curr;
+ xmlChar *s_value;
+ VinagreRdpConnection *rdp_conn = VINAGRE_RDP_CONNECTION (conn);
+
VINAGRE_CONNECTION_CLASS (vinagre_rdp_connection_parent_class)->impl_parse_item (conn, root);
+
+ for (curr = root->children; curr; curr = curr->next)
+ {
+ s_value = xmlNodeGetContent (curr);
+
+ if (!xmlStrcmp(curr->name, BAD_CAST "scaling"))
+ {
+ vinagre_rdp_connection_set_scaling (rdp_conn, vinagre_utils_parse_boolean ((const gchar *)
s_value));
+ }
+
+ xmlFree (s_value);
+ }
}
static void
rdp_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
{
- GtkWidget *u_entry, *spin_button;
+ GtkWidget *u_entry, *spin_button, *scaling_button;
+ gboolean scaling;
guint width, height;
u_entry = g_object_get_data (G_OBJECT (widget), "username_entry");
@@ -101,6 +171,22 @@ rdp_parse_options_widget (VinagreConnection *conn, GtkWidget *widget)
vinagre_cache_prefs_set_integer ("rdp-connection", "height", height);
vinagre_connection_set_height (conn, height);
+
+
+ scaling_button = g_object_get_data (G_OBJECT (widget), "scaling");
+ if (!scaling_button)
+ {
+ g_warning ("Wrong widget passed to rdp_parse_options_widget()");
+ return;
+ }
+
+ scaling = (gboolean) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scaling_button));
+
+ vinagre_cache_prefs_set_boolean ("rdp-connection", "scaling", scaling);
+
+ g_object_set (conn,
+ "scaling", scaling,
+ NULL);
}
static void
@@ -111,11 +197,24 @@ vinagre_rdp_connection_class_init (VinagreRdpConnectionClass *klass)
g_type_class_add_private (klass, sizeof (VinagreRdpConnectionPrivate));
+ object_class->set_property = vinagre_rdp_connection_set_property;
+ object_class->get_property = vinagre_rdp_connection_get_property;
object_class->constructed = vinagre_rdp_connection_constructed;
parent_class->impl_fill_writer = rdp_fill_writer;
parent_class->impl_parse_item = rdp_parse_item;
parent_class->impl_parse_options_widget = rdp_parse_options_widget;
+
+ g_object_class_install_property (object_class,
+ PROP_SCALING,
+ g_param_spec_boolean ("scaling",
+ "Use scaling",
+ "Whether to use scaling on this connection",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
}
VinagreConnection *
@@ -124,4 +223,22 @@ vinagre_rdp_connection_new (void)
return VINAGRE_CONNECTION (g_object_new (VINAGRE_TYPE_RDP_CONNECTION, NULL));
}
+void
+vinagre_rdp_connection_set_scaling (VinagreRdpConnection *conn,
+ gboolean scaling)
+{
+ g_return_if_fail (VINAGRE_IS_RDP_CONNECTION (conn));
+
+ conn->priv->scaling = scaling;
+}
+
+gboolean
+vinagre_rdp_connection_get_scaling (VinagreRdpConnection *conn)
+{
+ g_return_val_if_fail (VINAGRE_IS_RDP_CONNECTION (conn), FALSE);
+
+ return conn->priv->scaling;
+}
+
+
/* vim: set ts=8: */
diff --git a/plugins/rdp/vinagre-rdp-connection.h b/plugins/rdp/vinagre-rdp-connection.h
index b9e48be..b96fb1b 100644
--- a/plugins/rdp/vinagre-rdp-connection.h
+++ b/plugins/rdp/vinagre-rdp-connection.h
@@ -51,7 +51,11 @@ struct _VinagreRdpConnection
GType vinagre_rdp_connection_get_type (void) G_GNUC_CONST;
-VinagreConnection* vinagre_rdp_connection_new (void);
+VinagreConnection* vinagre_rdp_connection_new (void);
+
+gboolean vinagre_rdp_connection_get_scaling (VinagreRdpConnection *conn);
+void vinagre_rdp_connection_set_scaling (VinagreRdpConnection *conn,
+ gboolean scaling);
G_END_DECLS
diff --git a/plugins/rdp/vinagre-rdp-plugin.c b/plugins/rdp/vinagre-rdp-plugin.c
index 3929065..f41da37 100644
--- a/plugins/rdp/vinagre-rdp-plugin.c
+++ b/plugins/rdp/vinagre-rdp-plugin.c
@@ -100,7 +100,7 @@ vinagre_rdp_plugin_init (VinagreRdpPlugin *plugin)
static GtkWidget *
impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
{
- GtkWidget *grid, *label, *u_entry, *spin_button;
+ GtkWidget *grid, *label, *u_entry, *spin_button, *check;
gchar *str;
gint width, height;
@@ -115,16 +115,28 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
+
+ /* Scaling check button */
+ check = gtk_check_button_new_with_mnemonic (_("_Scaling"));
+ g_object_set_data (G_OBJECT (grid), "scaling", check);
+ gtk_widget_set_margin_left (check, 12);
+ gtk_grid_attach (GTK_GRID (grid), check, 0, 1, 1, 1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
+ VINAGRE_IS_CONNECTION (conn) ?
+ vinagre_rdp_connection_get_scaling (VINAGRE_RDP_CONNECTION (conn)) :
+ vinagre_cache_prefs_get_boolean ("rdp-connection", "scaling", FALSE));
+
+
label = gtk_label_new_with_mnemonic (_("_Username:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
gtk_widget_set_margin_left (label, 12);
u_entry = gtk_entry_new ();
/* Translators: This is the tooltip for the username field in a RDP connection */
gtk_widget_set_tooltip_text (u_entry, _("Optional. If blank, your username will be used. Also, it can be
supplied in the Host field above, in the form username hostname "));
g_object_set_data (G_OBJECT (grid), "username_entry", u_entry);
- gtk_grid_attach (GTK_GRID (grid), u_entry, 1, 1, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), u_entry, 1, 2, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), u_entry);
str = g_strdup (VINAGRE_IS_CONNECTION (conn) ?
vinagre_connection_get_username (conn) :
@@ -137,7 +149,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
/* Host width */
label = gtk_label_new_with_mnemonic (_("_Width:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
gtk_widget_set_margin_left (label, 12);
spin_button = gtk_spin_button_new_with_range (MIN_SIZE, MAX_SIZE, 1);
@@ -145,7 +157,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
gtk_widget_set_tooltip_text (spin_button, _("Set width of the remote desktop"));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), DEFAULT_WIDTH);
g_object_set_data (G_OBJECT (grid), "width_spin_button", spin_button);
- gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 2, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 3, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button);
width = VINAGRE_IS_CONNECTION (conn) ?
vinagre_connection_get_width (conn) :
@@ -157,7 +169,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
/* Host height */
label = gtk_label_new_with_mnemonic (_("_Height:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), label, 0, 4, 1, 1);
gtk_widget_set_margin_left (label, 12);
spin_button = gtk_spin_button_new_with_range (MIN_SIZE, MAX_SIZE, 1);
@@ -165,7 +177,7 @@ impl_get_connect_widget (VinagreProtocol *plugin, VinagreConnection *conn)
gtk_widget_set_tooltip_text (spin_button, _("Set height of the remote desktop"));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), DEFAULT_HEIGHT);
g_object_set_data (G_OBJECT (grid), "height_spin_button", spin_button);
- gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 3, 1, 1);
+ gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 4, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button);
height = VINAGRE_IS_CONNECTION (conn) ?
vinagre_connection_get_height (conn) :
diff --git a/plugins/rdp/vinagre-rdp-tab.c b/plugins/rdp/vinagre-rdp-tab.c
index 1074a63..6900864 100644
--- a/plugins/rdp/vinagre-rdp-tab.c
+++ b/plugins/rdp/vinagre-rdp-tab.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
+#include <math.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
@@ -62,11 +63,23 @@ struct _VinagreRdpTabPrivate
guint key_press_handler_id;
guint key_release_handler_id;
guint motion_notify_handler_id;
+
+ GSList *connected_actions;
+ GtkWidget *scaling_button;
+ GtkAction *scaling_action;
+ gboolean scaling;
+ double scale;
+ double offset_x, offset_y;
};
G_DEFINE_TYPE (VinagreRdpTab, vinagre_rdp_tab, VINAGRE_TYPE_TAB)
static void open_freerdp (VinagreRdpTab *rdp_tab);
+static void setup_toolbar (VinagreRdpTab *rdp_tab);
+static void vinagre_rdp_tab_set_scaling (VinagreRdpTab *tab,
+ gboolean scaling);
+static void scaling_button_clicked (GtkToggleToolButton *button,
+ VinagreRdpTab *rdp_tab);
struct frdp_context
{
@@ -128,12 +141,42 @@ free_frdpEvent (gpointer event,
}
static void
+view_scaling_cb (GtkAction *action,
+ VinagreRdpTab *rdp_tab)
+{
+ VinagreRdpTabPrivate *priv = rdp_tab->priv;
+ gboolean scaling;
+
+ scaling = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+ vinagre_rdp_tab_set_scaling (rdp_tab, scaling);
+
+ g_signal_handlers_block_by_func (priv->scaling_button, scaling_button_clicked, rdp_tab);
+ gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (priv->scaling_button), scaling);
+ g_signal_handlers_unblock_by_func (priv->scaling_button, scaling_button_clicked, rdp_tab);
+}
+
+const static GSList *
+rdp_get_connected_actions (VinagreTab *tab)
+{
+ VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (tab);
+
+ return rdp_tab->priv->connected_actions;
+}
+
+static void
vinagre_rdp_tab_dispose (GObject *object)
{
VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (object);
VinagreRdpTabPrivate *priv = rdp_tab->priv;
GtkWindow *window = GTK_WINDOW (vinagre_tab_get_window (VINAGRE_TAB (rdp_tab)));
+ if (priv->connected_actions)
+ {
+ vinagre_tab_free_actions (priv->connected_actions);
+ priv->connected_actions = NULL;
+ }
+
if (priv->freerdp_session)
{
gdi_free (priv->freerdp_session);
@@ -195,6 +238,7 @@ vinagre_rdp_tab_constructed (GObject *object)
if (G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed)
G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed (object);
+ setup_toolbar (rdp_tab);
open_freerdp (rdp_tab);
}
@@ -208,6 +252,7 @@ vinagre_rdp_tab_class_init (VinagreRdpTabClass *klass)
object_class->dispose = vinagre_rdp_tab_dispose;
tab_class->impl_get_tooltip = rdp_tab_get_tooltip;
+ tab_class->impl_get_connected_actions = rdp_get_connected_actions;
g_type_class_add_private (object_class, sizeof (VinagreRdpTabPrivate));
}
@@ -220,12 +265,110 @@ idle_close (VinagreTab *tab)
return FALSE;
}
+static GSList *
+create_connected_actions (VinagreRdpTab *tab)
+{
+ GSList *list = NULL;
+ VinagreTabUiAction *action;
+
+ /* View->Scaling */
+ action = g_slice_new (VinagreTabUiAction);
+ action->paths = g_new (gchar *, 3);
+ action->paths[0] = g_strdup ("/MenuBar/ViewMenu");
+ action->paths[1] = g_strdup ("/ToolBar");
+ action->paths[2] = NULL;
+ action->action = GTK_ACTION (gtk_toggle_action_new ("RDPViewScaling",
+ _("S_caling"),
+ _("Fit the remote screen into the current window size"),
+ "zoom-fit-best"));
+ gtk_action_set_icon_name (action->action, "zoom-fit-best");
+ g_signal_connect (action->action, "activate", G_CALLBACK (view_scaling_cb), tab);
+ list = g_slist_append (list, action);
+ tab->priv->scaling_action = action->action;
+
+ return list;
+}
+
+static void
+scaling_button_clicked (GtkToggleToolButton *button,
+ VinagreRdpTab *rdp_tab)
+{
+ vinagre_rdp_tab_set_scaling (rdp_tab,
+ gtk_toggle_tool_button_get_active (button));
+}
+
+static void
+vinagre_rdp_tab_set_scaling (VinagreRdpTab *tab,
+ gboolean scaling)
+{
+ VinagreRdpTabPrivate *priv = tab->priv;
+ VinagreConnection *conn = vinagre_tab_get_conn (VINAGRE_TAB (tab));
+ GtkWidget *scrolled;
+ gint window_width, window_height;
+
+ priv->scaling = scaling;
+
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->scaling_action),
+ priv->scaling);
+
+ if (scaling)
+ {
+ scrolled = gtk_widget_get_ancestor (priv->display, GTK_TYPE_SCROLLED_WINDOW);
+ window_width = gtk_widget_get_allocated_width (scrolled);
+ window_height = gtk_widget_get_allocated_height (scrolled);
+
+ gtk_widget_set_size_request (priv->display,
+ window_width,
+ window_height);
+
+ gtk_widget_set_halign (priv->display, GTK_ALIGN_FILL);
+ gtk_widget_set_valign (priv->display, GTK_ALIGN_FILL);
+ }
+ else
+ {
+ gtk_widget_set_size_request (priv->display,
+ vinagre_connection_get_width (VINAGRE_CONNECTION (conn)),
+ vinagre_connection_get_height (VINAGRE_CONNECTION (conn)));
+ gtk_widget_set_halign (priv->display, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (priv->display, GTK_ALIGN_CENTER);
+ }
+
+ gtk_widget_queue_draw_area (priv->display, 0, 0,
+ gtk_widget_get_allocated_width (priv->display),
+ gtk_widget_get_allocated_height (priv->display));
+}
+
+static void
+setup_toolbar (VinagreRdpTab *rdp_tab)
+{
+ GtkWidget *toolbar = vinagre_tab_get_toolbar (VINAGRE_TAB (rdp_tab));
+ GtkWidget *button;
+
+ /* Space */
+ button = GTK_WIDGET (gtk_separator_tool_item_new ());
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE);
+ gtk_widget_show (GTK_WIDGET (button));
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), -1);
+
+ /* Scaling */
+ button = GTK_WIDGET (gtk_toggle_tool_button_new ());
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), _("Scaling"));
+ gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (button), _("Scaling"));
+ gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), "zoom-fit-best");
+ gtk_widget_show (GTK_WIDGET (button));
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (button), -1);
+ g_signal_connect (button, "toggled", G_CALLBACK (scaling_button_clicked), rdp_tab);
+ rdp_tab->priv->scaling_button = button;
+}
static void
frdp_process_events (freerdp *instance,
GQueue *events)
{
- frdpEvent *event;
+ VinagreRdpTab *rdp_tab = ((frdpContext *) instance->context)->rdp_tab;
+ VinagreRdpTabPrivate *priv = rdp_tab->priv;
+ frdpEvent *event;
+ gint x, y;
while (!g_queue_is_empty (events))
{
@@ -240,10 +383,27 @@ frdp_process_events (freerdp *instance,
((frdpEventKey *) event)->code);
break;
case FRDP_EVENT_TYPE_BUTTON:
+ if (priv->scaling)
+ {
+ x = (((frdpEventButton *) event)->x - priv->offset_x) / priv->scale;
+ y = (((frdpEventButton *) event)->y - priv->offset_y) / priv->scale;
+ }
+ else
+ {
+ x = ((frdpEventButton *) event)->x;
+ y = ((frdpEventButton *) event)->y;
+ }
+
+ if (x < 0)
+ x = 0;
+
+ if (y < 0)
+ y = 0;
+
instance->input->MouseEvent (instance->input,
((frdpEventButton *) event)->flags,
- ((frdpEventButton *) event)->x,
- ((frdpEventButton *) event)->y);
+ x,
+ y);
break;
default:
break;
@@ -261,10 +421,44 @@ frdp_drawing_area_draw (GtkWidget *area,
{
VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
VinagreRdpTabPrivate *priv = rdp_tab->priv;
+ VinagreRdpConnection *conn = VINAGRE_RDP_CONNECTION (vinagre_tab_get_conn (VINAGRE_TAB (rdp_tab)));
+ GtkWidget *scrolled;
+ double scale_x, scale_y;
+ gint window_width, window_height;
if (priv->surface == NULL)
return FALSE;
+ if (priv->scaling)
+ {
+ scrolled = gtk_widget_get_ancestor (area, GTK_TYPE_SCROLLED_WINDOW);
+ window_width = gtk_widget_get_allocated_width (scrolled);
+ window_height = gtk_widget_get_allocated_height (scrolled);
+
+ scale_x = (double) window_width / vinagre_connection_get_width (VINAGRE_CONNECTION (conn));
+ scale_y = (double) window_height / vinagre_connection_get_height (VINAGRE_CONNECTION (conn));
+
+ priv->scale = scale_x < scale_y ? scale_x : scale_y;
+
+ priv->offset_x = (window_width - vinagre_connection_get_width (VINAGRE_CONNECTION (conn)) *
priv->scale) / 2.0;
+ priv->offset_y = (window_height - vinagre_connection_get_height (VINAGRE_CONNECTION (conn)) *
priv->scale) / 2.0;
+
+ if (priv->offset_x < 0)
+ priv->offset_x = 0;
+
+ if (priv->offset_y < 0)
+ priv->offset_y = 0;
+
+ cairo_translate (cr, priv->offset_x, priv->offset_y);
+ cairo_scale (cr, priv->scale, priv->scale);
+
+ if (window_width != gtk_widget_get_allocated_width (area) ||
+ window_height != gtk_widget_get_allocated_height (area))
+ gtk_widget_set_size_request (area,
+ window_width,
+ window_height);
+ }
+
cairo_set_source_surface (cr, priv->surface, 0, 0);
cairo_paint (cr);
@@ -286,6 +480,7 @@ frdp_end_paint (rdpContext *context)
VinagreRdpTab *rdp_tab = ((frdpContext *) context)->rdp_tab;
VinagreRdpTabPrivate *priv = rdp_tab->priv;
rdpGdi *gdi = context->gdi;
+ double pos_x, pos_y;
gint x, y, w, h;
if (gdi->primary->hdc->hwnd->invalid->null)
@@ -296,7 +491,21 @@ frdp_end_paint (rdpContext *context)
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
- gtk_widget_queue_draw_area (priv->display, x, y, w, h);
+ if (priv->scaling)
+ {
+ pos_x = priv->offset_x + x * priv->scale;
+ pos_y = priv->offset_y + y * priv->scale;
+
+ gtk_widget_queue_draw_area (priv->display,
+ floor (pos_x),
+ floor (pos_y),
+ ceil (pos_x + w * priv->scale) - floor (pos_x),
+ ceil (pos_y + h * priv->scale) - floor (pos_y));
+ }
+ else
+ {
+ gtk_widget_queue_draw_area (priv->display, x, y, w, h);
+ }
}
static BOOL
@@ -845,7 +1054,7 @@ open_freerdp (VinagreRdpTab *rdp_tab)
rdpSettings *settings;
GtkWindow *window = GTK_WINDOW (vinagre_tab_get_window (tab));
gboolean success = TRUE;
- gboolean fullscreen;
+ gboolean fullscreen, scaling;
gchar *hostname, *username;
gint port, width, height;
@@ -855,6 +1064,7 @@ open_freerdp (VinagreRdpTab *rdp_tab)
"width", &width,
"height", &height,
"fullscreen", &fullscreen,
+ "scaling", &scaling,
"username", &username,
NULL);
@@ -946,8 +1156,6 @@ open_freerdp (VinagreRdpTab *rdp_tab)
priv->display = gtk_drawing_area_new ();
if (priv->display)
{
- gtk_widget_set_size_request (priv->display, width, height);
-
g_signal_connect (priv->display, "draw",
G_CALLBACK (frdp_drawing_area_draw), rdp_tab);
@@ -980,6 +1188,8 @@ open_freerdp (VinagreRdpTab *rdp_tab)
if (fullscreen)
gtk_window_fullscreen (window);
+
+ vinagre_rdp_tab_set_scaling (rdp_tab, scaling);
}
priv->key_press_handler_id = g_signal_connect (window, "key-press-event",
@@ -1011,6 +1221,8 @@ static void
vinagre_rdp_tab_init (VinagreRdpTab *rdp_tab)
{
rdp_tab->priv = VINAGRE_RDP_TAB_GET_PRIVATE (rdp_tab);
+
+ rdp_tab->priv->connected_actions = create_connected_actions (rdp_tab);
}
GtkWidget *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]