winex11.drv: Add TIMESTAMP to X clipboard TARGETS

Andrey Vostrikov av.linux.dev at gmail.com
Tue Nov 5 03:32:22 CST 2013


Hi,

This is reworked patch after small discussion on wine-devel. It obtains 
X server timestamp similar as in GTK+ library, by pinging X window when 
selection is acquired.

Best regards,
Andrey
-------------- next part --------------
From 539a169ef1fb4820b8d8feb126cb41028452d72e Mon Sep 17 00:00:00 2001
From: Andrey Vostrikov <av.linux.dev at gmail.com>
Date: Wed, 30 Oct 2013 17:37:22 +0400
Subject: winex11.drv: Add TIMESTAMP to X clipboard TARGETS

---
 dlls/winex11.drv/clipboard.c   | 44 +++++++++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/x11drv.h      |  1 +
 dlls/winex11.drv/x11drv_main.c |  1 +
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 730b6c9..03fdf02 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -133,6 +133,7 @@ typedef struct tagWINE_CLIPDATA {
 static int selectionAcquired = 0;              /* Contains the current selection masks */
 static Window selectionWindow = None;          /* The top level X window which owns the selection */
 static Atom selectionCacheSrc = XA_PRIMARY;    /* The selection source from which the clipboard cache was filled */
+static UINT selectionTimestamp = 0;            /* X serverTimestamp when selection was acquired */
 
 void CDECL X11DRV_EmptyClipboard(BOOL keepunowned);
 void CDECL X11DRV_EndClipboardUpdate(void);
@@ -2626,6 +2627,27 @@ static BOOL X11DRV_CLIPBOARD_IsSelectionOwner(void)
  *                X11DRV Clipboard Exports
  **************************************************************************/
 
+/**************************************************************************
+ * timestamp_predicate
+ *
+ * Returns: TRUE if it was TIMESTAMP request
+ */
+static Bool
+timestamp_predicate (Display *display,
+             XEvent  *event,
+             XPointer arg)
+{
+    Window window = (Window)arg;
+    Atom atom = x11drv_atom(TIMESTAMP);
+
+    if (event->type == PropertyNotify &&
+        event->xproperty.window == window &&
+        event->xproperty.atom == atom) {
+        return True;
+    }
+
+    return False;
+}
 
 static void selection_acquire(void)
 {
@@ -2653,6 +2675,19 @@ static void selection_acquire(void)
 
     if (selectionAcquired)
     {
+        XEvent event;
+        Atom atom;
+        unsigned char dummy = 0;
+
+        /* ping X window and retrieve current X server timestamp from XEvent structure */
+        atom = x11drv_atom(TIMESTAMP);
+        XChangeProperty (display, owner, atom, atom,
+                         8, PropModeReplace, &dummy, 1);
+
+        XIfEvent (display, &event, timestamp_predicate, (XPointer)owner);
+
+        selectionTimestamp = event.xproperty.time;
+
         selectionWindow = owner;
         TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
     }
@@ -3017,7 +3052,7 @@ static Atom X11DRV_SelectionRequest_TARGETS( Display *display, Window requestor,
     /*
      * Count the number of items we wish to expose as selection targets.
      */
-    cTargets = 1; /* Include TARGETS */
+    cTargets = 2; /* Include TARGETS and TIMESTAMP by default */
 
     if (!list_head( &data_list )) return None;
 
@@ -3036,6 +3071,7 @@ static Atom X11DRV_SelectionRequest_TARGETS( Display *display, Window requestor,
 
     i = 0;
     targets[i++] = x11drv_atom(TARGETS);
+    targets[i++] = x11drv_atom(TIMESTAMP);
 
     LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry )
         LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry )
@@ -3211,6 +3247,12 @@ static void X11DRV_HandleSelectionRequest( HWND hWnd, XSelectionRequestEvent *ev
         /* TARGETS selection request */
         rprop = X11DRV_SelectionRequest_TARGETS( display, request, event->target, rprop );
     }
+    else if(event->target == x11drv_atom(TIMESTAMP))  /*  Return event timestamp */
+    {
+        /* TIMESTAMP selection request */
+        XChangeProperty(display, request, rprop, event->target,
+                        32, PropModeReplace, (unsigned char*)&selectionTimestamp, 1);
+    }
     else if(event->target == x11drv_atom(MULTIPLE))  /*  rprop contains a list of (target, property) atom pairs */
     {
         /* MULTIPLE selection request */
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98386ce..64cec1f 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -398,6 +398,7 @@ enum x11drv_atoms
     XATOM_SELECTION_DATA,
     XATOM_TARGETS,
     XATOM_TEXT,
+    XATOM_TIMESTAMP,
     XATOM_UTF8_STRING,
     XATOM_RAW_ASCENT,
     XATOM_RAW_DESCENT,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index a6572ba..b9e1883 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -111,6 +111,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
     "SELECTION_DATA",
     "TARGETS",
     "TEXT",
+    "TIMESTAMP",
     "UTF8_STRING",
     "RAW_ASCENT",
     "RAW_DESCENT",
-- 
1.8.1.4


More information about the wine-patches mailing list