Moved more code to the X11 driver.
diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c
new file mode 100644
index 0000000..39c1f47
--- /dev/null
+++ b/windows/x11drv/clipboard.c
@@ -0,0 +1,299 @@
+/*
+ * X11 windows driver
+ *
+ * Copyright 1994 Martin Ayotte
+ * 1996 Alex Korobka
+ */
+
+#include "config.h"
+
+#ifndef X_DISPLAY_MISSING
+
+#include <X11/Xatom.h>
+#include "ts_xlib.h"
+
+#include "windows.h"
+#include "wintypes.h"
+
+#include "clipboard.h"
+#include "debug.h"
+#include "message.h"
+#include "win.h"
+#include "x11drv.h"
+
+extern HWND32 hWndClipOwner;
+extern HWND32 hWndClipWindow;
+extern CLIPFORMAT ClipFormats[];
+
+static Bool selectionWait = False;
+static Bool selectionAcquired = False;
+static Window selectionWindow = None;
+static Window selectionPrevWindow = None;
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_CheckSelection [Internal]
+ *
+ * Prevent X selection from being lost when a top level window is
+ * destroyed.
+ */
+static void X11DRV_CLIPBOARD_CheckSelection(WND* pWnd)
+{
+ TRACE(clipboard,"\tchecking %08x\n", (unsigned)pWnd->window);
+
+ if( selectionAcquired && selectionWindow != None &&
+ pWnd->window == selectionWindow )
+ {
+ selectionPrevWindow = selectionWindow;
+ selectionWindow = None;
+
+ if( pWnd->next )
+ selectionWindow = pWnd->next->window;
+ else if( pWnd->parent )
+ if( pWnd->parent->child != pWnd )
+ selectionWindow = pWnd->parent->child->window;
+
+ TRACE(clipboard,"\tswitching selection from %08x to %08x\n",
+ (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
+
+ if( selectionWindow != None )
+ {
+ TSXSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+ if( TSXGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
+ selectionWindow = None;
+ }
+ }
+}
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_ReadSelection
+ *
+ * Called from the SelectionNotify event handler.
+ */
+void X11DRV_CLIPBOARD_ReadSelection(Window w,Atom prop)
+{
+ HANDLE32 hText = 0;
+ LPCLIPFORMAT lpFormat = ClipFormats;
+
+ TRACE(clipboard,"ReadSelection callback\n");
+
+ if(prop != None)
+ {
+ Atom atype=AnyPropertyType;
+ int aformat;
+ unsigned long nitems,remain;
+ unsigned char* val=NULL;
+
+ TRACE(clipboard,"\tgot property %s\n",TSXGetAtomName(display,prop));
+
+ /* TODO: Properties longer than 64K */
+
+ if(TSXGetWindowProperty(display,w,prop,0,0x3FFF,True,XA_STRING,
+ &atype, &aformat, &nitems, &remain, &val) != Success)
+ WARN(clipboard, "\tcouldn't read property\n");
+ else
+ {
+ TRACE(clipboard,"\tType %s,Format %d,nitems %ld,value %s\n",
+ TSXGetAtomName(display,atype),aformat,nitems,val);
+
+ if(atype == XA_STRING && aformat == 8)
+ {
+ int i,inlcount = 0;
+ char* lpstr;
+
+ TRACE(clipboard,"\tselection is '%s'\n",val);
+
+ for(i=0; i <= nitems; i++)
+ if( val[i] == '\n' ) inlcount++;
+
+ if( nitems )
+ {
+ hText=GlobalAlloc32(GMEM_MOVEABLE, nitems + inlcount + 1);
+ if( (lpstr = (char*)GlobalLock32(hText)) )
+ for(i=0,inlcount=0; i <= nitems; i++)
+ {
+ if( val[i] == '\n' ) lpstr[inlcount++]='\r';
+ lpstr[inlcount++]=val[i];
+ }
+ else hText = 0;
+ }
+ }
+ TSXFree(val);
+ }
+ }
+
+ /* delete previous CF_TEXT and CF_OEMTEXT data */
+
+ if( hText )
+ {
+ lpFormat = &ClipFormats[CF_TEXT-1];
+ if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
+ CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
+ lpFormat = &ClipFormats[CF_OEMTEXT-1];
+ if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
+ CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
+
+ lpFormat->wDataPresent = 1;
+ lpFormat->hData32 = hText;
+ lpFormat->hData16 = 0;
+ }
+
+ selectionWait=False;
+}
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_ReleaseSelection
+ *
+ * Wine might have lost XA_PRIMARY selection because of
+ * EmptyClipboard() or other client.
+ */
+void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND32 hwnd)
+{
+ /* w is the window that lost selection,
+ *
+ * selectionPrevWindow is nonzero if CheckSelection() was called.
+ */
+
+ TRACE(clipboard,"\tevent->window = %08x (sw = %08x, spw=%08x)\n",
+ (unsigned)w, (unsigned)selectionWindow, (unsigned)selectionPrevWindow );
+
+ if( selectionAcquired )
+ {
+ if( w == selectionWindow || selectionPrevWindow == None)
+ {
+ /* alright, we really lost it */
+
+ selectionAcquired = False;
+ selectionWindow = None;
+
+ /* but we'll keep existing data for internal use */
+ }
+ else if( w == selectionPrevWindow )
+ {
+ w = TSXGetSelectionOwner(display, XA_PRIMARY);
+ if( w == None )
+ TSXSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+ }
+ }
+
+ selectionPrevWindow = None;
+}
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_EmptyClipboard
+ */
+void X11DRV_CLIPBOARD_EmptyClipboard()
+{
+ if(selectionAcquired)
+ {
+ selectionAcquired = False;
+ selectionPrevWindow = selectionWindow;
+ selectionWindow = None;
+
+ TRACE(clipboard, "\tgiving up selection (spw = %08x)\n",
+ (unsigned)selectionPrevWindow);
+
+ TSXSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
+ }
+}
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_SetClipboardData
+ */
+void X11DRV_CLIPBOARD_SetClipboardData(UINT32 wFormat)
+{
+ Window owner;
+
+ /* Acquire X selection if text format */
+
+ if( !selectionAcquired &&
+ (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
+ {
+ owner = X11DRV_WND_GetXWindow( hWndClipWindow ? hWndClipWindow : AnyPopup32() );
+
+ TSXSetSelectionOwner(display,XA_PRIMARY, owner, CurrentTime);
+ if( TSXGetSelectionOwner(display,XA_PRIMARY) == owner )
+ {
+ selectionAcquired = True;
+ selectionWindow = owner;
+
+ TRACE(clipboard,"Grabbed X selection, owner=(%08x)\n",
+ (unsigned) owner);
+ }
+ }
+}
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_RequestSelection
+ */
+BOOL32 X11DRV_CLIPBOARD_RequestSelection()
+{
+ HWND32 hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow32();
+
+ if( selectionAcquired )
+ return TRUE;
+
+ if( !hWnd ) return FALSE;
+
+ TRACE(clipboard,"Requesting selection...\n");
+
+ /* request data type XA_STRING, later
+ * CLIPBOARD_ReadSelection() will be invoked
+ * from the SelectionNotify event handler */
+
+ TSXConvertSelection(display,XA_PRIMARY,XA_STRING,
+ TSXInternAtom(display,"PRIMARY_TEXT",False),
+ X11DRV_WND_GetXWindow(hWnd),CurrentTime);
+
+ /* wait until SelectionNotify is processed
+ *
+ * FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the
+ * CLIPBOARD_CheckSelection() ).
+ */
+
+ selectionWait=True;
+ while(selectionWait) EVENT_WaitNetEvent( TRUE, FALSE );
+
+ /* we treat Unix text as CF_OEMTEXT */
+ TRACE(clipboard,"\tgot CF_OEMTEXT = %i\n",
+ ClipFormats[CF_OEMTEXT-1].wDataPresent);
+
+ return (BOOL32)ClipFormats[CF_OEMTEXT-1].wDataPresent;
+}
+
+/**************************************************************************
+ * X11DRV_CLIPBOARD_ResetOwner
+ *
+ * Called from DestroyWindow().
+ */
+void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd)
+{
+ LPCLIPFORMAT lpFormat = ClipFormats;
+
+ TRACE(clipboard,"clipboard owner = %04x, selection = %08x\n",
+ hWndClipOwner, (unsigned)selectionWindow);
+
+ if( pWnd->hwndSelf == hWndClipOwner)
+ {
+ SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
+
+ /* check if all formats were rendered */
+
+ while(lpFormat)
+ {
+ if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
+ {
+ TRACE(clipboard,"\tdata missing for clipboard format %i\n",
+ lpFormat->wFormatID);
+ lpFormat->wDataPresent = 0;
+ }
+ lpFormat = lpFormat->NextFormat;
+ }
+ hWndClipOwner = 0;
+ }
+
+ /* now try to salvage current selection from being destroyed by X */
+
+ if( pWnd->window ) X11DRV_CLIPBOARD_CheckSelection(pWnd);
+}
+
+#endif /* !defined(X_DISPLAY_MISSING) */