Moved more things to the X11 driver.
[wine/dcerpc.git] / windows / x11drv / clipboard.c
blob7d987378c42814768da6dcde0625159e7c8e9e20
1 /*
2 * X11 windows driver
4 * Copyright 1994 Martin Ayotte
5 * 1996 Alex Korobka
6 */
8 #include "config.h"
10 #ifndef X_DISPLAY_MISSING
12 #include <X11/Xatom.h>
13 #include "ts_xlib.h"
15 #include "windows.h"
16 #include "wintypes.h"
18 #include "clipboard.h"
19 #include "debug.h"
20 #include "message.h"
21 #include "win.h"
22 #include "x11drv.h"
24 extern HWND32 hWndClipOwner;
25 extern HWND32 hWndClipWindow;
26 extern CLIPFORMAT ClipFormats[];
28 static Bool selectionWait = False;
29 static Bool selectionAcquired = False;
30 static Window selectionWindow = None;
31 static Window selectionPrevWindow = None;
33 /**************************************************************************
34 * X11DRV_CLIPBOARD_CheckSelection [Internal]
36 * Prevent X selection from being lost when a top level window is
37 * destroyed.
39 static void X11DRV_CLIPBOARD_CheckSelection(WND* pWnd)
41 TRACE(clipboard,"\tchecking %08x\n",
42 (unsigned) X11DRV_WND_GetXWindow(pWnd)
45 if( selectionAcquired && selectionWindow != None &&
46 X11DRV_WND_GetXWindow(pWnd) == selectionWindow )
48 selectionPrevWindow = selectionWindow;
49 selectionWindow = None;
51 if( pWnd->next )
52 selectionWindow = X11DRV_WND_GetXWindow(pWnd->next);
53 else if( pWnd->parent )
54 if( pWnd->parent->child != pWnd )
55 selectionWindow = X11DRV_WND_GetXWindow(pWnd->parent->child);
57 TRACE(clipboard,"\tswitching selection from %08x to %08x\n",
58 (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
60 if( selectionWindow != None )
62 TSXSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
63 if( TSXGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
64 selectionWindow = None;
69 /**************************************************************************
70 * X11DRV_CLIPBOARD_ReadSelection
72 * Called from the SelectionNotify event handler.
74 void X11DRV_CLIPBOARD_ReadSelection(Window w,Atom prop)
76 HANDLE32 hText = 0;
77 LPCLIPFORMAT lpFormat = ClipFormats;
79 TRACE(clipboard,"ReadSelection callback\n");
81 if(prop != None)
83 Atom atype=AnyPropertyType;
84 int aformat;
85 unsigned long nitems,remain;
86 unsigned char* val=NULL;
88 TRACE(clipboard,"\tgot property %s\n",TSXGetAtomName(display,prop));
90 /* TODO: Properties longer than 64K */
92 if(TSXGetWindowProperty(display,w,prop,0,0x3FFF,True,XA_STRING,
93 &atype, &aformat, &nitems, &remain, &val) != Success)
94 WARN(clipboard, "\tcouldn't read property\n");
95 else
97 TRACE(clipboard,"\tType %s,Format %d,nitems %ld,value %s\n",
98 TSXGetAtomName(display,atype),aformat,nitems,val);
100 if(atype == XA_STRING && aformat == 8)
102 int i,inlcount = 0;
103 char* lpstr;
105 TRACE(clipboard,"\tselection is '%s'\n",val);
107 for(i=0; i <= nitems; i++)
108 if( val[i] == '\n' ) inlcount++;
110 if( nitems )
112 hText=GlobalAlloc32(GMEM_MOVEABLE, nitems + inlcount + 1);
113 if( (lpstr = (char*)GlobalLock32(hText)) )
114 for(i=0,inlcount=0; i <= nitems; i++)
116 if( val[i] == '\n' ) lpstr[inlcount++]='\r';
117 lpstr[inlcount++]=val[i];
119 else hText = 0;
122 TSXFree(val);
126 /* delete previous CF_TEXT and CF_OEMTEXT data */
128 if( hText )
130 lpFormat = &ClipFormats[CF_TEXT-1];
131 if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
132 CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
133 lpFormat = &ClipFormats[CF_OEMTEXT-1];
134 if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32)
135 CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow));
137 lpFormat->wDataPresent = 1;
138 lpFormat->hData32 = hText;
139 lpFormat->hData16 = 0;
142 selectionWait=False;
145 /**************************************************************************
146 * X11DRV_CLIPBOARD_ReleaseSelection
148 * Wine might have lost XA_PRIMARY selection because of
149 * EmptyClipboard() or other client.
151 void X11DRV_CLIPBOARD_ReleaseSelection(Window w, HWND32 hwnd)
153 /* w is the window that lost selection,
155 * selectionPrevWindow is nonzero if CheckSelection() was called.
158 TRACE(clipboard,"\tevent->window = %08x (sw = %08x, spw=%08x)\n",
159 (unsigned)w, (unsigned)selectionWindow, (unsigned)selectionPrevWindow );
161 if( selectionAcquired )
163 if( w == selectionWindow || selectionPrevWindow == None)
165 /* alright, we really lost it */
167 selectionAcquired = False;
168 selectionWindow = None;
170 /* but we'll keep existing data for internal use */
172 else if( w == selectionPrevWindow )
174 w = TSXGetSelectionOwner(display, XA_PRIMARY);
175 if( w == None )
176 TSXSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
180 selectionPrevWindow = None;
183 /**************************************************************************
184 * X11DRV_CLIPBOARD_EmptyClipboard
186 void X11DRV_CLIPBOARD_EmptyClipboard()
188 if(selectionAcquired)
190 selectionAcquired = False;
191 selectionPrevWindow = selectionWindow;
192 selectionWindow = None;
194 TRACE(clipboard, "\tgiving up selection (spw = %08x)\n",
195 (unsigned)selectionPrevWindow);
197 TSXSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
201 /**************************************************************************
202 * X11DRV_CLIPBOARD_SetClipboardData
204 void X11DRV_CLIPBOARD_SetClipboardData(UINT32 wFormat)
206 Window owner;
208 /* Acquire X selection if text format */
210 if( !selectionAcquired &&
211 (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
213 owner = X11DRV_WND_FindXWindow(
214 WIN_FindWndPtr( hWndClipWindow ? hWndClipWindow : AnyPopup32() )
217 TSXSetSelectionOwner(display,XA_PRIMARY, owner, CurrentTime);
218 if( TSXGetSelectionOwner(display,XA_PRIMARY) == owner )
220 selectionAcquired = True;
221 selectionWindow = owner;
223 TRACE(clipboard,"Grabbed X selection, owner=(%08x)\n",
224 (unsigned) owner);
229 /**************************************************************************
230 * X11DRV_CLIPBOARD_RequestSelection
232 BOOL32 X11DRV_CLIPBOARD_RequestSelection()
234 HWND32 hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow32();
236 if( selectionAcquired )
237 return TRUE;
239 if( !hWnd ) return FALSE;
241 TRACE(clipboard,"Requesting selection...\n");
243 /* request data type XA_STRING, later
244 * CLIPBOARD_ReadSelection() will be invoked
245 * from the SelectionNotify event handler */
247 TSXConvertSelection(display, XA_PRIMARY, XA_STRING,
248 TSXInternAtom(display, "PRIMARY_TEXT", False),
249 X11DRV_WND_FindXWindow( WIN_FindWndPtr( hWnd ) ),
250 CurrentTime);
252 /* wait until SelectionNotify is processed
254 * FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the
255 * CLIPBOARD_CheckSelection() ).
258 selectionWait=True;
259 while(selectionWait) EVENT_WaitNetEvent( TRUE, FALSE );
261 /* we treat Unix text as CF_OEMTEXT */
262 TRACE(clipboard,"\tgot CF_OEMTEXT = %i\n",
263 ClipFormats[CF_OEMTEXT-1].wDataPresent);
265 return (BOOL32)ClipFormats[CF_OEMTEXT-1].wDataPresent;
268 /**************************************************************************
269 * X11DRV_CLIPBOARD_ResetOwner
271 * Called from DestroyWindow().
273 void X11DRV_CLIPBOARD_ResetOwner(WND *pWnd, BOOL32 bFooBar)
275 LPCLIPFORMAT lpFormat = ClipFormats;
277 if(bFooBar && X11DRV_WND_GetXWindow(pWnd))
278 return;
280 if(!bFooBar && !X11DRV_WND_GetXWindow(pWnd))
281 return;
283 TRACE(clipboard,"clipboard owner = %04x, selection = %08x\n",
284 hWndClipOwner, (unsigned)selectionWindow);
286 if( pWnd->hwndSelf == hWndClipOwner)
288 SendMessage16(hWndClipOwner,WM_RENDERALLFORMATS,0,0L);
290 /* check if all formats were rendered */
292 while(lpFormat)
294 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
296 TRACE(clipboard,"\tdata missing for clipboard format %i\n",
297 lpFormat->wFormatID);
298 lpFormat->wDataPresent = 0;
300 lpFormat = lpFormat->NextFormat;
302 hWndClipOwner = 0;
305 /* now try to salvage current selection from being destroyed by X */
307 if( X11DRV_WND_GetXWindow(pWnd) ) X11DRV_CLIPBOARD_CheckSelection(pWnd);
310 #endif /* !defined(X_DISPLAY_MISSING) */