Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 316453 Details for
Bug 423841
net-misc/remmina-1.0.0_p20120309: rdp clipboard patch
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
clipboard rdr patch
fix-cliprdr.patch (text/plain), 17.54 KB, created by
Marcus van Dam
on 2012-06-27 15:02:30 UTC
(
hide
)
Description:
clipboard rdr patch
Filename:
MIME Type:
Creator:
Marcus van Dam
Created:
2012-06-27 15:02:30 UTC
Size:
17.54 KB
patch
obsolete
>--- /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 <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 >@@ -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); >@@ -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 <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) * (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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 423841
: 316453 |
322196
|
322198