Moved clipboard event handling functions and some private data
structures to clipboard.c.

diff --git a/dlls/x11drv/clipboard.c b/dlls/x11drv/clipboard.c
index ae3bc85..7797c9b 100644
--- a/dlls/x11drv/clipboard.c
+++ b/dlls/x11drv/clipboard.c
@@ -107,6 +107,35 @@
     UINT flags;
 } CLIPBOARDINFO, *LPCLIPBOARDINFO;
 
+typedef struct tagWINE_CLIPDATA {
+    UINT        wFormatID;
+    HANDLE16    hData16;
+    HANDLE      hData32;
+    UINT        drvData;
+    UINT        wFlags;
+    struct tagWINE_CLIPDATA *PrevData;
+    struct tagWINE_CLIPDATA *NextData;
+} WINE_CLIPDATA, *LPWINE_CLIPDATA;
+
+typedef HANDLE (*DRVEXPORTFUNC)(Window requestor, Atom aTarget, Atom rprop,
+    LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
+typedef HANDLE (*DRVIMPORTFUNC)(LPBYTE hData, UINT cBytes);
+
+typedef struct tagWINE_CLIPFORMAT {
+    UINT        wFormatID;
+    LPCWSTR     Name;
+    UINT        drvData;
+    UINT        wFlags;
+    DRVIMPORTFUNC  lpDrvImportFunc;
+    DRVEXPORTFUNC  lpDrvExportFunc;
+    struct tagWINE_CLIPFORMAT *PrevFormat;
+    struct tagWINE_CLIPFORMAT *NextFormat;
+} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
+
+#define CF_FLAG_BUILTINFMT   1 /* Built-in windows format */
+#define CF_FLAG_UNOWNED      2 /* cached data is not owned */
+#define CF_FLAG_SYNTHESIZED  8 /* Implicitly converted data */
+
 static int selectionAcquired = 0;              /* Contains the current selection masks */
 static Window selectionWindow = None;          /* The top level X window which owns the selection */
 static BOOL usePrimary = FALSE;                /* Use primary selection in additon to the clipboard selection */
@@ -115,20 +144,20 @@
 INT X11DRV_RegisterClipboardFormat(LPCWSTR FormatName);
 void X11DRV_EmptyClipboard(BOOL keepunowned);
 void X11DRV_EndClipboardUpdate(void);
-HANDLE X11DRV_CLIPBOARD_ImportClipboardData(LPBYTE lpdata, UINT cBytes);
-HANDLE X11DRV_CLIPBOARD_ImportEnhMetaFile(LPBYTE lpdata, UINT cBytes);
-HANDLE X11DRV_CLIPBOARD_ImportMetaFilePict(LPBYTE lpdata, UINT cBytes);
-HANDLE X11DRV_CLIPBOARD_ImportXAPIXMAP(LPBYTE lpdata, UINT cBytes);
-HANDLE X11DRV_CLIPBOARD_ImportXAString(LPBYTE lpdata, UINT cBytes);
-HANDLE X11DRV_CLIPBOARD_ExportClipboardData(Window requestor, Atom aTarget,
+static HANDLE X11DRV_CLIPBOARD_ImportClipboardData(LPBYTE lpdata, UINT cBytes);
+static HANDLE X11DRV_CLIPBOARD_ImportEnhMetaFile(LPBYTE lpdata, UINT cBytes);
+static HANDLE X11DRV_CLIPBOARD_ImportMetaFilePict(LPBYTE lpdata, UINT cBytes);
+static HANDLE X11DRV_CLIPBOARD_ImportXAPIXMAP(LPBYTE lpdata, UINT cBytes);
+static HANDLE X11DRV_CLIPBOARD_ImportXAString(LPBYTE lpdata, UINT cBytes);
+static HANDLE X11DRV_CLIPBOARD_ExportClipboardData(Window requestor, Atom aTarget,
     Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportString(Window requestor, Atom aTarget,
+static HANDLE X11DRV_CLIPBOARD_ExportString(Window requestor, Atom aTarget,
     Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget,
+static HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget,
     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget,
+static HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget,
     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
-HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget,
+static HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget,
     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
 static WINE_CLIPFORMAT *X11DRV_CLIPBOARD_InsertClipboardFormat(LPCWSTR FormatName, Atom prop);
 static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, Atom prop);
@@ -143,6 +172,7 @@
 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData);
 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedDIB(void);
 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedBitmap(void);
+static void X11DRV_HandleSelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
 
 /* Clipboard formats
  * WARNING: This data ordering is dependent on the WINE_CLIPFORMAT structure
@@ -2574,3 +2604,355 @@
 
     TRACE("%d formats added to cached data\n", ClipDataCount - count);
 }
+
+
+/***********************************************************************
+ *           add_targets
+ *
+ * Utility function for X11DRV_SelectionRequest_TARGETS.
+ */
+static BOOL add_targets(Atom* targets, unsigned long cTargets, Atom prop)
+{
+    unsigned int i;
+    BOOL bExists;
+
+    /* Scan through what we have so far to avoid duplicates */
+    for (i = 0, bExists = FALSE; i < cTargets; i++)
+    {
+        if (targets[i] == prop)
+        {
+            bExists = TRUE;
+            break;
+        }
+    }
+
+    if (!bExists)
+        targets[cTargets] = prop;
+
+    return !bExists;
+}
+
+
+/***********************************************************************
+ *           X11DRV_SelectionRequest_TARGETS
+ *  Service a TARGETS selection request event
+ */
+static Atom X11DRV_SelectionRequest_TARGETS( Display *display, Window requestor,
+                                             Atom target, Atom rprop )
+{
+    Atom* targets;
+    UINT wFormat;
+    UINT alias;
+    ULONG cTargets;
+    LPWINE_CLIPFORMAT lpFormat;
+
+    /*
+     * Count the number of items we wish to expose as selection targets.
+     * We include the TARGETS item, and property aliases
+     */
+    cTargets = X11DRV_CountClipboardFormats() + 1;
+
+    for (wFormat = 0; (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
+    {
+        lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
+
+        if (lpFormat)
+        {
+            if (!lpFormat->lpDrvExportFunc)
+                cTargets--;
+
+            if (X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
+                cTargets++;
+        }
+        /* else most likely unregistered format such as CF_PRIVATE or CF_GDIOBJ */
+    }
+
+    TRACE(" found %ld formats\n", cTargets);
+
+    /* Allocate temp buffer */
+    targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
+    if(targets == NULL)
+        return None;
+
+    /* Create TARGETS property list (First item in list is TARGETS itself) */
+    for (targets[0] = x11drv_atom(TARGETS), cTargets = 1, wFormat = 0;
+         (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
+    {
+        lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
+
+        if (lpFormat)
+        {
+            if (lpFormat->lpDrvExportFunc)
+            {
+                if (add_targets(targets, cTargets, lpFormat->drvData))
+                    cTargets++;
+            }
+
+            /* Check if any alias should be listed */
+            alias = X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData);
+            if (alias)
+            {
+                if (add_targets(targets, cTargets, alias))
+                    cTargets++;
+            }
+        }
+    }
+
+    wine_tsx11_lock();
+
+    if (TRACE_ON(clipboard))
+    {
+        unsigned int i;
+        for ( i = 0; i < cTargets; i++)
+        {
+            if (targets[i])
+            {
+                char *itemFmtName = XGetAtomName(display, targets[i]);
+                TRACE("\tAtom# %d:  Property %ld Type %s\n", i, targets[i], itemFmtName);
+                XFree(itemFmtName);
+            }
+        }
+    }
+
+    /* We may want to consider setting the type to xaTargets instead,
+     * in case some apps expect this instead of XA_ATOM */
+    XChangeProperty(display, requestor, rprop, XA_ATOM, 32,
+                    PropModeReplace, (unsigned char *)targets, cTargets);
+    wine_tsx11_unlock();
+
+    HeapFree(GetProcessHeap(), 0, targets);
+
+    return rprop;
+}
+
+
+/***********************************************************************
+ *           X11DRV_SelectionRequest_MULTIPLE
+ *  Service a MULTIPLE selection request event
+ *  rprop contains a list of (target,property) atom pairs.
+ *  The first atom names a target and the second names a property.
+ *  The effect is as if we have received a sequence of SelectionRequest events
+ *  (one for each atom pair) except that:
+ *  1. We reply with a SelectionNotify only when all the requested conversions
+ *  have been performed.
+ *  2. If we fail to convert the target named by an atom in the MULTIPLE property,
+ *  we replace the atom in the property by None.
+ */
+static Atom X11DRV_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent )
+{
+    Display *display = pevent->display;
+    Atom           rprop;
+    Atom           atype=AnyPropertyType;
+    int            aformat;
+    unsigned long  remain;
+    Atom*          targetPropList=NULL;
+    unsigned long  cTargetPropList = 0;
+
+    /* If the specified property is None the requestor is an obsolete client.
+     * We support these by using the specified target atom as the reply property.
+     */
+    rprop = pevent->property;
+    if( rprop == None )
+        rprop = pevent->target;
+    if (!rprop)
+        return 0;
+
+    /* Read the MULTIPLE property contents. This should contain a list of
+     * (target,property) atom pairs.
+     */
+    wine_tsx11_lock();
+    if(XGetWindowProperty(display, pevent->requestor, rprop,
+                          0, 0x3FFF, False, AnyPropertyType, &atype,&aformat,
+                          &cTargetPropList, &remain,
+                          (unsigned char**)&targetPropList) != Success)
+    {
+        wine_tsx11_unlock();
+        TRACE("\tCouldn't read MULTIPLE property\n");
+    }
+    else
+    {
+        TRACE("\tType %s,Format %d,nItems %ld, Remain %ld\n",
+              XGetAtomName(display, atype), aformat, cTargetPropList, remain);
+        wine_tsx11_unlock();
+
+        /*
+         * Make sure we got what we expect.
+         * NOTE: According to the X-ICCCM Version 2.0 documentation the property sent
+         * in a MULTIPLE selection request should be of type ATOM_PAIR.
+         * However some X apps(such as XPaint) are not compliant with this and return
+         * a user defined atom in atype when XGetWindowProperty is called.
+         * The data *is* an atom pair but is not denoted as such.
+         */
+        if(aformat == 32 /* atype == xAtomPair */ )
+        {
+            unsigned int i;
+
+            /* Iterate through the ATOM_PAIR list and execute a SelectionRequest
+             * for each (target,property) pair */
+
+            for (i = 0; i < cTargetPropList; i+=2)
+            {
+                XSelectionRequestEvent event;
+
+                if (TRACE_ON(clipboard))
+                {
+                    char *targetName, *propName;
+                    wine_tsx11_lock();
+                    targetName = XGetAtomName(display, targetPropList[i]);
+                    propName = XGetAtomName(display, targetPropList[i+1]);
+                    TRACE("MULTIPLE(%d): Target='%s' Prop='%s'\n",
+                          i/2, targetName, propName);
+                    XFree(targetName);
+                    XFree(propName);
+                    wine_tsx11_unlock();
+                }
+
+                /* We must have a non "None" property to service a MULTIPLE target atom */
+                if ( !targetPropList[i+1] )
+                {
+                    TRACE("\tMULTIPLE(%d): Skipping target with empty property!\n", i);
+                    continue;
+                }
+
+                /* Set up an XSelectionRequestEvent for this (target,property) pair */
+                memcpy( &event, pevent, sizeof(XSelectionRequestEvent) );
+                event.target = targetPropList[i];
+                event.property = targetPropList[i+1];
+
+                /* Fire a SelectionRequest, informing the handler that we are processing
+                 * a MULTIPLE selection request event.
+                 */
+                X11DRV_HandleSelectionRequest( hWnd, &event, TRUE );
+            }
+        }
+
+        /* Free the list of targets/properties */
+        wine_tsx11_lock();
+        XFree(targetPropList);
+        wine_tsx11_unlock();
+    }
+
+    return rprop;
+}
+
+
+/***********************************************************************
+ *           X11DRV_HandleSelectionRequest
+ *  Process an event selection request event.
+ *  The bIsMultiple flag is used to signal when EVENT_SelectionRequest is called
+ *  recursively while servicing a "MULTIPLE" selection target.
+ *
+ *  Note: We only receive this event when WINE owns the X selection
+ */
+static void X11DRV_HandleSelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple )
+{
+    Display *display = event->display;
+    XSelectionEvent result;
+    Atom rprop = None;
+    Window request = event->requestor;
+
+    TRACE("\n");
+
+    /*
+     * We can only handle the selection request if :
+     * The selection is PRIMARY or CLIPBOARD, AND we can successfully open the clipboard.
+     * Don't do these checks or open the clipboard while recursively processing MULTIPLE,
+     * since this has been already done.
+     */
+    if ( !bIsMultiple )
+    {
+        if (((event->selection != XA_PRIMARY) && (event->selection != x11drv_atom(CLIPBOARD))))
+            goto END;
+    }
+
+    /* If the specified property is None the requestor is an obsolete client.
+     * We support these by using the specified target atom as the reply property.
+     */
+    rprop = event->property;
+    if( rprop == None )
+        rprop = event->target;
+
+    if(event->target == x11drv_atom(TARGETS))  /*  Return a list of all supported targets */
+    {
+        /* TARGETS selection request */
+        rprop = X11DRV_SelectionRequest_TARGETS( display, request, event->target, rprop );
+    }
+    else if(event->target == x11drv_atom(MULTIPLE))  /*  rprop contains a list of (target, property) atom pairs */
+    {
+        /* MULTIPLE selection request */
+        rprop = X11DRV_SelectionRequest_MULTIPLE( hWnd, event );
+    }
+    else
+    {
+        LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupProperty(event->target);
+
+        if (!lpFormat)
+            lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(event->target);
+
+        if (lpFormat && lpFormat->lpDrvExportFunc)
+        {
+            LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(lpFormat->wFormatID);
+
+            if (lpData)
+            {
+                unsigned char* lpClipData;
+                DWORD cBytes;
+                HANDLE hClipData = lpFormat->lpDrvExportFunc(request, event->target,
+                                                             rprop, lpData, &cBytes);
+
+                if (hClipData && (lpClipData = GlobalLock(hClipData)))
+                {
+                    TRACE("\tUpdating property %s, %ld bytes\n", debugstr_w(lpFormat->Name), cBytes);
+
+                    wine_tsx11_lock();
+                    XChangeProperty(display, request, rprop, event->target,
+                                    8, PropModeReplace, (unsigned char *)lpClipData, cBytes);
+                    wine_tsx11_unlock();
+
+                    GlobalUnlock(hClipData);
+                    GlobalFree(hClipData);
+                }
+            }
+        }
+    }
+
+END:
+    /* reply to sender
+     * SelectionNotify should be sent only at the end of a MULTIPLE request
+     */
+    if ( !bIsMultiple )
+    {
+        result.type = SelectionNotify;
+        result.display = display;
+        result.requestor = request;
+        result.selection = event->selection;
+        result.property = rprop;
+        result.target = event->target;
+        result.time = event->time;
+        TRACE("Sending SelectionNotify event...\n");
+        wine_tsx11_lock();
+        XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
+        wine_tsx11_unlock();
+    }
+}
+
+
+/***********************************************************************
+ *           X11DRV_SelectionRequest
+ */
+void X11DRV_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event )
+{
+    if (!hWnd) return;
+    X11DRV_HandleSelectionRequest( hWnd, event, FALSE );
+}
+
+
+/***********************************************************************
+ *           X11DRV_SelectionClear
+ */
+void X11DRV_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
+{
+    if (!hWnd) return;
+    if (event->selection == XA_PRIMARY || event->selection == x11drv_atom(CLIPBOARD))
+        X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd, event->time );
+}
diff --git a/dlls/x11drv/event.c b/dlls/x11drv/event.c
index 15361ec..9da9b1b 100644
--- a/dlls/x11drv/event.c
+++ b/dlls/x11drv/event.c
@@ -84,8 +84,6 @@
   /* Event handlers */
 static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event );
 static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event );
-static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
-static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event);
 static void EVENT_PropertyNotify( XPropertyEvent *event );
 static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
 
@@ -346,13 +344,11 @@
       break;
 
     case SelectionRequest:
-      if (!hWnd) return;
-      EVENT_SelectionRequest( hWnd, (XSelectionRequestEvent *)event, FALSE );
+      X11DRV_SelectionRequest( hWnd, (XSelectionRequestEvent *)event );
       break;
 
     case SelectionClear:
-      if (!hWnd) return;
-      EVENT_SelectionClear( hWnd, (XSelectionClearEvent*) event );
+      X11DRV_SelectionClear( hWnd, (XSelectionClearEvent*) event );
       break;
 
     case PropertyNotify:
@@ -591,346 +587,6 @@
 
 
 /***********************************************************************
- *           EVENT_SelectionRequest_AddTARGETS
- *  Utility function for EVENT_SelectionRequest_TARGETS.
- */
-static BOOL EVENT_SelectionRequest_AddTARGETS(Atom* targets, unsigned long cTargets, Atom prop)
-{
-    unsigned int i;
-    BOOL bExists;
-
-    /* Scan through what we have so far to avoid duplicates */
-    for (i = 0, bExists = FALSE; i < cTargets; i++)
-    {
-        if (targets[i] == prop)
-        {
-            bExists = TRUE;
-            break;
-        }
-    }
-
-    if (!bExists)
-        targets[cTargets] = prop;
-
-    return !bExists;
-}
-
-
-/***********************************************************************
- *           EVENT_SelectionRequest_TARGETS
- *  Service a TARGETS selection request event
- */
-static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
-                                            Atom target, Atom rprop )
-{
-    Atom* targets;
-    UINT wFormat;
-    UINT alias;
-    ULONG cTargets;
-    LPWINE_CLIPFORMAT lpFormat;
-
-    /*
-     * Count the number of items we wish to expose as selection targets.
-     * We include the TARGETS item, and property aliases
-     */
-    cTargets = X11DRV_CountClipboardFormats() + 1;
-
-    for (wFormat = 0; (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
-    {
-        lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
-
-        if (lpFormat)
-        {
-            if (!lpFormat->lpDrvExportFunc)
-                cTargets--;
-
-            if (X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
-                cTargets++;
-        }
-        /* else most likely unregistered format such as CF_PRIVATE or CF_GDIOBJ */
-    }
-
-    TRACE_(clipboard)(" found %ld formats\n", cTargets);
-
-    /* Allocate temp buffer */
-    targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
-    if(targets == NULL) 
-        return None;
-
-    /* Create TARGETS property list (First item in list is TARGETS itself) */
-    for (targets[0] = x11drv_atom(TARGETS), cTargets = 1, wFormat = 0;
-          (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
-    {
-        lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
-
-        if (lpFormat)
-        {
-            if (lpFormat->lpDrvExportFunc)
-            {
-                if (EVENT_SelectionRequest_AddTARGETS(targets, cTargets, lpFormat->drvData))
-                   cTargets++;
-            }
-
-            /* Check if any alias should be listed */
-            alias = X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData);
-            if (alias)
-            {
-                if (EVENT_SelectionRequest_AddTARGETS(targets, cTargets, alias))
-                   cTargets++;
-            }
-        }
-    }
-
-    wine_tsx11_lock();
-
-    if (TRACE_ON(clipboard))
-    {
-        unsigned int i;
-        for ( i = 0; i < cTargets; i++)
-        {
-            if (targets[i])
-            {
-                char *itemFmtName = XGetAtomName(display, targets[i]);
-                TRACE_(clipboard)("\tAtom# %d:  Property %ld Type %s\n", i, targets[i], itemFmtName);
-                XFree(itemFmtName);
-            }
-        }
-    }
-
-    /* We may want to consider setting the type to xaTargets instead,
-     * in case some apps expect this instead of XA_ATOM */
-    XChangeProperty(display, requestor, rprop, XA_ATOM, 32,
-                    PropModeReplace, (unsigned char *)targets, cTargets);
-    wine_tsx11_unlock();
-
-    HeapFree(GetProcessHeap(), 0, targets);
-
-    return rprop;
-}
-
-
-/***********************************************************************
- *           EVENT_SelectionRequest_MULTIPLE
- *  Service a MULTIPLE selection request event
- *  rprop contains a list of (target,property) atom pairs.
- *  The first atom names a target and the second names a property.
- *  The effect is as if we have received a sequence of SelectionRequest events
- *  (one for each atom pair) except that:
- *  1. We reply with a SelectionNotify only when all the requested conversions
- *  have been performed.
- *  2. If we fail to convert the target named by an atom in the MULTIPLE property,
- *  we replace the atom in the property by None.
- */
-static Atom EVENT_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent )
-{
-    Display *display = pevent->display;
-    Atom           rprop;
-    Atom           atype=AnyPropertyType;
-    int		   aformat;
-    unsigned long  remain;
-    Atom*	   targetPropList=NULL;
-    unsigned long  cTargetPropList = 0;
-
-   /* If the specified property is None the requestor is an obsolete client.
-    * We support these by using the specified target atom as the reply property.
-    */
-    rprop = pevent->property;
-    if( rprop == None )
-        rprop = pevent->target;
-    if (!rprop)
-        goto END;
-
-    /* Read the MULTIPLE property contents. This should contain a list of
-     * (target,property) atom pairs.
-     */
-    wine_tsx11_lock();
-    if(XGetWindowProperty(display, pevent->requestor, rprop,
-                            0, 0x3FFF, False, AnyPropertyType, &atype,&aformat,
-                            &cTargetPropList, &remain,
-                            (unsigned char**)&targetPropList) != Success)
-    {
-        wine_tsx11_unlock();
-        TRACE("\tCouldn't read MULTIPLE property\n");
-    }
-    else
-    {
-       TRACE("\tType %s,Format %d,nItems %ld, Remain %ld\n",
-             XGetAtomName(display, atype), aformat, cTargetPropList, remain);
-       wine_tsx11_unlock();
-
-       /*
-        * Make sure we got what we expect.
-        * NOTE: According to the X-ICCCM Version 2.0 documentation the property sent
-        * in a MULTIPLE selection request should be of type ATOM_PAIR.
-        * However some X apps(such as XPaint) are not compliant with this and return
-        * a user defined atom in atype when XGetWindowProperty is called.
-        * The data *is* an atom pair but is not denoted as such.
-        */
-       if(aformat == 32 /* atype == xAtomPair */ )
-       {
-          unsigned int i;
-
-          /* Iterate through the ATOM_PAIR list and execute a SelectionRequest
-           * for each (target,property) pair */
-
-          for (i = 0; i < cTargetPropList; i+=2)
-          {
-              XSelectionRequestEvent event;
-
-              if (TRACE_ON(event))
-              {
-                  char *targetName, *propName;
-                  wine_tsx11_lock();
-                  targetName = XGetAtomName(display, targetPropList[i]);
-                  propName = XGetAtomName(display, targetPropList[i+1]);
-                  TRACE("MULTIPLE(%d): Target='%s' Prop='%s'\n",
-                        i/2, targetName, propName);
-                  XFree(targetName);
-                  XFree(propName);
-                  wine_tsx11_unlock();
-              }
-
-              /* We must have a non "None" property to service a MULTIPLE target atom */
-              if ( !targetPropList[i+1] )
-              {
-                  TRACE("\tMULTIPLE(%d): Skipping target with empty property!\n", i);
-                  continue;
-              }
-
-              /* Set up an XSelectionRequestEvent for this (target,property) pair */
-              memcpy( &event, pevent, sizeof(XSelectionRequestEvent) );
-              event.target = targetPropList[i];
-              event.property = targetPropList[i+1];
-
-              /* Fire a SelectionRequest, informing the handler that we are processing
-               * a MULTIPLE selection request event.
-               */
-              EVENT_SelectionRequest( hWnd, &event, TRUE );
-          }
-       }
-
-       /* Free the list of targets/properties */
-       wine_tsx11_lock();
-       XFree(targetPropList);
-       wine_tsx11_unlock();
-    }
-
-END:
-    return rprop;
-}
-
-
-/***********************************************************************
- *           EVENT_SelectionRequest
- *  Process an event selection request event.
- *  The bIsMultiple flag is used to signal when EVENT_SelectionRequest is called
- *  recursively while servicing a "MULTIPLE" selection target.
- *
- *  Note: We only receive this event when WINE owns the X selection
- */
-static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple )
-{
-    Display *display = event->display;
-  XSelectionEvent result;
-  Atom 	          rprop = None;
-  Window          request = event->requestor;
-
-  TRACE_(clipboard)("\n");
-
-  /*
-   * We can only handle the selection request if :
-   * The selection is PRIMARY or CLIPBOARD, AND we can successfully open the clipboard.
-   * Don't do these checks or open the clipboard while recursively processing MULTIPLE,
-   * since this has been already done.
-   */
-  if ( !bIsMultiple )
-  {
-    if (((event->selection != XA_PRIMARY) && (event->selection != x11drv_atom(CLIPBOARD))))
-       goto END;
-  }
-
-  /* If the specified property is None the requestor is an obsolete client.
-   * We support these by using the specified target atom as the reply property.
-   */
-  rprop = event->property;
-  if( rprop == None )
-      rprop = event->target;
-
-  if(event->target == x11drv_atom(TARGETS))  /*  Return a list of all supported targets */
-  {
-      /* TARGETS selection request */
-      rprop = EVENT_SelectionRequest_TARGETS( display, request, event->target, rprop );
-  }
-  else if(event->target == x11drv_atom(MULTIPLE))  /*  rprop contains a list of (target, property) atom pairs */
-  {
-      /* MULTIPLE selection request */
-      rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
-  }
-  else
-  {
-      LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupProperty(event->target);
-
-      if (!lpFormat)
-          lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(event->target);
-
-      if (lpFormat && lpFormat->lpDrvExportFunc)
-      {
-          LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(lpFormat->wFormatID);
-
-          if (lpData)
-          {
-              unsigned char* lpClipData;
-              DWORD cBytes;
-              HANDLE hClipData = lpFormat->lpDrvExportFunc(request, event->target,
-                  rprop, lpData, &cBytes);
-
-              if (hClipData && (lpClipData = GlobalLock(hClipData)))
-              {
-                  TRACE_(clipboard)("\tUpdating property %s, %ld bytes\n",
-                                    debugstr_w(lpFormat->Name), cBytes);
-
-                  wine_tsx11_lock();
-                  XChangeProperty(display, request, rprop, event->target,
-                      8, PropModeReplace, (unsigned char *)lpClipData, cBytes);
-                  wine_tsx11_unlock();
-
-                  GlobalUnlock(hClipData);
-		  GlobalFree(hClipData);
-              }
-          }
-      }
-  }
-
-END:
-  /* reply to sender
-   * SelectionNotify should be sent only at the end of a MULTIPLE request
-   */
-  if ( !bIsMultiple )
-  {
-    result.type = SelectionNotify;
-    result.display = display;
-    result.requestor = request;
-    result.selection = event->selection;
-    result.property = rprop;
-    result.target = event->target;
-    result.time = event->time;
-    TRACE("Sending SelectionNotify event...\n");
-    wine_tsx11_lock();
-    XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
-    wine_tsx11_unlock();
-  }
-}
-
-/***********************************************************************
- *           EVENT_SelectionClear
- */
-static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
-{
-  if (event->selection == XA_PRIMARY || event->selection == x11drv_atom(CLIPBOARD))
-      X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd, event->time );
-}
-
-/***********************************************************************
  *           EVENT_PropertyNotify
  *   We use this to release resources like Pixmaps when a selection
  *   client no longer needs them.
diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h
index 7364595..65a368c 100644
--- a/dlls/x11drv/x11drv.h
+++ b/dlls/x11drv/x11drv.h
@@ -454,47 +454,6 @@
 
 #define x11drv_atom(name) (X11DRV_Atoms[XATOM_##name - FIRST_XATOM])
 
-/* X11 clipboard driver */
-
-typedef struct tagWINE_CLIPDATA {
-    UINT        wFormatID;
-    HANDLE16    hData16;
-    HANDLE      hData32;
-    UINT        drvData;
-    UINT        wFlags;
-    struct tagWINE_CLIPDATA *PrevData;
-    struct tagWINE_CLIPDATA *NextData;
-} WINE_CLIPDATA, *LPWINE_CLIPDATA;
-
-typedef HANDLE (*DRVEXPORTFUNC)(Window requestor, Atom aTarget, Atom rprop,
-    LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
-typedef HANDLE (*DRVIMPORTFUNC)(LPBYTE hData, UINT cBytes);
-
-typedef struct tagWINE_CLIPFORMAT {
-    UINT        wFormatID;
-    LPCWSTR     Name;
-    UINT        drvData;
-    UINT        wFlags;
-    DRVIMPORTFUNC  lpDrvImportFunc;
-    DRVEXPORTFUNC  lpDrvExportFunc;
-    struct tagWINE_CLIPFORMAT *PrevFormat;
-    struct tagWINE_CLIPFORMAT *NextFormat;
-} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
-
-#define CF_FLAG_BUILTINFMT   1 /* Built-in windows format */
-#define CF_FLAG_UNOWNED      2 /* cached data is not owned */
-#define CF_FLAG_SYNTHESIZED  8 /* Implicitly converted data */
-
-extern void X11DRV_InitClipboard(void);
-extern void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd, Time time);
-extern INT X11DRV_CountClipboardFormats(void);
-extern UINT X11DRV_EnumClipboardFormats(UINT wFormat);
-extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupFormat(WORD wID);
-extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupProperty(UINT drvData);
-extern LPWINE_CLIPDATA X11DRV_CLIPBOARD_LookupData(DWORD wID);
-extern UINT X11DRV_CLIPBOARD_LookupPropertyAlias(UINT drvDataProperty);
-extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupAliasProperty(UINT drvDataAlias);
-
 /* X11 event driver */
 
 typedef enum {
@@ -513,6 +472,8 @@
 extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
 extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
 extern void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
+extern void X11DRV_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event );
+extern void X11DRV_SelectionClear( HWND hWnd, XSelectionClearEvent *event );
 extern void X11DRV_MappingNotify( XMappingEvent *event );
 
 #ifdef HAVE_LIBXXF86DGA2
@@ -551,6 +512,7 @@
 /* X context to associate a hwnd to an X window */
 extern XContext winContext;
 
+extern void X11DRV_InitClipboard(void);
 extern void X11DRV_SetFocus( HWND hwnd );
 extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );