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 */ |
104 |
XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); |
XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); |
105 |
} |
} |
106 |
|
|
107 |
|
#ifndef MAKE_PROTO |
108 |
void |
void |
109 |
xclip_handle_SelectionNotify(XSelectionEvent * event) |
xclip_handle_SelectionNotify(XSelectionEvent * event) |
110 |
{ |
{ |
111 |
unsigned long nitems, bytes_left; |
unsigned long nitems, bytes_left; |
112 |
|
XWindowAttributes wa; |
113 |
Atom type, best_target, text_target; |
Atom type, best_target, text_target; |
114 |
Atom *supported_targets; |
Atom *supported_targets; |
115 |
int res, i, format; |
int res, i, format; |
166 |
|
|
167 |
if (type == incr_atom) |
if (type == incr_atom) |
168 |
{ |
{ |
169 |
warning("We don't support INCR transfers at this time. Try cutting less data.\n"); |
DEBUG_CLIPBOARD(("Received INCR.\n")); |
170 |
goto fail; |
|
171 |
|
XGetWindowAttributes(g_display, g_wnd, &wa); |
172 |
|
if ((wa.your_event_mask | PropertyChangeMask) != wa.your_event_mask) |
173 |
|
{ |
174 |
|
XSelectInput(g_display, g_wnd, (wa.your_event_mask | PropertyChangeMask)); |
175 |
|
} |
176 |
|
XDeleteProperty(g_display, g_wnd, type); |
177 |
|
XFree(data); |
178 |
|
g_waiting_for_INCR = 1; |
179 |
|
|
180 |
|
if ((XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom, 0, |
181 |
|
4096L, True, AnyPropertyType, |
182 |
|
&type, &format, &nitems, &bytes_left, &data) != Success)) |
183 |
|
{ |
184 |
|
DEBUG_CLIPBOARD(("XGetWindowProperty failed.\n")); |
185 |
|
goto fail; |
186 |
|
} |
187 |
|
else |
188 |
|
{ |
189 |
|
uint8 *translated_data; |
190 |
|
uint32 length = nitems; |
191 |
|
|
192 |
|
translated_data = lf2crlf(data, &length); |
193 |
|
|
194 |
|
g_clip_buffer = (uint8 *) xmalloc(length); |
195 |
|
strncpy((char *) g_clip_buffer, (char *) translated_data, length); |
196 |
|
xfree(translated_data); |
197 |
|
g_clip_buflen = length; |
198 |
|
|
199 |
|
XFree(data); |
200 |
|
return; |
201 |
|
} |
202 |
} |
} |
203 |
|
|
204 |
/* Translate linebreaks, but only if not getting data from |
/* Translate linebreaks, but only if not getting data from |
220 |
XFree(data); |
XFree(data); |
221 |
|
|
222 |
if (!rdesktop_is_selection_owner) |
if (!rdesktop_is_selection_owner) |
223 |
cliprdr_send_text_format_announce(); |
cliprdr_send_simple_native_format_announce(CF_TEXT); |
224 |
return; |
return; |
225 |
|
|
226 |
fail: |
fail: |
276 |
DEBUG_CLIPBOARD(("xclip_handle_SelectionClear\n")); |
DEBUG_CLIPBOARD(("xclip_handle_SelectionClear\n")); |
277 |
have_primary = 0; |
have_primary = 0; |
278 |
XDeleteProperty(g_display, DefaultRootWindow(g_display), rdesktop_clipboard_formats_atom); |
XDeleteProperty(g_display, DefaultRootWindow(g_display), rdesktop_clipboard_formats_atom); |
279 |
cliprdr_send_text_format_announce(); |
cliprdr_send_simple_native_format_announce(CF_TEXT); |
280 |
} |
} |
281 |
|
|
282 |
void |
void |
284 |
{ |
{ |
285 |
unsigned long nitems, bytes_left; |
unsigned long nitems, bytes_left; |
286 |
int format, res; |
int format, res; |
287 |
|
XWindowAttributes wa; |
288 |
uint8 *data; |
uint8 *data; |
289 |
Atom type; |
Atom type; |
290 |
|
|
291 |
|
if (event->state == PropertyNewValue && g_waiting_for_INCR) |
292 |
|
{ |
293 |
|
DEBUG_CLIPBOARD(("x_clip_handle_PropertyNotify: g_waiting_for_INCR != 0\n")); |
294 |
|
if ((XGetWindowProperty(g_display, g_wnd, rdesktop_clipboard_target_atom, 0, |
295 |
|
4096L, True, AnyPropertyType, |
296 |
|
&type, &format, &nitems, &bytes_left, &data) != Success)) |
297 |
|
{ |
298 |
|
XFree(data); |
299 |
|
return; |
300 |
|
} |
301 |
|
|
302 |
|
if (nitems == 0) |
303 |
|
{ |
304 |
|
XGetWindowAttributes(g_display, g_wnd, &wa); |
305 |
|
XSelectInput(g_display, g_wnd, (wa.your_event_mask ^ PropertyChangeMask)); |
306 |
|
XFree(data); |
307 |
|
g_waiting_for_INCR = 0; |
308 |
|
|
309 |
|
if (g_clip_buflen > 0) |
310 |
|
{ |
311 |
|
cliprdr_send_data(g_clip_buffer, g_clip_buflen + 1); |
312 |
|
|
313 |
|
if (!rdesktop_is_selection_owner) |
314 |
|
cliprdr_send_simple_native_format_announce(CF_TEXT); |
315 |
|
|
316 |
|
xfree(g_clip_buffer); |
317 |
|
g_clip_buffer = 0; |
318 |
|
g_clip_buflen = 0; |
319 |
|
} |
320 |
|
} |
321 |
|
else |
322 |
|
{ |
323 |
|
uint8 *translated_data; |
324 |
|
uint32 length = nitems; |
325 |
|
uint8 *tmp; |
326 |
|
|
327 |
|
DEBUG_CLIPBOARD(("Translating linebreaks before sending data\n")); |
328 |
|
translated_data = lf2crlf(data, &length); |
329 |
|
|
330 |
|
tmp = xmalloc(length + g_clip_buflen); |
331 |
|
strncpy((char *) tmp, (char *) g_clip_buffer, g_clip_buflen); |
332 |
|
xfree(g_clip_buffer); |
333 |
|
|
334 |
|
strncpy((char *) (tmp + g_clip_buflen), (char *) translated_data, length); |
335 |
|
xfree(translated_data); |
336 |
|
|
337 |
|
g_clip_buffer = tmp; |
338 |
|
g_clip_buflen += length; |
339 |
|
|
340 |
|
XFree(data); |
341 |
|
return; |
342 |
|
} |
343 |
|
} |
344 |
|
|
345 |
if (event->atom != rdesktop_clipboard_formats_atom) |
if (event->atom != rdesktop_clipboard_formats_atom) |
346 |
return; |
return; |
347 |
|
|
364 |
} |
} |
365 |
|
|
366 |
/* PropertyDelete, or XGetWindowProperty failed */ |
/* PropertyDelete, or XGetWindowProperty failed */ |
367 |
cliprdr_send_text_format_announce(); |
cliprdr_send_simple_native_format_announce(CF_TEXT); |
368 |
rdesktop_is_selection_owner = 0; |
rdesktop_is_selection_owner = 0; |
369 |
} |
} |
370 |
|
#endif |
371 |
|
|
372 |
|
|
373 |
void |
void |
402 |
crlf2lf(data, &length); |
crlf2lf(data, &length); |
403 |
|
|
404 |
/* Only send data up to null byte, if any */ |
/* Only send data up to null byte, if any */ |
405 |
firstnull = (uint8 *)strchr((char*)data, '\0'); |
firstnull = (uint8 *) strchr((char *) data, '\0'); |
406 |
if (firstnull) |
if (firstnull) |
407 |
{ |
{ |
408 |
length = firstnull - data + 1; |
length = firstnull - data + 1; |
453 |
void |
void |
454 |
ui_clip_sync(void) |
ui_clip_sync(void) |
455 |
{ |
{ |
456 |
cliprdr_send_text_format_announce(); |
cliprdr_send_simple_native_format_announce(CF_TEXT); |
457 |
} |
} |
458 |
|
|
459 |
|
|
472 |
incr_atom = XInternAtom(g_display, "INCR", False); |
incr_atom = XInternAtom(g_display, "INCR", False); |
473 |
targets[0] = targets_atom; |
targets[0] = targets_atom; |
474 |
targets[1] = XInternAtom(g_display, "TEXT", False); |
targets[1] = XInternAtom(g_display, "TEXT", False); |
475 |
targets[2] = XInternAtom(g_display, "UTF8_STRING", False); |
targets[2] = XInternAtom(g_display, "STRING", False); |
476 |
targets[3] = XInternAtom(g_display, "text/unicode", False); |
targets[3] = XInternAtom(g_display, "text/unicode", False); |
477 |
targets[4] = XInternAtom(g_display, "TIMESTAMP", False); |
targets[4] = XInternAtom(g_display, "TIMESTAMP", False); |
478 |
targets[5] = XA_STRING; |
targets[5] = XA_STRING; |