diff -Nru remmina-1.0.0/debian/changelog remmina-1.0.0/debian/changelog --- remmina-1.0.0/debian/changelog 2012-04-25 16:18:09.000000000 +0200 +++ remmina-1.0.0/debian/changelog 2012-05-08 20:50:19.000000000 +0200 @@ -1,3 +1,10 @@ +remmina (1.0.0-1ubuntu7) quantal; urgency=low + + * debian/patches/clipboard.patch: add clipboard support. + (LP: #937522) + + -- Jean-Louis Dupond Tue, 08 May 2012 20:50:11 +0200 + remmina (1.0.0-1ubuntu6) precise-proposed; urgency=low * debian/patches/scroll_smooth.patch: fix scrolling with GDK_SCROLL_SMOOTH diff -Nru remmina-1.0.0/debian/patches/clipboard.patch remmina-1.0.0/debian/patches/clipboard.patch --- remmina-1.0.0/debian/patches/clipboard.patch 1970-01-01 01:00:00.000000000 +0100 +++ remmina-1.0.0/debian/patches/clipboard.patch 2012-05-08 20:53:59.000000000 +0200 @@ -0,0 +1,638 @@ +--- /dev/null ++++ remmina-1.0.0/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 +--- remmina-1.0.0.orig/remmina-plugins/rdp/CMakeLists.txt ++++ remmina-1.0.0/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}) +--- remmina-1.0.0.orig/remmina-plugins/rdp/rdp_event.c ++++ remmina-1.0.0/remmina-plugins/rdp/rdp_event.c +@@ -461,6 +461,16 @@ static gboolean remmina_rdp_event_on_key + 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(RemminaProto + XPixmapFormatValues* pf; + XPixmapFormatValues* pfs; + rfContext* rfi; ++ GtkClipboard* clipboard; + + rfi = GET_DATA(gp); + rfi->drawing_area = gtk_drawing_area_new(); +@@ -508,6 +519,13 @@ void remmina_rdp_event_init(RemminaProto + 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); ++ 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)); + rfi->event_queue = g_async_queue_new_full(g_free); + rfi->ui_queue = g_async_queue_new(); +@@ -556,6 +574,13 @@ void remmina_rdp_event_uninit(RemminaPro + + 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); +--- remmina-1.0.0.orig/remmina-plugins/rdp/rdp_plugin.c ++++ remmina-1.0.0/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 + #include +@@ -31,6 +32,7 @@ + #include + #include + #include ++#include + + #define REMMINA_RDP_FEATURE_TOOL_REFRESH 1 + #define REMMINA_RDP_FEATURE_SCALE 2 +@@ -155,6 +157,14 @@ boolean rf_check_fds(RemminaProtocolWidg + 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 <= 0) ++ { ++ remmina_rdp_cliprdr_send_format_list_event(gp); ++ rfi->clipboard_wait = 0; ++ } ++ rfi->clipboard_wait--; ++ break; + } + + g_free(event); +@@ -530,6 +540,7 @@ static boolean remmina_rdp_verify_certif + + 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); + } + +@@ -545,6 +556,7 @@ static void remmina_rdp_main_loop(Remmin + fd_set rfds_set; + fd_set wfds_set; + rfContext* rfi; ++ RDP_EVENT* event; + + memset(rfds, 0, sizeof(rfds)); + memset(wfds, 0, sizeof(wfds)); +@@ -618,6 +630,12 @@ static void remmina_rdp_main_loop(Remmin + { + break; + } ++ else ++ { ++ event = freerdp_channels_pop_event(rfi->channels); ++ if (event) ++ remmina_handle_channel_event(gp, event); ++ } + /* check ui */ + if (!rf_check_fds(gp)) + { +--- /dev/null ++++ remmina-1.0.0/remmina-plugins/rdp/rdp_cliprdr.c +@@ -0,0 +1,450 @@ ++/* ++ * 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 ++#include ++#include ++#include ++ ++/* ++ * 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) * (count+1)); ++ ++ 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++; ++ } ++ g_free(name); ++ } ++ //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; ++ ++ 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); ++ ++ 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) ++{ ++ 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 ++ ++ /* No data received, send nothing */ ++ if (inbuf == NULL && image == NULL) ++ { ++ *size = 0; ++ return NULL; ++ } ++ ++ ++ if (format == CB_FORMAT_TEXT || format == CB_FORMAT_HTML || format == CB_FORMAT_UNICODETEXT) ++ { ++ *size = strlen((char*)inbuf); ++ inbuf = 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); ++ g_free(inbuf); ++ *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); ++ outbuf = (uint8*) xmalloc(buffersize); ++ memcpy(outbuf, data, buffersize); ++ *size = 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); ++ *size = buffersize; ++ } ++ if (format == CB_FORMAT_DIB) ++ { ++ gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "bmp", NULL, NULL); ++ *size = buffersize - 14; ++ outbuf = (uint8*) xmalloc(*size); ++ memcpy(outbuf, data + 14, *size); ++ } ++ g_object_unref(image); ++ } ++ ++ return outbuf; ++} ++ ++void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVENT* event) ++{ ++ 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; ++ GdkPixbufLoader *pixbuf; ++ data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*) event; ++ data = data_response_event->data; ++ size = data_response_event->size; ++ ++ 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); ++ } ++ 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 = 2; ++ } ++ if (text) ++ { ++ 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 ++ ++} ++ ++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: ++ if (event->event_type == RDP_EVENT_TYPE_CB_MONITOR_READY) ++ { ++ /* 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 */ ++ int i; ++ uint32 format = CB_FORMAT_RAW; ++ RDP_CB_FORMAT_LIST_EVENT* format_list_event; ++ ++ format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; ++ ++ for (i = 0; i < format_list_event->num_formats; i++) ++ { ++ if (format_list_event->formats[i] > format) ++ { ++ 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; ++ } ++ } ++ } ++ rfi->requested_format = 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) ++ { ++ 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; ++ ++ /* 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); ++ } ++ } ++} +--- remmina-1.0.0.orig/remmina-plugins/rdp/rdp_plugin.h ++++ remmina-1.0.0/remmina-plugins/rdp/rdp_plugin.h +@@ -133,12 +133,17 @@ struct rf_context + GArray* pressed_keys; + GAsyncQueue* event_queue; + gint event_pipe[2]; ++ ++ gint clipboard_handler; ++ gint 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 diff -Nru remmina-1.0.0/debian/patches/series remmina-1.0.0/debian/patches/series --- remmina-1.0.0/debian/patches/series 2012-04-25 16:18:09.000000000 +0200 +++ remmina-1.0.0/debian/patches/series 2012-05-08 20:50:08.000000000 +0200 @@ -6,3 +6,4 @@ unity_launcher_list.patch translations.patch scroll_smooth.patch +clipboard.patch