INT21_GetFreeDiskSpace(): The drive parameter is found in the DL
[wine] / dlls / x11drv / clipboard.c
1 /*
2  * X11 clipboard windows driver
3  *
4  * Copyright 1994 Martin Ayotte
5  *           1996 Alex Korobka
6  *           1999 Noel Borthwick
7  *           2003 Ulrich Czekalla for CodeWeavers
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  * NOTES:
24  *    This file contains the X specific implementation for the windows
25  *    Clipboard API.
26  *
27  *    Wine's internal clipboard is exposed to external apps via the X
28  *    selection mechanism.
29  *    Currently the driver asserts ownership via two selection atoms:
30  *    1. PRIMARY(XA_PRIMARY)
31  *    2. CLIPBOARD
32  *
33  *    In our implementation, the CLIPBOARD selection takes precedence over PRIMARY,
34  *    i.e. if a CLIPBOARD selection is available, it is used instead of PRIMARY.
35  *    When Wine takes ownership of the clipboard, it takes ownership of BOTH selections.
36  *    While giving up selection ownership, if the CLIPBOARD selection is lost,
37  *    it will lose both PRIMARY and CLIPBOARD and empty the clipboard.
38  *    However if only PRIMARY is lost, it will continue to hold the CLIPBOARD selection
39  *    (leaving the clipboard cache content unaffected).
40  *
41  *      Every format exposed via a windows clipboard format is also exposed through
42  *    a corresponding X selection target. A selection target atom is synthesized
43  *    whenever a new Windows clipboard format is registered via RegisterClipboardFormat,
44  *    or when a built-in format is used for the first time.
45  *    Windows native format are exposed by prefixing the format name with "<WCF>"
46  *    This allows us to uniquely identify windows native formats exposed by other
47  *    running WINE apps.
48  *
49  *      In order to allow external applications to query WINE for supported formats,
50  *    we respond to the "TARGETS" selection target. (See EVENT_SelectionRequest
51  *    for implementation) We use the same mechanism to query external clients for
52  *    availability of a particular format, by caching the list of available targets
53  *    by using the clipboard cache's "delayed render" mechanism. If a selection client
54  *    does not support the "TARGETS" selection target, we actually attempt to retrieve
55  *    the format requested as a fallback mechanism.
56  *
57  *      Certain Windows native formats are automatically converted to X native formats
58  *    and vice versa. If a native format is available in the selection, it takes
59  *    precedence, in order to avoid unnecessary conversions.
60  *
61  * FIXME: global format list needs a critical section
62  */
63
64 #include "config.h"
65
66 #include <string.h>
67 #include <stdarg.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #ifdef HAVE_UNISTD_H
71 # include <unistd.h>
72 #endif
73 #include <fcntl.h>
74 #include <time.h>
75
76 #include "windef.h"
77 #include "winbase.h"
78 #include "winreg.h"
79 #include "clipboard.h"
80 #include "win.h"
81 #include "x11drv.h"
82 #include "wine/debug.h"
83 #include "wine/unicode.h"
84 #include "wine/server.h"
85
86 WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
87
88 #define HGDIOBJ_32(handle16)  ((HGDIOBJ)(ULONG_PTR)(handle16))
89
90 /* Maximum wait time for selection notify */
91 #define SELECTION_RETRIES 500  /* wait for .1 seconds */
92 #define SELECTION_WAIT    1000 /* us */
93 /* Minimum seconds that must lapse between owner queries */
94 #define OWNERQUERYLAPSETIME 1
95
96 /* Selection masks */
97 #define S_NOSELECTION    0
98 #define S_PRIMARY        1
99 #define S_CLIPBOARD      2
100
101 static int selectionAcquired = 0;              /* Contains the current selection masks */
102 static Window selectionWindow = None;          /* The top level X window which owns the selection */
103 static BOOL clearAllSelections = FALSE;        /* Always lose all selections */
104 static Atom selectionCacheSrc = XA_PRIMARY;    /* The selection source from which the clipboard cache was filled */
105 static Window PrimarySelectionOwner = None;    /* The window which owns the primary selection */
106 static Window ClipboardSelectionOwner = None;  /* The window which owns the clipboard selection */
107
108 INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName);
109 void X11DRV_EmptyClipboard(void);
110 void X11DRV_EndClipboardUpdate(void);
111 HANDLE X11DRV_CLIPBOARD_ImportClipboardData(LPBYTE lpdata, UINT cBytes);
112 HANDLE X11DRV_CLIPBOARD_ImportEnhMetaFile(LPBYTE lpdata, UINT cBytes);
113 HANDLE X11DRV_CLIPBOARD_ImportMetaFilePict(LPBYTE lpdata, UINT cBytes);
114 HANDLE X11DRV_CLIPBOARD_ImportXAPIXMAP(LPBYTE lpdata, UINT cBytes);
115 HANDLE X11DRV_CLIPBOARD_ImportXAString(LPBYTE lpdata, UINT cBytes);
116 HANDLE X11DRV_CLIPBOARD_ExportClipboardData(Window requestor, Atom aTarget,
117     Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
118 HANDLE X11DRV_CLIPBOARD_ExportString(Window requestor, Atom aTarget,
119     Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
120 HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget,
121     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
122 HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget,
123     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
124 HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget,
125     Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
126 static WINE_CLIPFORMAT *X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop);
127 static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, Atom prop);
128 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID);
129 static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
130 static BOOL X11DRV_CLIPBOARD_IsSelectionOwner(void);
131 static int X11DRV_CLIPBOARD_QueryAvailableData(LPCLIPBOARDINFO lpcbinfo);
132 static BOOL X11DRV_CLIPBOARD_ReadClipboardData(UINT wFormat);
133 static BOOL X11DRV_CLIPBOARD_RenderFormat(LPWINE_CLIPDATA lpData);
134 static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDWORD lpcbytes, BOOL out);
135 static BOOL X11DRV_CLIPBOARD_SynthesizeData(UINT wFormatID);
136 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData);
137
138 /* Clipboard formats
139  * WARNING: This data ordering is dependent on the WINE_CLIPFORMAT structure
140  * declared in clipboard.h
141  */
142 static WINE_CLIPFORMAT ClipFormats[]  =
143 {
144     { CF_TEXT, "WCF_TEXT",  0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
145         X11DRV_CLIPBOARD_ExportClipboardData, NULL, &ClipFormats[1]},
146
147     { CF_BITMAP, "WCF_BITMAP", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
148         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[0], &ClipFormats[2]},
149
150     { CF_METAFILEPICT, "WCF_METAFILEPICT", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportMetaFilePict,
151         X11DRV_CLIPBOARD_ExportMetaFilePict, &ClipFormats[1], &ClipFormats[3]},
152
153     { CF_SYLK, "WCF_SYLK", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
154         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[2], &ClipFormats[4]},
155
156     { CF_DIF, "WCF_DIF", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
157         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[3], &ClipFormats[5]},
158
159     { CF_TIFF, "WCF_TIFF", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
160         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[4], &ClipFormats[6]},
161
162     { CF_OEMTEXT, "WCF_OEMTEXT", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
163         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[5], &ClipFormats[7]},
164
165     { CF_DIB, "WCF_DIB", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportXAPIXMAP,
166         X11DRV_CLIPBOARD_ExportXAPIXMAP, &ClipFormats[6], &ClipFormats[8]},
167
168     { CF_PALETTE, "WCF_PALETTE", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
169         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[7], &ClipFormats[9]},
170
171     { CF_PENDATA, "WCF_PENDATA", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
172         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[8], &ClipFormats[10]},
173
174     { CF_RIFF, "WCF_RIFF", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
175         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[9], &ClipFormats[11]},
176
177     { CF_WAVE, "WCF_WAVE", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
178         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[10], &ClipFormats[12]},
179
180     { CF_UNICODETEXT, "WCF_UNICODETEXT", XA_STRING, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportXAString,
181         X11DRV_CLIPBOARD_ExportString, &ClipFormats[11], &ClipFormats[13]},
182
183     { CF_ENHMETAFILE, "WCF_ENHMETAFILE", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportEnhMetaFile,
184         X11DRV_CLIPBOARD_ExportEnhMetaFile, &ClipFormats[12], &ClipFormats[14]},
185
186     { CF_HDROP, "WCF_HDROP", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
187         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[13], &ClipFormats[15]},
188
189     { CF_LOCALE, "WCF_LOCALE", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
190         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[14], &ClipFormats[16]},
191
192     { CF_DIBV5, "WCF_DIBV5", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
193         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[15], &ClipFormats[17]},
194
195     { CF_OWNERDISPLAY, "WCF_OWNERDISPLAY", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
196         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[16], &ClipFormats[18]},
197
198     { CF_DSPTEXT, "WCF_DSPTEXT", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
199         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[17], &ClipFormats[19]},
200
201     { CF_DSPBITMAP, "WCF_DSPBITMAP", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
202         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[18], &ClipFormats[20]},
203
204     { CF_DSPMETAFILEPICT, "WCF_DSPMETAFILEPICT", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
205         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[19], &ClipFormats[21]},
206
207     { CF_DSPENHMETAFILE, "WCF_DSPENHMETAFILE", 0, CF_FLAG_BUILTINFMT, X11DRV_CLIPBOARD_ImportClipboardData,
208         X11DRV_CLIPBOARD_ExportClipboardData, &ClipFormats[20], NULL}
209 };
210
211 #define GET_ATOM(prop)  (((prop) < FIRST_XATOM) ? (Atom)(prop) : X11DRV_Atoms[(prop) - FIRST_XATOM])
212
213 /* Maps X properties to Windows formats */
214 static const struct
215 {
216     LPCSTR lpszFormat;
217     UINT   prop;
218 } PropertyFormatMap[] =
219 {
220     { "Rich Text Format", XATOM_text_rtf },
221     /* Temporarily disable text/html because Evolution incorrectly pastes strings with extra nulls */
222     /*{ "text/html", "HTML Format" },*/
223     { "GIF", XATOM_image_gif }
224 };
225
226
227 /* Maps equivalent X properties. It is assumed that lpszProperty must already 
228    be in ClipFormats or PropertyFormatMap. */
229 static const struct
230 {
231     UINT drvDataProperty;
232     UINT drvDataAlias;
233 } PropertyAliasMap[] =
234 {
235     /* DataProperty,   DataAlias */
236     { XATOM_text_rtf,  XATOM_text_richtext },
237     { XA_STRING,       XATOM_COMPOUND_TEXT },
238     { XA_STRING,       XATOM_TEXT },
239 };
240
241
242 /*
243  * Cached clipboard data.
244  */
245 static LPWINE_CLIPDATA ClipData = NULL;
246 static UINT ClipDataCount = 0;
247
248 /*
249  * Clipboard sequence number
250  */
251 static UINT wSeqNo = 0;
252
253 /**************************************************************************
254  *                Internal Clipboard implementation methods
255  **************************************************************************/
256
257 /**************************************************************************
258  *              X11DRV_InitClipboard
259  */
260 void X11DRV_InitClipboard(void)
261 {
262     INT i;
263     HKEY hkey;
264
265     if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Clipboard", &hkey))
266     {
267         char buffer[20];
268         DWORD type, count = sizeof(buffer);
269         if(!RegQueryValueExA(hkey, "ClearAllSelections", 0, &type, buffer, &count))
270             clearAllSelections = atoi(buffer);
271         RegCloseKey(hkey);
272     }
273
274     /* Register known mapping between window formats and X properties */
275     for (i = 0; i < sizeof(PropertyFormatMap)/sizeof(PropertyFormatMap[0]); i++)
276         X11DRV_CLIPBOARD_InsertClipboardFormat(PropertyFormatMap[i].lpszFormat,
277                                                GET_ATOM(PropertyFormatMap[i].prop));
278 }
279
280
281 /**************************************************************************
282  *                intern_atoms
283  *
284  * Intern atoms for formats that don't have one yet.
285  */
286 static void intern_atoms(void)
287 {
288     LPWINE_CLIPFORMAT format;
289     int i, count;
290     char **names;
291     Atom *atoms;
292
293     for (format = ClipFormats, count = 0; format; format = format->NextFormat)
294         if (!format->drvData) count++;
295     if (!count) return;
296
297     names = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*names) );
298     atoms = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*atoms) );
299
300     for (format = ClipFormats, i = 0; format; format = format->NextFormat)
301         if (!format->drvData) names[i++] = format->Name;
302
303     wine_tsx11_lock();
304     XInternAtoms( thread_display(), names, count, False, atoms );
305     wine_tsx11_unlock();
306
307     for (format = ClipFormats, i = 0; format; format = format->NextFormat)
308         if (!format->drvData) format->drvData = atoms[i];
309
310     HeapFree( GetProcessHeap(), 0, names );
311     HeapFree( GetProcessHeap(), 0, atoms );
312 }
313
314
315 /**************************************************************************
316  *              register_format
317  *
318  * Register a custom X clipboard format.
319  */
320 static WINE_CLIPFORMAT *register_format( LPCSTR FormatName, Atom prop )
321 {
322     LPWINE_CLIPFORMAT lpFormat = ClipFormats;
323
324     TRACE("'%s'\n", FormatName);
325
326     /* walk format chain to see if it's already registered */
327     while (lpFormat)
328     {
329         if ( !strcasecmp(lpFormat->Name, FormatName) && 
330              (lpFormat->wFlags & CF_FLAG_BUILTINFMT) == 0)
331              return lpFormat;
332         lpFormat = lpFormat->NextFormat;
333     }
334
335     return X11DRV_CLIPBOARD_InsertClipboardFormat(FormatName, prop);
336 }
337
338
339 /**************************************************************************
340  *                X11DRV_CLIPBOARD_LookupFormat
341  */
342 LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupFormat(WORD wID)
343 {
344     LPWINE_CLIPFORMAT lpFormat = ClipFormats;
345
346     while(lpFormat)
347     {
348         if (lpFormat->wFormatID == wID) 
349             break;
350
351         lpFormat = lpFormat->NextFormat;
352     }
353     if (!lpFormat->drvData) intern_atoms();
354     return lpFormat;
355 }
356
357
358 /**************************************************************************
359  *                X11DRV_CLIPBOARD_LookupProperty
360  */
361 LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupProperty(UINT drvData)
362 {
363     for (;;)
364     {
365         LPWINE_CLIPFORMAT lpFormat = ClipFormats;
366         BOOL need_intern = FALSE;
367
368         while(lpFormat)
369         {
370             if (lpFormat->drvData == drvData) return lpFormat;
371             if (!lpFormat->drvData) need_intern = TRUE;
372             lpFormat = lpFormat->NextFormat;
373         }
374         if (!need_intern) return NULL;
375         intern_atoms();
376         /* restart the search for the new atoms */
377     }
378 }
379
380
381 /**************************************************************************
382  *                X11DRV_CLIPBOARD_LookupAliasProperty
383  */
384 LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupAliasProperty(UINT drvDataAlias)
385 {
386     unsigned int i;
387     LPWINE_CLIPFORMAT lpFormat = NULL;
388
389     for (i = 0; i < sizeof(PropertyAliasMap)/sizeof(PropertyAliasMap[0]); i++)
390     {
391         if (GET_ATOM(PropertyAliasMap[i].drvDataAlias) == drvDataAlias)
392         {
393             lpFormat = X11DRV_CLIPBOARD_LookupProperty(GET_ATOM(PropertyAliasMap[i].drvDataProperty));
394             break;
395         }
396    }
397
398     return lpFormat;
399 }
400
401
402 /**************************************************************************
403  *                X11DRV_CLIPBOARD_LookupPropertyAlias
404  */
405 UINT  X11DRV_CLIPBOARD_LookupPropertyAlias(UINT drvDataProperty)
406 {
407     unsigned int i;
408     UINT alias = 0;
409
410     for (i = 0; i < sizeof(PropertyAliasMap)/sizeof(PropertyAliasMap[0]); i++)
411     {
412         if (GET_ATOM(PropertyAliasMap[i].drvDataProperty) == drvDataProperty)
413         {
414             alias = GET_ATOM(PropertyAliasMap[i].drvDataAlias);
415             break;
416         }
417    }
418
419     return alias;
420 }
421
422
423 /**************************************************************************
424  *               X11DRV_CLIPBOARD_LookupData
425  */
426 LPWINE_CLIPDATA X11DRV_CLIPBOARD_LookupData(DWORD wID)
427 {
428     LPWINE_CLIPDATA lpData = ClipData;
429
430     if (lpData)
431     {
432         do
433         {
434             if (lpData->wFormatID == wID) 
435                 break;
436
437             lpData = lpData->NextData;
438         }
439         while(lpData != ClipData);
440
441         if (lpData->wFormatID != wID)
442             lpData = NULL;
443     }
444
445     return lpData;
446 }
447
448
449 /**************************************************************************
450  *              InsertClipboardFormat
451  */
452 static WINE_CLIPFORMAT *X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop)
453 {
454     LPWINE_CLIPFORMAT lpFormat;
455     LPWINE_CLIPFORMAT lpNewFormat;
456    
457     /* allocate storage for new format entry */
458     lpNewFormat = (LPWINE_CLIPFORMAT) HeapAlloc(GetProcessHeap(), 
459         0, sizeof(WINE_CLIPFORMAT));
460
461     if(lpNewFormat == NULL) 
462     {
463         WARN("No more memory for a new format!\n");
464         return NULL;
465     }
466
467     if (!(lpNewFormat->Name = HeapAlloc(GetProcessHeap(), 0, strlen(FormatName)+1)))
468     {
469         WARN("No more memory for the new format name!\n");
470         HeapFree(GetProcessHeap(), 0, lpNewFormat);
471         return NULL;
472     }
473
474     strcpy(lpNewFormat->Name, FormatName);
475     lpNewFormat->wFlags = 0;
476     lpNewFormat->wFormatID = GlobalAddAtomA(lpNewFormat->Name);
477     lpNewFormat->drvData = prop;
478     lpNewFormat->lpDrvImportFunc = X11DRV_CLIPBOARD_ImportClipboardData;
479     lpNewFormat->lpDrvExportFunc = X11DRV_CLIPBOARD_ExportClipboardData;
480
481     /* Link Format */
482     lpFormat = ClipFormats;
483
484     while(lpFormat->NextFormat) /* Move to last entry */
485         lpFormat = lpFormat->NextFormat;
486
487     lpNewFormat->NextFormat = NULL;
488     lpFormat->NextFormat = lpNewFormat;
489     lpNewFormat->PrevFormat = lpFormat;
490
491     TRACE("Registering format(%d): %s drvData %d\n",
492         lpNewFormat->wFormatID, FormatName, lpNewFormat->drvData);
493
494     return lpNewFormat;
495 }
496
497
498
499
500 /**************************************************************************
501  *                      X11DRV_CLIPBOARD_GetClipboardInfo
502  */
503 static BOOL X11DRV_CLIPBOARD_GetClipboardInfo(LPCLIPBOARDINFO cbInfo)
504 {
505     BOOL bRet = FALSE;
506
507     SERVER_START_REQ( set_clipboard_info )
508     {
509         req->flags = 0;
510
511         if (wine_server_call_err( req ))
512         {
513             ERR("Failed to get clipboard owner.\n");
514         }
515         else
516         {
517             cbInfo->hWndOpen = reply->old_clipboard;
518             cbInfo->hWndOwner = reply->old_owner;
519             cbInfo->hWndViewer = reply->old_viewer;
520             cbInfo->seqno = reply->seqno;
521             cbInfo->flags = reply->flags;
522
523             bRet = TRUE;
524         }
525     }
526     SERVER_END_REQ;
527
528     return bRet;
529 }
530
531
532 /**************************************************************************
533  *      X11DRV_CLIPBOARD_ReleaseOwnership
534  */
535 static BOOL X11DRV_CLIPBOARD_ReleaseOwnership(void)
536 {
537     BOOL bRet = FALSE;
538
539     SERVER_START_REQ( set_clipboard_info )
540     {
541         req->flags = SET_CB_RELOWNER | SET_CB_SEQNO;
542
543         if (wine_server_call_err( req ))
544         {
545             ERR("Failed to set clipboard.\n");
546         }
547         else
548         {
549             bRet = TRUE;
550         }
551     }
552     SERVER_END_REQ;
553
554     return bRet;
555 }
556
557
558
559 /**************************************************************************
560  *                      X11DRV_CLIPBOARD_InsertClipboardData
561  *
562  * Caller *must* have the clipboard open and be the owner.
563  */
564 static BOOL X11DRV_CLIPBOARD_InsertClipboardData(UINT wFormat, HANDLE16 hData16, HANDLE hData32, DWORD flags)
565 {
566     LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(wFormat);
567
568     TRACE("format=%d lpData=%p hData16=%08x hData32=%08x flags=0x%08lx\n", 
569         wFormat, lpData, hData16, (unsigned int)hData32, flags);
570
571     if (lpData)
572     {
573         X11DRV_CLIPBOARD_FreeData(lpData);
574
575         lpData->hData16 = hData16;  /* 0 is legal, see WM_RENDERFORMAT */
576         lpData->hData32 = hData32;
577     }
578     else
579     {
580         lpData = (LPWINE_CLIPDATA) HeapAlloc(GetProcessHeap(), 
581             0, sizeof(WINE_CLIPDATA));
582
583         lpData->wFormatID = wFormat;
584         lpData->hData16 = hData16;  /* 0 is legal, see WM_RENDERFORMAT */
585         lpData->hData32 = hData32;
586
587         if (ClipData)
588         {
589             LPWINE_CLIPDATA lpPrevData = ClipData->PrevData;
590
591             lpData->PrevData = lpPrevData;
592             lpData->NextData = ClipData;
593
594             lpPrevData->NextData = lpData;
595             ClipData->PrevData = lpData;
596         }
597         else
598         {
599             lpData->NextData = lpData;
600             lpData->PrevData = lpData;
601             ClipData = lpData;
602         }
603
604         ClipDataCount++;
605     }
606
607     lpData->wFlags = flags;
608
609     return TRUE;
610 }
611
612
613 /**************************************************************************
614  *                      X11DRV_CLIPBOARD_FreeData
615  *
616  * Free clipboard data handle.
617  */
618 static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
619 {
620     TRACE("%d\n", lpData->wFormatID);
621
622     if ((lpData->wFormatID >= CF_GDIOBJFIRST &&
623         lpData->wFormatID <= CF_GDIOBJLAST) || 
624         lpData->wFormatID == CF_BITMAP || 
625         lpData->wFormatID == CF_DIB || 
626         lpData->wFormatID == CF_PALETTE)
627     {
628       if (lpData->hData32)
629         DeleteObject(lpData->hData32);
630
631       if (lpData->hData16)
632         DeleteObject(HGDIOBJ_32(lpData->hData16));
633     }
634     else if (lpData->wFormatID == CF_METAFILEPICT)
635     {
636       if (lpData->hData32)
637       {
638         DeleteMetaFile(((METAFILEPICT *)GlobalLock( lpData->hData32 ))->hMF );
639         GlobalFree(lpData->hData32);
640
641         if (lpData->hData16)
642           /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
643              and a shallow copy is enough to share a METAFILEPICT
644              structure between 16bit and 32bit clipboards.  The MetaFile
645              should of course only be deleted once. */
646           GlobalFree16(lpData->hData16);
647       }
648
649       if (lpData->hData16)
650       {
651         METAFILEPICT16* lpMetaPict = (METAFILEPICT16 *) GlobalLock16(lpData->hData16);
652
653         if (lpMetaPict)
654         {
655             DeleteMetaFile16(lpMetaPict->hMF);
656             lpMetaPict->hMF = 0;
657         }
658
659         GlobalFree16(lpData->hData16);
660       }
661     }
662     else if (lpData->wFormatID == CF_ENHMETAFILE)
663     {
664         if (lpData->hData32)
665             DeleteEnhMetaFile(lpData->hData32);
666     }
667     else if (lpData->wFormatID < CF_PRIVATEFIRST ||
668              lpData->wFormatID > CF_PRIVATELAST)
669     {
670       if (lpData->hData32)
671         GlobalFree(lpData->hData32);
672
673       if (lpData->hData16)
674         GlobalFree16(lpData->hData16);
675     }
676
677     lpData->hData16 = 0;
678     lpData->hData32 = 0;
679 }
680
681
682 /**************************************************************************
683  *                      X11DRV_CLIPBOARD_UpdateCache
684  */
685 static BOOL X11DRV_CLIPBOARD_UpdateCache(LPCLIPBOARDINFO lpcbinfo)
686 {
687     BOOL bret = TRUE;
688
689     if (!X11DRV_CLIPBOARD_IsSelectionOwner())
690     {
691         if (!X11DRV_CLIPBOARD_GetClipboardInfo(lpcbinfo))
692         {
693             ERR("Failed to retrieve clipboard information.\n");
694             bret = FALSE;
695         }
696         else if (wSeqNo < lpcbinfo->seqno)
697         {
698             X11DRV_EmptyClipboard();
699
700             if (X11DRV_CLIPBOARD_QueryAvailableData(lpcbinfo) < 0)
701             {
702                 ERR("Failed to cache clipboard data owned by another process.\n");
703                 bret = FALSE;
704             }
705             else
706             {
707                 X11DRV_EndClipboardUpdate();
708             }
709
710             wSeqNo = lpcbinfo->seqno;
711         }
712     }
713
714     return bret;
715 }
716
717
718 /**************************************************************************
719  *                      X11DRV_CLIPBOARD_RenderFormat
720  */
721 static BOOL X11DRV_CLIPBOARD_RenderFormat(LPWINE_CLIPDATA lpData)
722 {
723     BOOL bret = TRUE;
724
725     TRACE(" 0x%04x hData32(0x%08x) hData16(0x%08x)\n", 
726         lpData->wFormatID, (unsigned int)lpData->hData32, lpData->hData16);
727
728     if (lpData->hData32 || lpData->hData16)
729         return bret; /* Already rendered */
730
731     if (lpData->wFlags & CF_FLAG_SYNTHESIZED)
732         bret = X11DRV_CLIPBOARD_RenderSynthesizedFormat(lpData);
733     else if (!X11DRV_CLIPBOARD_IsSelectionOwner())
734     {
735         if (!X11DRV_CLIPBOARD_ReadClipboardData(lpData->wFormatID))
736         {
737             ERR("Failed to cache clipboard data owned by another process. Format=%d\n", 
738                 lpData->wFormatID);
739             bret = FALSE;
740         }
741     }
742     else
743     {
744             CLIPBOARDINFO cbInfo;
745
746         if (X11DRV_CLIPBOARD_GetClipboardInfo(&cbInfo) && cbInfo.hWndOwner)
747             {
748                 /* Send a WM_RENDERFORMAT message to notify the owner to render the
749                  * data requested into the clipboard.
750                  */
751                 TRACE("Sending WM_RENDERFORMAT message to hwnd(%p)\n", cbInfo.hWndOwner);
752                 SendMessageW(cbInfo.hWndOwner, WM_RENDERFORMAT, (WPARAM)lpData->wFormatID, 0);
753
754                 if (!lpData->hData32 && !lpData->hData16)
755                     bret = FALSE;
756             }
757             else
758             {
759                 ERR("hWndClipOwner is lost!\n");
760                 bret = FALSE;
761             }
762         }
763
764     return bret;
765 }
766
767
768 /**************************************************************************
769  *                      CLIPBOARD_ConvertText
770  * Returns number of required/converted characters - not bytes!
771  */
772 static INT CLIPBOARD_ConvertText(WORD src_fmt, void const *src, INT src_size,
773                                  WORD dst_fmt, void *dst, INT dst_size)
774 {
775     UINT cp;
776
777     if(src_fmt == CF_UNICODETEXT)
778     {
779         switch(dst_fmt)
780         {
781         case CF_TEXT:
782             cp = CP_ACP;
783             break;
784         case CF_OEMTEXT:
785             cp = CP_OEMCP;
786             break;
787         default:
788             return 0;
789         }
790         return WideCharToMultiByte(cp, 0, src, src_size, dst, dst_size, NULL, NULL);
791     }
792
793     if(dst_fmt == CF_UNICODETEXT)
794     {
795         switch(src_fmt)
796         {
797         case CF_TEXT:
798             cp = CP_ACP;
799             break;
800         case CF_OEMTEXT:
801             cp = CP_OEMCP;
802             break;
803         default:
804             return 0;
805         }
806         return MultiByteToWideChar(cp, 0, src, src_size, dst, dst_size);
807     }
808
809     if(!dst_size) return src_size;
810
811     if(dst_size > src_size) dst_size = src_size;
812
813     if(src_fmt == CF_TEXT )
814         CharToOemBuffA(src, dst, dst_size);
815     else
816         OemToCharBuffA(src, dst, dst_size);
817
818     return dst_size;
819 }
820
821
822 /**************************************************************************
823  *                      X11DRV_CLIPBOARD_RenderSynthesizedFormat
824  */
825 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedFormat(LPWINE_CLIPDATA lpData)
826 {
827     BOOL bret = FALSE;
828
829     TRACE("\n");
830
831     if (lpData->wFlags & CF_FLAG_SYNTHESIZED)
832     {
833         UINT wFormatID = lpData->wFormatID;
834
835         if (wFormatID == CF_UNICODETEXT || wFormatID == CF_TEXT || wFormatID == CF_OEMTEXT)
836             bret = X11DRV_CLIPBOARD_RenderSynthesizedText(wFormatID);
837         else 
838         {
839             switch (wFormatID)
840             {
841                 case CF_ENHMETAFILE:
842                 case CF_METAFILEPICT:
843                 case CF_DIB:
844                 case CF_BITMAP:
845                     FIXME("Synthesizing wFormatID(0x%08x) not implemented\n", wFormatID);
846                     break;
847
848                 default:
849                     FIXME("Called to synthesize unknown format\n");
850                     break;
851             }
852         }
853
854         lpData->wFlags &= ~CF_FLAG_SYNTHESIZED;
855     }
856
857     return bret;
858 }
859
860
861 /**************************************************************************
862  *                      X11DRV_CLIPBOARD_RenderSynthesizedText
863  *
864  * Renders synthesized text
865  */
866 static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID)
867 {
868     LPCSTR lpstrS;
869     LPSTR  lpstrT;
870     HANDLE hData32;
871     INT src_chars, dst_chars, alloc_size;
872     LPWINE_CLIPDATA lpSource = NULL;
873
874     TRACE(" %d\n", wFormatID);
875
876     if ((lpSource = X11DRV_CLIPBOARD_LookupData(wFormatID)) &&
877         lpSource->hData32)
878         return TRUE;
879
880     /* Look for rendered source or non-synthesized source */
881     if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_UNICODETEXT)) &&
882         (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
883     {
884         TRACE("UNICODETEXT -> %d\n", wFormatID);
885     }
886     else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_TEXT)) &&
887         (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
888     {
889         TRACE("TEXT -> %d\n", wFormatID);
890     }
891     else if ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_OEMTEXT)) &&
892         (!(lpSource->wFlags & CF_FLAG_SYNTHESIZED) || lpSource->hData32))
893     {
894         TRACE("OEMTEXT -> %d\n", wFormatID);
895     }
896
897     if (!lpSource || (lpSource->wFlags & CF_FLAG_SYNTHESIZED &&
898         !lpSource->hData32))
899         return FALSE;
900
901     /* Ask the clipboard owner to render the source text if necessary */
902     if (!lpSource->hData32 && !X11DRV_CLIPBOARD_RenderFormat(lpSource))
903         return FALSE;
904
905     if (lpSource->hData32)
906     {
907         lpstrS = (LPSTR)GlobalLock(lpSource->hData32);
908     }
909     else
910     {
911         lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
912     }
913
914     if (!lpstrS)
915         return FALSE;
916
917     /* Text always NULL terminated */
918     if(lpSource->wFormatID == CF_UNICODETEXT)
919         src_chars = strlenW((LPCWSTR)lpstrS) + 1;
920     else
921         src_chars = strlen(lpstrS) + 1;
922
923     /* Calculate number of characters in the destination buffer */
924     dst_chars = CLIPBOARD_ConvertText(lpSource->wFormatID, lpstrS, 
925         src_chars, wFormatID, NULL, 0);
926
927     if (!dst_chars)
928         return FALSE;
929
930     TRACE("Converting from '%d' to '%d', %i chars\n",
931         lpSource->wFormatID, wFormatID, src_chars);
932
933     /* Convert characters to bytes */
934     if(wFormatID == CF_UNICODETEXT)
935         alloc_size = dst_chars * sizeof(WCHAR);
936     else
937         alloc_size = dst_chars;
938
939     hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | 
940         GMEM_DDESHARE, alloc_size);
941
942     lpstrT = (LPSTR)GlobalLock(hData32);
943
944     if (lpstrT)
945     {
946         CLIPBOARD_ConvertText(lpSource->wFormatID, lpstrS, src_chars,
947             wFormatID, lpstrT, dst_chars);
948         GlobalUnlock(hData32);
949     }
950
951     /* Unlock source */
952     if (lpSource->hData32)
953         GlobalUnlock(lpSource->hData32);
954     else
955         GlobalUnlock16(lpSource->hData16);
956
957     return X11DRV_CLIPBOARD_InsertClipboardData(wFormatID, 0, hData32, 0);
958 }
959
960
961 /**************************************************************************
962  *              X11DRV_CLIPBOARD_ImportXAString
963  *
964  *  Import XA_STRING, converting the string to CF_UNICODE.
965  */
966 HANDLE X11DRV_CLIPBOARD_ImportXAString(LPBYTE lpdata, UINT cBytes)
967 {
968     LPSTR lpstr;
969     UINT i, inlcount = 0;
970     HANDLE hUnicodeText = 0;
971
972     for (i = 0; i <= cBytes; i++)
973     {
974         if (lpdata[i] == '\n')
975             inlcount++;
976     }
977
978     if ((lpstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes + inlcount + 1)))
979     {
980         UINT count;
981
982         for (i = 0, inlcount = 0; i <= cBytes; i++)
983         {
984             if (lpdata[i] == '\n')
985                 lpstr[inlcount++] = '\r';
986
987             lpstr[inlcount++] = lpdata[i];
988         }
989
990         count = MultiByteToWideChar(CP_UNIXCP, 0, lpstr, -1, NULL, 0);
991         hUnicodeText = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, count * sizeof(WCHAR));
992
993         if(hUnicodeText)
994         {
995             WCHAR *textW = GlobalLock(hUnicodeText);
996             MultiByteToWideChar(CP_UNIXCP, 0, lpstr, -1, textW, count);
997             GlobalUnlock(hUnicodeText);
998         }
999
1000         HeapFree(GetProcessHeap(), 0, lpstr);
1001     }
1002
1003     return hUnicodeText;
1004 }
1005
1006
1007 /**************************************************************************
1008  *              X11DRV_CLIPBOARD_ImportXAPIXMAP
1009  *
1010  *  Import XA_PIXMAP, converting the image to CF_DIB.
1011  */
1012 HANDLE X11DRV_CLIPBOARD_ImportXAPIXMAP(LPBYTE lpdata, UINT cBytes)
1013 {
1014     HANDLE hTargetImage = 0;  /* Handle to store the converted DIB */
1015     Pixmap *pPixmap = (Pixmap *) lpdata;
1016     HWND hwnd = GetOpenClipboardWindow();
1017     HDC hdc = GetDC(hwnd);
1018
1019     hTargetImage = X11DRV_DIB_CreateDIBFromPixmap(*pPixmap, hdc, TRUE);
1020
1021     ReleaseDC(hwnd, hdc);
1022
1023     return hTargetImage;
1024 }
1025
1026
1027 /**************************************************************************
1028  *              X11DRV_CLIPBOARD_ImportMetaFilePict
1029  *
1030  *  Import MetaFilePict.
1031  */
1032 HANDLE X11DRV_CLIPBOARD_ImportMetaFilePict(LPBYTE lpdata, UINT cBytes)
1033 {
1034     return X11DRV_CLIPBOARD_SerializeMetafile(CF_METAFILEPICT, (HANDLE)lpdata, (LPDWORD)&cBytes, FALSE);
1035 }
1036
1037
1038 /**************************************************************************
1039  *              X11DRV_ImportEnhMetaFile
1040  *
1041  *  Import EnhMetaFile.
1042  */
1043 HANDLE X11DRV_CLIPBOARD_ImportEnhMetaFile(LPBYTE lpdata, UINT cBytes)
1044 {
1045     return X11DRV_CLIPBOARD_SerializeMetafile(CF_ENHMETAFILE, (HANDLE)lpdata, (LPDWORD)&cBytes, FALSE);
1046 }
1047
1048
1049 /**************************************************************************
1050  *              X11DRV_ImportClipbordaData
1051  *
1052  *  Generic import clipboard data routine.
1053  */
1054 HANDLE X11DRV_CLIPBOARD_ImportClipboardData(LPBYTE lpdata, UINT cBytes)
1055 {
1056     LPVOID lpClipData;
1057     HANDLE hClipData = 0;
1058
1059     if (cBytes)
1060     {
1061         /* Turn on the DDESHARE flag to enable shared 32 bit memory */
1062         hClipData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cBytes);
1063         if ((lpClipData = GlobalLock(hClipData)))
1064         {
1065             memcpy(lpClipData, lpdata, cBytes);
1066             GlobalUnlock(hClipData);
1067         }
1068         else
1069             hClipData = 0;
1070     }
1071
1072     return hClipData;
1073 }
1074
1075
1076 /**************************************************************************
1077  *              X11DRV_CLIPBOARD_ExportClipboardData
1078  *
1079  *  Generic export clipboard data routine.
1080  */
1081 HANDLE X11DRV_CLIPBOARD_ExportClipboardData(Window requestor, Atom aTarget,
1082     Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
1083 {
1084     LPVOID lpClipData;
1085     UINT cBytes = 0;
1086     HANDLE hClipData = 0;
1087
1088     *lpBytes = 0; /* Assume failure */
1089
1090     if (!X11DRV_CLIPBOARD_RenderFormat(lpData))
1091         ERR("Failed to export %d format\n", lpData->wFormatID);
1092     else
1093     {
1094         cBytes = GlobalSize(lpData->hData32);
1095
1096         hClipData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cBytes);
1097
1098         if ((lpClipData = GlobalLock(hClipData)))
1099         {
1100             LPVOID lpdata = GlobalLock(lpData->hData32);
1101
1102             memcpy(lpClipData, lpdata, cBytes);
1103             *lpBytes = cBytes;
1104
1105             GlobalUnlock(lpData->hData32);
1106             GlobalUnlock(hClipData);
1107         }
1108     }
1109
1110     return hClipData;
1111 }
1112
1113
1114 /**************************************************************************
1115  *              X11DRV_CLIPBOARD_ExportXAString
1116  *
1117  *  Export CF_UNICODE converting the string to XA_STRING.
1118  *  Helper function for X11DRV_CLIPBOARD_ExportString.
1119  */
1120 HANDLE X11DRV_CLIPBOARD_ExportXAString(LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
1121 {
1122     INT i, j;
1123     UINT size;
1124     LPWSTR uni_text;
1125     LPSTR text, lpstr;
1126
1127     *lpBytes = 0; /* Assume return has zero bytes */
1128
1129     uni_text = GlobalLock(lpData->hData32);
1130
1131     size = WideCharToMultiByte(CP_UNIXCP, 0, uni_text, -1, NULL, 0, NULL, NULL);
1132
1133     text = HeapAlloc(GetProcessHeap(), 0, size);
1134     if (!text)
1135        return None;
1136     WideCharToMultiByte(CP_UNIXCP, 0, uni_text, -1, text, size, NULL, NULL);
1137
1138     /* remove carriage returns */
1139
1140     lpstr = (char*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size-- );
1141     if(lpstr == NULL) return None;
1142     for(i = 0,j = 0; i < size && text[i]; i++ )
1143     {
1144         if( text[i] == '\r' &&
1145             (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
1146         lpstr[j++] = text[i];
1147     }
1148     lpstr[j]='\0';
1149
1150     *lpBytes = j; /* Number of bytes in string */
1151
1152     HeapFree(GetProcessHeap(), 0, text);
1153     GlobalUnlock(lpData->hData32);
1154
1155     return lpstr;
1156 }
1157
1158
1159 /**************************************************************************
1160  *              X11DRV_CLIPBOARD_ExportCompoundText
1161  *
1162  *  Export CF_UNICODE to COMPOUND_TEXT or TEXT
1163  *  Helper function for X11DRV_CLIPBOARD_ExportString.
1164  */
1165 HANDLE X11DRV_CLIPBOARD_ExportCompoundText(Window requestor, Atom aTarget, Atom rprop,
1166     LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
1167 {
1168     Display *display = thread_display();
1169     char* lpstr = 0;
1170     XTextProperty prop;
1171     XICCEncodingStyle style;
1172
1173     lpstr = (char*) X11DRV_CLIPBOARD_ExportXAString(lpData, lpBytes);
1174
1175     if (lpstr)
1176     {
1177         if (aTarget == x11drv_atom(COMPOUND_TEXT))
1178            style = XCompoundTextStyle;
1179         else
1180            style = XStdICCTextStyle;
1181
1182         /* Update the X property */
1183         wine_tsx11_lock();
1184         if (XmbTextListToTextProperty(display, &lpstr, 1, style, &prop) == Success)
1185         {
1186            XSetTextProperty(display, requestor, &prop, rprop);
1187            XFree(prop.value);
1188         }
1189         wine_tsx11_unlock();
1190
1191         HeapFree( GetProcessHeap(), 0, lpstr );
1192     }
1193
1194     return 0;
1195 }
1196
1197 /**************************************************************************
1198  *              X11DRV_CLIPBOARD_ExportString
1199  *
1200  *  Export CF_UNICODE string
1201  */
1202 HANDLE X11DRV_CLIPBOARD_ExportString(Window requestor, Atom aTarget, Atom rprop,
1203     LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
1204 {
1205     if (X11DRV_CLIPBOARD_RenderFormat(lpData))
1206     {
1207         if (aTarget == XA_STRING)
1208             return X11DRV_CLIPBOARD_ExportXAString(lpData, lpBytes);
1209         else if (aTarget == x11drv_atom(COMPOUND_TEXT) || aTarget == x11drv_atom(TEXT))
1210             return X11DRV_CLIPBOARD_ExportCompoundText(requestor, aTarget,
1211                 rprop, lpData, lpBytes);
1212         else
1213             ERR("Unknown target %ld to %d format\n", aTarget, lpData->wFormatID);
1214     }
1215     else
1216         ERR("Failed to render %d format\n", lpData->wFormatID);
1217
1218     return 0;
1219 }
1220
1221
1222 /**************************************************************************
1223  *              X11DRV_CLIPBOARD_ExportXAPIXMAP
1224  *
1225  *  Export CF_DIB to XA_PIXMAP.
1226  */
1227 HANDLE X11DRV_CLIPBOARD_ExportXAPIXMAP(Window requestor, Atom aTarget, Atom rprop,
1228     LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
1229 {
1230     HDC hdc;
1231     Pixmap pixmap;
1232
1233     if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
1234     {
1235         ERR("Failed to export %d format\n", lpdata->wFormatID);
1236         return 0;
1237     }
1238
1239     hdc = GetDC(0);
1240
1241     /* For convert from packed DIB to Pixmap */
1242     pixmap = X11DRV_DIB_CreatePixmapFromDIB(lpdata, hdc);
1243     *lpBytes = 4; /* pixmap is a 32bit value */
1244
1245     ReleaseDC(0, hdc);
1246
1247     return (HANDLE) pixmap;
1248 }
1249
1250
1251 /**************************************************************************
1252  *              X11DRV_CLIPBOARD_ExportMetaFilePict
1253  *
1254  *  Export MetaFilePict.
1255  */
1256 HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget, Atom rprop,
1257     LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
1258 {
1259     if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
1260     {
1261         ERR("Failed to export %d format\n", lpdata->wFormatID);
1262         return 0;
1263     }
1264
1265     return X11DRV_CLIPBOARD_SerializeMetafile(CF_METAFILEPICT, (HANDLE)lpdata->hData32, 
1266         lpBytes, TRUE);
1267 }
1268
1269
1270 /**************************************************************************
1271  *              X11DRV_CLIPBOARD_ExportEnhMetaFile
1272  *
1273  *  Export EnhMetaFile.
1274  */
1275 HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget, Atom rprop,
1276     LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
1277 {
1278     if (!X11DRV_CLIPBOARD_RenderFormat(lpdata))
1279     {
1280         ERR("Failed to export %d format\n", lpdata->wFormatID);
1281         return 0;
1282     }
1283
1284     return X11DRV_CLIPBOARD_SerializeMetafile(CF_ENHMETAFILE, (HANDLE)lpdata->hData32, 
1285         lpBytes, TRUE);
1286 }
1287
1288
1289 /**************************************************************************
1290  *              X11DRV_CLIPBOARD_QueryTargets
1291  */
1292 static BOOL X11DRV_CLIPBOARD_QueryTargets(Display *display, Window w, Atom selection, XEvent *xe)
1293 {
1294     INT i;
1295     Bool res;
1296
1297     wine_tsx11_lock();
1298     XConvertSelection(display, selection, x11drv_atom(TARGETS),
1299                       x11drv_atom(SELECTION_DATA), w, CurrentTime);
1300     wine_tsx11_unlock();
1301
1302     /*
1303      * Wait until SelectionNotify is received
1304      */
1305     for (i = 0; i < SELECTION_RETRIES; i++)
1306     {
1307         wine_tsx11_lock();
1308         res = XCheckTypedWindowEvent(display, w, SelectionNotify, xe);
1309         wine_tsx11_unlock();
1310         if (res && xe->xselection.selection == selection) break;
1311
1312         usleep(SELECTION_WAIT);
1313     }
1314
1315     /* Verify that the selection returned a valid TARGETS property */
1316     if ((xe->xselection.target != x11drv_atom(TARGETS)) || (xe->xselection.property == None))
1317     {
1318         /* Selection owner failed to respond or we missed the SelectionNotify */
1319         WARN("Failed to retrieve TARGETS for selection %ld.\n", selection);
1320         return FALSE;
1321     }
1322
1323     return TRUE;
1324 }
1325
1326
1327 /**************************************************************************
1328  *              X11DRV_CLIPBOARD_QueryAvailableData
1329  *
1330  * Caches the list of data formats available from the current selection.
1331  * This queries the selection owner for the TARGETS property and saves all
1332  * reported property types.
1333  */
1334 static int X11DRV_CLIPBOARD_QueryAvailableData(LPCLIPBOARDINFO lpcbinfo)
1335 {
1336     Display *display = thread_display();
1337     XEvent         xe;
1338     Atom           atype=AnyPropertyType;
1339     int            aformat;
1340     unsigned long  remain;
1341     Atom*          targetList=NULL;
1342     Window         w;
1343     HWND           hWndClipWindow; 
1344     unsigned long  cSelectionTargets = 0;
1345
1346     if (selectionAcquired & (S_PRIMARY | S_CLIPBOARD))
1347     {
1348         ERR("Received request to cache selection but process is owner=(%08x)\n", 
1349             (unsigned) selectionWindow);
1350
1351         selectionAcquired  = S_NOSELECTION;
1352
1353         wine_tsx11_lock();
1354         if (XGetSelectionOwner(display,XA_PRIMARY) == selectionWindow)
1355             selectionAcquired |= S_PRIMARY;
1356
1357         if (XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)) == selectionWindow)
1358             selectionAcquired |= S_CLIPBOARD;
1359         wine_tsx11_unlock();
1360
1361         if (!(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)))
1362         {
1363             WARN("Lost selection but process didn't process SelectClear\n");
1364             selectionWindow = None;
1365         }
1366         else
1367         {
1368             return -1; /* Prevent self request */
1369         }
1370     }
1371
1372     if (lpcbinfo->flags & CB_OWNER)
1373         hWndClipWindow = lpcbinfo->hWndOwner;
1374     else if (lpcbinfo->flags & CB_OPEN)
1375         hWndClipWindow = lpcbinfo->hWndOpen;
1376     else
1377         hWndClipWindow = GetActiveWindow();
1378
1379     if (!hWndClipWindow)
1380     {
1381         WARN("No window available to retrieve selection!n");
1382         return -1;
1383     }
1384
1385     w = X11DRV_get_whole_window(GetAncestor(hWndClipWindow, GA_ROOT));
1386
1387     /*
1388      * Query the selection owner for the TARGETS property
1389      */
1390     wine_tsx11_lock();
1391     if (XGetSelectionOwner(display,XA_PRIMARY) ||
1392         XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)))
1393     {
1394         wine_tsx11_unlock();
1395         if (X11DRV_CLIPBOARD_QueryTargets(display, w, XA_PRIMARY, &xe))
1396             selectionCacheSrc = XA_PRIMARY;
1397         else if (X11DRV_CLIPBOARD_QueryTargets(display, w, x11drv_atom(CLIPBOARD), &xe))
1398             selectionCacheSrc = x11drv_atom(CLIPBOARD);
1399         else
1400             return -1;
1401     }
1402     else /* No selection owner so report 0 targets available */
1403     {
1404         wine_tsx11_unlock();
1405         return 0;
1406     }
1407
1408     /* Read the TARGETS property contents */
1409     wine_tsx11_lock();
1410     if(XGetWindowProperty(display, xe.xselection.requestor, xe.xselection.property,
1411         0, 0x3FFF, True, AnyPropertyType/*XA_ATOM*/, &atype, &aformat, &cSelectionTargets, 
1412         &remain, (unsigned char**)&targetList) != Success)
1413     {
1414         wine_tsx11_unlock();
1415         WARN("Failed to read TARGETS property\n");
1416     }
1417     else
1418     {
1419         wine_tsx11_unlock();
1420        TRACE("Type %lx,Format %d,nItems %ld, Remain %ld\n",
1421              atype, aformat, cSelectionTargets, remain);
1422        /*
1423         * The TARGETS property should have returned us a list of atoms
1424         * corresponding to each selection target format supported.
1425         */
1426        if ((atype == XA_ATOM || atype == x11drv_atom(TARGETS)) && aformat == 32)
1427        {
1428           INT i, nb_atoms = 0;
1429           Atom *atoms = NULL;
1430
1431           /* Cache these formats in the clipboard cache */
1432           for (i = 0; i < cSelectionTargets; i++)
1433           {
1434               LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupProperty(targetList[i]);
1435
1436               if (!lpFormat)
1437                   lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(targetList[i]);
1438
1439               if (!lpFormat)
1440               {
1441                   /* add it to the list of atoms that we don't know about yet */
1442                   if (!atoms) atoms = HeapAlloc( GetProcessHeap(), 0,
1443                                                  (cSelectionTargets - i) * sizeof(*atoms) );
1444                   if (atoms) atoms[nb_atoms++] = targetList[i];
1445               }
1446               else
1447               {
1448                   TRACE("Atom#%d Property(%d): --> FormatID(%d) %s\n",
1449                         i, lpFormat->drvData, lpFormat->wFormatID, lpFormat->Name);
1450                   X11DRV_CLIPBOARD_InsertClipboardData(lpFormat->wFormatID, 0, 0, 0);
1451               }
1452           }
1453
1454           /* query all unknown atoms in one go */
1455           if (atoms)
1456           {
1457               char **names = HeapAlloc( GetProcessHeap(), 0, nb_atoms * sizeof(*names) );
1458               if (names)
1459               {
1460                   wine_tsx11_lock();
1461                   XGetAtomNames( display, atoms, nb_atoms, names );
1462                   wine_tsx11_unlock();
1463                   for (i = 0; i < nb_atoms; i++)
1464                   {
1465                       WINE_CLIPFORMAT *lpFormat = register_format( names[i], atoms[i] );
1466                       if (!lpFormat)
1467                       {
1468                           ERR("Failed to cache %s property\n", names[i]);
1469                           continue;
1470                       }
1471                       TRACE("Atom#%d Property(%d): --> FormatID(%d) %s\n",
1472                             i, lpFormat->drvData, lpFormat->wFormatID, lpFormat->Name);
1473                       X11DRV_CLIPBOARD_InsertClipboardData(lpFormat->wFormatID, 0, 0, 0);
1474                   }
1475                   wine_tsx11_lock();
1476                   for (i = 0; i < nb_atoms; i++) XFree( names[i] );
1477                   wine_tsx11_unlock();
1478                   HeapFree( GetProcessHeap(), 0, names );
1479               }
1480           }
1481        }
1482
1483        /* Free the list of targets */
1484        wine_tsx11_lock();
1485        XFree(targetList);
1486        wine_tsx11_unlock();
1487     }
1488
1489     return cSelectionTargets;
1490 }
1491
1492
1493 /**************************************************************************
1494  *      X11DRV_CLIPBOARD_ReadClipboardData
1495  *
1496  * This method is invoked only when we DO NOT own the X selection
1497  *
1498  * We always get the data from the selection client each time,
1499  * since we have no way of determining if the data in our cache is stale.
1500  */
1501 static BOOL X11DRV_CLIPBOARD_ReadClipboardData(UINT wFormat)
1502 {
1503     Display *display = thread_display();
1504     BOOL bRet = FALSE;
1505     Bool res;
1506
1507     HWND hWndClipWindow = GetOpenClipboardWindow();
1508     HWND hWnd = (hWndClipWindow) ? hWndClipWindow : GetActiveWindow();
1509
1510     LPWINE_CLIPFORMAT lpFormat;
1511
1512     TRACE("%d\n", wFormat);
1513
1514     if (!selectionAcquired)
1515     {
1516         Window w = X11DRV_get_whole_window(GetAncestor(hWnd, GA_ROOT));
1517         if(!w)
1518         {
1519             FIXME("No parent win found %p %p\n", hWnd, hWndClipWindow);
1520             return FALSE;
1521         }
1522
1523         lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
1524
1525         if (lpFormat->drvData)
1526         {
1527             DWORD i;
1528             UINT alias;
1529             XEvent xe;
1530
1531             TRACE("Requesting %s selection (%d) from win(%08x)\n", 
1532                 lpFormat->Name, lpFormat->drvData, (UINT)selectionCacheSrc);
1533
1534             wine_tsx11_lock();
1535             XConvertSelection(display, selectionCacheSrc, lpFormat->drvData,
1536                               x11drv_atom(SELECTION_DATA), w, CurrentTime);
1537             wine_tsx11_unlock();
1538
1539             /* wait until SelectionNotify is received */
1540             for (i = 0; i < SELECTION_RETRIES; i++)
1541             {
1542                 wine_tsx11_lock();
1543                 res = XCheckTypedWindowEvent(display, w, SelectionNotify, &xe);
1544                 wine_tsx11_unlock();
1545                 if (res && xe.xselection.selection == selectionCacheSrc) break;
1546
1547                 usleep(SELECTION_WAIT);
1548             }
1549
1550             /* If the property wasn't available check for aliases */
1551             if (xe.xselection.property == None &&
1552                 (alias = X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData)))
1553             {
1554                 wine_tsx11_lock();
1555                 XConvertSelection(display, selectionCacheSrc, alias,
1556                                   x11drv_atom(SELECTION_DATA), w, CurrentTime);
1557                 wine_tsx11_unlock();
1558
1559                 /* wait until SelectionNotify is received */
1560                 for (i = 0; i < SELECTION_RETRIES; i++)
1561                 {
1562                     wine_tsx11_lock();
1563                     res = XCheckTypedWindowEvent(display, w, SelectionNotify, &xe);
1564                     wine_tsx11_unlock();
1565                     if (res && xe.xselection.selection == selectionCacheSrc) break;
1566
1567                     usleep(SELECTION_WAIT);
1568                 }
1569             }
1570
1571             /* Verify that the selection returned a valid TARGETS property */
1572             if (xe.xselection.property != None)
1573             {
1574                 /*
1575                  *  Read the contents of the X selection property 
1576                  *  into WINE's clipboard cache converting the 
1577                  *  selection to be compatible if possible.
1578                  */
1579                 bRet = X11DRV_CLIPBOARD_ReadSelection(lpFormat, xe.xselection.requestor, 
1580                     xe.xselection.property);
1581             }
1582         }
1583     }
1584     else
1585     {
1586         ERR("Received request to cache selection data but process is owner\n");
1587     }
1588
1589     TRACE("Returning %d\n", bRet);
1590
1591     return bRet;
1592 }
1593
1594
1595 /**************************************************************************
1596  *              X11DRV_CLIPBOARD_ReadSelection
1597  *  Reads the contents of the X selection property into the WINE clipboard cache
1598  *  converting the selection into a format compatible with the windows clipboard
1599  *  if possible.
1600  *  This method is invoked only to read the contents of a the selection owned
1601  *  by an external application. i.e. when we do not own the X selection.
1602  */
1603 static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, Atom prop)
1604 {
1605     Display *display = thread_display();
1606     Atom              atype=AnyPropertyType;
1607     int               aformat;
1608     unsigned long     total,nitems,remain,itemSize,val_cnt;
1609     long              lRequestLength,bwc;
1610     unsigned char*    val;
1611     unsigned char*    buffer;
1612     BOOL              bRet = FALSE;
1613
1614     if(prop == None)
1615         return bRet;
1616
1617     TRACE("Reading X selection type %s\n", lpData->Name);
1618
1619     /*
1620      * First request a zero length in order to figure out the request size.
1621      */
1622     wine_tsx11_lock();
1623     if(XGetWindowProperty(display,w,prop,0,0,False, AnyPropertyType,
1624         &atype, &aformat, &nitems, &itemSize, &val) != Success)
1625     {
1626         wine_tsx11_unlock();
1627         WARN("Failed to get property size\n");
1628         return bRet;
1629     }
1630
1631     /* Free zero length return data if any */
1632     if (val)
1633     {
1634        XFree(val);
1635        val = NULL;
1636     }
1637
1638     TRACE("Retrieving %ld bytes\n", itemSize * aformat/8);
1639
1640     lRequestLength = (itemSize * aformat/8)/4  + 1;
1641     bwc = aformat/8;
1642
1643     /* Read property in 4K blocks */
1644     if (XGetWindowProperty(display,w,prop,0,4096,False, AnyPropertyType/*reqType*/, 
1645         &atype, &aformat, &nitems, &remain, &buffer) != Success)
1646     {
1647         wine_tsx11_unlock();
1648         WARN("Failed to read property\n");
1649         return bRet;
1650     }
1651
1652     val = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nitems*bwc);
1653     memcpy(val,buffer,nitems*bwc);
1654
1655     XFree(buffer);
1656
1657     for (total = nitems*bwc, val_cnt = 0; remain;)
1658     {
1659        val_cnt +=nitems*bwc;
1660        if (XGetWindowProperty(display, w, prop, (total / 4), 4096, False,
1661            AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success)
1662        {
1663            wine_tsx11_unlock();
1664            WARN("Failed to read property\n");
1665            HeapFree(GetProcessHeap(), 0, val);
1666            return bRet;
1667        }
1668
1669        total += nitems*bwc;
1670        HeapReAlloc(GetProcessHeap(),0,val, total);
1671        memcpy(&val[val_cnt], buffer, nitems*(aformat/8));
1672        XFree(buffer);
1673     }
1674     wine_tsx11_unlock();
1675
1676     bRet = X11DRV_CLIPBOARD_InsertClipboardData(lpData->wFormatID, 0, lpData->lpDrvImportFunc(val, total), 0);
1677
1678     /* Delete the property on the window now that we are done
1679      * This will send a PropertyNotify event to the selection owner. */
1680     wine_tsx11_lock();
1681     XDeleteProperty(display,w,prop);
1682     wine_tsx11_unlock();
1683
1684     /* Free the retrieved property data */
1685     HeapFree(GetProcessHeap(),0,val);
1686
1687     return bRet;
1688 }
1689
1690
1691 /**************************************************************************
1692  *              CLIPBOARD_SerializeMetafile
1693  */
1694 static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDWORD lpcbytes, BOOL out)
1695 {
1696     HANDLE h = 0;
1697
1698     TRACE(" wFormat=%d hdata=%08x out=%d\n", wformat, (unsigned int) hdata, out);
1699
1700     if (out) /* Serialize out, caller should free memory */
1701     {
1702         *lpcbytes = 0; /* Assume failure */
1703
1704         if (wformat == CF_METAFILEPICT)
1705         {
1706             LPMETAFILEPICT lpmfp = (LPMETAFILEPICT) GlobalLock(hdata);
1707             int size = GetMetaFileBitsEx(lpmfp->hMF, 0, NULL);
1708
1709             h = GlobalAlloc(0, size + sizeof(METAFILEPICT));
1710             if (h)
1711             {
1712                 char *pdata = GlobalLock(h);
1713
1714                 memcpy(pdata, lpmfp, sizeof(METAFILEPICT));
1715                 GetMetaFileBitsEx(lpmfp->hMF, size, pdata + sizeof(METAFILEPICT));
1716
1717                 *lpcbytes = size + sizeof(METAFILEPICT);
1718
1719                 GlobalUnlock(h);
1720             }
1721
1722             GlobalUnlock(hdata);
1723         }
1724         else if (wformat == CF_ENHMETAFILE)
1725         {
1726             int size = GetEnhMetaFileBits(hdata, 0, NULL);
1727
1728             h = GlobalAlloc(0, size);
1729             if (h)
1730             {
1731                 LPVOID pdata = GlobalLock(h);
1732
1733                 GetEnhMetaFileBits(hdata, size, pdata);
1734                 *lpcbytes = size;
1735
1736                 GlobalUnlock(h);
1737             }
1738         }
1739     }
1740     else
1741     {
1742         if (wformat == CF_METAFILEPICT)
1743         {
1744             h = GlobalAlloc(0, sizeof(METAFILEPICT));
1745             if (h)
1746             {
1747                 LPMETAFILEPICT pmfp = (LPMETAFILEPICT) GlobalLock(h);
1748
1749                 memcpy(pmfp, (LPVOID)hdata, sizeof(METAFILEPICT));
1750                 pmfp->hMF = SetMetaFileBitsEx(*lpcbytes - sizeof(METAFILEPICT),
1751                                               (char *)hdata + sizeof(METAFILEPICT));
1752
1753                 GlobalUnlock(h);
1754             }
1755         }
1756         else if (wformat == CF_ENHMETAFILE)
1757         {
1758             h = SetEnhMetaFileBits(*lpcbytes, (LPVOID)hdata);
1759         }
1760     }
1761
1762     return h;
1763 }
1764
1765
1766 /**************************************************************************
1767  *              X11DRV_CLIPBOARD_ReleaseSelection
1768  *
1769  * Release an XA_PRIMARY or XA_CLIPBOARD selection that we own, in response
1770  * to a SelectionClear event.
1771  * This can occur in response to another client grabbing the X selection.
1772  * If the XA_CLIPBOARD selection is lost, we relinquish XA_PRIMARY as well.
1773  */
1774 void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd)
1775 {
1776     Display *display = thread_display();
1777
1778     /* w is the window that lost the selection
1779      */
1780     TRACE("event->window = %08x (selectionWindow = %08x) selectionAcquired=0x%08x\n",
1781           (unsigned)w, (unsigned)selectionWindow, (unsigned)selectionAcquired);
1782
1783     if (selectionAcquired)
1784     {
1785         if (w == selectionWindow)
1786         {
1787             /* If we're losing the CLIPBOARD selection, or if the preferences in .winerc
1788              * dictate that *all* selections should be cleared on loss of a selection,
1789              * we must give up all the selections we own.
1790              */
1791             if (clearAllSelections || (selType == x11drv_atom(CLIPBOARD)))
1792             {
1793                 CLIPBOARDINFO cbinfo;
1794
1795                 /* completely give up the selection */
1796                 TRACE("Lost CLIPBOARD (+PRIMARY) selection\n");
1797
1798               /* We are completely giving up the selection. There is a
1799                * potential race condition where the apps that now owns
1800                * the selection has already grabbed both selections. In
1801                * this case, if we clear any selection we may clear the
1802                * new owners selection. To prevent this common case we
1803                * try to open the clipboard. If we can't, we assume it
1804                * was a wine apps that took it and has taken both selections.
1805                * In this case, don't bother releasing the other selection.
1806                * Otherwise only release the selection if we still own it.
1807                */
1808                 X11DRV_CLIPBOARD_GetClipboardInfo(&cbinfo);
1809
1810                 if (cbinfo.flags & CB_OWNER)
1811                 {
1812                     /* Since we're still the owner, this wasn't initiated by 
1813                        another Wine process */
1814                     if (OpenClipboard(hwnd))
1815                     {
1816                       /* We really lost CLIPBOARD but want to voluntarily lose PRIMARY */
1817                       if ((selType == x11drv_atom(CLIPBOARD)) && (selectionAcquired & S_PRIMARY))
1818                       {
1819                           TRACE("Lost clipboard. Check if we need to release PRIMARY\n");
1820                           wine_tsx11_lock();
1821                           if (selectionWindow == XGetSelectionOwner(display,XA_PRIMARY))
1822                           {
1823                              TRACE("We still own PRIMARY. Releasing PRIMARY.\n");
1824                              XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
1825                           }
1826                           else
1827                              TRACE("We no longer own PRIMARY\n");
1828                           wine_tsx11_unlock();
1829                       }
1830
1831                       /* We really lost PRIMARY but want to voluntarily lose CLIPBOARD  */
1832                       if ((selType == XA_PRIMARY) && (selectionAcquired & S_CLIPBOARD))
1833                       {
1834                           TRACE("Lost PRIMARY. Check if we need to release CLIPBOARD\n");
1835                           wine_tsx11_lock();
1836                           if (selectionWindow == XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)))
1837                           {
1838                               TRACE("We still own CLIPBOARD. Releasing CLIPBOARD.\n");
1839                               XSetSelectionOwner(display, x11drv_atom(CLIPBOARD), None, CurrentTime);
1840                           }
1841                           else
1842                               TRACE("We no longer own CLIPBOARD\n");
1843                           wine_tsx11_unlock();
1844                       }
1845
1846                       /* Destroy private objects */
1847                       SendMessageW(cbinfo.hWndOwner, WM_DESTROYCLIPBOARD, 0, 0);
1848    
1849                       /* Give up ownership of the windows clipboard */
1850                       X11DRV_CLIPBOARD_ReleaseOwnership();
1851
1852                       CloseClipboard();
1853                     }
1854                 }
1855                 else
1856                 {
1857                     TRACE("Lost selection to other Wine process.\n");
1858                 }
1859
1860                 selectionWindow = None;
1861                 PrimarySelectionOwner = ClipboardSelectionOwner = 0;
1862
1863                 X11DRV_EmptyClipboard();
1864
1865                 /* Reset the selection flags now that we are done */
1866                 selectionAcquired = S_NOSELECTION;
1867             }
1868             else if ( selType == XA_PRIMARY ) /* Give up only PRIMARY selection */
1869             {
1870                 TRACE("Lost PRIMARY selection\n");
1871                 PrimarySelectionOwner = 0;
1872                 selectionAcquired &= ~S_PRIMARY;  /* clear S_PRIMARY mask */
1873             }
1874         }
1875     }
1876 }
1877
1878
1879 /**************************************************************************
1880  *              IsSelectionOwner (X11DRV.@)
1881  *
1882  * Returns: TRUE if the selection is owned by this process, FALSE otherwise
1883  */
1884 static BOOL X11DRV_CLIPBOARD_IsSelectionOwner(void)
1885 {
1886     return selectionAcquired;
1887 }
1888
1889
1890 /**************************************************************************
1891  *                X11DRV Clipboard Exports
1892  **************************************************************************/
1893
1894
1895 /**************************************************************************
1896  *              RegisterClipboardFormat (X11DRV.@)
1897  *
1898  * Registers a custom X clipboard format
1899  * Returns: Format id or 0 on failure
1900  */
1901 INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName)
1902 {
1903     LPWINE_CLIPFORMAT lpFormat;
1904
1905     if (FormatName == NULL) return 0;
1906     if (!(lpFormat = register_format( FormatName, 0 ))) return 0;
1907     return lpFormat->wFormatID;
1908 }
1909
1910
1911 /**************************************************************************
1912  *              X11DRV_GetClipboardFormatName
1913  */
1914 INT X11DRV_GetClipboardFormatName(UINT wFormat, LPSTR retStr, INT maxlen)
1915 {
1916     INT len = 0;
1917     LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
1918
1919     TRACE("(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
1920
1921     if (!lpFormat || (lpFormat->wFlags & CF_FLAG_BUILTINFMT))
1922     {
1923         TRACE("Unknown format 0x%08x!\n", wFormat);
1924         SetLastError(ERROR_INVALID_PARAMETER);
1925     }
1926     else
1927     {
1928         strncpy(retStr, lpFormat->Name, maxlen - 1);
1929         retStr[maxlen - 1] = 0;
1930
1931         len = strlen(retStr);
1932     }
1933
1934     return len;
1935 }
1936
1937
1938 /**************************************************************************
1939  *              AcquireClipboard (X11DRV.@)
1940  */
1941 void X11DRV_AcquireClipboard(HWND hWndClipWindow)
1942 {
1943     Display *display = thread_display();
1944
1945     /*
1946      * Acquire X selection if we don't already own it.
1947      * Note that we only acquire the selection if it hasn't been already
1948      * acquired by us, and ignore the fact that another X window may be
1949      * asserting ownership. The reason for this is we need *any* top level
1950      * X window to hold selection ownership. The actual clipboard data requests
1951      * are made via GetClipboardData from EVENT_SelectionRequest and this
1952      * ensures that the real HWND owner services the request.
1953      * If the owning X window gets destroyed the selection ownership is
1954      * re-cycled to another top level X window in X11DRV_CLIPBOARD_ResetOwner.
1955      *
1956      */
1957     if (!(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)))
1958     {
1959         Window owner;
1960
1961         if (!hWndClipWindow)
1962             hWndClipWindow = GetActiveWindow();
1963
1964         owner = X11DRV_get_whole_window(GetAncestor(hWndClipWindow, GA_ROOT));
1965
1966         wine_tsx11_lock();
1967         /* Grab PRIMARY selection if not owned */
1968         if (!(selectionAcquired & S_PRIMARY))
1969             XSetSelectionOwner(display, XA_PRIMARY, owner, CurrentTime);
1970
1971         /* Grab CLIPBOARD selection if not owned */
1972         if (!(selectionAcquired & S_CLIPBOARD))
1973             XSetSelectionOwner(display, x11drv_atom(CLIPBOARD), owner, CurrentTime);
1974
1975         if (XGetSelectionOwner(display,XA_PRIMARY) == owner)
1976             selectionAcquired |= S_PRIMARY;
1977
1978         if (XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)) == owner)
1979             selectionAcquired |= S_CLIPBOARD;
1980         wine_tsx11_unlock();
1981
1982         if (selectionAcquired)
1983         {
1984             selectionWindow = owner;
1985             TRACE("Grabbed X selection, owner=(%08x)\n", (unsigned) owner);
1986         }
1987     }
1988     else
1989     {
1990         WARN("Received request to acquire selection but process is already owner=(%08x)\n", (unsigned) selectionWindow);
1991
1992         selectionAcquired  = S_NOSELECTION;
1993
1994         wine_tsx11_lock();
1995         if (XGetSelectionOwner(display,XA_PRIMARY) == selectionWindow)
1996             selectionAcquired |= S_PRIMARY;
1997
1998         if (XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)) == selectionWindow)
1999             selectionAcquired |= S_CLIPBOARD;
2000         wine_tsx11_unlock();
2001
2002         if (!(selectionAcquired == (S_PRIMARY | S_CLIPBOARD)))
2003         {
2004             WARN("Lost selection but process didn't process SelectClear\n");
2005             selectionWindow = None;
2006         }
2007     }
2008 }
2009
2010
2011 /**************************************************************************
2012  *      X11DRV_EmptyClipboard
2013  */
2014 void X11DRV_EmptyClipboard(void)
2015 {
2016     if (ClipData)
2017     {
2018         LPWINE_CLIPDATA lpData;
2019         LPWINE_CLIPDATA lpNext = ClipData;
2020
2021         do
2022         {
2023             lpData = lpNext;
2024             lpNext = lpData->NextData;
2025             lpData->PrevData->NextData = lpData->NextData;
2026             lpData->NextData->PrevData = lpData->PrevData;
2027             X11DRV_CLIPBOARD_FreeData(lpData);
2028             HeapFree(GetProcessHeap(), 0, lpData);
2029         } while (lpNext != lpData);
2030     }
2031
2032     TRACE(" %d entries deleted from cache.\n", ClipDataCount);
2033
2034     ClipData = NULL;
2035     ClipDataCount = 0;
2036 }
2037
2038
2039
2040 /**************************************************************************
2041  *              X11DRV_SetClipboardData
2042  */
2043 BOOL X11DRV_SetClipboardData(UINT wFormat, HANDLE16 hData16, HANDLE hData32)
2044 {
2045     BOOL bResult = FALSE;
2046
2047     if (X11DRV_CLIPBOARD_InsertClipboardData(wFormat, hData16, hData32, 0))
2048         bResult = TRUE;
2049
2050     return bResult;
2051 }
2052
2053
2054 /**************************************************************************
2055  *              CountClipboardFormats
2056  */
2057 INT X11DRV_CountClipboardFormats(void)
2058 {
2059     CLIPBOARDINFO cbinfo;
2060
2061     X11DRV_CLIPBOARD_UpdateCache(&cbinfo);
2062
2063     TRACE(" count=%d\n", ClipDataCount);
2064
2065     return ClipDataCount;
2066 }
2067
2068
2069 /**************************************************************************
2070  *              X11DRV_EnumClipboardFormats
2071  */
2072 UINT X11DRV_EnumClipboardFormats(UINT wFormat)
2073 {
2074     CLIPBOARDINFO cbinfo;
2075     UINT wNextFormat = 0;
2076
2077     TRACE("(%04X)\n", wFormat);
2078
2079     X11DRV_CLIPBOARD_UpdateCache(&cbinfo);
2080
2081     if (!wFormat)
2082     {
2083         if (ClipData)
2084             wNextFormat = ClipData->wFormatID;
2085     }
2086     else
2087     {
2088         LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(wFormat);
2089
2090         if (lpData && lpData->NextData != ClipData)
2091             wNextFormat = lpData->NextData->wFormatID;
2092     }
2093
2094     return wNextFormat;
2095 }
2096
2097
2098 /**************************************************************************
2099  *              X11DRV_IsClipboardFormatAvailable
2100  */
2101 BOOL X11DRV_IsClipboardFormatAvailable(UINT wFormat)
2102 {
2103     BOOL bRet = FALSE;
2104     CLIPBOARDINFO cbinfo;
2105
2106     TRACE("(%04X)\n", wFormat);
2107
2108     X11DRV_CLIPBOARD_UpdateCache(&cbinfo);
2109
2110     if (wFormat != 0 && X11DRV_CLIPBOARD_LookupData(wFormat))
2111         bRet = TRUE;
2112
2113     TRACE("(%04X)- ret(%d)\n", wFormat, bRet);
2114
2115     return bRet;
2116 }
2117
2118
2119 /**************************************************************************
2120  *              GetClipboardData (USER.142)
2121  */
2122 BOOL X11DRV_GetClipboardData(UINT wFormat, HANDLE16* phData16, HANDLE* phData32)
2123 {
2124     CLIPBOARDINFO cbinfo;
2125     LPWINE_CLIPDATA lpRender;
2126
2127     TRACE("(%04X)\n", wFormat);
2128
2129     X11DRV_CLIPBOARD_UpdateCache(&cbinfo);
2130
2131     if ((lpRender = X11DRV_CLIPBOARD_LookupData(wFormat)))
2132     {
2133         if ( !lpRender->hData32 )
2134             X11DRV_CLIPBOARD_RenderFormat(lpRender);
2135
2136         /* Convert between 32 -> 16 bit data, if necessary */
2137         if (lpRender->hData32 && !lpRender->hData16)
2138         {
2139             int size;
2140
2141             if (lpRender->wFormatID == CF_METAFILEPICT)
2142                 size = sizeof(METAFILEPICT16);
2143             else
2144                 size = GlobalSize(lpRender->hData32);
2145
2146             lpRender->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
2147
2148             if (!lpRender->hData16)
2149                 ERR("(%04X) -- not enough memory in 16b heap\n", wFormat);
2150             else
2151             {
2152                 if (lpRender->wFormatID == CF_METAFILEPICT)
2153                 {
2154                     FIXME("\timplement function CopyMetaFilePict32to16\n");
2155                     FIXME("\tin the appropriate file.\n");
2156   #ifdef SOMEONE_IMPLEMENTED_ME
2157                     CopyMetaFilePict32to16(GlobalLock16(lpRender->hData16),
2158                         GlobalLock(lpRender->hData32));
2159   #endif
2160                 }
2161                 else
2162                 {
2163                     memcpy(GlobalLock16(lpRender->hData16),
2164                         GlobalLock(lpRender->hData32), size);
2165                 }
2166
2167                 GlobalUnlock16(lpRender->hData16);
2168                 GlobalUnlock(lpRender->hData32);
2169             }
2170         }
2171
2172         /* Convert between 32 -> 16 bit data, if necessary */
2173         if (lpRender->hData16 && !lpRender->hData32)
2174         {
2175             int size;
2176
2177             if (lpRender->wFormatID == CF_METAFILEPICT)
2178                 size = sizeof(METAFILEPICT16);
2179             else
2180                 size = GlobalSize(lpRender->hData32);
2181
2182             lpRender->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | 
2183                 GMEM_DDESHARE, size);
2184
2185             if (lpRender->wFormatID == CF_METAFILEPICT)
2186             {
2187                 FIXME("\timplement function CopyMetaFilePict16to32\n");
2188                 FIXME("\tin the appropriate file.\n");
2189 #ifdef SOMEONE_IMPLEMENTED_ME
2190                 CopyMetaFilePict16to32(GlobalLock16(lpRender->hData32),
2191                     GlobalLock(lpRender->hData16));
2192 #endif
2193             }
2194             else
2195             {
2196                 memcpy(GlobalLock(lpRender->hData32),
2197                     GlobalLock16(lpRender->hData16), size);
2198             }
2199
2200             GlobalUnlock(lpRender->hData32);
2201             GlobalUnlock16(lpRender->hData16);
2202         }
2203
2204         if (phData16)
2205             *phData16 = lpRender->hData16;
2206
2207         if (phData32)
2208             *phData32 = lpRender->hData32;
2209
2210         TRACE(" returning hData16(%04x) hData32(%04x) (type %d)\n", 
2211             lpRender->hData16, (unsigned int) lpRender->hData32, lpRender->wFormatID);
2212
2213         return lpRender->hData16 || lpRender->hData32;
2214     }
2215
2216     return 0;
2217 }
2218
2219
2220 /**************************************************************************
2221  *              ResetSelectionOwner (X11DRV.@)
2222  *
2223  * Called from DestroyWindow() to prevent X selection from being lost when
2224  * a top level window is destroyed, by switching ownership to another top
2225  * level window.
2226  * Any top level window can own the selection. See X11DRV_CLIPBOARD_Acquire
2227  * for a more detailed description of this.
2228  */
2229 void X11DRV_ResetSelectionOwner(HWND hwnd, BOOL bFooBar)
2230 {
2231     Display *display = thread_display();
2232     HWND hWndClipOwner = 0;
2233     HWND tmp;
2234     Window XWnd = X11DRV_get_whole_window(hwnd);
2235     BOOL bLostSelection = FALSE;
2236     Window selectionPrevWindow;
2237
2238     /* There is nothing to do if we don't own the selection,
2239      * or if the X window which currently owns the selection is different
2240      * from the one passed in.
2241      */
2242     if (!selectionAcquired || XWnd != selectionWindow
2243          || selectionWindow == None )
2244        return;
2245
2246     if ((bFooBar && XWnd) || (!bFooBar && !XWnd))
2247        return;
2248
2249     hWndClipOwner = GetClipboardOwner();
2250
2251     TRACE("clipboard owner = %p, selection window = %08x\n",
2252           hWndClipOwner, (unsigned)selectionWindow);
2253
2254     /* now try to salvage current selection from being destroyed by X */
2255     TRACE("checking %08x\n", (unsigned) XWnd);
2256
2257     selectionPrevWindow = selectionWindow;
2258     selectionWindow = None;
2259
2260     if (!(tmp = GetWindow(hwnd, GW_HWNDNEXT)))
2261         tmp = GetWindow(hwnd, GW_HWNDFIRST);
2262
2263     if (tmp && tmp != hwnd) 
2264         selectionWindow = X11DRV_get_whole_window(tmp);
2265
2266     if (selectionWindow != None)
2267     {
2268         /* We must pretend that we don't own the selection while making the switch
2269          * since a SelectionClear event will be sent to the last owner.
2270          * If there is no owner X11DRV_CLIPBOARD_ReleaseSelection will do nothing.
2271          */
2272         int saveSelectionState = selectionAcquired;
2273         selectionAcquired = S_NOSELECTION;
2274
2275         TRACE("\tswitching selection from %08x to %08x\n",
2276                     (unsigned)selectionPrevWindow, (unsigned)selectionWindow);
2277
2278         wine_tsx11_lock();
2279
2280         /* Assume ownership for the PRIMARY and CLIPBOARD selection */
2281         if (saveSelectionState & S_PRIMARY)
2282             XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
2283
2284         XSetSelectionOwner(display, x11drv_atom(CLIPBOARD), selectionWindow, CurrentTime);
2285
2286         /* Restore the selection masks */
2287         selectionAcquired = saveSelectionState;
2288
2289         /* Lose the selection if something went wrong */
2290         if (((saveSelectionState & S_PRIMARY) &&
2291            (XGetSelectionOwner(display, XA_PRIMARY) != selectionWindow)) || 
2292            (XGetSelectionOwner(display, x11drv_atom(CLIPBOARD)) != selectionWindow))
2293         {
2294             bLostSelection = TRUE;
2295         }
2296         else
2297         {
2298             /* Update selection state */
2299             if (saveSelectionState & S_PRIMARY)
2300                PrimarySelectionOwner = selectionWindow;
2301
2302             ClipboardSelectionOwner = selectionWindow;
2303         }
2304         wine_tsx11_unlock();
2305     }
2306     else
2307     {
2308         bLostSelection = TRUE;
2309     }
2310
2311     if (bLostSelection)
2312     {
2313         TRACE("Lost the selection!\n");
2314
2315         X11DRV_CLIPBOARD_ReleaseOwnership();
2316         selectionAcquired = S_NOSELECTION;
2317         ClipboardSelectionOwner = PrimarySelectionOwner = 0;
2318         selectionWindow = 0;
2319     }
2320 }
2321
2322
2323 /**************************************************************************
2324  *                      X11DRV_CLIPBOARD_SynthesizeData
2325  */
2326 static BOOL X11DRV_CLIPBOARD_SynthesizeData(UINT wFormatID)
2327 {
2328     BOOL bsyn = TRUE;
2329     LPWINE_CLIPDATA lpSource = NULL;
2330
2331     TRACE(" %d\n", wFormatID);
2332
2333     /* Don't need to synthesize if it already exists */
2334     if (X11DRV_CLIPBOARD_LookupData(wFormatID))
2335         return TRUE;
2336
2337     if (wFormatID == CF_UNICODETEXT || wFormatID == CF_TEXT || wFormatID == CF_OEMTEXT)
2338     {
2339         bsyn = ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_UNICODETEXT)) &&
2340             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED) ||
2341             ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_TEXT)) &&
2342             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED) ||
2343             ((lpSource = X11DRV_CLIPBOARD_LookupData(CF_OEMTEXT)) &&
2344             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED);
2345     }
2346     else if (wFormatID == CF_ENHMETAFILE)
2347     {
2348         bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_METAFILEPICT)) &&
2349             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
2350     }
2351     else if (wFormatID == CF_METAFILEPICT)
2352     {
2353         bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_METAFILEPICT)) &&
2354             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
2355     }
2356     else if (wFormatID == CF_DIB)
2357     {
2358         bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_BITMAP)) &&
2359             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
2360     }
2361     else if (wFormatID == CF_BITMAP)
2362     {
2363         bsyn = (lpSource = X11DRV_CLIPBOARD_LookupData(CF_DIB)) &&
2364             ~lpSource->wFlags & CF_FLAG_SYNTHESIZED;
2365     }
2366
2367     if (bsyn)
2368         X11DRV_CLIPBOARD_InsertClipboardData(wFormatID, 0, 0, CF_FLAG_SYNTHESIZED);
2369
2370     return bsyn;
2371 }
2372
2373
2374
2375 /**************************************************************************
2376  *              X11DRV_EndClipboardUpdate
2377  * TODO:
2378  *  Add locale if it hasn't already been added
2379  */
2380 void X11DRV_EndClipboardUpdate(void)
2381 {
2382     INT count = ClipDataCount;
2383
2384     /* Do Unicode <-> Text <-> OEM mapping */
2385     X11DRV_CLIPBOARD_SynthesizeData(CF_UNICODETEXT);
2386     X11DRV_CLIPBOARD_SynthesizeData(CF_TEXT);
2387     X11DRV_CLIPBOARD_SynthesizeData(CF_OEMTEXT);
2388
2389     /* Enhmetafile <-> MetafilePict mapping */
2390     X11DRV_CLIPBOARD_SynthesizeData(CF_ENHMETAFILE);
2391     X11DRV_CLIPBOARD_SynthesizeData(CF_METAFILEPICT);
2392
2393     /* DIB <-> Bitmap mapping */
2394     X11DRV_CLIPBOARD_SynthesizeData(CF_DIB);
2395     X11DRV_CLIPBOARD_SynthesizeData(CF_BITMAP);
2396
2397     TRACE("%d formats added to cached data\n", ClipDataCount - count);
2398 }