Include <arpa/nameser.h> before <resolv.h>.
[wine] / windows / clipboard.c
1 /*
2  * WIN32 clipboard implementation
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 implementation for the WIN32 Clipboard API
25  * and Wine's internal clipboard cache.
26  * The actual contents of the clipboard are held in the clipboard cache.
27  * The internal implementation talks to a "clipboard driver" to fill or
28  * expose the cache to the native device. (Currently only the X11 and
29  * TTY clipboard  driver are available)
30  */
31
32 #include "config.h"
33 #include "wine/port.h"
34
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <sys/types.h>
38 #include <fcntl.h>
39 #ifdef HAVE_UNISTD_H
40 # include <unistd.h>
41 #endif
42 #include <string.h>
43
44 #include "windef.h"
45 #include "winbase.h"
46 #include "wingdi.h"
47 #include "winuser.h"
48 #include "winerror.h"
49 #include "wine/winuser16.h"
50 #include "wine/winbase16.h"
51 #include "heap.h"
52 #include "user.h"
53 #include "win.h"
54 #include "clipboard.h"
55
56 #include "wine/debug.h"
57 #include "wine/unicode.h"
58 #include "wine/server.h"
59
60 WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
61
62 #define  CF_REGFORMATBASE       0xC000
63
64
65 /*
66  * Indicates if data has changed since open.
67  */
68 static BOOL bCBHasChanged = FALSE;
69
70
71 /**************************************************************************
72  *                      CLIPBOARD_SetClipboardOwner
73  */
74 BOOL CLIPBOARD_SetClipboardOwner(HWND hWnd)
75 {
76     BOOL bRet = FALSE;
77
78     TRACE(" hWnd(%p)\n", hWnd);
79
80     SERVER_START_REQ( set_clipboard_info )
81     {
82         req->flags = SET_CB_OWNER;
83         req->owner = WIN_GetFullHandle( hWnd );
84
85         if (wine_server_call_err( req ))
86         {
87             ERR("Failed to set clipboard.\n");
88         }
89         else
90         {
91             bRet = TRUE;
92         }
93     }
94     SERVER_END_REQ;
95
96     return bRet;
97 }
98
99
100 /**************************************************************************
101  *                      CLIPBOARD_GetClipboardInfo
102  */
103 BOOL CLIPBOARD_GetClipboardInfo(LPCLIPBOARDINFO cbInfo)
104 {
105     BOOL bRet = FALSE;
106
107     SERVER_START_REQ( set_clipboard_info )
108     {
109         req->flags = 0;
110
111         if (wine_server_call_err( req ))
112         {
113             ERR("Failed to get clipboard owner.\n");
114         }
115         else
116         {
117             cbInfo->hWndOpen = reply->old_clipboard;
118             cbInfo->hWndOwner = reply->old_owner;
119             cbInfo->hWndViewer = reply->old_viewer;
120             cbInfo->seqno = reply->seqno;
121             cbInfo->flags = reply->flags;
122
123             bRet = TRUE;
124         }
125     }
126     SERVER_END_REQ;
127
128     return bRet;
129 }
130
131
132 /**************************************************************************
133  *      CLIPBOARD_ReleaseOwner
134  */
135 BOOL CLIPBOARD_ReleaseOwner(void)
136 {
137     BOOL bRet = FALSE;
138
139     SERVER_START_REQ( set_clipboard_info )
140     {
141         req->flags = SET_CB_RELOWNER | SET_CB_SEQNO;
142
143         if (wine_server_call_err( req ))
144         {
145             ERR("Failed to set clipboard.\n");
146         }
147         else
148         {
149             bRet = TRUE;
150         }
151     }
152     SERVER_END_REQ;
153
154     return bRet;
155 }
156
157
158 /**************************************************************************
159  *              CLIPBOARD_OpenClipboard
160  */
161 static BOOL CLIPBOARD_OpenClipboard(HWND hWnd)
162 {
163     BOOL bRet = FALSE;
164
165     SERVER_START_REQ( set_clipboard_info )
166     {
167         req->flags = SET_CB_OPEN;
168         req->clipboard = WIN_GetFullHandle( hWnd );
169
170         if (wine_server_call_err( req ))
171         {
172             ERR("Failed to set clipboard.\n");
173         }
174         else
175         {
176             bRet = TRUE;
177         }
178     }
179     SERVER_END_REQ;
180
181     return bRet;
182 }
183
184
185 /**************************************************************************
186  *              CLIPBOARD_CloseClipboard
187  */
188 static BOOL CLIPBOARD_CloseClipboard(void)
189 {
190     BOOL bRet = FALSE;
191
192     TRACE(" Changed=%d\n", bCBHasChanged);
193
194     SERVER_START_REQ( set_clipboard_info )
195     {
196         req->flags = SET_CB_CLOSE;
197
198         if (bCBHasChanged)
199         {
200             req->flags |= SET_CB_SEQNO;
201             TRACE("Clipboard data changed\n");
202         }
203
204         if (wine_server_call_err( req ))
205         {
206             ERR("Failed to set clipboard.\n");
207         }
208         else
209         {
210             bRet = TRUE;
211         }
212     }
213     SERVER_END_REQ;
214
215     return bRet;
216 }
217
218
219 /**************************************************************************
220  *                WIN32 Clipboard implementation
221  **************************************************************************/
222
223 /**************************************************************************
224  *              RegisterClipboardFormatA (USER32.@)
225  */
226 UINT WINAPI RegisterClipboardFormatA(LPCSTR FormatName)
227 {
228     UINT wFormatID = 0;
229
230     TRACE("%s\n", debugstr_a(FormatName));
231
232     if (USER_Driver.pRegisterClipboardFormat)
233         wFormatID = USER_Driver.pRegisterClipboardFormat(FormatName);
234
235     return wFormatID;
236 }
237
238
239 /**************************************************************************
240  *              RegisterClipboardFormat (USER.145)
241  */
242 UINT16 WINAPI RegisterClipboardFormat16(LPCSTR FormatName)
243 {
244     UINT wFormatID = 0;
245
246     TRACE("%s\n", debugstr_a(FormatName));
247
248     if (USER_Driver.pRegisterClipboardFormat)
249         wFormatID = USER_Driver.pRegisterClipboardFormat(FormatName);
250
251     return wFormatID;
252 }
253
254
255 /**************************************************************************
256  *              RegisterClipboardFormatW (USER32.@)
257  */
258 UINT WINAPI RegisterClipboardFormatW(LPCWSTR formatName)
259 {
260     LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
261     UINT ret = RegisterClipboardFormatA( aFormat );
262     HeapFree( GetProcessHeap(), 0, aFormat );
263     return ret;
264 }
265
266
267 /**************************************************************************
268  *              GetClipboardFormatName (USER.146)
269  */
270 INT16 WINAPI GetClipboardFormatName16(UINT16 wFormat, LPSTR retStr, INT16 maxlen)
271 {
272     TRACE("%04x,%p,%d\n", wFormat, retStr, maxlen);
273
274     return GetClipboardFormatNameA(wFormat, retStr, maxlen);
275 }
276
277
278 /**************************************************************************
279  *              GetClipboardFormatNameA (USER32.@)
280  */
281 INT WINAPI GetClipboardFormatNameA(UINT wFormat, LPSTR retStr, INT maxlen)
282 {
283     INT len = 0;
284
285     TRACE("%04x,%p,%d\n", wFormat, retStr, maxlen);
286
287     if (USER_Driver.pGetClipboardFormatName)
288         len = USER_Driver.pGetClipboardFormatName(wFormat, retStr, maxlen);
289
290     return len;
291 }
292
293
294 /**************************************************************************
295  *              GetClipboardFormatNameW (USER32.@)
296  */
297 INT WINAPI GetClipboardFormatNameW(UINT wFormat, LPWSTR retStr, INT maxlen)
298 {
299     INT ret;
300     LPSTR p = HeapAlloc( GetProcessHeap(), 0, maxlen );
301     if(p == NULL) return 0; /* FIXME: is this the correct failure value? */
302
303     ret = GetClipboardFormatNameA( wFormat, p, maxlen );
304
305     if (maxlen > 0 && !MultiByteToWideChar( CP_ACP, 0, p, -1, retStr, maxlen ))
306         retStr[maxlen-1] = 0;
307     HeapFree( GetProcessHeap(), 0, p );
308     return ret;
309 }
310
311
312 /**************************************************************************
313  *              OpenClipboard (USER32.@)
314  *
315  * Note: Netscape uses NULL hWnd to open the clipboard.
316  */
317 BOOL WINAPI OpenClipboard( HWND hWnd )
318 {
319     BOOL bRet;
320
321     TRACE("(%p)...\n", hWnd);
322
323     bRet = CLIPBOARD_OpenClipboard(hWnd);
324
325     TRACE(" returning %i\n", bRet);
326
327     return bRet;
328 }
329
330
331 /**************************************************************************
332  *              CloseClipboard (USER.138)
333  */
334 BOOL16 WINAPI CloseClipboard16(void)
335 {
336     return CloseClipboard();
337 }
338
339
340 /**************************************************************************
341  *              CloseClipboard (USER32.@)
342  */
343 BOOL WINAPI CloseClipboard(void)
344 {
345     BOOL bRet = FALSE;
346
347     TRACE("(%d)\n", bCBHasChanged);
348
349     if (CLIPBOARD_CloseClipboard())
350     {
351         if (bCBHasChanged)
352         {
353             HWND hWndViewer = GetClipboardViewer();
354
355             if (USER_Driver.pEndClipboardUpdate)
356                 USER_Driver.pEndClipboardUpdate();
357  
358             if (hWndViewer)
359                 SendMessageW(hWndViewer, WM_DRAWCLIPBOARD, 0, 0);
360  
361             bCBHasChanged = FALSE;
362         }
363
364         bRet = TRUE;
365     }
366
367     return bRet;
368 }
369
370
371 /**************************************************************************
372  *              EmptyClipboard (USER.139)
373  */
374 BOOL16 WINAPI EmptyClipboard16(void)
375 {
376     return EmptyClipboard();
377 }
378
379
380 /**************************************************************************
381  *              EmptyClipboard (USER32.@)
382  * Empties and acquires ownership of the clipboard
383  */
384 BOOL WINAPI EmptyClipboard(void)
385 {
386     CLIPBOARDINFO cbinfo;
387  
388     TRACE("()\n");
389
390     if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
391         ~cbinfo.flags & CB_OPEN)
392     { 
393         WARN("Clipboard not opened by calling task!\n");
394         SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
395         return FALSE;
396     }
397
398     /* Destroy private objects */
399     if (cbinfo.hWndOwner) 
400         SendMessageW(cbinfo.hWndOwner, WM_DESTROYCLIPBOARD, 0, 0);
401
402     /* Tell the driver to acquire the selection. The current owner
403      * will be signaled to delete it's own cache. */
404     if (~cbinfo.flags & CB_OWNER)
405     {
406         /* Assign ownership of the clipboard to the current client. We do
407          * this before acquiring the selection so that when we do acquire the
408          * selection and the selection loser gets notified, it can check if 
409          * it has lost the Wine clipboard ownership. If it did then it knows
410          * that a WM_DESTORYCLIPBOARD has already been sent. Otherwise it
411          * lost the selection to a X app and it should send the 
412          * WM_DESTROYCLIPBOARD itself. */
413         CLIPBOARD_SetClipboardOwner(cbinfo.hWndOpen);
414
415         /* Acquire the selection. This will notify the previous owner
416          * to clear it's cache. */ 
417         if (USER_Driver.pAcquireClipboard) 
418             USER_Driver.pAcquireClipboard(cbinfo.hWndOpen);
419     }
420
421     /* Empty the local cache */
422     if (USER_Driver.pEmptyClipboard) 
423         USER_Driver.pEmptyClipboard();
424  
425     bCBHasChanged = TRUE;
426
427     return TRUE;
428 }
429
430
431 /**************************************************************************
432  *              GetClipboardOwner (USER32.@)
433  *  FIXME: Can't return the owner if the clipboard is owned by an external X-app
434  */
435 HWND WINAPI GetClipboardOwner(void)
436 {
437     HWND hWndOwner = 0;
438     CLIPBOARDINFO cbinfo;
439
440     if (CLIPBOARD_GetClipboardInfo(&cbinfo))
441         hWndOwner = cbinfo.hWndOwner;
442
443     TRACE(" hWndOwner(%p)\n", hWndOwner);
444
445     return hWndOwner;
446 }
447
448
449 /**************************************************************************
450  *              GetOpenClipboardWindow (USER32.@)
451  */
452 HWND WINAPI GetOpenClipboardWindow(void)
453 {
454     HWND hWndOpen = 0;
455     CLIPBOARDINFO cbinfo;
456
457     if (CLIPBOARD_GetClipboardInfo(&cbinfo))
458         hWndOpen = cbinfo.hWndOpen;
459
460     TRACE(" hWndClipWindow(%p)\n", hWndOpen);
461
462     return hWndOpen;
463 }
464
465
466 /**************************************************************************
467  *              SetClipboardViewer (USER32.@)
468  */
469 HWND WINAPI SetClipboardViewer( HWND hWnd )
470 {
471     HWND hwndPrev = 0;
472  
473     SERVER_START_REQ( set_clipboard_info )
474     {
475         req->flags = SET_CB_VIEWER;
476         req->viewer = WIN_GetFullHandle(hWnd);
477  
478         if (wine_server_call_err( req ))
479         {
480             ERR("Failed to set clipboard.\n");
481         }
482         else
483         {
484             hwndPrev = reply->old_viewer;
485         }
486     }
487     SERVER_END_REQ;
488  
489     TRACE("(%p): returning %p\n", hWnd, hwndPrev);
490   
491     return hwndPrev;
492 }
493
494
495 /**************************************************************************
496  *              GetClipboardViewer (USER32.@)
497  */
498 HWND WINAPI GetClipboardViewer(void)
499 {
500     HWND hWndViewer = 0;
501     CLIPBOARDINFO cbinfo;
502
503     if (CLIPBOARD_GetClipboardInfo(&cbinfo))
504         hWndViewer = cbinfo.hWndViewer;
505
506     TRACE(" hWndViewer=%p\n", hWndViewer);
507
508     return hWndViewer;
509 }
510
511
512 /**************************************************************************
513  *              ChangeClipboardChain (USER32.@)
514  */
515 BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
516 {
517     BOOL bRet = TRUE;
518     HWND hWndViewer = GetClipboardViewer();
519
520     if (hWndViewer)
521     {
522         if (WIN_GetFullHandle(hWnd) == hWndViewer) 
523             SetClipboardViewer(WIN_GetFullHandle(hWndNext));
524         else
525             bRet = !SendMessageW(hWndViewer, WM_CHANGECBCHAIN, (WPARAM)hWnd, (LPARAM)hWndNext);
526     }
527     else
528         ERR("hWndViewer is lost\n");
529
530     return bRet;
531 }
532
533
534 /**************************************************************************
535  *              SetClipboardData (USER.141)
536  */
537 HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData)
538 {
539     CLIPBOARDINFO cbinfo;
540     HANDLE16 hResult = 0;
541
542     TRACE("(%04X, %04x) !\n", wFormat, hData);
543
544     if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
545         (~cbinfo.flags & CB_OPEN) ||
546         (~cbinfo.flags & CB_OWNER))
547     {
548         WARN("Clipboard not opened by calling task!\n");
549     }
550     else if (USER_Driver.pSetClipboardData &&
551         USER_Driver.pSetClipboardData(wFormat, hData, 0))
552     {
553         hResult = hData;
554         bCBHasChanged = TRUE;
555     }
556
557     return hResult;
558 }
559
560
561 /**************************************************************************
562  *              SetClipboardData (USER32.@)
563  */
564 HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
565 {
566     CLIPBOARDINFO cbinfo;
567     HANDLE hResult = 0;
568
569     TRACE("(%04X, %p) !\n", wFormat, hData);
570
571     if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
572         (~cbinfo.flags & CB_OWNER))
573     {
574         WARN("Clipboard not owned by calling task!\n");
575     }
576     else if (USER_Driver.pSetClipboardData &&
577         USER_Driver.pSetClipboardData(wFormat, 0, hData))
578     {
579         hResult = hData;
580         bCBHasChanged = TRUE;
581     }
582
583     return hResult;
584 }
585
586
587 /**************************************************************************
588  *              CountClipboardFormats (USER.143)
589  */
590 INT16 WINAPI CountClipboardFormats16(void)
591 {
592     return CountClipboardFormats();
593 }
594
595
596 /**************************************************************************
597  *              CountClipboardFormats (USER32.@)
598  */
599 INT WINAPI CountClipboardFormats(void)
600 {
601     INT count = 0;
602
603     if (USER_Driver.pCountClipboardFormats)
604         count = USER_Driver.pCountClipboardFormats();
605
606     TRACE("returning %d\n", count);
607     return count;
608 }
609
610
611 /**************************************************************************
612  *              EnumClipboardFormats (USER.144)
613  */
614 UINT16 WINAPI EnumClipboardFormats16(UINT16 wFormat)
615 {
616     return EnumClipboardFormats(wFormat);
617 }
618
619
620 /**************************************************************************
621  *              EnumClipboardFormats (USER32.@)
622  */
623 UINT WINAPI EnumClipboardFormats(UINT wFormat)
624 {
625     UINT wFmt = 0;
626     CLIPBOARDINFO cbinfo;
627
628     TRACE("(%04X)\n", wFormat);
629
630     if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
631         (~cbinfo.flags & CB_OPEN))
632     {
633         WARN("Clipboard not opened by calling task.\n");
634         SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
635         return 0;
636     }
637
638     if (USER_Driver.pEnumClipboardFormats)
639         wFmt = USER_Driver.pEnumClipboardFormats(wFormat);
640
641     return wFmt;
642 }
643
644
645 /**************************************************************************
646  *              IsClipboardFormatAvailable (USER.193)
647  */
648 BOOL16 WINAPI IsClipboardFormatAvailable16(UINT16 wFormat)
649 {
650     return IsClipboardFormatAvailable(wFormat);
651 }
652
653
654 /**************************************************************************
655  *              IsClipboardFormatAvailable (USER32.@)
656  */
657 BOOL WINAPI IsClipboardFormatAvailable(UINT wFormat)
658 {
659     BOOL bret = FALSE;
660
661     if (USER_Driver.pIsClipboardFormatAvailable)
662         bret = USER_Driver.pIsClipboardFormatAvailable(wFormat);
663
664     TRACE("%04x, returning %d\n", wFormat, bret);
665     return bret;
666 }
667
668
669 /**************************************************************************
670  *              GetClipboardData (USER.142)
671  */
672 HANDLE16 WINAPI GetClipboardData16(UINT16 wFormat)
673 {
674     HANDLE16 hData = 0;
675     CLIPBOARDINFO cbinfo;
676
677     if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
678         (~cbinfo.flags & CB_OPEN))
679     {
680         WARN("Clipboard not opened by calling task.\n");
681         SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
682         return 0;
683     }
684
685     if (USER_Driver.pGetClipboardData)
686         USER_Driver.pGetClipboardData(wFormat, &hData, NULL);
687
688     return hData;
689 }
690
691
692 /**************************************************************************
693  *              GetClipboardData (USER32.@)
694  */
695 HANDLE WINAPI GetClipboardData(UINT wFormat)
696 {
697     HANDLE hData = 0;
698     CLIPBOARDINFO cbinfo;
699
700     TRACE("%04x\n", wFormat);
701
702     if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
703         (~cbinfo.flags & CB_OPEN))
704     {
705         WARN("Clipboard not opened by calling task.\n");
706         SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
707         return 0;
708     }
709
710     if (USER_Driver.pGetClipboardData)
711         USER_Driver.pGetClipboardData(wFormat, NULL, &hData);
712
713     TRACE("returning %p\n", hData);
714     return hData;
715 }
716
717
718 /**************************************************************************
719  *              GetPriorityClipboardFormat (USER32.@)
720  */
721 INT WINAPI GetPriorityClipboardFormat(UINT *list, INT nCount)
722 {
723     int i;
724
725     TRACE("()\n");
726
727     if(CountClipboardFormats() == 0)
728         return 0;
729
730     for (i = 0; i < nCount; i++)
731         if (IsClipboardFormatAvailable(list[i]))
732             return list[i];
733
734     return -1;
735 }
736
737
738 /**************************************************************************
739  *              GetClipboardSequenceNumber (USER32.@)
740  * Supported on Win2k/Win98
741  * MSDN: Windows clipboard code keeps a serial number for the clipboard
742  * for each window station.  The number is incremented whenever the
743  * contents change or are emptied.
744  * If you do not have WINSTA_ACCESSCLIPBOARD then the function returns 0
745  */
746 DWORD WINAPI GetClipboardSequenceNumber(VOID)
747 {
748     CLIPBOARDINFO cbinfo;
749
750     if (!CLIPBOARD_GetClipboardInfo(&cbinfo))
751     {
752         ERR("Failed to get clipboard information.\n");
753         return 0;
754     }
755
756     TRACE("returning %x\n", cbinfo.seqno);
757     return cbinfo.seqno;
758 }