36 |
static int have_primary = 0; |
static int have_primary = 0; |
37 |
static int rdesktop_is_selection_owner = 0; |
static int rdesktop_is_selection_owner = 0; |
38 |
|
|
39 |
|
static int g_waiting_for_INCR = 0; |
40 |
|
static uint8 *g_clip_buffer = 0; |
41 |
|
static uint32 g_clip_buflen = 0; |
42 |
|
|
43 |
/* Replace CR-LF to LF (well, rather removing all CR:s) This is done |
/* Replace CR-LF to LF (well, rather removing all CR:s) This is done |
44 |
in-place. The length is updated. Handles embedded nulls */ |
in-place. The length is updated. Handles embedded nulls */ |
108 |
xclip_handle_SelectionNotify(XSelectionEvent * event) |
xclip_handle_SelectionNotify(XSelectionEvent * event) |
109 |
{ |
{ |
110 |
unsigned long nitems, bytes_left; |
unsigned long nitems, bytes_left; |
111 |
|
XWindowAttributes wa; |
112 |
Atom type, best_target, text_target; |
Atom type, best_target, text_target; |
113 |
Atom *supported_targets; |
Atom *supported_targets; |
114 |
int res, i, format; |
int res, i, format; |
165 |
|
|
166 |
if (type == incr_atom) |
if (type == incr_atom) |
167 |
{ |
{ |
168 |
warning("We don't support INCR transfers at this time. Try cutting less data.\n"); |
DEBUG_CLIPBOARD(("Received INCR.\n")); |
169 |
goto fail; |
|
170 |
|
XGetWindowAttributes(g_display, g_wnd, &wa); |
171 |
|
if ((wa.your_event_mask | PropertyChangeMask) != wa.your_event_mask) |
172 |
|
{ |
173 |
|
XSelectInput(g_display, g_wnd, (wa.your_event_mask | PropertyChangeMask)); |
174 |
|
} |
175 |
|
XDeleteProperty(g_display, g_wnd, type); |
176 |
|
XFree(data); |
177 |
|
g_waiting_for_INCR = 1; |
178 |
|
|
179 |
|
if ((XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom, 0, |
180 |
|
4096L, True, AnyPropertyType, |
181 |
|
&type, &format, &nitems, &bytes_left, &data) != Success)) |
182 |
|
{ |
183 |
|
DEBUG_CLIPBOARD(("XGetWindowProperty failed.\n")); |
184 |
|
goto fail; |
185 |
|
} |
186 |
|
else |
187 |
|
{ |
188 |
|
uint8 *translated_data; |
189 |
|
uint32 length = nitems; |
190 |
|
|
191 |
|
translated_data = lf2crlf(data, &length); |
192 |
|
|
193 |
|
g_clip_buffer = (uint8 *) xmalloc(length); |
194 |
|
strncpy((char *) g_clip_buffer, (char *) translated_data, length); |
195 |
|
xfree(translated_data); |
196 |
|
g_clip_buflen = length; |
197 |
|
|
198 |
|
XFree(data); |
199 |
|
return; |
200 |
|
} |
201 |
} |
} |
202 |
|
|
203 |
/* Translate linebreaks, but only if not getting data from |
/* Translate linebreaks, but only if not getting data from |
283 |
{ |
{ |
284 |
unsigned long nitems, bytes_left; |
unsigned long nitems, bytes_left; |
285 |
int format, res; |
int format, res; |
286 |
|
XWindowAttributes wa; |
287 |
uint8 *data; |
uint8 *data; |
288 |
Atom type; |
Atom type; |
289 |
|
|
290 |
|
if (event->state == PropertyNewValue && g_waiting_for_INCR) |
291 |
|
{ |
292 |
|
DEBUG_CLIPBOARD(("x_clip_handle_PropertyNotify: g_waiting_for_INCR != 0\n")); |
293 |
|
if ((XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom, 0, |
294 |
|
4096L, True, AnyPropertyType, |
295 |
|
&type, &format, &nitems, &bytes_left, &data) != Success)) |
296 |
|
{ |
297 |
|
XFree(data); |
298 |
|
return; |
299 |
|
} |
300 |
|
|
301 |
|
if (nitems == 0) |
302 |
|
{ |
303 |
|
XGetWindowAttributes(g_display, g_wnd, &wa); |
304 |
|
XSelectInput(g_display, g_wnd, (wa.your_event_mask ^ PropertyChangeMask)); |
305 |
|
XFree(data); |
306 |
|
g_waiting_for_INCR = 0; |
307 |
|
|
308 |
|
if (g_clip_buflen > 0) |
309 |
|
{ |
310 |
|
cliprdr_send_data(g_clip_buffer, g_clip_buflen + 1); |
311 |
|
|
312 |
|
if (!rdesktop_is_selection_owner) |
313 |
|
cliprdr_send_text_format_announce(); |
314 |
|
|
315 |
|
xfree(g_clip_buffer); |
316 |
|
g_clip_buffer = 0; |
317 |
|
g_clip_buflen = 0; |
318 |
|
} |
319 |
|
} |
320 |
|
else |
321 |
|
{ |
322 |
|
uint8 *translated_data; |
323 |
|
uint32 length = nitems; |
324 |
|
uint8 *tmp; |
325 |
|
|
326 |
|
DEBUG_CLIPBOARD(("Translating linebreaks before sending data\n")); |
327 |
|
translated_data = lf2crlf(data, &length); |
328 |
|
|
329 |
|
tmp = xmalloc(length + g_clip_buflen); |
330 |
|
strncpy((char *) tmp, (char *) g_clip_buffer, g_clip_buflen); |
331 |
|
xfree(g_clip_buffer); |
332 |
|
|
333 |
|
strncpy((char *) (tmp + g_clip_buflen), (char *) translated_data, length); |
334 |
|
xfree(translated_data); |
335 |
|
|
336 |
|
g_clip_buffer = tmp; |
337 |
|
g_clip_buflen += length; |
338 |
|
|
339 |
|
XFree(data); |
340 |
|
return; |
341 |
|
} |
342 |
|
} |
343 |
|
|
344 |
if (event->atom != rdesktop_clipboard_formats_atom) |
if (event->atom != rdesktop_clipboard_formats_atom) |
345 |
return; |
return; |
346 |
|
|
400 |
crlf2lf(data, &length); |
crlf2lf(data, &length); |
401 |
|
|
402 |
/* Only send data up to null byte, if any */ |
/* Only send data up to null byte, if any */ |
403 |
firstnull = (uint8 *)strchr((char*)data, '\0'); |
firstnull = (uint8 *) strchr((char *) data, '\0'); |
404 |
if (firstnull) |
if (firstnull) |
405 |
{ |
{ |
406 |
length = firstnull - data + 1; |
length = firstnull - data + 1; |
470 |
incr_atom = XInternAtom(g_display, "INCR", False); |
incr_atom = XInternAtom(g_display, "INCR", False); |
471 |
targets[0] = targets_atom; |
targets[0] = targets_atom; |
472 |
targets[1] = XInternAtom(g_display, "TEXT", False); |
targets[1] = XInternAtom(g_display, "TEXT", False); |
473 |
targets[2] = XInternAtom(g_display, "UTF8_STRING", False); |
targets[2] = XInternAtom(g_display, "STRING", False); |
474 |
targets[3] = XInternAtom(g_display, "text/unicode", False); |
targets[3] = XInternAtom(g_display, "text/unicode", False); |
475 |
targets[4] = XInternAtom(g_display, "TIMESTAMP", False); |
targets[4] = XInternAtom(g_display, "TIMESTAMP", False); |
476 |
targets[5] = XA_STRING; |
targets[5] = XA_STRING; |