aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/remmina/APKBUILD26
-rw-r--r--main/remmina/remmina-1.0.0-add-clipboard-support.patch663
-rw-r--r--main/remmina/remmina-1.0.0-clipboard-bugfix.patch73
-rw-r--r--main/remmina/remmina-1.0.0-disconnect-signal-handler-after-disconnect.patch53
-rw-r--r--main/remmina/remmina-1.0.0-fix-memory-leak.patch24
-rw-r--r--main/remmina/remmina-1.0.0-some-more-clipboard-fixes.patch180
6 files changed, 1016 insertions, 3 deletions
diff --git a/main/remmina/APKBUILD b/main/remmina/APKBUILD
index a7a2821f47..86c08bf2df 100644
--- a/main/remmina/APKBUILD
+++ b/main/remmina/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=remmina
pkgver=1.0.0
-pkgrel=5
+pkgrel=6
pkgdesc="Remmina is a remote desktop client written in GTK+"
url="http://remmina.sourceforge.net/"
arch="all"
@@ -14,8 +14,16 @@ install=
replaces="remmina-plugins"
subpackages="$pkgname-dev $pkgname-lang"
source="https://github.com/downloads/FreeRDP/Remmina/Remmina-$pkgver.tar.gz
+ no-gnome-keyring.patch
underlinking.patch
- no-gnome-keyring.patch"
+
+ remmina-1.0.0-add-clipboard-support.patch
+ remmina-1.0.0-clipboard-bugfix.patch
+ remmina-1.0.0-some-more-clipboard-fixes.patch
+ remmina-1.0.0-disconnect-signal-handler-after-disconnect.patch
+
+ remmina-1.0.0-fix-memory-leak.patch
+ "
prepare() {
cd "$srcdir"/FreeRDP-Remmina-*
@@ -39,8 +47,20 @@ build() {
package() {
cd "$srcdir"/FreeRDP-Remmina-*
make DESTDIR="$pkgdir" install
+ # dirty hack
+ mkdir -p "$pkgdir"/usr/share/applications
+ sed 's,^_,,g' remmina/desktop/remmina.desktop.in \
+ > "$pkgdir"/usr/share/applications/remmina.desktop \
+ || return 1
+ mv "$pkgdir"/usr/share/remmina/icons "$pkgdir"/usr/share/icons \
+ || return 1
}
md5sums="701c540acaab961bc3adf130a2ddb8b1 Remmina-1.0.0.tar.gz
+178d55f7aa59d6dc73b19e03201ad1e4 no-gnome-keyring.patch
594668bf54d4068cc57f8cfdae482adb underlinking.patch
-178d55f7aa59d6dc73b19e03201ad1e4 no-gnome-keyring.patch"
+9312b5bf953a63e6203f0d0be6cb8134 remmina-1.0.0-add-clipboard-support.patch
+65bfcc39ae51343b90928ea329cc4900 remmina-1.0.0-clipboard-bugfix.patch
+42b971116f887657fc210da70c3afba5 remmina-1.0.0-some-more-clipboard-fixes.patch
+04b5bc1190b53211747e097897d1d19c remmina-1.0.0-disconnect-signal-handler-after-disconnect.patch
+3bc1a4e50cdd864c0e2d7c91a1e02e32 remmina-1.0.0-fix-memory-leak.patch"
diff --git a/main/remmina/remmina-1.0.0-add-clipboard-support.patch b/main/remmina/remmina-1.0.0-add-clipboard-support.patch
new file mode 100644
index 0000000000..b5fd340c90
--- /dev/null
+++ b/main/remmina/remmina-1.0.0-add-clipboard-support.patch
@@ -0,0 +1,663 @@
+From 3ebdd6e7b0ee53ecdaf0d14bada6b92e7334b12a Mon Sep 17 00:00:00 2001
+From: Jean-Louis Dupond <jean-louis@dupond.be>
+Date: Mon, 30 Apr 2012 23:10:04 +0200
+Subject: [PATCH] Add clipboard support
+
+---
+ remmina-plugins/rdp/CMakeLists.txt | 2 +
+ remmina-plugins/rdp/rdp_cliprdr.c | 459 ++++++++++++++++++++++++++++++++++++
+ remmina-plugins/rdp/rdp_cliprdr.h | 33 +++
+ remmina-plugins/rdp/rdp_event.c | 19 ++
+ remmina-plugins/rdp/rdp_plugin.c | 15 ++
+ remmina-plugins/rdp/rdp_plugin.h | 6 +-
+ 6 files changed, 533 insertions(+), 1 deletion(-)
+ create mode 100644 remmina-plugins/rdp/rdp_cliprdr.c
+ create mode 100644 remmina-plugins/rdp/rdp_cliprdr.h
+
+diff --git a/remmina-plugins/rdp/CMakeLists.txt b/remmina-plugins/rdp/CMakeLists.txt
+index e3ec20b..8ae4a4d 100644
+--- a/remmina-plugins/rdp/CMakeLists.txt
++++ b/remmina-plugins/rdp/CMakeLists.txt
+@@ -33,6 +33,8 @@ set(REMMINA_PLUGIN_RDP_SRCS
+ rdp_gdi.h
+ rdp_graphics.c
+ rdp_graphics.h
++ rdp_cliprdr.c
++ rdp_cliprdr.h
+ )
+
+ add_library(remmina-plugin-rdp ${REMMINA_PLUGIN_RDP_SRCS})
+diff --git a/remmina-plugins/rdp/rdp_cliprdr.c b/remmina-plugins/rdp/rdp_cliprdr.c
+new file mode 100644
+index 0000000..0821ffa
+--- /dev/null
++++ b/remmina-plugins/rdp/rdp_cliprdr.c
+@@ -0,0 +1,459 @@
++/*
++ * Remmina - The GTK+ Remote Desktop Client
++ * Copyright (C) 2012-2012 Jean-Louis Dupond
++ *
++ * 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.
++ */
++
++#include "rdp_plugin.h"
++#include "rdp_cliprdr.h"
++
++#include <freerdp/freerdp.h>
++#include <freerdp/utils/memory.h>
++#include <freerdp/channels/channels.h>
++#include <freerdp/plugins/cliprdr.h>
++
++/*
++ * Get the formats we can export based on the current clipboard data.
++ */
++void remmina_rdp_cliprdr_get_target_types(uint32** dst_formats, uint16* size, GdkAtom* types, int count)
++{
++ int i;
++ gboolean image = FALSE;
++ gboolean text = FALSE;
++ gboolean textutf8 = FALSE;
++ int matches = 1;
++ uint32* formats = (uint32*) xmalloc(sizeof(uint32) * 10);
++
++ formats[0] = CB_FORMAT_RAW;
++ for (i = 0; i < count; i++)
++ {
++ GdkAtom atom = GDK_POINTER_TO_ATOM(types[i]);
++ gchar* name = gdk_atom_name(atom);
++ if (g_strcmp0("UTF8_STRING", name) == 0 || g_strcmp0("text/plain;charset=utf-8", name) == 0)
++ {
++ textutf8 = TRUE;
++ }
++ if (g_strcmp0("TEXT", name) == 0 || g_strcmp0("text/plain", name) == 0)
++ {
++ text = TRUE;
++ }
++ if (g_strcmp0("text/html", name) == 0)
++ {
++ formats[matches] = CB_FORMAT_HTML;
++ matches++;
++ }
++ if (g_strcmp0("image/png", name) == 0)
++ {
++ formats[matches] = CB_FORMAT_PNG;
++ image = TRUE;
++ matches++;
++ }
++ if (g_strcmp0("image/jpeg", name) == 0)
++ {
++ formats[matches] = CB_FORMAT_JPEG;
++ image = TRUE;
++ matches++;
++ }
++ if (g_strcmp0("image/bmp", name) == 0)
++ {
++ formats[matches] = CB_FORMAT_DIB;
++ image = TRUE;
++ matches++;
++ }
++ }
++ //Only add text formats if we don't have image formats
++ if (!image)
++ {
++ if (textutf8)
++ {
++ formats[matches] = CB_FORMAT_UNICODETEXT;
++ matches++;
++ }
++ if (text)
++ {
++ formats[matches] = CB_FORMAT_TEXT;
++ matches++;
++ }
++ }
++
++ *size = (uint16)matches;
++ *dst_formats = (uint32*) xmalloc(sizeof(uint32) * matches);
++ memcpy(*dst_formats, formats, sizeof(uint32) * matches);
++ g_free(formats);
++}
++
++int remmina_rdp_cliprdr_send_format_list_event(RemminaProtocolWidget* gp)
++{
++ GtkClipboard* clipboard;
++ GdkAtom* targets;
++ gboolean result = 0;
++ gint count;
++ RDP_EVENT* rdp_event;
++ RDP_CB_FORMAT_LIST_EVENT* format_list_event;
++ rfContext* rfi = GET_DATA(gp);
++
++ /* Lets see if we have something in our clipboard */
++ THREADS_ENTER
++ clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD);
++ if (clipboard)
++ {
++ result = gtk_clipboard_wait_for_targets(clipboard, &targets, &count);
++ }
++ THREADS_LEAVE
++
++ if (!result)
++ return 1;
++
++ int i;
++ for (i = 0; i < count; i++)
++ {
++ g_printf("Target %d: %s\n", i, gdk_atom_name(targets[i]));
++ }
++
++ rdp_event = (RDP_EVENT*) xnew(RDP_CB_FORMAT_LIST_EVENT);
++ rdp_event->event_class = RDP_EVENT_CLASS_CLIPRDR;
++ rdp_event->event_type = RDP_EVENT_TYPE_CB_FORMAT_LIST;
++ format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) rdp_event;
++
++ remmina_rdp_cliprdr_get_target_types(&format_list_event->formats, &format_list_event->num_formats, targets, count);
++ g_free(targets);
++
++ int num_formats = format_list_event->num_formats;
++ g_printf("Sending %d formats\n", num_formats);
++ for (i = 0; i < num_formats; i++)
++ {
++ g_printf("Sending format %#X\n", format_list_event->formats[i]);
++ }
++
++ return freerdp_channels_send_event(rfi->channels, (RDP_EVENT*) format_list_event);
++}
++
++static uint8* lf2crlf(uint8* data, int* size)
++{
++ uint8 c;
++ uint8* outbuf;
++ uint8* out;
++ uint8* in_end;
++ uint8* in;
++ int out_size;
++
++ out_size = (*size) * 2 + 1;
++ outbuf = (uint8*) xmalloc(out_size);
++ out = outbuf;
++ in = data;
++ in_end = data + (*size);
++
++ while (in < in_end)
++ {
++ c = *in++;
++ if (c == '\n')
++ {
++ *out++ = '\r';
++ *out++ = '\n';
++ }
++ else
++ {
++ *out++ = c;
++ }
++ }
++
++ *out++ = 0;
++ *size = out - outbuf;
++
++ return outbuf;
++}
++
++static void crlf2lf(uint8* data, int* size)
++{
++ uint8 c;
++ uint8* out;
++ uint8* in;
++ uint8* in_end;
++
++ out = data;
++ in = data;
++ in_end = data + (*size);
++
++ while (in < in_end)
++ {
++ c = *in++;
++
++ if (c != '\r')
++ *out++ = c;
++ }
++
++ *size = out - data;
++}
++
++uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, int* size)
++{
++ g_printf("GetData: Requested Format: %#X\n", format);
++ rfContext* rfi = GET_DATA(gp);
++ GtkClipboard* clipboard;
++ uint8* inbuf = NULL;
++ uint8* outbuf = NULL;
++ GdkPixbuf *image = NULL;
++
++ THREADS_ENTER
++ clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD);
++ if (clipboard)
++ {
++ if (format == CB_FORMAT_TEXT || format == CB_FORMAT_UNICODETEXT || format == CB_FORMAT_HTML)
++ {
++ inbuf = (uint8*)gtk_clipboard_wait_for_text(clipboard);
++ }
++ if (format == CB_FORMAT_PNG || format == CB_FORMAT_JPEG || format == CB_FORMAT_DIB)
++ {
++ image = gtk_clipboard_wait_for_image(clipboard);
++ }
++ }
++ THREADS_LEAVE
++
++ if (format == CB_FORMAT_TEXT || format == CB_FORMAT_HTML || format == CB_FORMAT_UNICODETEXT)
++ {
++ lf2crlf(inbuf, size);
++ if (format == CB_FORMAT_TEXT)
++ {
++ outbuf = inbuf;
++ }
++ if (format == CB_FORMAT_HTML)
++ {
++ //TODO: check if we need special handling for HTML
++ outbuf = inbuf;
++ }
++ if (format == CB_FORMAT_UNICODETEXT)
++ {
++ size_t out_size;
++ UNICONV* uniconv;
++
++ uniconv = freerdp_uniconv_new();
++ outbuf = (uint8*) freerdp_uniconv_out(uniconv, (char*) inbuf, &out_size);
++ freerdp_uniconv_free(uniconv);
++ *size = out_size + 2;
++ }
++ }
++ if (format == CB_FORMAT_PNG || format == CB_FORMAT_JPEG || format == CB_FORMAT_DIB)
++ {
++ gchar* data;
++ gsize buffersize;
++ if (format == CB_FORMAT_PNG)
++ {
++ gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "png", NULL, NULL);
++ memcpy(outbuf, data, buffersize);
++ }
++ if (format == CB_FORMAT_JPEG)
++ {
++ gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "jpeg", NULL, NULL);
++ memcpy(outbuf, data, buffersize);
++ }
++ if (format == CB_FORMAT_DIB)
++ {
++ gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "bmp", NULL, NULL);
++ *size = buffersize - 14;
++ g_printf("Size of pixels: %d\n", *size);
++ outbuf = (uint8*) xmalloc(*size);
++ memcpy(outbuf, data + 14, *size);
++ }
++ }
++
++ if (!outbuf)
++ outbuf = (uint8*)"";
++
++ return outbuf;
++}
++
++void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVENT* event)
++{
++ g_printf("Received RDP_EVENT_TYPE_CB_DATA_RESPONSE\n");
++
++ GtkClipboard* clipboard;
++ GdkPixbuf *image = NULL;
++ uint8* data;
++ int size;
++ gboolean text = FALSE;
++ gboolean img = FALSE;
++ rfContext* rfi = GET_DATA(gp);
++ RDP_CB_DATA_RESPONSE_EVENT* data_response_event;
++
++ data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*) event;
++ data = data_response_event->data;
++ size = data_response_event->size;
++
++ g_printf("Requested format was: 0x%x\n", rfi->requested_format);
++
++ if (rfi->requested_format == CB_FORMAT_TEXT || rfi->requested_format == CB_FORMAT_UNICODETEXT || rfi->requested_format == CB_FORMAT_HTML)
++ {
++ if (rfi->requested_format == CB_FORMAT_UNICODETEXT)
++ {
++ UNICONV* uniconv;
++
++ uniconv = freerdp_uniconv_new();
++ data = (uint8*) freerdp_uniconv_in(uniconv, data, size);
++ size = strlen((char*) data);
++ freerdp_uniconv_free(uniconv);
++ }
++ crlf2lf(data, &size);
++ text = TRUE;
++ }
++ if (rfi->requested_format == CB_FORMAT_DIB || rfi->requested_format == CB_FORMAT_PNG || rfi->requested_format == CB_FORMAT_JPEG)
++ {
++ /* Reconstruct header */
++ if (rfi->requested_format == CB_FORMAT_DIB)
++ {
++ STREAM* s;
++ uint16 bpp;
++ uint32 offset;
++ uint32 ncolors;
++
++ s = stream_new(0);
++ stream_attach(s, data, size);
++ stream_seek(s, 14);
++ stream_read_uint16(s, bpp);
++ stream_read_uint32(s, ncolors);
++ offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0);
++ stream_detach(s);
++ stream_free(s);
++
++ s = stream_new(14 + size);
++ stream_write_uint8(s, 'B');
++ stream_write_uint8(s, 'M');
++ stream_write_uint32(s, 14 + size);
++ stream_write_uint32(s, 0);
++ stream_write_uint32(s, offset);
++ stream_write(s, data, size);
++
++ data = stream_get_head(s);
++ size = stream_get_length(s);
++ stream_detach(s);
++ stream_free(s);
++ }
++ GdkPixbufLoader *pixbuf;
++ pixbuf = gdk_pixbuf_loader_new();
++ gdk_pixbuf_loader_write(pixbuf, data, size, NULL);
++ image = gdk_pixbuf_loader_get_pixbuf(pixbuf);
++ img = TRUE;
++ }
++
++ THREADS_ENTER
++ clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD);
++ if (clipboard)
++ {
++ if (text || img)
++ rfi->clipboard_wait = TRUE;
++ if (text)
++ gtk_clipboard_set_text(clipboard, (gchar*)data, size);
++ if (img)
++ gtk_clipboard_set_image(clipboard, image);
++ }
++ THREADS_LEAVE
++
++}
++
++void remmina_handle_channel_event(RemminaProtocolWidget* gp, RDP_EVENT* event)
++{
++ RDP_EVENT* rdp_event = NULL;
++ rfContext* rfi = GET_DATA(gp);
++
++ switch (event->event_class)
++ {
++ case RDP_EVENT_CLASS_CLIPRDR:
++ g_printf("Event ID: %d\n", event->event_type);
++ if (event->event_type == RDP_EVENT_TYPE_CB_MONITOR_READY)
++ {
++ g_printf("Received CB_MONITOR_READY - Sending RDP_EVENT_TYPE_CB_FORMAT_LIST\n");
++ /* Sending our format list */
++ remmina_rdp_cliprdr_send_format_list_event(gp);
++ }
++ if (event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST)
++ {
++ /* We received a FORMAT_LIST from the server, update our clipboard */
++ g_printf("Received RDP_EVENT_TYPE_CB_FORMAT_LIST\n");
++ int i;
++ uint32 format = CB_FORMAT_RAW;
++ RDP_CB_FORMAT_LIST_EVENT* format_list_event;
++
++ format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event;
++
++ g_printf("Format List Size: %d\n", format_list_event->num_formats);
++ for (i = 0; i < format_list_event->num_formats; i++)
++ {
++ g_printf("Format: 0x%X\n", format_list_event->formats[i]);
++ if (format_list_event->formats[i] == CB_FORMAT_UNICODETEXT)
++ {
++ format = CB_FORMAT_UNICODETEXT;
++ break;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_DIB)
++ {
++ format = CB_FORMAT_DIB;
++ break;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_JPEG)
++ {
++ format = CB_FORMAT_JPEG;
++ break;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_PNG)
++ {
++ format = CB_FORMAT_PNG;
++ break;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_TEXT)
++ {
++ format = CB_FORMAT_TEXT;
++ break;
++ }
++ }
++ rfi->requested_format = format;
++
++ g_printf("Format Requested: 0x%X\n", format);
++ /* Request Clipboard data of the server */
++ RDP_CB_DATA_REQUEST_EVENT* data_request_event;
++ rdp_event = (RDP_EVENT*) xnew(RDP_CB_DATA_REQUEST_EVENT);
++ rdp_event->event_class = RDP_EVENT_CLASS_CLIPRDR;
++ rdp_event->event_type = RDP_EVENT_TYPE_CB_DATA_REQUEST;
++ data_request_event = (RDP_CB_DATA_REQUEST_EVENT*) rdp_event;
++ data_request_event->format = format;
++ freerdp_channels_send_event(rfi->channels, (RDP_EVENT*) data_request_event);
++ }
++ if (event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST)
++ {
++ g_printf("Received RDP_EVENT_TYPE_CB_DATA_REQUEST\n");
++
++ uint8* data;
++ int size;
++ RDP_CB_DATA_REQUEST_EVENT* data_request_event = (RDP_CB_DATA_REQUEST_EVENT*) event;
++ RDP_CB_DATA_RESPONSE_EVENT* data_response_event;
++
++ g_printf("Event Format: %d\n", data_request_event->format);
++
++ /* Send Data */
++ rdp_event = (RDP_EVENT*) xnew(RDP_CB_DATA_RESPONSE_EVENT);
++ rdp_event->event_class = RDP_EVENT_CLASS_CLIPRDR;
++ rdp_event->event_type = RDP_EVENT_TYPE_CB_DATA_RESPONSE;
++ data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*) rdp_event;
++ data = remmina_rdp_cliprdr_get_data(gp, data_request_event->format, &size);
++ data_response_event->data = data;
++ data_response_event->size = size;
++ freerdp_channels_send_event(rfi->channels, rdp_event);
++ }
++ if (event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE)
++ {
++ remmina_rdp_cliprdr_parse_response_event(gp, event);
++ }
++ }
++}
+diff --git a/remmina-plugins/rdp/rdp_cliprdr.h b/remmina-plugins/rdp/rdp_cliprdr.h
+new file mode 100644
+index 0000000..ed6bf70
+--- /dev/null
++++ b/remmina-plugins/rdp/rdp_cliprdr.h
+@@ -0,0 +1,33 @@
++/*
++ * Remmina - The GTK+ Remote Desktop Client
++ * Copyright (C) 2010-2011 Vic Lee
++ * Copyright (C) 2012-2012 Jean-Louis Dupond
++ *
++ * 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.
++ */
++
++#ifndef __REMMINA_RDP_CLIPRDR_H__
++#define __REMMINA_RDP_CLIPRDR_H__
++
++G_BEGIN_DECLS
++
++RDP_EVENT* remmina_rdp_cliprdr_get_event(uint16 event_type);
++int remmina_rdp_cliprdr_send_format_list_event(RemminaProtocolWidget* gp);
++void remmina_handle_channel_event(RemminaProtocolWidget* gp, RDP_EVENT* event);
++
++G_END_DECLS
++
++#endif
+diff --git a/remmina-plugins/rdp/rdp_event.c b/remmina-plugins/rdp/rdp_event.c
+index f77f5f1..a936fb1 100644
+--- a/remmina-plugins/rdp/rdp_event.c
++++ b/remmina-plugins/rdp/rdp_event.c
+@@ -461,6 +461,16 @@ static gboolean remmina_rdp_event_on_key(GtkWidget* widget, GdkEventKey* event,
+ return TRUE;
+ }
+
++static gboolean remmina_rdp_event_on_clipboard(GtkClipboard *clipboard, GdkEvent *event, RemminaProtocolWidget *gp)
++{
++ RemminaPluginRdpEvent rdp_event = { 0 };
++
++ rdp_event.type = REMMINA_RDP_EVENT_TYPE_CLIPBOARD;
++ remmina_rdp_event_event_push(gp, &rdp_event);
++
++ return TRUE;
++}
++
+ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
+ {
+ gint n;
+@@ -470,6 +480,7 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
+ XPixmapFormatValues* pf;
+ XPixmapFormatValues* pfs;
+ rfContext* rfi;
++ GtkClipboard* clipboard;
+
+ rfi = GET_DATA(gp);
+ rfi->drawing_area = gtk_drawing_area_new();
+@@ -508,6 +519,14 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
+ g_signal_connect(G_OBJECT(rfi->drawing_area), "key-release-event",
+ G_CALLBACK(remmina_rdp_event_on_key), gp);
+
++ RemminaFile* remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
++ if (!remmina_plugin_service->file_get_int(remminafile, "disableclipboard", FALSE))
++ {
++ clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD);
++ g_signal_connect(clipboard, "owner-change",
++ G_CALLBACK(remmina_rdp_event_on_clipboard), gp);
++ }
++
+ rfi->pressed_keys = g_array_new(FALSE, TRUE, sizeof (gint));
+ rfi->event_queue = g_async_queue_new_full(g_free);
+ rfi->ui_queue = g_async_queue_new();
+diff --git a/remmina-plugins/rdp/rdp_plugin.c b/remmina-plugins/rdp/rdp_plugin.c
+index 08874e6..fd0fe08 100644
+--- a/remmina-plugins/rdp/rdp_plugin.c
++++ b/remmina-plugins/rdp/rdp_plugin.c
+@@ -24,6 +24,7 @@
+ #include "rdp_graphics.h"
+ #include "rdp_file.h"
+ #include "rdp_settings.h"
++#include "rdp_cliprdr.h"
+
+ #include <errno.h>
+ #include <pthread.h>
+@@ -31,6 +32,7 @@
+ #include <freerdp/freerdp.h>
+ #include <freerdp/constants.h>
+ #include <freerdp/utils/memory.h>
++#include <freerdp/plugins/cliprdr.h>
+
+ #define REMMINA_RDP_FEATURE_TOOL_REFRESH 1
+ #define REMMINA_RDP_FEATURE_SCALE 2
+@@ -128,6 +130,11 @@ boolean rf_check_fds(RemminaProtocolWidget* gp)
+ input->MouseEvent(input, event->mouse_event.flags,
+ event->mouse_event.x, event->mouse_event.y);
+ break;
++ case REMMINA_RDP_EVENT_TYPE_CLIPBOARD:
++ if (!rfi->clipboard_wait)
++ remmina_rdp_cliprdr_send_format_list_event(gp);
++ rfi->clipboard_wait = FALSE;
++ break;
+ }
+
+ g_free(event);
+@@ -503,6 +510,7 @@ static boolean remmina_rdp_verify_certificate(freerdp* instance, char* subject,
+
+ static int remmina_rdp_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size)
+ {
++ g_printf("EVENT RECEIVED -> DATA: %s\nSIZE: %d\nFLAGS: %d\n", (char*)data, size, flags);
+ return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
+ }
+
+@@ -518,6 +526,7 @@ static void remmina_rdp_main_loop(RemminaProtocolWidget* gp)
+ fd_set rfds_set;
+ fd_set wfds_set;
+ rfContext* rfi;
++ RDP_EVENT* event;
+
+ memset(rfds, 0, sizeof(rfds));
+ memset(wfds, 0, sizeof(wfds));
+@@ -591,6 +600,12 @@ static void remmina_rdp_main_loop(RemminaProtocolWidget* gp)
+ {
+ break;
+ }
++ else
++ {
++ event = freerdp_channels_pop_event(rfi->channels);
++ if (event)
++ remmina_handle_channel_event(gp, event);
++ }
+ /* check ui */
+ if (!rf_check_fds(gp))
+ {
+diff --git a/remmina-plugins/rdp/rdp_plugin.h b/remmina-plugins/rdp/rdp_plugin.h
+index a3774d9..1931384 100644
+--- a/remmina-plugins/rdp/rdp_plugin.h
++++ b/remmina-plugins/rdp/rdp_plugin.h
+@@ -133,12 +133,16 @@ struct rf_context
+ GArray* pressed_keys;
+ GAsyncQueue* event_queue;
+ gint event_pipe[2];
++
++ gboolean clipboard_wait;
++ uint32 requested_format;
+ };
+
+ typedef enum
+ {
+ REMMINA_RDP_EVENT_TYPE_SCANCODE,
+- REMMINA_RDP_EVENT_TYPE_MOUSE
++ REMMINA_RDP_EVENT_TYPE_MOUSE,
++ REMMINA_RDP_EVENT_TYPE_CLIPBOARD
+ } RemminaPluginRdpEventType;
+
+ struct remmina_plugin_rdp_event
+--
+1.7.10
+
diff --git a/main/remmina/remmina-1.0.0-clipboard-bugfix.patch b/main/remmina/remmina-1.0.0-clipboard-bugfix.patch
new file mode 100644
index 0000000000..c564c8e730
--- /dev/null
+++ b/main/remmina/remmina-1.0.0-clipboard-bugfix.patch
@@ -0,0 +1,73 @@
+From 97c2af8ccc913b0850ed4a54ed6c477cfbd7b475 Mon Sep 17 00:00:00 2001
+From: Jean-Louis Dupond <jean-louis@dupond.be>
+Date: Tue, 1 May 2012 17:37:21 +0200
+Subject: [PATCH] clipboard bugfix + cleanup of memory
+
+---
+ remmina-plugins/rdp/rdp_cliprdr.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/remmina-plugins/rdp/rdp_cliprdr.c b/remmina-plugins/rdp/rdp_cliprdr.c
+index 0821ffa..b9b37ad 100644
+--- a/remmina-plugins/rdp/rdp_cliprdr.c
++++ b/remmina-plugins/rdp/rdp_cliprdr.c
+@@ -225,7 +225,7 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+
+ if (format == CB_FORMAT_TEXT || format == CB_FORMAT_HTML || format == CB_FORMAT_UNICODETEXT)
+ {
+- lf2crlf(inbuf, size);
++ inbuf = lf2crlf(inbuf, size);
+ if (format == CB_FORMAT_TEXT)
+ {
+ outbuf = inbuf;
+@@ -269,6 +269,11 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+ memcpy(outbuf, data + 14, *size);
+ }
+ }
++
++ if (inbuf)
++ g_free(inbuf);
++ if (G_IS_OBJECT(image))
++ g_object_unref(image);
+
+ if (!outbuf)
+ outbuf = (uint8*)"";
+@@ -288,7 +293,7 @@ void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVE
+ gboolean img = FALSE;
+ rfContext* rfi = GET_DATA(gp);
+ RDP_CB_DATA_RESPONSE_EVENT* data_response_event;
+-
++ GdkPixbufLoader *pixbuf;
+ data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*) event;
+ data = data_response_event->data;
+ size = data_response_event->size;
+@@ -341,7 +346,6 @@ void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVE
+ stream_detach(s);
+ stream_free(s);
+ }
+- GdkPixbufLoader *pixbuf;
+ pixbuf = gdk_pixbuf_loader_new();
+ gdk_pixbuf_loader_write(pixbuf, data, size, NULL);
+ image = gdk_pixbuf_loader_get_pixbuf(pixbuf);
+@@ -355,9 +359,17 @@ void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVE
+ if (text || img)
+ rfi->clipboard_wait = TRUE;
+ if (text)
+- gtk_clipboard_set_text(clipboard, (gchar*)data, size);
++ {
++ gtk_clipboard_set_text(clipboard, (gchar*)data, size);
++ gtk_clipboard_store(clipboard);
++ }
+ if (img)
++ {
+ gtk_clipboard_set_image(clipboard, image);
++ gtk_clipboard_store(clipboard);
++ gdk_pixbuf_loader_close(pixbuf, NULL);
++ g_object_unref(pixbuf);
++ }
+ }
+ THREADS_LEAVE
+
+--
+1.7.10
+
diff --git a/main/remmina/remmina-1.0.0-disconnect-signal-handler-after-disconnect.patch b/main/remmina/remmina-1.0.0-disconnect-signal-handler-after-disconnect.patch
new file mode 100644
index 0000000000..dc4ae33310
--- /dev/null
+++ b/main/remmina/remmina-1.0.0-disconnect-signal-handler-after-disconnect.patch
@@ -0,0 +1,53 @@
+From c1ef3a162622942d7c556c5a4352e626c7bcb28f Mon Sep 17 00:00:00 2001
+From: Jean-Louis Dupond <jean-louis@dupond.be>
+Date: Tue, 8 May 2012 14:44:16 +0200
+Subject: [PATCH] Disconnect signal handler after disconnect
+
+---
+ remmina-plugins/rdp/rdp_event.c | 10 ++++++++--
+ remmina-plugins/rdp/rdp_plugin.h | 1 +
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/remmina-plugins/rdp/rdp_event.c b/remmina-plugins/rdp/rdp_event.c
+index a936fb1..2c050c6 100644
+--- a/remmina-plugins/rdp/rdp_event.c
++++ b/remmina-plugins/rdp/rdp_event.c
+@@ -523,8 +523,7 @@ void remmina_rdp_event_init(RemminaProtocolWidget* gp)
+ if (!remmina_plugin_service->file_get_int(remminafile, "disableclipboard", FALSE))
+ {
+ clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD);
+- g_signal_connect(clipboard, "owner-change",
+- G_CALLBACK(remmina_rdp_event_on_clipboard), gp);
++ rfi->clipboard_handler = g_signal_connect(clipboard, "owner-change", G_CALLBACK(remmina_rdp_event_on_clipboard), gp);
+ }
+
+ rfi->pressed_keys = g_array_new(FALSE, TRUE, sizeof (gint));
+@@ -575,6 +574,13 @@ void remmina_rdp_event_uninit(RemminaProtocolWidget* gp)
+
+ rfi = GET_DATA(gp);
+
++
++ /* unregister the clipboard monitor */
++ if (rfi->clipboard_handler)
++ {
++ g_signal_handler_disconnect(G_OBJECT(gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD)), rfi->clipboard_handler);
++ rfi->clipboard_handler = NULL;
++ }
+ if (rfi->scale_handler)
+ {
+ g_source_remove(rfi->scale_handler);
+diff --git a/remmina-plugins/rdp/rdp_plugin.h b/remmina-plugins/rdp/rdp_plugin.h
+index ff66906..08b8891 100644
+--- a/remmina-plugins/rdp/rdp_plugin.h
++++ b/remmina-plugins/rdp/rdp_plugin.h
+@@ -134,6 +134,7 @@ struct rf_context
+ GAsyncQueue* event_queue;
+ gint event_pipe[2];
+
++ gint clipboard_handler;
+ gint clipboard_wait;
+ uint32 requested_format;
+ };
+--
+1.7.10
+
diff --git a/main/remmina/remmina-1.0.0-fix-memory-leak.patch b/main/remmina/remmina-1.0.0-fix-memory-leak.patch
new file mode 100644
index 0000000000..a0aac1a88f
--- /dev/null
+++ b/main/remmina/remmina-1.0.0-fix-memory-leak.patch
@@ -0,0 +1,24 @@
+From b22778270ad05fed21797d5a5d4b782d6e273a59 Mon Sep 17 00:00:00 2001
+From: Jean-Louis Dupond <jean-louis@dupond.be>
+Date: Sat, 5 May 2012 17:15:29 +0200
+Subject: [PATCH] Fix memory leak
+
+---
+ remmina-plugins/rdp/rdp_cliprdr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/remmina-plugins/rdp/rdp_cliprdr.c b/remmina-plugins/rdp/rdp_cliprdr.c
+index 772709c..ea8baa0 100644
+--- a/remmina-plugins/rdp/rdp_cliprdr.c
++++ b/remmina-plugins/rdp/rdp_cliprdr.c
+@@ -74,6 +74,7 @@ void remmina_rdp_cliprdr_get_target_types(uint32** dst_formats, uint16* size, Gd
+ image = TRUE;
+ matches++;
+ }
++ g_free(name);
+ }
+ //Only add text formats if we don't have image formats
+ if (!image)
+--
+1.7.10
+
diff --git a/main/remmina/remmina-1.0.0-some-more-clipboard-fixes.patch b/main/remmina/remmina-1.0.0-some-more-clipboard-fixes.patch
new file mode 100644
index 0000000000..ad31d512b5
--- /dev/null
+++ b/main/remmina/remmina-1.0.0-some-more-clipboard-fixes.patch
@@ -0,0 +1,180 @@
+From 84327f81995b4efe56503b94216e35eb9e99f243 Mon Sep 17 00:00:00 2001
+From: Jean-Louis Dupond <jean-louis@dupond.be>
+Date: Thu, 3 May 2012 15:25:02 +0200
+Subject: [PATCH] Some more clipboard fixes
+
+---
+ remmina-plugins/rdp/rdp_cliprdr.c | 68 ++++++++++++++++++++++---------------
+ remmina-plugins/rdp/rdp_plugin.c | 9 +++--
+ remmina-plugins/rdp/rdp_plugin.h | 2 +-
+ 3 files changed, 48 insertions(+), 31 deletions(-)
+
+diff --git a/remmina-plugins/rdp/rdp_cliprdr.c b/remmina-plugins/rdp/rdp_cliprdr.c
+index b9b37ad..1424ac9 100644
+--- a/remmina-plugins/rdp/rdp_cliprdr.c
++++ b/remmina-plugins/rdp/rdp_cliprdr.c
+@@ -204,7 +204,7 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+ g_printf("GetData: Requested Format: %#X\n", format);
+ rfContext* rfi = GET_DATA(gp);
+ GtkClipboard* clipboard;
+- uint8* inbuf = NULL;
++ uint8* inbuf = (uint8*)"";
+ uint8* outbuf = NULL;
+ GdkPixbuf *image = NULL;
+
+@@ -225,6 +225,8 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+
+ if (format == CB_FORMAT_TEXT || format == CB_FORMAT_HTML || format == CB_FORMAT_UNICODETEXT)
+ {
++ if (inbuf == NULL)
++ inbuf = (uint8*)"";
+ inbuf = lf2crlf(inbuf, size);
+ if (format == CB_FORMAT_TEXT)
+ {
+@@ -243,6 +245,7 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+ uniconv = freerdp_uniconv_new();
+ outbuf = (uint8*) freerdp_uniconv_out(uniconv, (char*) inbuf, &out_size);
+ freerdp_uniconv_free(uniconv);
++ g_free(inbuf);
+ *size = out_size + 2;
+ }
+ }
+@@ -253,11 +256,13 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+ if (format == CB_FORMAT_PNG)
+ {
+ gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "png", NULL, NULL);
++ outbuf = (uint8*) xmalloc(buffersize);
+ memcpy(outbuf, data, buffersize);
+ }
+ if (format == CB_FORMAT_JPEG)
+ {
+ gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "jpeg", NULL, NULL);
++ outbuf = (uint8*) xmalloc(buffersize);
+ memcpy(outbuf, data, buffersize);
+ }
+ if (format == CB_FORMAT_DIB)
+@@ -268,13 +273,9 @@ uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, in
+ outbuf = (uint8*) xmalloc(*size);
+ memcpy(outbuf, data + 14, *size);
+ }
++ g_object_unref(image);
+ }
+
+- if (inbuf)
+- g_free(inbuf);
+- if (G_IS_OBJECT(image))
+- g_object_unref(image);
+-
+ if (!outbuf)
+ outbuf = (uint8*)"";
+
+@@ -357,7 +358,10 @@ void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVE
+ if (clipboard)
+ {
+ if (text || img)
+- rfi->clipboard_wait = TRUE;
++ {
++ rfi->clipboard_wait = 2;
++ g_printf("Setting Clipboard Wait\n");
++ }
+ if (text)
+ {
+ gtk_clipboard_set_text(clipboard, (gchar*)data, size);
+@@ -404,31 +408,39 @@ void remmina_handle_channel_event(RemminaProtocolWidget* gp, RDP_EVENT* event)
+ for (i = 0; i < format_list_event->num_formats; i++)
+ {
+ g_printf("Format: 0x%X\n", format_list_event->formats[i]);
+- if (format_list_event->formats[i] == CB_FORMAT_UNICODETEXT)
+- {
+- format = CB_FORMAT_UNICODETEXT;
+- break;
+- }
+- if (format_list_event->formats[i] == CB_FORMAT_DIB)
+- {
+- format = CB_FORMAT_DIB;
+- break;
+- }
+- if (format_list_event->formats[i] == CB_FORMAT_JPEG)
++ }
++
++ for (i = 0; i < format_list_event->num_formats; i++)
++ {
++ g_printf("Format: 0x%X\n", format_list_event->formats[i]);
++ if (format_list_event->formats[i] > format)
+ {
+- format = CB_FORMAT_JPEG;
+- break;
++ g_printf("Format 0x%X is bigger!\n", format_list_event->formats[i]);
++ if (format_list_event->formats[i] == CB_FORMAT_UNICODETEXT)
++ {
++ format = CB_FORMAT_UNICODETEXT;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_DIB)
++ {
++ format = CB_FORMAT_DIB;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_JPEG)
++ {
++ format = CB_FORMAT_JPEG;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_PNG)
++ {
++ format = CB_FORMAT_PNG;
++ }
++ if (format_list_event->formats[i] == CB_FORMAT_TEXT)
++ {
++ format = CB_FORMAT_TEXT;
++ }
+ }
+- if (format_list_event->formats[i] == CB_FORMAT_PNG)
++ else
+ {
+- format = CB_FORMAT_PNG;
+- break;
++ g_printf("Format 0x%X is smaller!\n", format_list_event->formats[i]);
+ }
+- if (format_list_event->formats[i] == CB_FORMAT_TEXT)
+- {
+- format = CB_FORMAT_TEXT;
+- break;
+- }
+ }
+ rfi->requested_format = format;
+
+diff --git a/remmina-plugins/rdp/rdp_plugin.c b/remmina-plugins/rdp/rdp_plugin.c
+index fd0fe08..3c7fc0a 100644
+--- a/remmina-plugins/rdp/rdp_plugin.c
++++ b/remmina-plugins/rdp/rdp_plugin.c
+@@ -131,9 +131,14 @@ boolean rf_check_fds(RemminaProtocolWidget* gp)
+ event->mouse_event.x, event->mouse_event.y);
+ break;
+ case REMMINA_RDP_EVENT_TYPE_CLIPBOARD:
+- if (!rfi->clipboard_wait)
++ if (rfi->clipboard_wait <= 0)
++ {
+ remmina_rdp_cliprdr_send_format_list_event(gp);
+- rfi->clipboard_wait = FALSE;
++ g_printf("Clipboard Wait ON\n");
++ rfi->clipboard_wait = 0;
++ }
++ g_printf("Setting Clipboard Wait To FALSE\n");
++ rfi->clipboard_wait--;
+ break;
+ }
+
+diff --git a/remmina-plugins/rdp/rdp_plugin.h b/remmina-plugins/rdp/rdp_plugin.h
+index 1931384..ff66906 100644
+--- a/remmina-plugins/rdp/rdp_plugin.h
++++ b/remmina-plugins/rdp/rdp_plugin.h
+@@ -134,7 +134,7 @@ struct rf_context
+ GAsyncQueue* event_queue;
+ gint event_pipe[2];
+
+- gboolean clipboard_wait;
++ gint clipboard_wait;
+ uint32 requested_format;
+ };
+
+--
+1.7.10
+