Package: rdesktop Version: 1.6.0-3 Severity: important Tags: patch *** Please type your report below this line ***
Summary: Don't abort a clipboard operation on a failed timestamp transfer. X clients that register selections for clipboard and primary selections are supposed to support the TIMESTAMP query to find out the time that they acquired the selection. Not all clients support the timestamp query. rdesktop will pull from either the primary or clipboard selection when a Unix to Windows clipboard operation is requested, if only one of the two is currently owned that one is selected for a transfer. If both are owned rdesktop sends both selection owners a timestamp request and selects the newer of the two for the clipboard operation. Without this patch if both primary and clipboard are owned, rdesktop aborts the transfer on the first failed (not supported) timestamp query, this is very non-obvious and difficult to clear. The user just sees clipboard transfers fail randomly and until the application that doesn't support timestamps looses its selection clipboard operations Unix to Windows fail. Currently if a client returns a timestamp of 0 it is set to 1 for the purpose of comparing the to selection timestamp values. rdesktop uses 0 to mean it has not yet received a timestamp for that application. A returned 0 timestamp value indicates the client supports timestamp, but probably used 0 when acquiring the selection in the first place even though clients are not supposed to. This patch will set the timestamp to 1 for any client that doesn't support timestamps so at least a transfer can take place even though it can't know for sure which selection is the newest and will select the clipboard over the primary selection in the case of a tie. -- System Information: Debian Release: squeeze/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 2.6.35-rc1+ (SMP w/2 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/dash Versions of packages rdesktop depends on: ii libasound2 1.0.22-2 shared library for ALSA applicatio ii libc6 2.10.2-9 Embedded GNU C Library: Shared lib ii libssl0.9.8 0.9.8n-1 SSL shared libraries ii libx11-6 2:1.3.3-3 X11 client-side library rdesktop recommends no packages. rdesktop suggests no packages. -- no debconf information
--- xclip.c | 47 ++++++++++++++++++++++++----------------------- 1 files changed, 24 insertions(+), 23 deletions(-) diff --git a/xclip.c b/xclip.c index 37290fc..5de88dd 100644 --- a/xclip.c +++ b/xclip.c @@ -508,58 +508,59 @@ xclip_handle_SelectionNotify(XSelectionEvent * event) int res, i, format; uint8 *data = NULL; - if (event->property == None) + if (event->target != timestamp_atom && event->property == None) goto fail; DEBUG_CLIPBOARD(("xclip_handle_SelectionNotify: selection=%s, target=%s, property=%s\n", XGetAtomName(g_display, event->selection), XGetAtomName(g_display, event->target), - XGetAtomName(g_display, event->property))); + event->property ? XGetAtomName(g_display, event->property) : "None")); if (event->target == timestamp_atom) { - if (event->selection == primary_atom) + Time timestamp; + Atom query = event->selection == primary_atom ? + rdesktop_primary_timestamp_target_atom : + rdesktop_clipboard_timestamp_target_atom; + if (event->property == None) { - res = XGetWindowProperty(g_display, g_wnd, - rdesktop_primary_timestamp_target_atom, 0, - XMaxRequestSize(g_display), False, AnyPropertyType, - &type, &format, &nitems, &bytes_left, &data); + /* If a client doesn't support timestamp, treat it the same as ones that + * return zero. + */ + timestamp = 1; } else { - res = XGetWindowProperty(g_display, g_wnd, - rdesktop_clipboard_timestamp_target_atom, 0, + res = XGetWindowProperty(g_display, g_wnd, query, 0, XMaxRequestSize(g_display), False, AnyPropertyType, &type, &format, &nitems, &bytes_left, &data); - } + if ((res != Success) || (nitems != 1) || (format != 32)) + { + DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n")); + goto fail; + } - if ((res != Success) || (nitems != 1) || (format != 32)) - { - DEBUG_CLIPBOARD(("XGetWindowProperty failed!\n")); - goto fail; + timestamp = *(Time *) data; + if (timestamp == 0) + timestamp++; + XDeleteProperty(g_display, g_wnd, query); + XFree(data); } if (event->selection == primary_atom) { - primary_timestamp = *(Time *) data; - if (primary_timestamp == 0) - primary_timestamp++; - XDeleteProperty(g_display, g_wnd, rdesktop_primary_timestamp_target_atom); + primary_timestamp = timestamp; DEBUG_CLIPBOARD(("Got PRIMARY timestamp: %u\n", (unsigned) primary_timestamp)); } else { - clipboard_timestamp = *(Time *) data; - if (clipboard_timestamp == 0) - clipboard_timestamp++; - XDeleteProperty(g_display, g_wnd, rdesktop_clipboard_timestamp_target_atom); + clipboard_timestamp = timestamp; DEBUG_CLIPBOARD(("Got CLIPBOARD timestamp: %u\n", (unsigned) clipboard_timestamp)); } - XFree(data); if (primary_timestamp && clipboard_timestamp) { -- 1.7.0