Remove file from cache when flushing it (based on a patch by Ian
[wine/wine-kai.git] / windows / clipboard.c
blob542b02c715ba5f5bae65229190978798863099fc
1 /*
2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
5 * 1996 Alex Korobka
7 */
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include "winuser.h"
16 #include "wine/winuser16.h"
17 #include "heap.h"
18 #include "task.h"
19 #include "message.h"
20 #include "clipboard.h"
21 #include "xmalloc.h"
22 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(clipboard)
26 #define CF_REGFORMATBASE 0xC000
28 /**************************************************************************
29 * internal variables
32 CLIPBOARD_DRIVER *CLIPBOARD_Driver = NULL;
34 static HQUEUE16 hqClipLock = 0;
35 static BOOL bCBHasChanged = FALSE;
37 HWND hWndClipOwner = 0; /* current clipboard owner */
38 HWND hWndClipWindow = 0; /* window that opened clipboard */
39 static HWND hWndViewer = 0; /* start of viewers chain */
41 static WORD LastRegFormat = CF_REGFORMATBASE;
43 WINE_CLIPFORMAT ClipFormats[16] = {
44 { CF_TEXT, 1, 0, "Text", (HANDLE)NULL, (HANDLE)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
45 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
46 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
47 { CF_SYLK, 1, 0, "Sylk", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
48 { CF_DIF, 1, 0, "DIF", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
49 { CF_TIFF, 1, 0, "TIFF", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
50 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
51 { CF_DIB, 1, 0, "DIB", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
52 { CF_PALETTE, 1, 0, "Palette", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
53 { CF_PENDATA, 1, 0, "PenData", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
54 { CF_RIFF, 1, 0, "RIFF", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
55 { CF_WAVE, 1, 0, "Wave", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
56 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
57 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
58 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
59 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE)NULL, (HANDLE)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
62 static LPWINE_CLIPFORMAT __lookup_format( LPWINE_CLIPFORMAT lpFormat, WORD wID )
64 while(TRUE)
66 if (lpFormat == NULL ||
67 lpFormat->wFormatID == wID) break;
68 lpFormat = lpFormat->NextFormat;
70 return lpFormat;
73 /**************************************************************************
74 * CLIPBOARD_ResetLock
76 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
78 if( hqClipLock == hqCurrent )
80 if( hqNew )
81 hqClipLock = hqNew;
82 else
84 hWndClipOwner = 0;
85 hWndClipWindow = 0;
86 EmptyClipboard();
87 hqClipLock = 0;
93 /**************************************************************************
94 * CLIPBOARD_DeleteRecord
96 void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange)
98 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
99 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
101 if (lpFormat->hData32)
102 DeleteObject(lpFormat->hData32);
103 if (lpFormat->hData16)
104 DeleteObject16(lpFormat->hData16);
106 else if( lpFormat->wFormatID == CF_METAFILEPICT )
108 if (lpFormat->hData32)
110 DeleteMetaFile( ((METAFILEPICT *)GlobalLock( lpFormat->hData32 ))->hMF );
111 GlobalFree(lpFormat->hData32);
112 if (lpFormat->hDataSrc32)
113 GlobalFree(lpFormat->hDataSrc32);
114 if (lpFormat->hData16)
115 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
116 and a shallow copy is enough to share a METAFILEPICT
117 structure between 16bit and 32bit clipboards. The MetaFile
118 should of course only be deleted once. */
119 GlobalFree16(lpFormat->hData16);
121 if (lpFormat->hData16)
123 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
124 GlobalFree16(lpFormat->hData16);
127 else
129 if (lpFormat->hData32)
130 GlobalFree(lpFormat->hData32);
131 if (lpFormat->hDataSrc32)
132 GlobalFree(lpFormat->hDataSrc32);
133 if (lpFormat->hData16)
134 GlobalFree16(lpFormat->hData16);
137 lpFormat->wDataPresent = 0;
138 lpFormat->hData16 = 0;
139 lpFormat->hData32 = 0;
141 if( bChange ) bCBHasChanged = TRUE;
144 /**************************************************************************
145 * CLIPBOARD_IsPresent
147 BOOL CLIPBOARD_IsPresent(WORD wFormat)
149 /* special case */
151 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
152 return ClipFormats[CF_TEXT-1].wDataPresent ||
153 ClipFormats[CF_OEMTEXT-1].wDataPresent;
154 else
156 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
157 if( lpFormat ) return (lpFormat->wDataPresent);
159 return FALSE;
162 /**************************************************************************
163 * CLIPBOARD_IsMemoryObject
164 * Tests if the clipboard format specifies a memory object
166 BOOL CLIPBOARD_IsMemoryObject( WORD wFormat )
168 switch(wFormat)
170 case CF_BITMAP:
171 case CF_METAFILEPICT:
172 case CF_DSPTEXT:
173 case CF_ENHMETAFILE:
174 case CF_HDROP:
175 case CF_PALETTE:
176 case CF_PENDATA:
177 return FALSE;
178 default:
179 return TRUE;
183 /***********************************************************************
184 * CLIPBOARD_GlobalDupMem( HGLOBAL )
185 * Helper method to duplicate an HGLOBAL chunk of memory into shared memory
187 HGLOBAL CLIPBOARD_GlobalDupMem( HGLOBAL hGlobalSrc )
189 HGLOBAL hGlobalDest;
190 PVOID pGlobalSrc, pGlobalDest;
191 DWORD cBytes;
193 if ( !hGlobalSrc )
194 return 0;
196 cBytes = GlobalSize(hGlobalSrc);
197 if ( 0 == cBytes )
198 return 0;
200 /* Turn on the DDESHARE and _MOVEABLE flags explicitly */
201 hGlobalDest = GlobalAlloc( GlobalFlags(hGlobalSrc) | GMEM_DDESHARE | GMEM_MOVEABLE,
202 cBytes );
203 if ( !hGlobalDest )
204 return 0;
206 pGlobalSrc = GlobalLock(hGlobalSrc);
207 pGlobalDest = GlobalLock(hGlobalDest);
208 if ( !pGlobalSrc || !pGlobalDest )
209 return 0;
211 memcpy(pGlobalDest, pGlobalSrc, cBytes);
213 GlobalUnlock(hGlobalSrc);
214 GlobalUnlock(hGlobalDest);
216 return hGlobalDest;
219 /**************************************************************************
220 * OpenClipboard16 (USER.137)
222 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
224 return OpenClipboard( hWnd );
228 /**************************************************************************
229 * OpenClipboard32 (USER32.407)
231 * Note: Netscape uses NULL hWnd to open the clipboard.
233 BOOL WINAPI OpenClipboard( HWND hWnd )
235 BOOL bRet;
237 TRACE("(%04x)...\n", hWnd);
239 if (!hqClipLock)
241 hqClipLock = GetFastQueue16();
242 hWndClipWindow = hWnd;
243 bCBHasChanged = FALSE;
244 bRet = TRUE;
246 else bRet = FALSE;
248 TRACE(" returning %i\n", bRet);
249 return bRet;
253 /**************************************************************************
254 * CloseClipboard16 (USER.138)
256 BOOL16 WINAPI CloseClipboard16(void)
258 return CloseClipboard();
262 /**************************************************************************
263 * CloseClipboard32 (USER32.54)
265 BOOL WINAPI CloseClipboard(void)
267 TRACE("!\n");
269 if (hqClipLock == GetFastQueue16())
271 hWndClipWindow = 0;
273 if (bCBHasChanged && hWndViewer)
274 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
275 hqClipLock = 0;
277 return TRUE;
281 /**************************************************************************
282 * EmptyClipboard16 (USER.139)
284 BOOL16 WINAPI EmptyClipboard16(void)
286 return EmptyClipboard();
290 /**************************************************************************
291 * EmptyClipboard32 (USER32.169)
293 BOOL WINAPI EmptyClipboard(void)
295 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
297 TRACE("(void)\n");
299 if (hqClipLock != GetFastQueue16()) return FALSE;
301 /* destroy private objects */
303 if (hWndClipOwner)
304 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
306 while(lpFormat)
308 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
309 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
311 lpFormat = lpFormat->NextFormat;
314 hWndClipOwner = hWndClipWindow;
316 CLIPBOARD_Driver->pEmpty();
318 return TRUE;
322 /**************************************************************************
323 * GetClipboardOwner16 (USER.140)
325 HWND16 WINAPI GetClipboardOwner16(void)
327 return hWndClipOwner;
331 /**************************************************************************
332 * GetClipboardOwner32 (USER32.225)
334 HWND WINAPI GetClipboardOwner(void)
336 return hWndClipOwner;
340 /**************************************************************************
341 * SetClipboardData16 (USER.141)
343 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
345 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
347 TRACE("(%04X, %04x) !\n", wFormat, hData);
349 /* NOTE: If the hData is zero and current owner doesn't match
350 * the window that opened the clipboard then this application
351 * is screwed because WM_RENDERFORMAT will go to the owner
352 * (to become the owner it must call EmptyClipboard() before
353 * adding new data).
356 if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
357 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
359 CLIPBOARD_Driver->pSetData(wFormat);
361 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
363 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
365 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
367 if( wFormat == CF_TEXT
368 && ( ClipFormats[CF_OEMTEXT-1].hData16
369 || ClipFormats[CF_OEMTEXT-1].hData32 )
370 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
371 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
372 if( wFormat == CF_OEMTEXT
373 && ( ClipFormats[CF_OEMTEXT-1].hData16
374 || ClipFormats[CF_OEMTEXT-1].hData32 )
375 && !ClipFormats[CF_TEXT-1].wDataPresent )
376 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
379 bCBHasChanged = TRUE;
380 lpFormat->wDataPresent = 1;
381 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
382 lpFormat->hData32 = 0;
384 return lpFormat->hData16;
388 /**************************************************************************
389 * SetClipboardData (USER32.470)
391 HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
393 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
395 TRACE("(%08X, %08x) !\n", wFormat, hData);
397 /* NOTE: If the hData is zero and current owner doesn't match
398 * the window that opened the clipboard then this application
399 * is screwed because WM_RENDERFORMAT will go to the owner
400 * (to become the owner it must call EmptyClipboard() before
401 * adding new data).
404 if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
405 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
407 CLIPBOARD_Driver->pSetData(wFormat);
409 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
411 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
413 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
415 if( wFormat == CF_TEXT
416 && ( ClipFormats[CF_OEMTEXT-1].hData16
417 || ClipFormats[CF_OEMTEXT-1].hData32 )
418 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
419 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
420 if( wFormat == CF_OEMTEXT
421 && ( ClipFormats[CF_OEMTEXT-1].hData16
422 || ClipFormats[CF_OEMTEXT-1].hData32 )
423 && !ClipFormats[CF_TEXT-1].wDataPresent )
424 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
427 bCBHasChanged = TRUE;
428 lpFormat->wDataPresent = 1;
429 lpFormat->hDataSrc32 = hData; /* Save the source handle */
432 * Make a shared duplicate if the memory is not shared
433 * TODO: What should be done for non-memory objects
435 if ( CLIPBOARD_IsMemoryObject(wFormat) && hData && !(GlobalFlags(hData) & GMEM_DDESHARE) )
436 lpFormat->hData32 = CLIPBOARD_GlobalDupMem( hData );
437 else
438 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
440 lpFormat->hData16 = 0;
442 return lpFormat->hData32;
446 /**************************************************************************
447 * CLIPBOARD_RenderFormat
449 static BOOL CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat)
451 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
453 if( IsWindow(hWndClipOwner) )
454 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
455 (WPARAM16)lpFormat->wFormatID,0L);
456 else
458 WARN("\thWndClipOwner (%04x) is lost!\n",
459 hWndClipOwner);
460 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
461 return FALSE;
464 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
467 /**************************************************************************
468 * CLIPBOARD_RenderText
470 * Convert text between UNIX and DOS formats.
472 * FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
475 static BOOL CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget, LPWINE_CLIPFORMAT lpSource)
477 UINT16 size;
478 LPCSTR lpstrS;
479 LPSTR lpstrT;
481 if (lpSource->hData32)
483 size = GlobalSize( lpSource->hData32 );
484 lpstrS = (LPSTR)GlobalLock(lpSource->hData32);
486 else
488 size = GlobalSize16( lpSource->hData16 );
489 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
492 if( !lpstrS ) return FALSE;
493 TRACE("\tconverting from '%s' to '%s', %i chars\n",
494 lpSource->Name, lpTarget->Name, size);
496 lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT, size);
497 lpstrT = (LPSTR)GlobalLock(lpTarget->hData32);
499 if( lpstrT )
501 if( lpSource->wFormatID == CF_TEXT )
502 CharToOemBuffA(lpstrS, lpstrT, size);
503 else
504 OemToCharBuffA(lpstrS, lpstrT, size);
505 TRACE("\tgot %s\n", lpstrT);
506 GlobalUnlock(lpTarget->hData32);
507 if (lpSource->hData32)
508 GlobalUnlock(lpSource->hData32);
509 else
510 GlobalUnlock16(lpSource->hData16);
511 return TRUE;
514 lpTarget->hData32 = 0;
515 if (lpSource->hData32)
516 GlobalUnlock(lpSource->hData32);
517 else
518 GlobalUnlock16(lpSource->hData16);
519 return FALSE;
522 /**************************************************************************
523 * GetClipboardData16 (USER.142)
525 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
527 LPWINE_CLIPFORMAT lpRender = ClipFormats;
528 LPWINE_CLIPFORMAT lpUpdate = NULL;
530 if (hqClipLock != GetFastQueue16()) return 0;
532 TRACE("(%04X)\n", wFormat);
534 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
535 && lpRender[CF_OEMTEXT-1].wDataPresent )
537 lpRender = &ClipFormats[CF_OEMTEXT-1];
538 lpUpdate = &ClipFormats[CF_TEXT-1];
540 TRACE("\tOEMTEXT -> TEXT\n");
542 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
543 && lpRender[CF_TEXT-1].wDataPresent )
545 lpRender = &ClipFormats[CF_TEXT-1];
546 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
548 TRACE("\tTEXT -> OEMTEXT\n");
550 else
552 lpRender = __lookup_format( ClipFormats, wFormat );
553 lpUpdate = lpRender;
556 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
557 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
558 CLIPBOARD_RenderText(lpUpdate, lpRender);
560 if( lpUpdate->hData32 && !lpUpdate->hData16 )
562 int size;
563 if( lpUpdate->wFormatID == CF_METAFILEPICT )
564 size = sizeof( METAFILEPICT16 );
565 else
566 size = GlobalSize(lpUpdate->hData32);
567 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
568 if( !lpUpdate->hData16 )
569 ERR("(%04X) -- not enough memory in 16b heap\n", wFormat);
570 else
572 if( lpUpdate->wFormatID == CF_METAFILEPICT )
574 FIXME("\timplement function CopyMetaFilePict32to16\n");
575 FIXME("\tin the appropriate file.\n");
576 #ifdef SOMEONE_IMPLEMENTED_ME
577 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
578 GlobalLock(lpUpdate->hData32) );
579 #endif
581 else
583 memcpy( GlobalLock16(lpUpdate->hData16),
584 GlobalLock(lpUpdate->hData32),
585 size );
587 GlobalUnlock16(lpUpdate->hData16);
588 GlobalUnlock(lpUpdate->hData32);
592 TRACE("\treturning %04x (type %i)\n",
593 lpUpdate->hData16, lpUpdate->wFormatID);
594 return lpUpdate->hData16;
598 /**************************************************************************
599 * GetClipboardData32 (USER32.222)
601 HANDLE WINAPI GetClipboardData( UINT wFormat )
603 LPWINE_CLIPFORMAT lpRender = ClipFormats;
604 LPWINE_CLIPFORMAT lpUpdate = NULL;
606 if (hqClipLock != GetFastQueue16()) return 0;
608 TRACE("(%08X)\n", wFormat);
610 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
611 && lpRender[CF_OEMTEXT-1].wDataPresent )
613 lpRender = &ClipFormats[CF_OEMTEXT-1];
614 lpUpdate = &ClipFormats[CF_TEXT-1];
616 TRACE("\tOEMTEXT -> TEXT\n");
618 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
619 && lpRender[CF_TEXT-1].wDataPresent )
621 lpRender = &ClipFormats[CF_TEXT-1];
622 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
624 TRACE("\tTEXT -> OEMTEXT\n");
626 else
628 lpRender = __lookup_format( ClipFormats, wFormat );
629 lpUpdate = lpRender;
632 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
633 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
634 CLIPBOARD_RenderText(lpUpdate, lpRender);
636 if( lpUpdate->hData16 && !lpUpdate->hData32 )
638 int size;
639 if( lpUpdate->wFormatID == CF_METAFILEPICT )
640 size = sizeof( METAFILEPICT );
641 else
642 size = GlobalSize16(lpUpdate->hData16);
643 lpUpdate->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE,
644 size);
645 if( lpUpdate->wFormatID == CF_METAFILEPICT )
647 FIXME("\timplement function CopyMetaFilePict16to32\n");
648 FIXME("\tin the appropriate file.\n");
649 #ifdef SOMEONE_IMPLEMENTED_ME
650 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
651 GlobalLock(lpUpdate->hData16) );
652 #endif
654 else
656 memcpy( GlobalLock(lpUpdate->hData32),
657 GlobalLock16(lpUpdate->hData16),
658 size );
660 GlobalUnlock(lpUpdate->hData32);
661 GlobalUnlock16(lpUpdate->hData16);
664 TRACE("\treturning %04x (type %i)\n",
665 lpUpdate->hData32, lpUpdate->wFormatID);
666 return lpUpdate->hData32;
669 /**************************************************************************
670 * CountClipboardFormats16 (USER.143)
672 INT16 WINAPI CountClipboardFormats16(void)
674 return CountClipboardFormats();
678 /**************************************************************************
679 * CountClipboardFormats32 (USER32.63)
681 INT WINAPI CountClipboardFormats(void)
683 INT FormatCount = 0;
684 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
686 TRACE("(void)\n");
688 while(TRUE)
690 if (lpFormat == NULL) break;
692 if( lpFormat->wFormatID != CF_TEXT )
693 CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
695 if (lpFormat->wDataPresent)
697 TRACE("\tdata found for format %i\n", lpFormat->wFormatID);
698 FormatCount++;
700 lpFormat = lpFormat->NextFormat;
703 /* these two are equivalent, adjust the total */
705 FormatCount += abs(ClipFormats[CF_TEXT-1].wDataPresent -
706 ClipFormats[CF_OEMTEXT-1].wDataPresent);
708 TRACE("\ttotal %d\n", FormatCount);
709 return FormatCount;
713 /**************************************************************************
714 * EnumClipboardFormats16 (USER.144)
716 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
718 return EnumClipboardFormats( wFormat );
722 /**************************************************************************
723 * EnumClipboardFormats32 (USER32.179)
725 UINT WINAPI EnumClipboardFormats( UINT wFormat )
727 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
729 TRACE("(%04X)\n", wFormat);
731 if( hqClipLock != GetFastQueue16() ) return 0;
733 if( wFormat < CF_OEMTEXT )
734 CLIPBOARD_Driver->pGetData( CF_OEMTEXT );
736 if (wFormat == 0) /* start from the beginning */
737 lpFormat = ClipFormats;
738 else
740 /* walk up to the specified format record */
742 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) )
743 return 0;
744 lpFormat = lpFormat->NextFormat; /* right */
747 while(TRUE)
749 if (lpFormat == NULL) return 0;
751 if( lpFormat->wFormatID != CF_OEMTEXT && lpFormat->wFormatID != CF_TEXT )
752 CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
754 if (lpFormat->wDataPresent ||
755 (lpFormat->wFormatID == CF_OEMTEXT && ClipFormats[CF_TEXT-1].wDataPresent) ||
756 (lpFormat->wFormatID == CF_TEXT && ClipFormats[CF_OEMTEXT-1].wDataPresent) )
757 break;
758 lpFormat = lpFormat->NextFormat;
761 return lpFormat->wFormatID;
765 /**************************************************************************
766 * RegisterClipboardFormat16 (USER.145)
768 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
770 LPWINE_CLIPFORMAT lpNewFormat;
771 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
773 if (FormatName == NULL) return 0;
775 TRACE("('%s') !\n", FormatName);
777 /* walk format chain to see if it's already registered */
779 while(TRUE)
781 if ( !strcmp(lpFormat->Name,FormatName) )
783 lpFormat->wRefCount++;
784 return lpFormat->wFormatID;
787 if ( lpFormat->NextFormat == NULL ) break;
789 lpFormat = lpFormat->NextFormat;
792 /* allocate storage for new format entry */
794 lpNewFormat = (LPWINE_CLIPFORMAT)xmalloc(sizeof(WINE_CLIPFORMAT));
795 lpFormat->NextFormat = lpNewFormat;
796 lpNewFormat->wFormatID = LastRegFormat;
797 lpNewFormat->wRefCount = 1;
799 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
800 strcpy(lpNewFormat->Name, FormatName);
802 lpNewFormat->wDataPresent = 0;
803 lpNewFormat->hData16 = 0;
804 lpNewFormat->hDataSrc32 = 0;
805 lpNewFormat->hData32 = 0;
806 lpNewFormat->BufSize = 0;
807 lpNewFormat->PrevFormat = lpFormat;
808 lpNewFormat->NextFormat = NULL;
810 return LastRegFormat++;
814 /**************************************************************************
815 * RegisterClipboardFormat32A (USER32.431)
817 UINT WINAPI RegisterClipboardFormatA( LPCSTR formatName )
819 return RegisterClipboardFormat16( formatName );
823 /**************************************************************************
824 * RegisterClipboardFormat32W (USER32.432)
826 UINT WINAPI RegisterClipboardFormatW( LPCWSTR formatName )
828 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
829 UINT ret = RegisterClipboardFormatA( aFormat );
830 HeapFree( GetProcessHeap(), 0, aFormat );
831 return ret;
834 /**************************************************************************
835 * GetClipboardFormatName16 (USER.146)
837 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
839 return GetClipboardFormatNameA( wFormat, retStr, maxlen );
843 /**************************************************************************
844 * GetClipboardFormatName32A (USER32.223)
846 INT WINAPI GetClipboardFormatNameA( UINT wFormat, LPSTR retStr, INT maxlen )
848 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
850 TRACE("(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
852 if (lpFormat == NULL || lpFormat->Name == NULL ||
853 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
855 TRACE("Name='%s' !\n", lpFormat->Name);
857 lstrcpynA( retStr, lpFormat->Name, maxlen );
858 return strlen(retStr);
862 /**************************************************************************
863 * GetClipboardFormatName32W (USER32.224)
865 INT WINAPI GetClipboardFormatNameW( UINT wFormat, LPWSTR retStr, INT maxlen )
867 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
868 INT ret = GetClipboardFormatNameA( wFormat, p, maxlen );
869 lstrcpynAtoW( retStr, p, maxlen );
870 HeapFree( GetProcessHeap(), 0, p );
871 return ret;
875 /**************************************************************************
876 * SetClipboardViewer16 (USER.147)
878 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
880 return SetClipboardViewer( hWnd );
884 /**************************************************************************
885 * SetClipboardViewer32 (USER32.471)
887 HWND WINAPI SetClipboardViewer( HWND hWnd )
889 HWND hwndPrev = hWndViewer;
891 TRACE("(%04x): returning %04x\n", hWnd, hwndPrev);
893 hWndViewer = hWnd;
894 return hwndPrev;
898 /**************************************************************************
899 * GetClipboardViewer16 (USER.148)
901 HWND16 WINAPI GetClipboardViewer16(void)
903 return hWndViewer;
907 /**************************************************************************
908 * GetClipboardViewer32 (USER32.226)
910 HWND WINAPI GetClipboardViewer(void)
912 return hWndViewer;
916 /**************************************************************************
917 * ChangeClipboardChain16 (USER.149)
919 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
921 return ChangeClipboardChain(hWnd, hWndNext);
924 /**************************************************************************
925 * ChangeClipboardChain32 (USER32.22)
927 BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
929 BOOL bRet = 0;
931 FIXME("(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
933 if( hWndViewer )
934 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
935 (WPARAM16)hWnd, (LPARAM)hWndNext);
936 else
937 WARN("hWndViewer is lost\n");
939 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
941 return bRet;
946 /**************************************************************************
947 * IsClipboardFormatAvailable16 (USER.193)
949 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
951 return IsClipboardFormatAvailable( wFormat );
955 /**************************************************************************
956 * IsClipboardFormatAvailable32 (USER32.340)
958 BOOL WINAPI IsClipboardFormatAvailable( UINT wFormat )
960 TRACE("(%04X) !\n", wFormat);
962 CLIPBOARD_Driver->pGetData( (wFormat == CF_TEXT) ? CF_OEMTEXT : wFormat );
964 return CLIPBOARD_IsPresent(wFormat);
968 /**************************************************************************
969 * GetOpenClipboardWindow16 (USER.248)
971 HWND16 WINAPI GetOpenClipboardWindow16(void)
973 return hWndClipWindow;
977 /**************************************************************************
978 * GetOpenClipboardWindow32 (USER32.277)
980 HWND WINAPI GetOpenClipboardWindow(void)
982 return hWndClipWindow;
986 /**************************************************************************
987 * GetPriorityClipboardFormat16 (USER.402)
989 INT16 WINAPI GetPriorityClipboardFormat16( UINT16 *lpPriorityList, INT16 nCount)
991 FIXME("(%p,%d): stub\n", lpPriorityList, nCount );
992 return 0;
996 /**************************************************************************
997 * GetPriorityClipboardFormat32 (USER32.279)
999 INT WINAPI GetPriorityClipboardFormat( UINT *lpPriorityList, INT nCount )
1001 int Counter;
1003 if(CountClipboardFormats() == 0)
1005 return 0;
1008 for(Counter = 0; Counter <= nCount; Counter++)
1010 if(IsClipboardFormatAvailable(*(lpPriorityList+sizeof(INT)*Counter)))
1011 return *(lpPriorityList+sizeof(INT)*Counter);
1014 return -1;