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

Reply via email to