Line
Link Here
|
0 |
-- /dev/null |
0 |
++ remmina-1.0.0/remmina-plugins/rdp/rdp_cliprdr.h |
Line 0
Link Here
|
0 |
-- remmina-1.0.0.orig/remmina-plugins/rdp/CMakeLists.txt |
1 |
/* |
|
|
2 |
* Remmina - The GTK+ Remote Desktop Client |
3 |
* Copyright (C) 2010-2011 Vic Lee |
4 |
* Copyright (C) 2012-2012 Jean-Louis Dupond |
5 |
* |
6 |
* This program is free software; you can redistribute it and/or modify |
7 |
* it under the terms of the GNU General Public License as published by |
8 |
* the Free Software Foundation; either version 2 of the License, or |
9 |
* (at your option) any later version. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 59 Temple Place, Suite 330, |
19 |
* Boston, MA 02111-1307, USA. |
20 |
*/ |
21 |
|
22 |
#ifndef __REMMINA_RDP_CLIPRDR_H__ |
23 |
#define __REMMINA_RDP_CLIPRDR_H__ |
24 |
|
25 |
G_BEGIN_DECLS |
26 |
|
27 |
RDP_EVENT* remmina_rdp_cliprdr_get_event(uint16 event_type); |
28 |
int remmina_rdp_cliprdr_send_format_list_event(RemminaProtocolWidget* gp); |
29 |
void remmina_handle_channel_event(RemminaProtocolWidget* gp, RDP_EVENT* event); |
30 |
|
31 |
G_END_DECLS |
32 |
|
33 |
#endif |
|
|
34 |
++ remmina-1.0.0/remmina-plugins/rdp/CMakeLists.txt |
Lines 33-38
set(REMMINA_PLUGIN_RDP_SRCS
Link Here
|
33 |
rdp_gdi.h |
33 |
rdp_gdi.h |
34 |
rdp_graphics.c |
34 |
rdp_graphics.c |
35 |
rdp_graphics.h |
35 |
rdp_graphics.h |
|
|
36 |
rdp_cliprdr.c |
37 |
rdp_cliprdr.h |
36 |
) |
38 |
) |
37 |
|
39 |
|
38 |
add_library(remmina-plugin-rdp ${REMMINA_PLUGIN_RDP_SRCS}) |
40 |
add_library(remmina-plugin-rdp ${REMMINA_PLUGIN_RDP_SRCS}) |
39 |
-- remmina-1.0.0.orig/remmina-plugins/rdp/rdp_event.c |
41 |
++ remmina-1.0.0/remmina-plugins/rdp/rdp_event.c |
Lines 461-466
static gboolean remmina_rdp_event_on_key
Link Here
|
461 |
return TRUE; |
461 |
return TRUE; |
462 |
} |
462 |
} |
463 |
|
463 |
|
|
|
464 |
static gboolean remmina_rdp_event_on_clipboard(GtkClipboard *clipboard, GdkEvent *event, RemminaProtocolWidget *gp) |
465 |
{ |
466 |
RemminaPluginRdpEvent rdp_event = { 0 }; |
467 |
|
468 |
rdp_event.type = REMMINA_RDP_EVENT_TYPE_CLIPBOARD; |
469 |
remmina_rdp_event_event_push(gp, &rdp_event); |
470 |
|
471 |
return TRUE; |
472 |
} |
473 |
|
464 |
void remmina_rdp_event_init(RemminaProtocolWidget* gp) |
474 |
void remmina_rdp_event_init(RemminaProtocolWidget* gp) |
465 |
{ |
475 |
{ |
466 |
gint n; |
476 |
gint n; |
Lines 470-475
void remmina_rdp_event_init(RemminaProto
Link Here
|
470 |
XPixmapFormatValues* pf; |
480 |
XPixmapFormatValues* pf; |
471 |
XPixmapFormatValues* pfs; |
481 |
XPixmapFormatValues* pfs; |
472 |
rfContext* rfi; |
482 |
rfContext* rfi; |
|
|
483 |
GtkClipboard* clipboard; |
473 |
|
484 |
|
474 |
rfi = GET_DATA(gp); |
485 |
rfi = GET_DATA(gp); |
475 |
rfi->drawing_area = gtk_drawing_area_new(); |
486 |
rfi->drawing_area = gtk_drawing_area_new(); |
Lines 508-513
void remmina_rdp_event_init(RemminaProto
Link Here
|
508 |
g_signal_connect(G_OBJECT(rfi->drawing_area), "key-release-event", |
519 |
g_signal_connect(G_OBJECT(rfi->drawing_area), "key-release-event", |
509 |
G_CALLBACK(remmina_rdp_event_on_key), gp); |
520 |
G_CALLBACK(remmina_rdp_event_on_key), gp); |
510 |
|
521 |
|
|
|
522 |
RemminaFile* remminafile = remmina_plugin_service->protocol_plugin_get_file(gp); |
523 |
if (!remmina_plugin_service->file_get_int(remminafile, "disableclipboard", FALSE)) |
524 |
{ |
525 |
clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD); |
526 |
rfi->clipboard_handler = g_signal_connect(clipboard, "owner-change", G_CALLBACK(remmina_rdp_event_on_clipboard), gp); |
527 |
} |
528 |
|
511 |
rfi->pressed_keys = g_array_new(FALSE, TRUE, sizeof (gint)); |
529 |
rfi->pressed_keys = g_array_new(FALSE, TRUE, sizeof (gint)); |
512 |
rfi->event_queue = g_async_queue_new_full(g_free); |
530 |
rfi->event_queue = g_async_queue_new_full(g_free); |
513 |
rfi->ui_queue = g_async_queue_new(); |
531 |
rfi->ui_queue = g_async_queue_new(); |
Lines 556-561
void remmina_rdp_event_uninit(RemminaPro
Link Here
|
556 |
|
574 |
|
557 |
rfi = GET_DATA(gp); |
575 |
rfi = GET_DATA(gp); |
558 |
|
576 |
|
|
|
577 |
|
578 |
/* unregister the clipboard monitor */ |
579 |
if (rfi->clipboard_handler) |
580 |
{ |
581 |
g_signal_handler_disconnect(G_OBJECT(gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD)), rfi->clipboard_handler); |
582 |
rfi->clipboard_handler = NULL; |
583 |
} |
559 |
if (rfi->scale_handler) |
584 |
if (rfi->scale_handler) |
560 |
{ |
585 |
{ |
561 |
g_source_remove(rfi->scale_handler); |
586 |
g_source_remove(rfi->scale_handler); |
562 |
-- remmina-1.0.0.orig/remmina-plugins/rdp/rdp_plugin.c |
587 |
++ remmina-1.0.0/remmina-plugins/rdp/rdp_plugin.c |
Lines 24-29
Link Here
|
24 |
#include "rdp_graphics.h" |
24 |
#include "rdp_graphics.h" |
25 |
#include "rdp_file.h" |
25 |
#include "rdp_file.h" |
26 |
#include "rdp_settings.h" |
26 |
#include "rdp_settings.h" |
|
|
27 |
#include "rdp_cliprdr.h" |
27 |
|
28 |
|
28 |
#include <errno.h> |
29 |
#include <errno.h> |
29 |
#include <pthread.h> |
30 |
#include <pthread.h> |
Lines 31-36
Link Here
|
31 |
#include <freerdp/freerdp.h> |
32 |
#include <freerdp/freerdp.h> |
32 |
#include <freerdp/constants.h> |
33 |
#include <freerdp/constants.h> |
33 |
#include <freerdp/utils/memory.h> |
34 |
#include <freerdp/utils/memory.h> |
|
|
35 |
#include <freerdp/plugins/cliprdr.h> |
34 |
|
36 |
|
35 |
#define REMMINA_RDP_FEATURE_TOOL_REFRESH 1 |
37 |
#define REMMINA_RDP_FEATURE_TOOL_REFRESH 1 |
36 |
#define REMMINA_RDP_FEATURE_SCALE 2 |
38 |
#define REMMINA_RDP_FEATURE_SCALE 2 |
Lines 155-160
boolean rf_check_fds(RemminaProtocolWidg
Link Here
|
155 |
input->MouseEvent(input, event->mouse_event.flags, |
157 |
input->MouseEvent(input, event->mouse_event.flags, |
156 |
event->mouse_event.x, event->mouse_event.y); |
158 |
event->mouse_event.x, event->mouse_event.y); |
157 |
break; |
159 |
break; |
|
|
160 |
case REMMINA_RDP_EVENT_TYPE_CLIPBOARD: |
161 |
if (rfi->clipboard_wait <= 0) |
162 |
{ |
163 |
remmina_rdp_cliprdr_send_format_list_event(gp); |
164 |
rfi->clipboard_wait = 0; |
165 |
} |
166 |
rfi->clipboard_wait--; |
167 |
break; |
158 |
} |
168 |
} |
159 |
|
169 |
|
160 |
g_free(event); |
170 |
g_free(event); |
Lines 545-550
static void remmina_rdp_main_loop(Remmin
Link Here
|
545 |
fd_set rfds_set; |
556 |
fd_set rfds_set; |
546 |
fd_set wfds_set; |
557 |
fd_set wfds_set; |
547 |
rfContext* rfi; |
558 |
rfContext* rfi; |
|
|
559 |
RDP_EVENT* event; |
548 |
|
560 |
|
549 |
memset(rfds, 0, sizeof(rfds)); |
561 |
memset(rfds, 0, sizeof(rfds)); |
550 |
memset(wfds, 0, sizeof(wfds)); |
562 |
memset(wfds, 0, sizeof(wfds)); |
Lines 618-623
static void remmina_rdp_main_loop(Remmin
Link Here
|
618 |
{ |
630 |
{ |
619 |
break; |
631 |
break; |
620 |
} |
632 |
} |
|
|
633 |
else |
634 |
{ |
635 |
event = freerdp_channels_pop_event(rfi->channels); |
636 |
if (event) |
637 |
remmina_handle_channel_event(gp, event); |
638 |
} |
621 |
/* check ui */ |
639 |
/* check ui */ |
622 |
if (!rf_check_fds(gp)) |
640 |
if (!rf_check_fds(gp)) |
623 |
{ |
641 |
{ |
624 |
-- /dev/null |
642 |
++ remmina-1.0.0/remmina-plugins/rdp/rdp_cliprdr.c |
Line 0
Link Here
|
0 |
-- remmina-1.0.0.orig/remmina-plugins/rdp/rdp_plugin.h |
1 |
/* |
|
|
2 |
* Remmina - The GTK+ Remote Desktop Client |
3 |
* Copyright (C) 2012-2012 Jean-Louis Dupond |
4 |
* |
5 |
* This program is free software; you can redistribute it and/or modify |
6 |
* it under the terms of the GNU General Public License as published by |
7 |
* the Free Software Foundation; either version 2 of the License, or |
8 |
* (at your option) any later version. |
9 |
* |
10 |
* This program is distributed in the hope that it will be useful, |
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
* GNU General Public License for more details. |
14 |
* |
15 |
* You should have received a copy of the GNU General Public License |
16 |
* along with this program; if not, write to the Free Software |
17 |
* Foundation, Inc., 59 Temple Place, Suite 330, |
18 |
* Boston, MA 02111-1307, USA. |
19 |
*/ |
20 |
|
21 |
#include "rdp_plugin.h" |
22 |
#include "rdp_cliprdr.h" |
23 |
|
24 |
#include <freerdp/freerdp.h> |
25 |
#include <freerdp/utils/memory.h> |
26 |
#include <freerdp/channels/channels.h> |
27 |
#include <freerdp/plugins/cliprdr.h> |
28 |
|
29 |
/* |
30 |
* Get the formats we can export based on the current clipboard data. |
31 |
*/ |
32 |
void remmina_rdp_cliprdr_get_target_types(uint32** dst_formats, uint16* size, GdkAtom* types, int count) |
33 |
{ |
34 |
int i; |
35 |
gboolean image = FALSE; |
36 |
gboolean text = FALSE; |
37 |
gboolean textutf8 = FALSE; |
38 |
int matches = 1; |
39 |
uint32* formats = (uint32*) xmalloc(sizeof(uint32) * (count+1)); |
40 |
|
41 |
formats[0] = CB_FORMAT_RAW; |
42 |
for (i = 0; i < count; i++) |
43 |
{ |
44 |
GdkAtom atom = GDK_POINTER_TO_ATOM(types[i]); |
45 |
gchar* name = gdk_atom_name(atom); |
46 |
if (g_strcmp0("UTF8_STRING", name) == 0 || g_strcmp0("text/plain;charset=utf-8", name) == 0) |
47 |
{ |
48 |
textutf8 = TRUE; |
49 |
} |
50 |
if (g_strcmp0("TEXT", name) == 0 || g_strcmp0("text/plain", name) == 0) |
51 |
{ |
52 |
text = TRUE; |
53 |
} |
54 |
if (g_strcmp0("text/html", name) == 0) |
55 |
{ |
56 |
formats[matches] = CB_FORMAT_HTML; |
57 |
matches++; |
58 |
} |
59 |
if (g_strcmp0("image/png", name) == 0) |
60 |
{ |
61 |
formats[matches] = CB_FORMAT_PNG; |
62 |
image = TRUE; |
63 |
matches++; |
64 |
} |
65 |
if (g_strcmp0("image/jpeg", name) == 0) |
66 |
{ |
67 |
formats[matches] = CB_FORMAT_JPEG; |
68 |
image = TRUE; |
69 |
matches++; |
70 |
} |
71 |
if (g_strcmp0("image/bmp", name) == 0) |
72 |
{ |
73 |
formats[matches] = CB_FORMAT_DIB; |
74 |
image = TRUE; |
75 |
matches++; |
76 |
} |
77 |
g_free(name); |
78 |
} |
79 |
//Only add text formats if we don't have image formats |
80 |
if (!image) |
81 |
{ |
82 |
if (textutf8) |
83 |
{ |
84 |
formats[matches] = CB_FORMAT_UNICODETEXT; |
85 |
matches++; |
86 |
} |
87 |
if (text) |
88 |
{ |
89 |
formats[matches] = CB_FORMAT_TEXT; |
90 |
matches++; |
91 |
} |
92 |
} |
93 |
|
94 |
*size = (uint16)matches; |
95 |
*dst_formats = (uint32*) xmalloc(sizeof(uint32) * matches); |
96 |
memcpy(*dst_formats, formats, sizeof(uint32) * matches); |
97 |
g_free(formats); |
98 |
} |
99 |
|
100 |
int remmina_rdp_cliprdr_send_format_list_event(RemminaProtocolWidget* gp) |
101 |
{ |
102 |
GtkClipboard* clipboard; |
103 |
GdkAtom* targets; |
104 |
gboolean result = 0; |
105 |
gint count; |
106 |
RDP_EVENT* rdp_event; |
107 |
RDP_CB_FORMAT_LIST_EVENT* format_list_event; |
108 |
rfContext* rfi = GET_DATA(gp); |
109 |
|
110 |
/* Lets see if we have something in our clipboard */ |
111 |
THREADS_ENTER |
112 |
clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD); |
113 |
if (clipboard) |
114 |
{ |
115 |
result = gtk_clipboard_wait_for_targets(clipboard, &targets, &count); |
116 |
} |
117 |
THREADS_LEAVE |
118 |
|
119 |
if (!result) |
120 |
return 1; |
121 |
|
122 |
rdp_event = (RDP_EVENT*) xnew(RDP_CB_FORMAT_LIST_EVENT); |
123 |
rdp_event->event_class = RDP_EVENT_CLASS_CLIPRDR; |
124 |
rdp_event->event_type = RDP_EVENT_TYPE_CB_FORMAT_LIST; |
125 |
format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) rdp_event; |
126 |
|
127 |
remmina_rdp_cliprdr_get_target_types(&format_list_event->formats, &format_list_event->num_formats, targets, count); |
128 |
g_free(targets); |
129 |
|
130 |
return freerdp_channels_send_event(rfi->channels, (RDP_EVENT*) format_list_event); |
131 |
} |
132 |
|
133 |
static uint8* lf2crlf(uint8* data, int* size) |
134 |
{ |
135 |
uint8 c; |
136 |
uint8* outbuf; |
137 |
uint8* out; |
138 |
uint8* in_end; |
139 |
uint8* in; |
140 |
int out_size; |
141 |
|
142 |
out_size = (*size) * 2 + 1; |
143 |
outbuf = (uint8*) xmalloc(out_size); |
144 |
out = outbuf; |
145 |
in = data; |
146 |
in_end = data + (*size); |
147 |
|
148 |
while (in < in_end) |
149 |
{ |
150 |
c = *in++; |
151 |
if (c == '\n') |
152 |
{ |
153 |
*out++ = '\r'; |
154 |
*out++ = '\n'; |
155 |
} |
156 |
else |
157 |
{ |
158 |
*out++ = c; |
159 |
} |
160 |
} |
161 |
|
162 |
*out++ = 0; |
163 |
*size = out - outbuf; |
164 |
|
165 |
return outbuf; |
166 |
} |
167 |
|
168 |
static void crlf2lf(uint8* data, int* size) |
169 |
{ |
170 |
uint8 c; |
171 |
uint8* out; |
172 |
uint8* in; |
173 |
uint8* in_end; |
174 |
|
175 |
out = data; |
176 |
in = data; |
177 |
in_end = data + (*size); |
178 |
|
179 |
while (in < in_end) |
180 |
{ |
181 |
c = *in++; |
182 |
|
183 |
if (c != '\r') |
184 |
*out++ = c; |
185 |
} |
186 |
|
187 |
*size = out - data; |
188 |
} |
189 |
|
190 |
uint8* remmina_rdp_cliprdr_get_data(RemminaProtocolWidget* gp, uint32 format, int* size) |
191 |
{ |
192 |
rfContext* rfi = GET_DATA(gp); |
193 |
GtkClipboard* clipboard; |
194 |
uint8* inbuf = NULL; |
195 |
uint8* outbuf = NULL; |
196 |
GdkPixbuf *image = NULL; |
197 |
|
198 |
THREADS_ENTER |
199 |
clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD); |
200 |
if (clipboard) |
201 |
{ |
202 |
if (format == CB_FORMAT_TEXT || format == CB_FORMAT_UNICODETEXT || format == CB_FORMAT_HTML) |
203 |
{ |
204 |
inbuf = (uint8*)gtk_clipboard_wait_for_text(clipboard); |
205 |
} |
206 |
if (format == CB_FORMAT_PNG || format == CB_FORMAT_JPEG || format == CB_FORMAT_DIB) |
207 |
{ |
208 |
image = gtk_clipboard_wait_for_image(clipboard); |
209 |
} |
210 |
} |
211 |
THREADS_LEAVE |
212 |
|
213 |
/* No data received, send nothing */ |
214 |
if (inbuf == NULL && image == NULL) |
215 |
{ |
216 |
*size = 0; |
217 |
return NULL; |
218 |
} |
219 |
|
220 |
|
221 |
if (format == CB_FORMAT_TEXT || format == CB_FORMAT_HTML || format == CB_FORMAT_UNICODETEXT) |
222 |
{ |
223 |
*size = strlen((char*)inbuf); |
224 |
inbuf = lf2crlf(inbuf, size); |
225 |
if (format == CB_FORMAT_TEXT) |
226 |
{ |
227 |
outbuf = inbuf; |
228 |
} |
229 |
if (format == CB_FORMAT_HTML) |
230 |
{ |
231 |
//TODO: check if we need special handling for HTML |
232 |
outbuf = inbuf; |
233 |
} |
234 |
if (format == CB_FORMAT_UNICODETEXT) |
235 |
{ |
236 |
size_t out_size; |
237 |
UNICONV* uniconv; |
238 |
|
239 |
uniconv = freerdp_uniconv_new(); |
240 |
outbuf = (uint8*) freerdp_uniconv_out(uniconv, (char*) inbuf, &out_size); |
241 |
freerdp_uniconv_free(uniconv); |
242 |
g_free(inbuf); |
243 |
*size = out_size + 2; |
244 |
} |
245 |
} |
246 |
if (format == CB_FORMAT_PNG || format == CB_FORMAT_JPEG || format == CB_FORMAT_DIB) |
247 |
{ |
248 |
gchar* data; |
249 |
gsize buffersize; |
250 |
if (format == CB_FORMAT_PNG) |
251 |
{ |
252 |
gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "png", NULL, NULL); |
253 |
outbuf = (uint8*) xmalloc(buffersize); |
254 |
memcpy(outbuf, data, buffersize); |
255 |
*size = buffersize; |
256 |
} |
257 |
if (format == CB_FORMAT_JPEG) |
258 |
{ |
259 |
gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "jpeg", NULL, NULL); |
260 |
outbuf = (uint8*) xmalloc(buffersize); |
261 |
memcpy(outbuf, data, buffersize); |
262 |
*size = buffersize; |
263 |
} |
264 |
if (format == CB_FORMAT_DIB) |
265 |
{ |
266 |
gdk_pixbuf_save_to_buffer(image, &data, &buffersize, "bmp", NULL, NULL); |
267 |
*size = buffersize - 14; |
268 |
outbuf = (uint8*) xmalloc(*size); |
269 |
memcpy(outbuf, data + 14, *size); |
270 |
} |
271 |
g_object_unref(image); |
272 |
} |
273 |
|
274 |
return outbuf; |
275 |
} |
276 |
|
277 |
void remmina_rdp_cliprdr_parse_response_event(RemminaProtocolWidget* gp, RDP_EVENT* event) |
278 |
{ |
279 |
GtkClipboard* clipboard; |
280 |
GdkPixbuf *image = NULL; |
281 |
uint8* data; |
282 |
int size; |
283 |
gboolean text = FALSE; |
284 |
gboolean img = FALSE; |
285 |
rfContext* rfi = GET_DATA(gp); |
286 |
RDP_CB_DATA_RESPONSE_EVENT* data_response_event; |
287 |
GdkPixbufLoader *pixbuf; |
288 |
data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*) event; |
289 |
data = data_response_event->data; |
290 |
size = data_response_event->size; |
291 |
|
292 |
if (rfi->requested_format == CB_FORMAT_TEXT || rfi->requested_format == CB_FORMAT_UNICODETEXT || rfi->requested_format == CB_FORMAT_HTML) |
293 |
{ |
294 |
if (rfi->requested_format == CB_FORMAT_UNICODETEXT) |
295 |
{ |
296 |
UNICONV* uniconv; |
297 |
|
298 |
uniconv = freerdp_uniconv_new(); |
299 |
data = (uint8*) freerdp_uniconv_in(uniconv, data, size); |
300 |
size = strlen((char*) data); |
301 |
freerdp_uniconv_free(uniconv); |
302 |
} |
303 |
crlf2lf(data, &size); |
304 |
text = TRUE; |
305 |
} |
306 |
if (rfi->requested_format == CB_FORMAT_DIB || rfi->requested_format == CB_FORMAT_PNG || rfi->requested_format == CB_FORMAT_JPEG) |
307 |
{ |
308 |
/* Reconstruct header */ |
309 |
if (rfi->requested_format == CB_FORMAT_DIB) |
310 |
{ |
311 |
STREAM* s; |
312 |
uint16 bpp; |
313 |
uint32 offset; |
314 |
uint32 ncolors; |
315 |
|
316 |
s = stream_new(0); |
317 |
stream_attach(s, data, size); |
318 |
stream_seek(s, 14); |
319 |
stream_read_uint16(s, bpp); |
320 |
stream_read_uint32(s, ncolors); |
321 |
offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0); |
322 |
stream_detach(s); |
323 |
stream_free(s); |
324 |
|
325 |
s = stream_new(14 + size); |
326 |
stream_write_uint8(s, 'B'); |
327 |
stream_write_uint8(s, 'M'); |
328 |
stream_write_uint32(s, 14 + size); |
329 |
stream_write_uint32(s, 0); |
330 |
stream_write_uint32(s, offset); |
331 |
stream_write(s, data, size); |
332 |
|
333 |
data = stream_get_head(s); |
334 |
size = stream_get_length(s); |
335 |
stream_detach(s); |
336 |
stream_free(s); |
337 |
} |
338 |
pixbuf = gdk_pixbuf_loader_new(); |
339 |
gdk_pixbuf_loader_write(pixbuf, data, size, NULL); |
340 |
image = gdk_pixbuf_loader_get_pixbuf(pixbuf); |
341 |
img = TRUE; |
342 |
} |
343 |
|
344 |
THREADS_ENTER |
345 |
clipboard = gtk_widget_get_clipboard(rfi->drawing_area, GDK_SELECTION_CLIPBOARD); |
346 |
if (clipboard) |
347 |
{ |
348 |
if (text || img) |
349 |
{ |
350 |
rfi->clipboard_wait = 2; |
351 |
} |
352 |
if (text) |
353 |
{ |
354 |
gtk_clipboard_set_text(clipboard, (gchar*)data, size); |
355 |
gtk_clipboard_store(clipboard); |
356 |
} |
357 |
if (img) |
358 |
{ |
359 |
gtk_clipboard_set_image(clipboard, image); |
360 |
gtk_clipboard_store(clipboard); |
361 |
gdk_pixbuf_loader_close(pixbuf, NULL); |
362 |
g_object_unref(pixbuf); |
363 |
} |
364 |
} |
365 |
THREADS_LEAVE |
366 |
|
367 |
} |
368 |
|
369 |
void remmina_handle_channel_event(RemminaProtocolWidget* gp, RDP_EVENT* event) |
370 |
{ |
371 |
RDP_EVENT* rdp_event = NULL; |
372 |
rfContext* rfi = GET_DATA(gp); |
373 |
|
374 |
switch (event->event_class) |
375 |
{ |
376 |
case RDP_EVENT_CLASS_CLIPRDR: |
377 |
if (event->event_type == RDP_EVENT_TYPE_CB_MONITOR_READY) |
378 |
{ |
379 |
/* Sending our format list */ |
380 |
remmina_rdp_cliprdr_send_format_list_event(gp); |
381 |
} |
382 |
if (event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST) |
383 |
{ |
384 |
/* We received a FORMAT_LIST from the server, update our clipboard */ |
385 |
int i; |
386 |
uint32 format = CB_FORMAT_RAW; |
387 |
RDP_CB_FORMAT_LIST_EVENT* format_list_event; |
388 |
|
389 |
format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; |
390 |
|
391 |
for (i = 0; i < format_list_event->num_formats; i++) |
392 |
{ |
393 |
if (format_list_event->formats[i] > format) |
394 |
{ |
395 |
if (format_list_event->formats[i] == CB_FORMAT_UNICODETEXT) |
396 |
{ |
397 |
format = CB_FORMAT_UNICODETEXT; |
398 |
} |
399 |
if (format_list_event->formats[i] == CB_FORMAT_DIB) |
400 |
{ |
401 |
format = CB_FORMAT_DIB; |
402 |
} |
403 |
if (format_list_event->formats[i] == CB_FORMAT_JPEG) |
404 |
{ |
405 |
format = CB_FORMAT_JPEG; |
406 |
} |
407 |
if (format_list_event->formats[i] == CB_FORMAT_PNG) |
408 |
{ |
409 |
format = CB_FORMAT_PNG; |
410 |
} |
411 |
if (format_list_event->formats[i] == CB_FORMAT_TEXT) |
412 |
{ |
413 |
format = CB_FORMAT_TEXT; |
414 |
} |
415 |
} |
416 |
} |
417 |
rfi->requested_format = format; |
418 |
|
419 |
/* Request Clipboard data of the server */ |
420 |
RDP_CB_DATA_REQUEST_EVENT* data_request_event; |
421 |
rdp_event = (RDP_EVENT*) xnew(RDP_CB_DATA_REQUEST_EVENT); |
422 |
rdp_event->event_class = RDP_EVENT_CLASS_CLIPRDR; |
423 |
rdp_event->event_type = RDP_EVENT_TYPE_CB_DATA_REQUEST; |
424 |
data_request_event = (RDP_CB_DATA_REQUEST_EVENT*) rdp_event; |
425 |
data_request_event->format = format; |
426 |
freerdp_channels_send_event(rfi->channels, (RDP_EVENT*) data_request_event); |
427 |
} |
428 |
if (event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST) |
429 |
{ |
430 |
uint8* data; |
431 |
int size; |
432 |
RDP_CB_DATA_REQUEST_EVENT* data_request_event = (RDP_CB_DATA_REQUEST_EVENT*) event; |
433 |
RDP_CB_DATA_RESPONSE_EVENT* data_response_event; |
434 |
|
435 |
/* Send Data */ |
436 |
rdp_event = (RDP_EVENT*) xnew(RDP_CB_DATA_RESPONSE_EVENT); |
437 |
rdp_event->event_class = RDP_EVENT_CLASS_CLIPRDR; |
438 |
rdp_event->event_type = RDP_EVENT_TYPE_CB_DATA_RESPONSE; |
439 |
data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*) rdp_event; |
440 |
data = remmina_rdp_cliprdr_get_data(gp, data_request_event->format, &size); |
441 |
data_response_event->data = data; |
442 |
data_response_event->size = size; |
443 |
freerdp_channels_send_event(rfi->channels, rdp_event); |
444 |
} |
445 |
if (event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE) |
446 |
{ |
447 |
remmina_rdp_cliprdr_parse_response_event(gp, event); |
448 |
} |
449 |
} |
450 |
} |
|
|
451 |
++ remmina-1.0.0/remmina-plugins/rdp/rdp_plugin.h |
Lines 133-144
struct rf_context
Link Here
|
133 |
GArray* pressed_keys; |
133 |
GArray* pressed_keys; |
134 |
GAsyncQueue* event_queue; |
134 |
GAsyncQueue* event_queue; |
135 |
gint event_pipe[2]; |
135 |
gint event_pipe[2]; |
|
|
136 |
|
137 |
gint clipboard_handler; |
138 |
gint clipboard_wait; |
139 |
uint32 requested_format; |
136 |
}; |
140 |
}; |
137 |
|
141 |
|
138 |
typedef enum |
142 |
typedef enum |
139 |
{ |
143 |
{ |
140 |
REMMINA_RDP_EVENT_TYPE_SCANCODE, |
144 |
REMMINA_RDP_EVENT_TYPE_SCANCODE, |
141 |
REMMINA_RDP_EVENT_TYPE_MOUSE |
145 |
REMMINA_RDP_EVENT_TYPE_MOUSE, |
|
|
146 |
REMMINA_RDP_EVENT_TYPE_CLIPBOARD |
142 |
} RemminaPluginRdpEventType; |
147 |
} RemminaPluginRdpEventType; |
143 |
|
148 |
|
144 |
struct remmina_plugin_rdp_event |
149 |
struct remmina_plugin_rdp_event |