114 |
/* Denotes that an rdesktop (not this rdesktop) is owning the selection, |
/* Denotes that an rdesktop (not this rdesktop) is owning the selection, |
115 |
allowing us to interchange Windows native clipboard data directly. */ |
allowing us to interchange Windows native clipboard data directly. */ |
116 |
static int rdesktop_is_selection_owner = 0; |
static int rdesktop_is_selection_owner = 0; |
117 |
|
/* Time when we acquired the selection. */ |
118 |
|
static Time acquire_time = 0; |
119 |
|
|
120 |
/* Denotes that an INCR ("chunked") transfer is in progress. */ |
/* Denotes that an INCR ("chunked") transfer is in progress. */ |
121 |
static int g_waiting_for_INCR = 0; |
static int g_waiting_for_INCR = 0; |
247 |
XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); |
XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); |
248 |
} |
} |
249 |
|
|
250 |
|
/* Examines the special root window property that contains the native Windows |
251 |
|
formats if another rdesktop process owns the clipboard. */ |
252 |
|
static void |
253 |
|
xclip_get_root_property() |
254 |
|
{ |
255 |
|
unsigned long nitems; |
256 |
|
unsigned long bytes_left; |
257 |
|
int format, res; |
258 |
|
uint8 *data; |
259 |
|
Atom type; |
260 |
|
|
261 |
|
res = XGetWindowProperty(g_display, DefaultRootWindow(g_display), |
262 |
|
rdesktop_clipboard_formats_atom, 0, |
263 |
|
XMaxRequestSize(g_display), False, XA_STRING, |
264 |
|
&type, &format, &nitems, &bytes_left, &data); |
265 |
|
|
266 |
|
if ((res == Success) && (nitems > 0)) |
267 |
|
{ |
268 |
|
DEBUG_CLIPBOARD(("xclip_get_root_property: got fellow rdesktop formats\n")); |
269 |
|
cliprdr_send_native_format_announce(data, nitems); |
270 |
|
rdesktop_is_selection_owner = 1; |
271 |
|
return; |
272 |
|
} |
273 |
|
|
274 |
|
/* For some reason, we couldn't announce the native formats */ |
275 |
|
cliprdr_send_simple_native_format_announce(RDP_CF_TEXT); |
276 |
|
rdesktop_is_selection_owner = 0; |
277 |
|
} |
278 |
|
|
279 |
/* Wrapper for cliprdr_send_data which also cleans the request state. */ |
/* Wrapper for cliprdr_send_data which also cleans the request state. */ |
280 |
static void |
static void |
281 |
helper_cliprdr_send_response(uint8 * data, uint32 length) |
helper_cliprdr_send_response(uint8 * data, uint32 length) |
645 |
} |
} |
646 |
else if (event->target == timestamp_atom) |
else if (event->target == timestamp_atom) |
647 |
{ |
{ |
648 |
xclip_provide_selection(event, XA_INTEGER, 32, (uint8 *) & g_last_gesturetime, 1); |
xclip_provide_selection(event, XA_INTEGER, 32, (uint8 *) & acquire_time, 1); |
649 |
return; |
return; |
650 |
} |
} |
651 |
else |
else |
734 |
unsigned long nitems; |
unsigned long nitems; |
735 |
unsigned long offset = 0; |
unsigned long offset = 0; |
736 |
unsigned long bytes_left = 1; |
unsigned long bytes_left = 1; |
737 |
int format, res; |
int format; |
738 |
XWindowAttributes wa; |
XWindowAttributes wa; |
739 |
uint8 *data; |
uint8 *data; |
740 |
Atom type; |
Atom type; |
795 |
if ((event->atom == rdesktop_clipboard_formats_atom) && |
if ((event->atom == rdesktop_clipboard_formats_atom) && |
796 |
(event->window == DefaultRootWindow(g_display)) && |
(event->window == DefaultRootWindow(g_display)) && |
797 |
!have_primary /* not interested in our own events */ ) |
!have_primary /* not interested in our own events */ ) |
798 |
{ |
xclip_get_root_property(); |
|
if (event->state == PropertyNewValue) |
|
|
{ |
|
|
DEBUG_CLIPBOARD(("xclip_handle_PropertyNotify: getting fellow rdesktop formats\n")); |
|
|
|
|
|
res = XGetWindowProperty(g_display, DefaultRootWindow(g_display), |
|
|
rdesktop_clipboard_formats_atom, 0, |
|
|
XMaxRequestSize(g_display), False, XA_STRING, |
|
|
&type, &format, &nitems, &bytes_left, &data); |
|
|
|
|
|
if ((res == Success) && (nitems > 0)) |
|
|
{ |
|
|
cliprdr_send_native_format_announce(data, nitems); |
|
|
rdesktop_is_selection_owner = 1; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
/* For some reason, we couldn't announce the native formats */ |
|
|
cliprdr_send_simple_native_format_announce(RDP_CF_TEXT); |
|
|
rdesktop_is_selection_owner = 0; |
|
|
} |
|
799 |
} |
} |
800 |
#endif |
#endif |
801 |
|
|
808 |
void |
void |
809 |
ui_clip_format_announce(uint8 * data, uint32 length) |
ui_clip_format_announce(uint8 * data, uint32 length) |
810 |
{ |
{ |
811 |
XSetSelectionOwner(g_display, primary_atom, g_wnd, g_last_gesturetime); |
acquire_time = g_last_gesturetime; |
812 |
|
|
813 |
|
XSetSelectionOwner(g_display, primary_atom, g_wnd, acquire_time); |
814 |
if (XGetSelectionOwner(g_display, primary_atom) != g_wnd) |
if (XGetSelectionOwner(g_display, primary_atom) != g_wnd) |
815 |
{ |
{ |
816 |
warning("Failed to aquire ownership of PRIMARY clipboard\n"); |
warning("Failed to aquire ownership of PRIMARY clipboard\n"); |
822 |
rdesktop_clipboard_formats_atom, XA_STRING, 8, PropModeReplace, data, |
rdesktop_clipboard_formats_atom, XA_STRING, 8, PropModeReplace, data, |
823 |
length); |
length); |
824 |
|
|
825 |
XSetSelectionOwner(g_display, clipboard_atom, g_wnd, g_last_gesturetime); |
XSetSelectionOwner(g_display, clipboard_atom, g_wnd, acquire_time); |
826 |
if (XGetSelectionOwner(g_display, clipboard_atom) != g_wnd) |
if (XGetSelectionOwner(g_display, clipboard_atom) != g_wnd) |
827 |
warning("Failed to aquire ownership of CLIPBOARD clipboard\n"); |
warning("Failed to aquire ownership of CLIPBOARD clipboard\n"); |
828 |
} |
} |
833 |
{ |
{ |
834 |
BOOL free_data = False; |
BOOL free_data = False; |
835 |
|
|
836 |
|
if (length == 0) |
837 |
|
{ |
838 |
|
xclip_refuse_selection(&selection_request); |
839 |
|
has_selection_request = False; |
840 |
|
return; |
841 |
|
} |
842 |
|
|
843 |
if (selection_request.target == format_string_atom || selection_request.target == XA_STRING) |
if (selection_request.target == format_string_atom || selection_request.target == XA_STRING) |
844 |
{ |
{ |
845 |
/* We're expecting a CF_TEXT response */ |
/* We're expecting a CF_TEXT response */ |
907 |
} |
} |
908 |
|
|
909 |
void |
void |
910 |
|
ui_clip_request_failed() |
911 |
|
{ |
912 |
|
xclip_refuse_selection(&selection_request); |
913 |
|
has_selection_request = False; |
914 |
|
} |
915 |
|
|
916 |
|
void |
917 |
ui_clip_request_data(uint32 format) |
ui_clip_request_data(uint32 format) |
918 |
{ |
{ |
919 |
Window primary_owner, clipboard_owner; |
Window primary_owner, clipboard_owner; |
975 |
void |
void |
976 |
ui_clip_sync(void) |
ui_clip_sync(void) |
977 |
{ |
{ |
978 |
cliprdr_send_simple_native_format_announce(RDP_CF_TEXT); |
xclip_get_root_property(); |
979 |
} |
} |
980 |
|
|
981 |
void |
void |