r42279 - in /desktop/unstable/vinagre/debian: changelog control control.in patches/01_Use-FreeRDP-API-in-RDP.patch patches/02_Request-RDP-certificate-verification.patch patches/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch patches/series rules
bigon at users.alioth.debian.org
bigon at users.alioth.debian.org
Tue Aug 26 13:09:17 UTC 2014
Author: bigon
Date: Tue Aug 26 13:09:17 2014
New Revision: 42279
URL: http://svn.debian.org/wsvn/pkg-gnome/?sc=1&rev=42279
Log:
* d/p/01_Use-FreeRDP-API-in-RDP.patch,
d/p/02_Request-RDP-certificate-verification.patch,
d/p/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch:
Use FreeRDP API to manage user interractions (authentication and
certificate fingerprint verification (Closes: #757911))
* debian/control.in: Add libfreerdp-dev to the build-dependencies
* debian/rules, debian/control.in: Call autoreconf and enable hardening
flags
Added:
desktop/unstable/vinagre/debian/patches/01_Use-FreeRDP-API-in-RDP.patch
desktop/unstable/vinagre/debian/patches/02_Request-RDP-certificate-verification.patch
desktop/unstable/vinagre/debian/patches/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch
Modified:
desktop/unstable/vinagre/debian/changelog
desktop/unstable/vinagre/debian/control
desktop/unstable/vinagre/debian/control.in
desktop/unstable/vinagre/debian/patches/series
desktop/unstable/vinagre/debian/rules
Modified: desktop/unstable/vinagre/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/changelog?rev=42279&op=diff
==============================================================================
--- desktop/unstable/vinagre/debian/changelog [utf-8] (original)
+++ desktop/unstable/vinagre/debian/changelog [utf-8] Tue Aug 26 13:09:17 2014
@@ -1,3 +1,16 @@
+vinagre (3.12.2-2) UNRELEASED; urgency=medium
+
+ * d/p/01_Use-FreeRDP-API-in-RDP.patch,
+ d/p/02_Request-RDP-certificate-verification.patch,
+ d/p/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch:
+ Use FreeRDP API to manage user interractions (authentication and
+ certificate fingerprint verification (Closes: #757911))
+ * debian/control.in: Add libfreerdp-dev to the build-dependencies
+ * debian/rules, debian/control.in: Call autoreconf and enable hardening
+ flags
+
+ -- Laurent Bigonville <bigon at debian.org> Tue, 26 Aug 2014 14:58:32 +0200
+
vinagre (3.12.2-1) unstable; urgency=medium
* New upstream release.
Modified: desktop/unstable/vinagre/debian/control
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/control?rev=42279&op=diff
==============================================================================
--- desktop/unstable/vinagre/debian/control [utf-8] (original)
+++ desktop/unstable/vinagre/debian/control [utf-8] Tue Aug 26 13:09:17 2014
@@ -7,10 +7,13 @@
Section: gnome
Priority: optional
Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers at lists.alioth.debian.org>
-Uploaders: Andreas Henriksson <andreas at fatal.se>, Emilio Pozuelo Monfort <pochu at debian.org>, Michael Biebl <biebl at debian.org>
+Uploaders: Andreas Henriksson <andreas at fatal.se>, Emilio Pozuelo Monfort <pochu at debian.org>, Laurent Bigonville <bigon at debian.org>, Michael Biebl <biebl at debian.org>
Build-Depends: cdbs (>= 0.4.52),
debhelper (>= 8),
+ dh-autoreconf (>= 4),
gnome-pkg-tools (>= 0.10),
+ gnome-common,
+ appdata-tools,
intltool (>= 0.50.0),
libglib2.0-dev (>= 2.28.0),
libgtk-3-dev (>= 3.9.6),
@@ -26,7 +29,8 @@
libxml2-dev (>= 2.6.31),
libtelepathy-glib-dev (>= 0.11.6),
openssh-client,
- docbook-xml
+ docbook-xml,
+ libfreerdp-dev
Standards-Version: 3.9.5
Homepage: https://wiki.gnome.org/Apps/Vinagre
Vcs-Svn: svn://anonscm.debian.org/pkg-gnome/desktop/unstable/vinagre
Modified: desktop/unstable/vinagre/debian/control.in
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/control.in?rev=42279&op=diff
==============================================================================
--- desktop/unstable/vinagre/debian/control.in [utf-8] (original)
+++ desktop/unstable/vinagre/debian/control.in [utf-8] Tue Aug 26 13:09:17 2014
@@ -5,7 +5,10 @@
Uploaders: @GNOME_TEAM@
Build-Depends: cdbs (>= 0.4.52),
debhelper (>= 8),
+ dh-autoreconf (>= 4),
gnome-pkg-tools (>= 0.10),
+ gnome-common,
+ appdata-tools,
intltool (>= 0.50.0),
libglib2.0-dev (>= 2.28.0),
libgtk-3-dev (>= 3.9.6),
@@ -21,7 +24,8 @@
libxml2-dev (>= 2.6.31),
libtelepathy-glib-dev (>= 0.11.6),
openssh-client,
- docbook-xml
+ docbook-xml,
+ libfreerdp-dev
Standards-Version: 3.9.5
Homepage: https://wiki.gnome.org/Apps/Vinagre
Vcs-Svn: svn://anonscm.debian.org/pkg-gnome/desktop/unstable/vinagre
Added: desktop/unstable/vinagre/debian/patches/01_Use-FreeRDP-API-in-RDP.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/patches/01_Use-FreeRDP-API-in-RDP.patch?rev=42279&op=file
==============================================================================
--- desktop/unstable/vinagre/debian/patches/01_Use-FreeRDP-API-in-RDP.patch (added)
+++ desktop/unstable/vinagre/debian/patches/01_Use-FreeRDP-API-in-RDP.patch [utf-8] Tue Aug 26 13:09:17 2014
@@ -0,0 +1,1109 @@
+From 7ac600bf3014d8d27bc73c69bad2b6f292fba3e6 Mon Sep 17 00:00:00 2001
+From: Marek Kasik <mkasik at redhat.com>
+Date: Tue, 1 Jul 2014 13:26:56 +0200
+Subject: Use FreeRDP API in RDP plugin
+
+FreeRDP API allows us to implement proper handling of NLA
+authentication by passing a callback during initialization to FreeRDP
+session.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=732496
+
+diff --git a/configure.ac b/configure.ac
+index 1f105d7..f617044 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -58,14 +58,16 @@ AS_IF([test "x$have_ssh" = "xyes"],
+ AM_CONDITIONAL([VINAGRE_ENABLE_SSH], [test "x$have_ssh" = "xyes"])
+
+ # Whether to enable support for RDP.
+-RDP_DEPS="$XML2_DEPS"
++RDP_DEPS="freerdp x11"
+ AC_ARG_ENABLE([rdp],
+ [AS_HELP_STRING([--disable-rdp],
+ [Disable Remote Desktop Protocol (RDP) support])])
+
+ AS_IF([test "x$enable_rdp" != "xno"],
+ [PKG_CHECK_EXISTS([$RDP_DEPS],
+- [have_rdp=yes],
++ [have_rdp=yes
++ PKG_CHECK_EXISTS(freerdp >= 1.1,
++ [AC_DEFINE([HAVE_FREERDP_1_1], [1], [FreeRDP is of version 1.1 or newer])], [])],
+ [have_rdp=no])],
+ [have_rdp=no])
+
+@@ -73,7 +75,7 @@ AS_IF([test "x$have_rdp" = "xyes"],
+ [AC_DEFINE([VINAGRE_ENABLE_RDP], [], [Build with RDP support])],
+ [RDP_DEPS=""
+ AS_IF([test "x$enable_rdp" = "xyes"],
+- [AC_MSG_ERROR([RDP support requested by required dependencies not found])])])
++ [AC_MSG_ERROR([RDP support requested but required dependencies not found])])])
+
+ AM_CONDITIONAL([VINAGRE_ENABLE_RDP], [test "x$have_rdp" = "xyes"])
+
+@@ -164,7 +166,7 @@ AS_IF([test "x$have_telepathy" = "xyes"],
+ AM_CONDITIONAL([VINAGRE_HAVE_TELEPATHY_GLIB], [test "x$have_telepathy" = "xyes"])
+
+ # Check required libraries
+-PKG_CHECK_MODULES([VINAGRE], [$GLIB_DEPS $GTHREAD_DEPS $GTK_DEPS libsecret-1 $XML2_DEPS $AVAHI_DEPS $TELEPATHY_GLIB_DEPS $SSH_DEPS])
++PKG_CHECK_MODULES([VINAGRE], [$GLIB_DEPS $GTHREAD_DEPS $GTK_DEPS libsecret-1 $XML2_DEPS $AVAHI_DEPS $TELEPATHY_GLIB_DEPS $SSH_DEPS $RDP_DEPS])
+
+ PKG_CHECK_MODULES([VNC], [$GTK_VNC_DEPS $GTK_DEPS $XML2_DEPS])
+
+diff --git a/data/vinagre.ui b/data/vinagre.ui
+index 3c3c191..041dfe7 100644
+--- a/data/vinagre.ui
++++ b/data/vinagre.ui
+@@ -206,6 +206,24 @@ Jonh Wendell <jwendell at gnome.org></property>
+ </packing>
+ </child>
+ <child>
++ <object class="GtkLabel" id="domain_label">
++ <property name="visible">False</property>
++ <property name="can_focus">False</property>
++ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
++ <property name="margin_left">12</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">_Domain:</property>
++ <property name="use_underline">True</property>
++ <property name="mnemonic_widget">domain_entry</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">3</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
+ <object class="GtkCheckButton" id="save_credential_check">
+ <property name="label" translatable="yes">_Remember this credential</property>
+ <property name="visible">True</property>
+@@ -262,6 +280,23 @@ Jonh Wendell <jwendell at gnome.org></property>
+ </packing>
+ </child>
+ <child>
++ <object class="GtkEntry" id="domain_entry">
++ <property name="visible">False</property>
++ <property name="can_focus">True</property>
++ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
++ <property name="max_length">254</property>
++ <property name="invisible_char">●</property>
++ <property name="activates_default">True</property>
++ <property name="invisible_char_set">True</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">3</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
+ <placeholder/>
+ </child>
+ </object>
+diff --git a/plugins/rdp/vinagre-rdp-tab.c b/plugins/rdp/vinagre-rdp-tab.c
+index abe33e1..1ca9bb6 100644
+--- a/plugins/rdp/vinagre-rdp-tab.c
++++ b/plugins/rdp/vinagre-rdp-tab.c
+@@ -4,6 +4,7 @@
+ * This file is part of vinagre
+ *
+ * Copyright (C) 2010 - Jonh Wendell <wendell at bani.com.br>
++ * Copyright (C) 2014 - Marek Kasik <mkasik at redhat.com>
+ *
+ * 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
+@@ -20,13 +21,20 @@
+ */
+
+ #include <config.h>
+-#include <sys/types.h>
+-#include <sys/wait.h>
+-
++#include <errno.h>
+ #include <glib/gi18n.h>
+-#include <gtk/gtkx.h>
+-
+-#include <vinagre/vinagre-prefs.h>
++#include <gdk/gdkkeysyms.h>
++#include <freerdp/api.h>
++#include <freerdp/types.h>
++#include <freerdp/freerdp.h>
++#include <freerdp/utils/event.h>
++#include <freerdp/gdi/gdi.h>
++#if HAVE_FREERDP_1_1
++#include <freerdp/locale/keyboard.h>
++#else
++#include <freerdp/kbd/vkcodes.h>
++#include <gdk/gdkx.h>
++#endif
+
+ #include "vinagre-rdp-tab.h"
+ #include "vinagre-rdp-connection.h"
+@@ -34,15 +42,73 @@
+
+ #define VINAGRE_RDP_TAB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), VINAGRE_TYPE_RDP_TAB, VinagreRdpTabPrivate))
+
++#define SELECT_TIMEOUT 50
++
++#if !HAVE_FREERDP_1_1
++typedef boolean BOOL;
++typedef uint8 UINT8;
++typedef uint16 UINT16;
++#endif
++
+ struct _VinagreRdpTabPrivate
+ {
+- GtkWidget *box;
+- GPid pid;
+- guint child;
++ freerdp *freerdp_session;
++ GtkWidget *display;
++ cairo_surface_t *surface;
++ GQueue *events;
++
++ guint update_id;
++ guint button_press_handler_id;
++ guint button_release_handler_id;
++ guint key_press_handler_id;
++ guint key_release_handler_id;
++ guint motion_notify_handler_id;
+ };
+
+ G_DEFINE_TYPE (VinagreRdpTab, vinagre_rdp_tab, VINAGRE_TYPE_TAB)
+
++static void open_freerdp (VinagreRdpTab *rdp_tab);
++
++struct frdp_context
++{
++ rdpContext context;
++ VinagreRdpTab *rdp_tab;
++};
++typedef struct frdp_context frdpContext;
++
++typedef enum
++{
++ FRDP_EVENT_TYPE_BUTTON = 0,
++ FRDP_EVENT_TYPE_KEY = 1
++} frdpEventType;
++
++typedef struct _frdpEventButton frdpEventButton;
++typedef struct _frdpEventKey frdpEventKey;
++typedef union _frdpEvent frdpEvent;
++
++struct _frdpEventKey
++{
++ frdpEventType type;
++ UINT16 code;
++ BOOL extended;
++ UINT16 flags;
++};
++
++struct _frdpEventButton
++{
++ frdpEventType type;
++ UINT16 x;
++ UINT16 y;
++ UINT16 flags;
++};
++
++union _frdpEvent
++{
++ frdpEventType type;
++ frdpEventKey key;
++ frdpEventButton button;
++};
++
+ static gchar *
+ rdp_tab_get_tooltip (VinagreTab *tab)
+ {
+@@ -56,170 +122,781 @@ rdp_tab_get_tooltip (VinagreTab *tab)
+ }
+
+ static void
+-rdp_tab_get_dimensions (VinagreTab *tab, int *w, int *h)
++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->freerdp_session)
++ {
++ gdi_free (priv->freerdp_session);
++ freerdp_disconnect (priv->freerdp_session);
++ freerdp_context_free (priv->freerdp_session);
++ g_clear_pointer (&priv->freerdp_session, freerdp_free);
++ }
++
++ if (priv->events)
++ {
++ while (!g_queue_is_empty (priv->events))
++ g_free ((frdpEvent *) g_queue_pop_head (priv->events));
++
++ g_queue_free (priv->events);
++ }
++
++ if (priv->update_id > 0)
++ {
++ g_source_remove (rdp_tab->priv->update_id);
++ rdp_tab->priv->update_id = 0;
++ }
++
++ if (priv->motion_notify_handler_id > 0)
++ {
++ g_signal_handler_disconnect (priv->display, priv->motion_notify_handler_id);
++ priv->motion_notify_handler_id = 0;
++ }
++
++ if (priv->button_press_handler_id > 0)
++ {
++ g_signal_handler_disconnect (priv->display, priv->button_press_handler_id);
++ priv->button_press_handler_id = 0;
++ }
++
++ if (priv->button_release_handler_id > 0)
++ {
++ g_signal_handler_disconnect (priv->display, priv->button_release_handler_id);
++ priv->button_release_handler_id = 0;
++ }
++
++ if (priv->key_press_handler_id > 0)
++ {
++ g_signal_handler_disconnect (window, priv->key_press_handler_id);
++ priv->key_press_handler_id = 0;
++ }
++
++ if (priv->key_release_handler_id > 0)
++ {
++ g_signal_handler_disconnect (window, priv->key_release_handler_id);
++ priv->key_release_handler_id = 0;
++ }
++
++ G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->dispose (object);
++}
++
++static void
++vinagre_rdp_tab_constructed (GObject *object)
+ {
+- VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (tab);
+- GdkWindow *window = gtk_widget_get_window (rdp_tab->priv->box);
++ VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (object);
++
++ if (G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed)
++ G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed (object);
+
+- *w = gdk_window_get_width (window);
+- *h = gdk_window_get_height (window);
++ open_freerdp (rdp_tab);
+ }
+
+ static void
+-emit_connected_signal (GtkSocket *socket, VinagreRdpTab *rdp_tab)
++vinagre_rdp_tab_class_init (VinagreRdpTabClass *klass)
+ {
+- g_signal_emit_by_name (rdp_tab, "tab-initialized");
+- gtk_widget_grab_focus (rdp_tab->priv->box);
++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
++ VinagreTabClass* tab_class = VINAGRE_TAB_CLASS (klass);
++
++ object_class->constructed = vinagre_rdp_tab_constructed;
++ object_class->dispose = vinagre_rdp_tab_dispose;
++
++ tab_class->impl_get_tooltip = rdp_tab_get_tooltip;
++
++ g_type_class_add_private (object_class, sizeof (VinagreRdpTabPrivate));
+ }
+
++static gboolean
++idle_close (VinagreTab *tab)
++{
++ vinagre_notebook_close_tab (vinagre_tab_get_notebook (tab), tab);
++
++ return FALSE;
++}
++
++
+ static void
+-child_exited (GPid pid, gint status, VinagreRdpTab *rdp_tab)
++frdp_process_events (freerdp *instance,
++ GQueue *events)
+ {
+- if (rdp_tab->priv->pid > 0)
++ frdpEvent *event;
++
++ while (!g_queue_is_empty (events))
+ {
+- g_spawn_close_pid (rdp_tab->priv->pid);
+- rdp_tab->priv->pid = 0;
+- if (WIFEXITED (status))
+- vinagre_tab_remove_from_notebook (VINAGRE_TAB (rdp_tab));
+- else
+- g_signal_emit_by_name (rdp_tab, "tab-disconnected");
++ event = g_queue_pop_head (events);
++ if (event != NULL)
++ {
++ switch (event->type)
++ {
++ case FRDP_EVENT_TYPE_KEY:
++ instance->input->KeyboardEvent (instance->input,
++ ((frdpEventKey *) event)->flags,
++ ((frdpEventKey *) event)->code);
++ break;
++ case FRDP_EVENT_TYPE_BUTTON:
++ instance->input->MouseEvent (instance->input,
++ ((frdpEventButton *) event)->flags,
++ ((frdpEventButton *) event)->x,
++ ((frdpEventButton *) event)->y);
++ break;
++ default:
++ break;
++ }
++
++ g_free (event);
++ }
+ }
+ }
+
+ static gboolean
+-delay_connect (GObject *object)
++frdp_drawing_area_draw (GtkWidget *area,
++ cairo_t *cr,
++ gpointer user_data)
+ {
+- gchar **arg;
+- const gchar *username;
+- gint i;
+- GError *error = NULL;
+- VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (object);
+- VinagreTab *tab = VINAGRE_TAB (object);
+- VinagreConnection *conn = vinagre_tab_get_conn (tab);
++ VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
+
+- username = vinagre_connection_get_username (conn);
+- i = 0;
++ if (priv->surface == NULL)
++ return FALSE;
+
+- arg = g_new (gchar *, 11);
+- arg[i++] = g_strdup ("xfreerdp");
++ cairo_set_source_surface (cr, priv->surface, 0, 0);
++ cairo_paint (cr);
+
+- arg[i++] = g_strdup ("-K");
++ return TRUE;
++}
+
+- if (vinagre_connection_get_fullscreen (conn))
+- arg[i++] = g_strdup ("-f");
++static void
++frdp_begin_paint (rdpContext *context)
++{
++ rdpGdi *gdi = context->gdi;
+
+- arg[i++] = g_strdup ("-g");
+- arg[i++] = g_strdup_printf ("%dx%d",
+- vinagre_connection_get_width (conn),
+- vinagre_connection_get_height (conn));
++ gdi->primary->hdc->hwnd->invalid->null = 1;
++ gdi->primary->hdc->hwnd->ninvalid = 0;
++}
++
++static void
++frdp_end_paint (rdpContext *context)
++{
++ VinagreRdpTab *rdp_tab = ((frdpContext *) context)->rdp_tab;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ rdpGdi *gdi = context->gdi;
++ gint x, y, w, h;
+
+- arg[i++] = g_strdup ("-X");
+- arg[i++] = g_strdup_printf ("%d", (int)gtk_socket_get_id (GTK_SOCKET (rdp_tab->priv->box)));
++ if (gdi->primary->hdc->hwnd->invalid->null)
++ return;
++
++ x = gdi->primary->hdc->hwnd->invalid->x;
++ y = gdi->primary->hdc->hwnd->invalid->y;
++ 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);
++}
++
++static BOOL
++frdp_pre_connect (freerdp *instance)
++{
++ rdpSettings *settings = instance->settings;
++
++#if HAVE_FREERDP_1_1
++ settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
++ settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
++ settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
++ settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
++ settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
++ settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
++ settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
++ settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
++ settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
++ settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
++ settings->OrderSupport[NEG_LINETO_INDEX] = TRUE;
++ settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
++ settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE;
++ settings->OrderSupport[NEG_MEM3BLT_INDEX] = FALSE;
++ settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = TRUE;
++ settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE;
++ settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
++ settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE;
++ settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE;
++ settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = FALSE;
++ settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
++ settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
++ settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
++ settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
++#else
++ settings->order_support[NEG_DSTBLT_INDEX] = true;
++ settings->order_support[NEG_PATBLT_INDEX] = true;
++ settings->order_support[NEG_SCRBLT_INDEX] = true;
++ settings->order_support[NEG_OPAQUE_RECT_INDEX] = true;
++ settings->order_support[NEG_DRAWNINEGRID_INDEX] = false;
++ settings->order_support[NEG_MULTIDSTBLT_INDEX] = false;
++ settings->order_support[NEG_MULTIPATBLT_INDEX] = false;
++ settings->order_support[NEG_MULTISCRBLT_INDEX] = false;
++ settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true;
++ settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false;
++ settings->order_support[NEG_LINETO_INDEX] = true;
++ settings->order_support[NEG_POLYLINE_INDEX] = true;
++ settings->order_support[NEG_MEMBLT_INDEX] = true;
++ settings->order_support[NEG_MEM3BLT_INDEX] = false;
++ settings->order_support[NEG_MEMBLT_V2_INDEX] = true;
++ settings->order_support[NEG_MEM3BLT_V2_INDEX] = false;
++ settings->order_support[NEG_SAVEBITMAP_INDEX] = false;
++ settings->order_support[NEG_GLYPH_INDEX_INDEX] = true;
++ settings->order_support[NEG_FAST_INDEX_INDEX] = true;
++ settings->order_support[NEG_FAST_GLYPH_INDEX] = false;
++ settings->order_support[NEG_POLYGON_SC_INDEX] = false;
++ settings->order_support[NEG_POLYGON_CB_INDEX] = false;
++ settings->order_support[NEG_ELLIPSE_SC_INDEX] = false;
++ settings->order_support[NEG_ELLIPSE_CB_INDEX] = false;
++#endif
++
++ return TRUE;
++}
++
++static BOOL
++frdp_post_connect (freerdp *instance)
++{
++ VinagreRdpTab *rdp_tab = ((frdpContext *) instance->context)->rdp_tab;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ rdpGdi *gdi;
++ int stride;
++
++ gdi_init (instance, CLRBUF_24BPP, NULL);
++ gdi = instance->context->gdi;
++
++ instance->update->BeginPaint = frdp_begin_paint;
++ instance->update->EndPaint = frdp_end_paint;
++
++ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, gdi->width);
++ rdp_tab->priv->surface = cairo_image_surface_create_for_data ((unsigned char*) gdi->primary_buffer,
++ CAIRO_FORMAT_RGB24,
++ gdi->width,
++ gdi->height,
++ stride);
++ gtk_widget_queue_draw_area (priv->display,
++ 0, 0,
++ gdi->width, gdi->height);
++
++ vinagre_tab_add_recent_used (VINAGRE_TAB (rdp_tab));
++ vinagre_tab_set_state (VINAGRE_TAB (rdp_tab), VINAGRE_TAB_STATE_CONNECTED);
++
++ return TRUE;
++}
+
+- if (username && *username)
++static gboolean
++update (gpointer user_data)
++{
++ VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ struct timeval timeout;
++ fd_set rfds_set;
++ fd_set wfds_set;
++ void *rfds[32];
++ void *wfds[32];
++ int i;
++ int fds;
++ int max_fds;
++ int rcount = 0;
++ int wcount = 0;
++ int result;
++
++ memset (rfds, 0, sizeof (rfds));
++ memset (wfds, 0, sizeof (wfds));
++
++ if (!freerdp_get_fds (priv->freerdp_session,
++ rfds, &rcount,
++ wfds, &wcount))
+ {
+- arg[i++] = g_strdup ("-u");
+- arg[i++] = g_strdup (username);
++ g_warning ("Failed to get FreeRDP file descriptor\n");
++ return FALSE;
+ }
+
+- arg[i++] = g_strdup_printf ("%s:%d",
+- vinagre_connection_get_host (conn),
+- vinagre_connection_get_port (conn));
+- arg[i++] = NULL;
++ max_fds = 0;
++ FD_ZERO (&rfds_set);
++ FD_ZERO (&wfds_set);
+
+- if (!g_spawn_async (NULL,
+- arg,
+- NULL,
+- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+- NULL,
+- NULL,
+- &rdp_tab->priv->pid,
+- &error))
++ for (i = 0; i < rcount; i++)
+ {
+- vinagre_utils_show_error_dialog (_("Error while executing xfreerdp"),
+- error ? error->message : _("Unknown error"),
+- GTK_WINDOW (vinagre_tab_get_window (tab)));
+- vinagre_tab_remove_from_notebook (tab);
+- goto _end;
++ fds = (int)(long) (rfds[i]);
++
++ if (fds > max_fds)
++ max_fds = fds;
++
++ FD_SET (fds, &rfds_set);
+ }
+
+- rdp_tab->priv->child = g_child_watch_add (rdp_tab->priv->pid,
+- (GChildWatchFunc)child_exited, rdp_tab);
+- gtk_widget_show_all (GTK_WIDGET (rdp_tab));
++ if (max_fds == 0)
++ return FALSE;
+
+- vinagre_tab_add_recent_used (tab);
+- vinagre_tab_set_state (tab, VINAGRE_TAB_STATE_CONNECTED);
++ timeout.tv_sec = 0;
++ timeout.tv_usec = SELECT_TIMEOUT;
+
+-_end:
+- g_strfreev (arg);
++ result = select (max_fds + 1, &rfds_set, NULL, NULL, &timeout);
++ if (result == -1)
++ {
++ /* these are not errors */
++ if (!((errno == EAGAIN) ||
++ (errno == EWOULDBLOCK) ||
++ (errno == EINPROGRESS) ||
++ (errno == EINTR))) /* signal occurred */
++ {
++ g_warning ("update: select failed\n");
++ return FALSE;
++ }
++ }
+
+- return FALSE;
++ if (!freerdp_check_fds (priv->freerdp_session))
++ {
++ g_warning ("Failed to check FreeRDP file descriptor\n");
++ return FALSE;
++ }
++
++ frdp_process_events (priv->freerdp_session, priv->events);
++
++ if (freerdp_shall_disconnect (priv->freerdp_session))
++ {
++ g_idle_add ((GSourceFunc) idle_close, rdp_tab);
++ return FALSE;
++ }
++
++ return TRUE;
+ }
+
+-static void
+-vinagre_rdp_tab_constructed (GObject *object)
++static gboolean
++frdp_key_pressed (GtkWidget *widget,
++ GdkEventKey *event,
++ gpointer user_data)
+ {
+- if (G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed)
+- G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->constructed (object);
++ VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ frdpEventKey *frdp_event;
++
++ frdp_event = g_new0 (frdpEventKey, 1);
++ frdp_event->type = FRDP_EVENT_TYPE_KEY;
++ frdp_event->flags = event->type == GDK_KEY_PRESS ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE;
+
+- g_idle_add ((GSourceFunc)delay_connect, object);
++#if HAVE_FREERDP_1_1
++ frdp_event->code = freerdp_keyboard_get_rdp_scancode_from_x11_keycode (event->hardware_keycode);
++#else
++ frdp_event->code = freerdp_kbd_get_scancode_by_keycode (event->hardware_keycode, &frdp_event->extended);
++#endif
++
++ g_queue_push_tail (priv->events, frdp_event);
++
++ return TRUE;
+ }
+
+-static void
+-vinagre_rdp_tab_dispose (GObject *object)
++static gboolean
++frdp_button_pressed (GtkWidget *widget,
++ GdkEventButton *event,
++ gpointer user_data)
+ {
+- VinagreRdpTab *rdp_tab = VINAGRE_RDP_TAB (object);
++ VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ frdpEventButton *frdp_event;
++
++ frdp_event = g_new0 (frdpEventButton, 1);
+
+- if (rdp_tab->priv->pid > 0)
++ frdp_event->type = FRDP_EVENT_TYPE_BUTTON;
++
++ switch (event->button)
+ {
+- g_spawn_close_pid (rdp_tab->priv->pid);
+- kill (rdp_tab->priv->pid, SIGTERM);
+- rdp_tab->priv->pid = 0;
++ case 1:
++ frdp_event->flags = PTR_FLAGS_BUTTON1;
++ break;
++
++ case 2:
++ frdp_event->flags = PTR_FLAGS_BUTTON3;
++ break;
++
++ case 3:
++ frdp_event->flags = PTR_FLAGS_BUTTON2;
++ break;
+ }
+
+- if (rdp_tab->priv->child > 0)
++ if (frdp_event->flags != 0)
++ {
++ frdp_event->flags |= event->type == GDK_BUTTON_PRESS ? PTR_FLAGS_DOWN : 0;
++
++ frdp_event->x = event->x;
++ frdp_event->y = event->y;
++
++ g_queue_push_tail (priv->events, frdp_event);
++ }
++ else
+ {
+- g_source_remove (rdp_tab->priv->child);
+- rdp_tab->priv->child = 0;
++ g_free (frdp_event);
+ }
+
+- G_OBJECT_CLASS (vinagre_rdp_tab_parent_class)->dispose (object);
++ return TRUE;
+ }
+
+-static void
+-vinagre_rdp_tab_class_init (VinagreRdpTabClass *klass)
++static gboolean
++frdp_scroll (GtkWidget *widget,
++ GdkEventScroll *event,
++ gpointer user_data)
+ {
+- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+- VinagreTabClass* tab_class = VINAGRE_TAB_CLASS (klass);
++ VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ frdpEventButton *frdp_event;
++ gdouble delta_x = 0.0;
++ gdouble delta_y = 0.0;
++
++ frdp_event = g_new0 (frdpEventButton, 1);
++ frdp_event->type = FRDP_EVENT_TYPE_BUTTON;
++
++ frdp_event->flags = 0;
++ /* http://msdn.microsoft.com/en-us/library/cc240586.aspx (section 2.2.8.1.1.3.1.1.3) */
++ switch (event->direction)
++ {
++ case GDK_SCROLL_UP:
++ frdp_event->flags = PTR_FLAGS_WHEEL;
++ frdp_event->flags |= 0x0078;
++ break;
++
++ case GDK_SCROLL_DOWN:
++ frdp_event->flags = PTR_FLAGS_WHEEL;
++ frdp_event->flags |= PTR_FLAGS_WHEEL_NEGATIVE;
++ frdp_event->flags |= 0x0088;
++ break;
++
++ case GDK_SCROLL_SMOOTH:
++ if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &delta_x, &delta_y))
++ {
++ if (delta_y != 0.0)
++ {
++ frdp_event->flags = PTR_FLAGS_WHEEL;
++ if (delta_y < 0.0)
++ {
++ frdp_event->flags |= 0x0078;
++ }
++ else
++ {
++ frdp_event->flags |= PTR_FLAGS_WHEEL_NEGATIVE;
++ frdp_event->flags |= 0x0088;
++ }
++ }
++ }
++ break;
++
++ default:
++ break;
++ }
+
+- object_class->constructed = vinagre_rdp_tab_constructed;
+- object_class->dispose = vinagre_rdp_tab_dispose;
++ if (frdp_event->flags != 0)
++ {
++ frdp_event->x = event->x;
++ frdp_event->y = event->y;
+
+- tab_class->impl_get_tooltip = rdp_tab_get_tooltip;
+- tab_class->impl_get_dimensions = rdp_tab_get_dimensions;
++ g_queue_push_tail (priv->events, frdp_event);
++ }
++ else
++ {
++ g_free (frdp_event);
++ }
+
+- g_type_class_add_private (object_class, sizeof (VinagreRdpTabPrivate));
++ return TRUE;
++}
++
++static gboolean
++frdp_mouse_moved (GtkWidget *widget,
++ GdkEventButton *event,
++ gpointer user_data)
++{
++ VinagreRdpTab *rdp_tab = (VinagreRdpTab *) user_data;
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ frdpEventButton *frdp_event;
++
++ frdp_event = g_new0 (frdpEventButton, 1);
++
++ frdp_event->type = FRDP_EVENT_TYPE_BUTTON;
++ frdp_event->flags = PTR_FLAGS_MOVE;
++ frdp_event->x = event->x;
++ frdp_event->y = event->y;
++
++ g_queue_push_tail (priv->events, frdp_event);
++
++ return TRUE;
+ }
+
+ static void
+-vinagre_rdp_tab_init (VinagreRdpTab *rdp_tab)
++entry_text_changed_cb (GtkEntry *entry,
++ GtkBuilder *builder)
+ {
+- rdp_tab->priv = VINAGRE_RDP_TAB_GET_PRIVATE (rdp_tab);
++ const gchar *text;
++ GtkWidget *widget;
++ gsize username_length;
++ gsize password_length;
+
+- rdp_tab->priv->pid = 0;
+- rdp_tab->priv->child = 0;
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "username_entry"));
++ text = gtk_entry_get_text (GTK_ENTRY (widget));
++ username_length = strlen (text);
+
+- /* Create the rdp widget */
+- rdp_tab->priv->box = gtk_socket_new ();
+- gtk_widget_set_can_focus (rdp_tab->priv->box, TRUE);
+- vinagre_tab_add_view (VINAGRE_TAB (rdp_tab), rdp_tab->priv->box);
+- gtk_widget_show (rdp_tab->priv->box);
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "password_entry"));
++ text = gtk_entry_get_text (GTK_ENTRY (widget));
++ password_length = strlen (text);
+
+- g_signal_connect (rdp_tab->priv->box,
+- "plug-added",
+- G_CALLBACK (emit_connected_signal),
+- rdp_tab);
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
++ gtk_widget_set_sensitive (widget, password_length > 0 && username_length > 0);
++}
++
++static gboolean
++frdp_authenticate (freerdp *instance,
++ char **username,
++ char **password,
++ char **domain)
++{
++ VinagreTab *tab = VINAGRE_TAB (((frdpContext *) instance->context)->rdp_tab);
++ VinagreConnection *conn = vinagre_tab_get_conn (tab);
++ const gchar *user_name;
++ const gchar *domain_name;
++ GtkBuilder *builder;
++ GtkWidget *dialog;
++ GtkWidget *widget;
++ GtkWidget *username_entry;
++ GtkWidget *password_entry;
++ GtkWidget *domain_entry;
++ gboolean save_credential_check_visible;
++ gboolean domain_label_visible;
++ gboolean domain_entry_visible;
++ gint response;
++
++ builder = vinagre_utils_get_builder ();
++
++ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "auth_required_dialog"));
++ gtk_window_set_modal ((GtkWindow *) dialog, TRUE);
++ gtk_window_set_transient_for ((GtkWindow *) dialog, GTK_WINDOW (vinagre_tab_get_window (tab)));
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "host_label"));
++ gtk_label_set_text (GTK_LABEL (widget), vinagre_connection_get_host (conn));
++
++ username_entry = GTK_WIDGET (gtk_builder_get_object (builder, "username_entry"));
++ password_entry = GTK_WIDGET (gtk_builder_get_object (builder, "password_entry"));
++ domain_entry = GTK_WIDGET (gtk_builder_get_object (builder, "domain_entry"));
++
++ if (*username != NULL && *username[0] != '\0')
++ {
++ gtk_entry_set_text (GTK_ENTRY (username_entry), *username);
++ gtk_widget_grab_focus (password_entry);
++ }
+
++ g_signal_connect (username_entry, "changed", G_CALLBACK (entry_text_changed_cb), builder);
++ g_signal_connect (password_entry, "changed", G_CALLBACK (entry_text_changed_cb), builder);
++
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "save_credential_check"));
++ save_credential_check_visible = gtk_widget_get_visible (widget);
++ gtk_widget_set_visible (widget, FALSE);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "domain_label"));
++ domain_label_visible = gtk_widget_get_visible (widget);
++ gtk_widget_set_visible (widget, TRUE);
++
++ domain_entry_visible = gtk_widget_get_visible (domain_entry);
++ gtk_widget_set_visible (domain_entry, TRUE);
++
++
++ response = gtk_dialog_run (GTK_DIALOG (dialog));
++ gtk_widget_hide (dialog);
++
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "save_credential_check"));
++ gtk_widget_set_visible (widget, save_credential_check_visible);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "domain_label"));
++ gtk_widget_set_visible (widget, domain_label_visible);
++
++ gtk_widget_set_visible (domain_entry, domain_entry_visible);
++
++
++ if (response == GTK_RESPONSE_OK)
++ {
++ domain_name = gtk_entry_get_text (GTK_ENTRY (domain_entry));
++ if (g_strcmp0 (*domain, domain_name) != 0)
++ *domain = g_strdup (domain_name);
++
++ user_name = gtk_entry_get_text (GTK_ENTRY (username_entry));
++ if (g_strcmp0 (*username, user_name) != 0)
++ *username = g_strdup (user_name);
++
++ *password = g_strdup (gtk_entry_get_text (GTK_ENTRY (password_entry)));
++
++ return TRUE;
++ }
++ else
++ {
++ return FALSE;
++ }
++}
++
++static void
++open_freerdp (VinagreRdpTab *rdp_tab)
++{
++ VinagreRdpTabPrivate *priv = rdp_tab->priv;
++ VinagreTab *tab = VINAGRE_TAB (rdp_tab);
++ VinagreConnection *conn = vinagre_tab_get_conn (tab);
++ rdpSettings *settings;
++ GtkWindow *window = GTK_WINDOW (vinagre_tab_get_window (tab));
++ gboolean success = TRUE;
++ gboolean fullscreen;
++ gchar *hostname, *username;
++ gint port, width, height;
++
++ g_object_get (conn,
++ "port", &port,
++ "host", &hostname,
++ "width", &width,
++ "height", &height,
++ "fullscreen", &fullscreen,
++ "username", &username,
++ NULL);
++
++ priv->events = g_queue_new ();
++
++ /* Setup FreeRDP session */
++ priv->freerdp_session = freerdp_new ();
++ priv->freerdp_session->PreConnect = frdp_pre_connect;
++ priv->freerdp_session->PostConnect = frdp_post_connect;
++ priv->freerdp_session->Authenticate = frdp_authenticate;
++
++#if HAVE_FREERDP_1_1
++ priv->freerdp_session->ContextSize = sizeof (frdpContext);
++#else
++ priv->freerdp_session->context_size = sizeof (frdpContext);
++#endif
++
++ freerdp_context_new (priv->freerdp_session);
++ ((frdpContext *) priv->freerdp_session->context)->rdp_tab = rdp_tab;
++
++ /* Set FreeRDP settings */
++ settings = priv->freerdp_session->settings;
++
++ /* Security settings */
++#if HAVE_FREERDP_1_1
++ settings->RdpSecurity = TRUE;
++ settings->TlsSecurity = TRUE;
++ settings->NlaSecurity = TRUE;
++ settings->DisableEncryption = FALSE;
++ settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
++ settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
++#else
++ settings->rdp_security = true;
++ settings->tls_security = true;
++ settings->nla_security = true;
++ settings->encryption = true;
++ settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
++ settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
++#endif
++
++ /* Set display size */
++#if HAVE_FREERDP_1_1
++ settings->DesktopWidth = width;
++ settings->DesktopHeight = height;
++#else
++ settings->width = width;
++ settings->height = height;
++#endif
++
++ /* Set hostname */
++#if HAVE_FREERDP_1_1
++ settings->WindowTitle = g_strdup (hostname);
++ settings->ServerHostname = g_strdup (hostname);
++ settings->ServerPort = port;
++#else
++ settings->window_title = g_strdup (hostname);
++ settings->hostname = g_strdup (hostname);
++ settings->port = port;
++#endif
++
++ /* Set username */
++ username = g_strstrip (username);
++ if (username != NULL && username[0] != '\0')
++ {
++#if HAVE_FREERDP_1_1
++ settings->Username = g_strdup (username);
++#else
++ settings->username = g_strdup (username);
++#endif
++ }
++
++ /* Set keyboard layout */
++#if HAVE_FREERDP_1_1
++ freerdp_keyboard_init (KBD_US);
++#else
++ freerdp_kbd_init (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), KBD_US);
++#endif
++
++ /* Setup display for FreeRDP session */
++ 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);
++
++ gtk_widget_add_events (priv->display,
++ GDK_POINTER_MOTION_MASK |
++ GDK_BUTTON_PRESS_MASK |
++ GDK_BUTTON_RELEASE_MASK |
++ GDK_SCROLL_MASK |
++ GDK_SMOOTH_SCROLL_MASK);
++
++ priv->button_press_handler_id = g_signal_connect (priv->display, "button-press-event",
++ G_CALLBACK (frdp_button_pressed),
++ rdp_tab);
++
++ priv->button_release_handler_id = g_signal_connect (priv->display, "button-release-event",
++ G_CALLBACK (frdp_button_pressed),
++ rdp_tab);
++
++ priv->button_release_handler_id = g_signal_connect (priv->display, "scroll-event",
++ G_CALLBACK (frdp_scroll),
++ rdp_tab);
++
++ priv->motion_notify_handler_id = g_signal_connect (priv->display, "motion-notify-event",
++ G_CALLBACK (frdp_mouse_moved),
++ rdp_tab);
++
++ gtk_widget_show (priv->display);
++
++ vinagre_tab_add_view (VINAGRE_TAB (rdp_tab), priv->display);
++
++ if (fullscreen)
++ gtk_window_fullscreen (window);
++ }
++
++ priv->key_press_handler_id = g_signal_connect (window, "key-press-event",
++ G_CALLBACK (frdp_key_pressed),
++ rdp_tab);
++
++ priv->key_release_handler_id = g_signal_connect (window, "key-release-event",
++ G_CALLBACK (frdp_key_pressed),
++ rdp_tab);
++
++ /* Run FreeRDP session */
++ success = freerdp_connect (priv->freerdp_session);
++
++ if (!success)
++ {
++ gtk_window_unfullscreen (window);
++ vinagre_utils_show_error_dialog (_("Error connecting to host."),
++ NULL,
++ window);
++ g_idle_add ((GSourceFunc) idle_close, rdp_tab);
++ }
++ else
++ {
++ priv->update_id = g_idle_add ((GSourceFunc) update, rdp_tab);
++ }
++}
++
++static void
++vinagre_rdp_tab_init (VinagreRdpTab *rdp_tab)
++{
++ rdp_tab->priv = VINAGRE_RDP_TAB_GET_PRIVATE (rdp_tab);
+ }
+
+ GtkWidget *
+--
+cgit v0.10.1
+
Added: desktop/unstable/vinagre/debian/patches/02_Request-RDP-certificate-verification.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/patches/02_Request-RDP-certificate-verification.patch?rev=42279&op=file
==============================================================================
--- desktop/unstable/vinagre/debian/patches/02_Request-RDP-certificate-verification.patch (added)
+++ desktop/unstable/vinagre/debian/patches/02_Request-RDP-certificate-verification.patch [utf-8] Tue Aug 26 13:09:17 2014
@@ -0,0 +1,438 @@
+From 9d93c22d64c4c22999f0947396a5c21cf2072f23 Mon Sep 17 00:00:00 2001
+From: Marek Kasik <mkasik at redhat.com>
+Date: Tue, 22 Jul 2014 12:01:12 +0200
+Subject: Request RDP certificate verification if needed
+
+Add dialogs for asking of user whether they accept certificate of the
+remote host if it is not known yet or if it has changed.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=724133
+
+diff --git a/data/vinagre.ui b/data/vinagre.ui
+index 041dfe7..7fa926e 100644
+--- a/data/vinagre.ui
++++ b/data/vinagre.ui
+@@ -845,6 +845,311 @@ Jonh Wendell <jwendell at gnome.org></property>
+ <action-widget response="-5">save_button</action-widget>
+ </action-widgets>
+ </object>
++ <object class="GtkMessageDialog" id="certificate_changed_dialog">
++ <property name="can_focus">False</property>
++ <property name="resizable">False</property>
++ <property name="modal">True</property>
++ <property name="destroy_with_parent">True</property>
++ <property name="type_hint">dialog</property>
++ <property name="message_type">warning</property>
++ <property name="buttons">yes-no</property>
++ <property name="text" translatable="yes">Certificate Verification</property>
++ <property name="secondary_text" translatable="yes">The remote host has changed its certificate.
++Do you trust the new certificate?</property>
++ <child internal-child="vbox">
++ <object class="GtkBox" id="messagedialog-vbox1">
++ <property name="can_focus">False</property>
++ <property name="orientation">vertical</property>
++ <property name="spacing">10</property>
++ <child internal-child="action_area">
++ <object class="GtkButtonBox" id="messagedialog-action_area1">
++ <property name="can_focus">False</property>
++ <property name="layout_style">end</property>
++ </object>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">True</property>
++ <property name="pack_type">end</property>
++ <property name="position">0</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkGrid" id="grid4">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="row_spacing">15</property>
++ <property name="column_spacing">10</property>
++ <child>
++ <object class="GtkLabel" id="label12">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Subject of the certificate.">Subject:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="label16">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Issuer of the certificate.">Issuer:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">1</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_changed_new_fingerprint_label">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Fingerprint of the new certificate.">New fingerprint:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">2</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_changed_subject">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">subject</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_changed_issuer">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">issuer</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">1</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_changed_new_fingerprint">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">2</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_changed_old_fingerprint_label">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Fingerprint of the old certificate.">Old fingerprint:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">3</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_changed_old_fingerprint">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">3</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ </object>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">True</property>
++ <property name="position">2</property>
++ </packing>
++ </child>
++ </object>
++ </child>
++ </object>
++ <object class="GtkMessageDialog" id="certificate_dialog">
++ <property name="can_focus">False</property>
++ <property name="resizable">False</property>
++ <property name="modal">True</property>
++ <property name="destroy_with_parent">True</property>
++ <property name="type_hint">dialog</property>
++ <property name="message_type">question</property>
++ <property name="buttons">yes-no</property>
++ <property name="text" translatable="yes">Certificate Verification</property>
++ <property name="secondary_text" translatable="yes">The below certificate could not be verified.
++Do you trust the certificate?</property>
++ <child internal-child="vbox">
++ <object class="GtkBox" id="messagedialog-vbox">
++ <property name="can_focus">False</property>
++ <property name="orientation">vertical</property>
++ <property name="spacing">10</property>
++ <child internal-child="action_area">
++ <object class="GtkButtonBox" id="messagedialog-action_area">
++ <property name="can_focus">False</property>
++ <property name="layout_style">end</property>
++ </object>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">True</property>
++ <property name="pack_type">end</property>
++ <property name="position">0</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkGrid" id="grid6">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="row_spacing">15</property>
++ <property name="column_spacing">10</property>
++ <child>
++ <object class="GtkLabel" id="label24">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Subject of the certificate.">Subject:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="label27">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Issuer of the certificate.">Issuer:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">1</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="label28">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="vexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="xpad">12</property>
++ <property name="label" translatable="yes" comments="Fingerprint of the certificate.">Fingerprint:</property>
++ </object>
++ <packing>
++ <property name="left_attach">0</property>
++ <property name="top_attach">2</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_subject">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">subject</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">0</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_issuer">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">issuer</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">1</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ <child>
++ <object class="GtkLabel" id="certificate_fingerprint">
++ <property name="visible">True</property>
++ <property name="can_focus">False</property>
++ <property name="hexpand">True</property>
++ <property name="xalign">0</property>
++ <property name="label">00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00</property>
++ </object>
++ <packing>
++ <property name="left_attach">1</property>
++ <property name="top_attach">2</property>
++ <property name="width">1</property>
++ <property name="height">1</property>
++ </packing>
++ </child>
++ </object>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">True</property>
++ <property name="position">2</property>
++ </packing>
++ </child>
++ </object>
++ </child>
++ </object>
+ <object class="GtkDialog" id="connect_dialog">
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+diff --git a/plugins/rdp/vinagre-rdp-tab.c b/plugins/rdp/vinagre-rdp-tab.c
+index 1ca9bb6..0d42d44 100644
+--- a/plugins/rdp/vinagre-rdp-tab.c
++++ b/plugins/rdp/vinagre-rdp-tab.c
+@@ -731,6 +731,93 @@ frdp_authenticate (freerdp *instance,
+ }
+ }
+
++static BOOL
++frdp_certificate_verify (freerdp *instance,
++ char *subject,
++ char *issuer,
++ char *fingerprint)
++{
++ VinagreTab *tab = VINAGRE_TAB (((frdpContext *) instance->context)->rdp_tab);
++ GtkBuilder *builder;
++ GtkWidget *dialog;
++ GtkWidget *widget;
++ gint response;
++
++ builder = vinagre_utils_get_builder ();
++
++ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_dialog"));
++ gtk_window_set_transient_for ((GtkWindow *) dialog, GTK_WINDOW (vinagre_tab_get_window (tab)));
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_subject"));
++ gtk_label_set_text (GTK_LABEL (widget), subject);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_issuer"));
++ gtk_label_set_text (GTK_LABEL (widget), issuer);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_fingerprint"));
++ gtk_label_set_text (GTK_LABEL (widget), fingerprint);
++
++
++ response = gtk_dialog_run (GTK_DIALOG (dialog));
++ gtk_widget_hide (dialog);
++
++
++ return response == GTK_RESPONSE_YES;
++}
++
++
++#if HAVE_FREERDP_1_1
++static BOOL
++frdp_changed_certificate_verify (freerdp *instance,
++ char *subject,
++ char *issuer,
++ char *new_fingerprint,
++ char *old_fingerprint)
++{
++ VinagreTab *tab = VINAGRE_TAB (((frdpContext *) instance->context)->rdp_tab);
++ GtkBuilder *builder;
++ GtkWidget *dialog;
++ GtkWidget *widget;
++ GtkWidget *label;
++ gint response;
++
++ builder = vinagre_utils_get_builder ();
++
++ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_dialog"));
++ gtk_window_set_transient_for ((GtkWindow *) dialog, GTK_WINDOW (vinagre_tab_get_window (tab)));
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_subject"));
++ gtk_label_set_text (GTK_LABEL (widget), subject);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_issuer"));
++ gtk_label_set_text (GTK_LABEL (widget), issuer);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_new_fingerprint"));
++ gtk_label_set_text (GTK_LABEL (widget), new_fingerprint);
++
++ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_old_fingerprint"));
++ label = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_old_fingerprint_label"));
++ if (old_fingerprint != NULL && old_fingerprint[0] != '\0')
++ {
++ gtk_label_set_text (GTK_LABEL (widget), old_fingerprint);
++ gtk_widget_show (widget);
++ gtk_widget_show (label);
++ }
++ else
++ {
++ gtk_widget_hide (widget);
++ gtk_widget_hide (label);
++ }
++
++
++ response = gtk_dialog_run (GTK_DIALOG (dialog));
++ gtk_widget_hide (dialog);
++
++
++ return response == GTK_RESPONSE_YES;
++}
++#endif
++
+ static void
+ open_freerdp (VinagreRdpTab *rdp_tab)
+ {
+@@ -760,6 +847,10 @@ open_freerdp (VinagreRdpTab *rdp_tab)
+ priv->freerdp_session->PreConnect = frdp_pre_connect;
+ priv->freerdp_session->PostConnect = frdp_post_connect;
+ priv->freerdp_session->Authenticate = frdp_authenticate;
++ priv->freerdp_session->VerifyCertificate = frdp_certificate_verify;
++#if HAVE_FREERDP_1_1
++ priv->freerdp_session->VerifyChangedCertificate = frdp_changed_certificate_verify;
++#endif
+
+ #if HAVE_FREERDP_1_1
+ priv->freerdp_session->ContextSize = sizeof (frdpContext);
+--
+cgit v0.10.1
+
Added: desktop/unstable/vinagre/debian/patches/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/patches/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch?rev=42279&op=file
==============================================================================
--- desktop/unstable/vinagre/debian/patches/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch (added)
+++ desktop/unstable/vinagre/debian/patches/03_Avoid-yes-no-buttons-in-certificate-dialogs.patch [utf-8] Tue Aug 26 13:09:17 2014
@@ -0,0 +1,54 @@
+From 853314e1a72f242ec95854f5eb36c14068452d6b Mon Sep 17 00:00:00 2001
+From: David King <amigadave at amigadave.com>
+Date: Mon, 18 Aug 2014 12:15:40 +0100
+Subject: Avoid yes-no buttons in certificate dialogs
+
+Use Connect/Cancel instead.
+
+diff --git a/data/vinagre.ui b/data/vinagre.ui
+index 7fa926e..8b3e7f3 100644
+--- a/data/vinagre.ui
++++ b/data/vinagre.ui
+@@ -852,7 +852,6 @@ Jonh Wendell <jwendell at gnome.org></property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="message_type">warning</property>
+- <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes">Certificate Verification</property>
+ <property name="secondary_text" translatable="yes">The remote host has changed its certificate.
+ Do you trust the new certificate?</property>
+@@ -1020,7 +1019,6 @@ Do you trust the new certificate?</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="message_type">question</property>
+- <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes">Certificate Verification</property>
+ <property name="secondary_text" translatable="yes">The below certificate could not be verified.
+ Do you trust the certificate?</property>
+diff --git a/plugins/rdp/vinagre-rdp-tab.c b/plugins/rdp/vinagre-rdp-tab.c
+index 0d42d44..02f5e4e 100644
+--- a/plugins/rdp/vinagre-rdp-tab.c
++++ b/plugins/rdp/vinagre-rdp-tab.c
+@@ -747,6 +747,9 @@ frdp_certificate_verify (freerdp *instance,
+
+ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_dialog"));
+ gtk_window_set_transient_for ((GtkWindow *) dialog, GTK_WINDOW (vinagre_tab_get_window (tab)));
++ gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_NO,
++ _("Connect"), GTK_RESPONSE_YES, NULL);
++ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_subject"));
+ gtk_label_set_text (GTK_LABEL (widget), subject);
+@@ -785,6 +788,9 @@ frdp_changed_certificate_verify (freerdp *instance,
+
+ dialog = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_dialog"));
+ gtk_window_set_transient_for ((GtkWindow *) dialog, GTK_WINDOW (vinagre_tab_get_window (tab)));
++ gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_NO,
++ _("Connect"), GTK_RESPONSE_YES, NULL);
++ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "certificate_changed_subject"));
+ gtk_label_set_text (GTK_LABEL (widget), subject);
+--
+cgit v0.10.1
+
Modified: desktop/unstable/vinagre/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/patches/series?rev=42279&op=diff
==============================================================================
--- desktop/unstable/vinagre/debian/patches/series [utf-8] (original)
+++ desktop/unstable/vinagre/debian/patches/series [utf-8] Tue Aug 26 13:09:17 2014
@@ -0,0 +1,3 @@
+01_Use-FreeRDP-API-in-RDP.patch
+02_Request-RDP-certificate-verification.patch
+03_Avoid-yes-no-buttons-in-certificate-dialogs.patch
Modified: desktop/unstable/vinagre/debian/rules
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/vinagre/debian/rules?rev=42279&op=diff
==============================================================================
--- desktop/unstable/vinagre/debian/rules [utf-8] (original)
+++ desktop/unstable/vinagre/debian/rules [utf-8] Tue Aug 26 13:09:17 2014
@@ -1,12 +1,16 @@
#!/usr/bin/make -f
+include /usr/share/cdbs/1/rules/autoreconf.mk
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/rules/utils.mk
include /usr/share/cdbs/1/class/gnome.mk
include /usr/share/gnome-pkg-tools/1/rules/uploaders.mk
-include /usr/share/gnome-pkg-tools/1/rules/gnome-get-source.mk
-LDFLAGS += -Wl,-O1 -Wl,--as-needed
+DEB_DH_AUTORECONF_ARGS = --as-needed
+
+DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 -Wl,--as-needed
+include /usr/share/dpkg/default.mk
DEB_CONFIGURE_EXTRA_FLAGS += --with-avahi \
--enable-ssh \
More information about the pkg-gnome-commits
mailing list