Fix a couple of 64bit platform problems and speed up compilation. See
[wine/multimedia.git] / windows / clipboard.c
blob5f2737645252f6cf0894786d6135f1535dadb3ad
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 "windows.h"
16 #include "win.h"
17 #include "heap.h"
18 #include "message.h"
19 #include "queue.h"
20 #include "task.h"
21 #include "clipboard.h"
22 #include "xmalloc.h"
23 #include "debug.h"
25 #ifndef X_DISPLAY_MISSING
26 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
27 #else /* X_DISPLAY_MISSING */
28 extern CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver;
29 #endif /* X_DISPLAY_MISSING */
31 #define CF_REGFORMATBASE 0xC000
33 /**************************************************************************
34 * internal variables
37 static HQUEUE16 hqClipLock = 0;
38 static BOOL32 bCBHasChanged = FALSE;
40 HWND32 hWndClipOwner = 0; /* current clipboard owner */
41 HWND32 hWndClipWindow = 0; /* window that opened clipboard */
42 static HWND32 hWndViewer = 0; /* start of viewers chain */
44 static WORD LastRegFormat = CF_REGFORMATBASE;
46 CLIPFORMAT ClipFormats[16] = {
47 { CF_TEXT, 1, 0, "Text", (HANDLE32)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
48 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE32)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
49 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
50 { CF_SYLK, 1, 0, "Sylk", (HANDLE32)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
51 { CF_DIF, 1, 0, "DIF", (HANDLE32)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
52 { CF_TIFF, 1, 0, "TIFF", (HANDLE32)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
53 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE32)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
54 { CF_DIB, 1, 0, "DIB", (HANDLE32)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
55 { CF_PALETTE, 1, 0, "Palette", (HANDLE32)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
56 { CF_PENDATA, 1, 0, "PenData", (HANDLE32)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
57 { CF_RIFF, 1, 0, "RIFF", (HANDLE32)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
58 { CF_WAVE, 1, 0, "Wave", (HANDLE32)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
59 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE32)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
60 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE32)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
61 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
62 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE32)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
65 static LPCLIPFORMAT __lookup_format( LPCLIPFORMAT lpFormat, WORD wID )
67 while(TRUE)
69 if (lpFormat == NULL ||
70 lpFormat->wFormatID == wID) break;
71 lpFormat = lpFormat->NextFormat;
73 return lpFormat;
77 /**************************************************************************
78 * CLIPBOARD_GetDriver
80 CLIPBOARD_DRIVER *CLIPBOARD_GetDriver()
82 #ifndef X_DISPLAY_MISSING
83 return &X11DRV_CLIPBOARD_Driver;
84 #else /* X_DISPLAY_MISSING */
85 return &TTYDRV_CLIPBOARD_Driver;
86 #endif /* X_DISPLAY_MISSING */
89 /**************************************************************************
90 * CLIPBOARD_ResetLock
92 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
94 if( hqClipLock == hqCurrent )
96 if( hqNew )
97 hqClipLock = hqNew;
98 else
100 hWndClipOwner = 0;
101 hWndClipWindow = 0;
102 EmptyClipboard32();
103 hqClipLock = 0;
109 /**************************************************************************
110 * CLIPBOARD_DeleteRecord
112 void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat, BOOL32 bChange)
114 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
115 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
117 if (lpFormat->hData32)
118 DeleteObject32(lpFormat->hData32);
119 if (lpFormat->hData16)
120 DeleteObject16(lpFormat->hData16);
122 else if( lpFormat->wFormatID == CF_METAFILEPICT )
124 if (lpFormat->hData32)
126 DeleteMetaFile32( ((METAFILEPICT32 *)GlobalLock32( lpFormat->hData32 ))->hMF );
127 GlobalFree32(lpFormat->hData32);
128 if (lpFormat->hData16)
129 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
130 and a shallow copy is enough to share a METAFILEPICT
131 structure between 16bit and 32bit clipboards. The MetaFile
132 should of course only be deleted once. */
133 GlobalFree16(lpFormat->hData16);
135 else if (lpFormat->hData16)
137 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
138 GlobalFree16(lpFormat->hData16);
141 else
143 if (lpFormat->hData32)
144 GlobalFree32(lpFormat->hData32);
145 if (lpFormat->hData16)
146 GlobalFree16(lpFormat->hData16);
149 lpFormat->wDataPresent = 0;
150 lpFormat->hData16 = 0;
151 lpFormat->hData32 = 0;
153 if( bChange ) bCBHasChanged = TRUE;
156 /**************************************************************************
157 * CLIPBOARD_IsPresent
159 BOOL32 CLIPBOARD_IsPresent(WORD wFormat)
161 /* special case */
163 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
164 return ClipFormats[CF_TEXT-1].wDataPresent ||
165 ClipFormats[CF_OEMTEXT-1].wDataPresent;
166 else
168 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
169 if( lpFormat ) return (lpFormat->wDataPresent);
171 return FALSE;
174 /**************************************************************************
175 * OpenClipboard16 (USER.137)
177 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
179 return OpenClipboard32( hWnd );
183 /**************************************************************************
184 * OpenClipboard32 (USER32.407)
186 * Note: Netscape uses NULL hWnd to open the clipboard.
188 BOOL32 WINAPI OpenClipboard32( HWND32 hWnd )
190 BOOL32 bRet;
192 TRACE(clipboard,"(%04x)...\n", hWnd);
194 if (!hqClipLock)
196 hqClipLock = GetFastQueue();
197 hWndClipWindow = hWnd;
198 bCBHasChanged = FALSE;
199 bRet = TRUE;
201 else bRet = FALSE;
203 TRACE(clipboard," returning %i\n", bRet);
204 return bRet;
208 /**************************************************************************
209 * CloseClipboard16 (USER.138)
211 BOOL16 WINAPI CloseClipboard16(void)
213 return CloseClipboard32();
217 /**************************************************************************
218 * CloseClipboard32 (USER32.54)
220 BOOL32 WINAPI CloseClipboard32(void)
222 TRACE(clipboard,"!\n");
224 if (hqClipLock == GetFastQueue())
226 hWndClipWindow = 0;
228 if (bCBHasChanged && hWndViewer)
229 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
230 hqClipLock = 0;
232 return TRUE;
236 /**************************************************************************
237 * EmptyClipboard16 (USER.139)
239 BOOL16 WINAPI EmptyClipboard16(void)
241 return EmptyClipboard32();
245 /**************************************************************************
246 * EmptyClipboard32 (USER32.169)
248 BOOL32 WINAPI EmptyClipboard32(void)
250 LPCLIPFORMAT lpFormat = ClipFormats;
252 TRACE(clipboard,"(void)\n");
254 if (hqClipLock != GetFastQueue()) return FALSE;
256 /* destroy private objects */
258 if (hWndClipOwner)
259 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
261 while(lpFormat)
263 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
264 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
266 lpFormat = lpFormat->NextFormat;
269 hWndClipOwner = hWndClipWindow;
271 CLIPBOARD_GetDriver()->pEmptyClipboard();
273 return TRUE;
277 /**************************************************************************
278 * GetClipboardOwner16 (USER.140)
280 HWND16 WINAPI GetClipboardOwner16(void)
282 return hWndClipOwner;
286 /**************************************************************************
287 * GetClipboardOwner32 (USER32.225)
289 HWND32 WINAPI GetClipboardOwner32(void)
291 return hWndClipOwner;
295 /**************************************************************************
296 * SetClipboardData16 (USER.141)
298 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
300 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
302 TRACE(clipboard, "(%04X, %04x) !\n", wFormat, hData);
304 /* NOTE: If the hData is zero and current owner doesn't match
305 * the window that opened the clipboard then this application
306 * is screwed because WM_RENDERFORMAT will go to the owner
307 * (to become the owner it must call EmptyClipboard() before
308 * adding new data).
311 if( (hqClipLock != GetFastQueue()) || !lpFormat ||
312 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
314 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
316 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
318 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
320 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
322 if( wFormat == CF_TEXT
323 && ( ClipFormats[CF_OEMTEXT-1].hData16
324 || ClipFormats[CF_OEMTEXT-1].hData32 )
325 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
326 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
327 if( wFormat == CF_OEMTEXT
328 && ( ClipFormats[CF_OEMTEXT-1].hData16
329 || ClipFormats[CF_OEMTEXT-1].hData32 )
330 && !ClipFormats[CF_TEXT-1].wDataPresent )
331 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
334 bCBHasChanged = TRUE;
335 lpFormat->wDataPresent = 1;
336 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
337 lpFormat->hData32 = 0;
339 return lpFormat->hData16;
343 /**************************************************************************
344 * SetClipboardData32 (USER32.470)
346 HANDLE32 WINAPI SetClipboardData32( UINT32 wFormat, HANDLE32 hData )
348 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
350 TRACE(clipboard, "(%08X, %08x) !\n", wFormat, hData);
352 /* NOTE: If the hData is zero and current owner doesn't match
353 * the window that opened the clipboard then this application
354 * is screwed because WM_RENDERFORMAT will go to the owner
355 * (to become the owner it must call EmptyClipboard() before
356 * adding new data).
359 if( (hqClipLock != GetFastQueue()) || !lpFormat ||
360 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
362 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
364 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
366 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
368 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
370 if( wFormat == CF_TEXT
371 && ( ClipFormats[CF_OEMTEXT-1].hData16
372 || ClipFormats[CF_OEMTEXT-1].hData32 )
373 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
374 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
375 if( wFormat == CF_OEMTEXT
376 && ( ClipFormats[CF_OEMTEXT-1].hData16
377 || ClipFormats[CF_OEMTEXT-1].hData32 )
378 && !ClipFormats[CF_TEXT-1].wDataPresent )
379 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
382 bCBHasChanged = TRUE;
383 lpFormat->wDataPresent = 1;
384 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
385 lpFormat->hData16 = 0;
387 return lpFormat->hData32;
391 /**************************************************************************
392 * CLIPBOARD_RenderFormat
394 static BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
396 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
398 if( IsWindow32(hWndClipOwner) )
399 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
400 (WPARAM16)lpFormat->wFormatID,0L);
401 else
403 WARN(clipboard, "\thWndClipOwner (%04x) is lost!\n",
404 hWndClipOwner);
405 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
406 return FALSE;
409 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
412 /**************************************************************************
413 * CLIPBOARD_RenderText
415 * Convert text between UNIX and DOS formats.
417 static BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
419 UINT16 size;
420 LPCSTR lpstrS;
421 LPSTR lpstrT;
423 if (lpSource->hData32)
425 size = GlobalSize32( lpSource->hData32 );
426 lpstrS = (LPSTR)GlobalLock32(lpSource->hData32);
428 else
430 size = GlobalSize16( lpSource->hData16 );
431 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
434 if( !lpstrS ) return FALSE;
435 TRACE(clipboard,"\tconverting from '%s' to '%s', %i chars\n",
436 lpSource->Name, lpTarget->Name, size);
438 lpTarget->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
439 lpstrT = (LPSTR)GlobalLock32(lpTarget->hData32);
441 if( lpstrT )
443 if( lpSource->wFormatID == CF_TEXT )
444 CharToOemBuff32A(lpstrS, lpstrT, size);
445 else
446 OemToCharBuff32A(lpstrS, lpstrT, size);
447 TRACE(clipboard,"\tgot %s\n", lpstrT);
448 GlobalUnlock32(lpTarget->hData32);
449 if (lpSource->hData32)
450 GlobalUnlock32(lpSource->hData32);
451 else
452 GlobalUnlock16(lpSource->hData16);
453 return TRUE;
456 lpTarget->hData32 = 0;
457 if (lpSource->hData32)
458 GlobalUnlock32(lpSource->hData32);
459 else
460 GlobalUnlock16(lpSource->hData16);
461 return FALSE;
464 /**************************************************************************
465 * GetClipboardData16 (USER.142)
467 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
469 LPCLIPFORMAT lpRender = ClipFormats;
470 LPCLIPFORMAT lpUpdate = NULL;
472 if (hqClipLock != GetFastQueue()) return 0;
474 TRACE(clipboard,"(%04X)\n", wFormat);
476 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
477 && lpRender[CF_OEMTEXT-1].wDataPresent )
479 lpRender = &ClipFormats[CF_OEMTEXT-1];
480 lpUpdate = &ClipFormats[CF_TEXT-1];
482 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
484 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
485 && lpRender[CF_TEXT-1].wDataPresent )
487 lpRender = &ClipFormats[CF_TEXT-1];
488 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
490 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
492 else
494 lpRender = __lookup_format( ClipFormats, wFormat );
495 lpUpdate = lpRender;
498 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
499 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
500 CLIPBOARD_RenderText(lpUpdate, lpRender);
502 if( lpUpdate->hData32 && !lpUpdate->hData16 )
504 int size;
505 if( lpUpdate->wFormatID == CF_METAFILEPICT )
506 size = sizeof( METAFILEPICT16 );
507 else
508 size = GlobalSize32(lpUpdate->hData32);
509 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
510 if( !lpUpdate->hData16 )
511 ERR(clipboard, "(%04X) -- not enough memory in 16b heap\n", wFormat);
512 else
514 if( lpUpdate->wFormatID == CF_METAFILEPICT )
516 FIXME(clipboard,"\timplement function CopyMetaFilePict32to16\n");
517 FIXME(clipboard,"\tin the appropriate file.\n");
518 #ifdef SOMEONE_IMPLEMENTED_ME
519 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
520 GlobalLock32(lpUpdate->hData32) );
521 #endif
523 else
525 memcpy( GlobalLock16(lpUpdate->hData16),
526 GlobalLock32(lpUpdate->hData32),
527 size );
529 GlobalUnlock16(lpUpdate->hData16);
530 GlobalUnlock32(lpUpdate->hData32);
534 TRACE(clipboard,"\treturning %04x (type %i)\n",
535 lpUpdate->hData16, lpUpdate->wFormatID);
536 return lpUpdate->hData16;
540 /**************************************************************************
541 * GetClipboardData32 (USER32.222)
543 HANDLE32 WINAPI GetClipboardData32( UINT32 wFormat )
545 LPCLIPFORMAT lpRender = ClipFormats;
546 LPCLIPFORMAT lpUpdate = NULL;
548 if (hqClipLock != GetFastQueue()) return 0;
550 TRACE(clipboard,"(%08X)\n", wFormat);
552 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
553 && lpRender[CF_OEMTEXT-1].wDataPresent )
555 lpRender = &ClipFormats[CF_OEMTEXT-1];
556 lpUpdate = &ClipFormats[CF_TEXT-1];
558 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
560 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
561 && lpRender[CF_TEXT-1].wDataPresent )
563 lpRender = &ClipFormats[CF_TEXT-1];
564 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
566 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
568 else
570 lpRender = __lookup_format( ClipFormats, wFormat );
571 lpUpdate = lpRender;
574 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
575 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
576 CLIPBOARD_RenderText(lpUpdate, lpRender);
578 if( lpUpdate->hData16 && !lpUpdate->hData32 )
580 int size;
581 if( lpUpdate->wFormatID == CF_METAFILEPICT )
582 size = sizeof( METAFILEPICT32 );
583 else
584 size = GlobalSize16(lpUpdate->hData16);
585 lpUpdate->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
586 if( lpUpdate->wFormatID == CF_METAFILEPICT )
588 FIXME(clipboard,"\timplement function CopyMetaFilePict16to32\n");
589 FIXME(clipboard,"\tin the appropriate file.\n");
590 #ifdef SOMEONE_IMPLEMENTED_ME
591 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
592 GlobalLock32(lpUpdate->hData16) );
593 #endif
595 else
597 memcpy( GlobalLock32(lpUpdate->hData32),
598 GlobalLock16(lpUpdate->hData16),
599 size );
601 GlobalUnlock32(lpUpdate->hData32);
602 GlobalUnlock16(lpUpdate->hData16);
605 TRACE(clipboard,"\treturning %04x (type %i)\n",
606 lpUpdate->hData32, lpUpdate->wFormatID);
607 return lpUpdate->hData32;
610 /**************************************************************************
611 * CountClipboardFormats16 (USER.143)
613 INT16 WINAPI CountClipboardFormats16(void)
615 return CountClipboardFormats32();
619 /**************************************************************************
620 * CountClipboardFormats32 (USER32.63)
622 INT32 WINAPI CountClipboardFormats32(void)
624 INT32 FormatCount = 0;
625 LPCLIPFORMAT lpFormat = ClipFormats;
627 TRACE(clipboard,"(void)\n");
629 /* FIXME: Returns BOOL32 */
630 CLIPBOARD_GetDriver()->pRequestSelection();
632 FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
633 lpFormat[CF_OEMTEXT-1].wDataPresent);
635 while(TRUE)
637 if (lpFormat == NULL) break;
638 if (lpFormat->wDataPresent)
640 TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
641 FormatCount++;
643 lpFormat = lpFormat->NextFormat;
646 TRACE(clipboard,"\ttotal %d\n", FormatCount);
647 return FormatCount;
651 /**************************************************************************
652 * EnumClipboardFormats16 (USER.144)
654 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
656 return EnumClipboardFormats32( wFormat );
660 /**************************************************************************
661 * EnumClipboardFormats32 (USER32.179)
663 UINT32 WINAPI EnumClipboardFormats32( UINT32 wFormat )
665 LPCLIPFORMAT lpFormat = ClipFormats;
667 TRACE(clipboard,"(%04X)\n", wFormat);
669 if( hqClipLock != GetFastQueue() ) return 0;
671 if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
672 CLIPBOARD_GetDriver()->pRequestSelection();
674 if (wFormat == 0)
676 if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent)
677 return lpFormat->wFormatID;
678 else
679 wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
682 /* walk up to the specified format record */
684 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
686 /* find next format with available data */
688 lpFormat = lpFormat->NextFormat;
689 while(TRUE)
691 if (lpFormat == NULL) return 0;
692 if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT &&
693 ClipFormats[CF_TEXT-1].wDataPresent))
694 break;
695 lpFormat = lpFormat->NextFormat;
698 return lpFormat->wFormatID;
702 /**************************************************************************
703 * RegisterClipboardFormat16 (USER.145)
705 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
707 LPCLIPFORMAT lpNewFormat;
708 LPCLIPFORMAT lpFormat = ClipFormats;
710 if (FormatName == NULL) return 0;
712 TRACE(clipboard,"('%s') !\n", FormatName);
714 /* walk format chain to see if it's already registered */
716 while(TRUE)
718 if ( !strcmp(lpFormat->Name,FormatName) )
720 lpFormat->wRefCount++;
721 return lpFormat->wFormatID;
724 if ( lpFormat->NextFormat == NULL ) break;
726 lpFormat = lpFormat->NextFormat;
729 /* allocate storage for new format entry */
731 lpNewFormat = (LPCLIPFORMAT)xmalloc(sizeof(CLIPFORMAT));
732 lpFormat->NextFormat = lpNewFormat;
733 lpNewFormat->wFormatID = LastRegFormat;
734 lpNewFormat->wRefCount = 1;
736 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
737 strcpy(lpNewFormat->Name, FormatName);
739 lpNewFormat->wDataPresent = 0;
740 lpNewFormat->hData16 = 0;
741 lpNewFormat->hData32 = 0;
742 lpNewFormat->BufSize = 0;
743 lpNewFormat->PrevFormat = lpFormat;
744 lpNewFormat->NextFormat = NULL;
746 return LastRegFormat++;
750 /**************************************************************************
751 * RegisterClipboardFormat32A (USER32.431)
753 UINT32 WINAPI RegisterClipboardFormat32A( LPCSTR formatName )
755 return RegisterClipboardFormat16( formatName );
759 /**************************************************************************
760 * RegisterClipboardFormat32W (USER32.432)
762 UINT32 WINAPI RegisterClipboardFormat32W( LPCWSTR formatName )
764 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
765 UINT32 ret = RegisterClipboardFormat32A( aFormat );
766 HeapFree( GetProcessHeap(), 0, aFormat );
767 return ret;
770 /**************************************************************************
771 * GetClipboardFormatName16 (USER.146)
773 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
775 return GetClipboardFormatName32A( wFormat, retStr, maxlen );
779 /**************************************************************************
780 * GetClipboardFormatName32A (USER32.223)
782 INT32 WINAPI GetClipboardFormatName32A( UINT32 wFormat, LPSTR retStr, INT32 maxlen )
784 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
786 TRACE(clipboard, "(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
788 if (lpFormat == NULL || lpFormat->Name == NULL ||
789 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
791 TRACE(clipboard, "Name='%s' !\n", lpFormat->Name);
793 lstrcpyn32A( retStr, lpFormat->Name, maxlen );
794 return strlen(retStr);
798 /**************************************************************************
799 * GetClipboardFormatName32W (USER32.224)
801 INT32 WINAPI GetClipboardFormatName32W( UINT32 wFormat, LPWSTR retStr, INT32 maxlen )
803 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
804 INT32 ret = GetClipboardFormatName32A( wFormat, p, maxlen );
805 lstrcpynAtoW( retStr, p, maxlen );
806 HeapFree( GetProcessHeap(), 0, p );
807 return ret;
811 /**************************************************************************
812 * SetClipboardViewer16 (USER.147)
814 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
816 return SetClipboardViewer32( hWnd );
820 /**************************************************************************
821 * SetClipboardViewer32 (USER32.471)
823 HWND32 WINAPI SetClipboardViewer32( HWND32 hWnd )
825 HWND32 hwndPrev = hWndViewer;
827 TRACE(clipboard,"(%04x): returning %04x\n", hWnd, hwndPrev);
829 hWndViewer = hWnd;
830 return hwndPrev;
834 /**************************************************************************
835 * GetClipboardViewer16 (USER.148)
837 HWND16 WINAPI GetClipboardViewer16(void)
839 return hWndViewer;
843 /**************************************************************************
844 * GetClipboardViewer32 (USER32.226)
846 HWND32 WINAPI GetClipboardViewer32(void)
848 return hWndViewer;
852 /**************************************************************************
853 * ChangeClipboardChain16 (USER.149)
855 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
857 return ChangeClipboardChain32(hWnd, hWndNext);
860 /**************************************************************************
861 * ChangeClipboardChain32 (USER32.22)
863 BOOL32 WINAPI ChangeClipboardChain32(HWND32 hWnd, HWND32 hWndNext)
865 BOOL32 bRet = 0;
867 FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
869 if( hWndViewer )
870 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
871 (WPARAM16)hWnd, (LPARAM)hWndNext);
872 else
873 WARN(clipboard, "hWndViewer is lost\n");
875 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
877 return bRet;
882 /**************************************************************************
883 * IsClipboardFormatAvailable16 (USER.193)
885 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
887 return IsClipboardFormatAvailable32( wFormat );
891 /**************************************************************************
892 * IsClipboardFormatAvailable32 (USER32.340)
894 BOOL32 WINAPI IsClipboardFormatAvailable32( UINT32 wFormat )
896 TRACE(clipboard,"(%04X) !\n", wFormat);
898 if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
899 CLIPBOARD_GetDriver()->pRequestSelection();
901 return CLIPBOARD_IsPresent(wFormat);
905 /**************************************************************************
906 * GetOpenClipboardWindow16 (USER.248)
908 HWND16 WINAPI GetOpenClipboardWindow16(void)
910 return hWndClipWindow;
914 /**************************************************************************
915 * GetOpenClipboardWindow32 (USER32.277)
917 HWND32 WINAPI GetOpenClipboardWindow32(void)
919 return hWndClipWindow;
923 /**************************************************************************
924 * GetPriorityClipboardFormat16 (USER.402)
926 INT16 WINAPI GetPriorityClipboardFormat16( UINT16 *lpPriorityList, INT16 nCount)
928 FIXME(clipboard, "(%p,%d): stub\n", lpPriorityList, nCount );
929 return 0;
933 /**************************************************************************
934 * GetPriorityClipboardFormat32 (USER32.279)
936 INT32 WINAPI GetPriorityClipboardFormat32( UINT32 *lpPriorityList, INT32 nCount )
938 int Counter;
940 if(CountClipboardFormats32() == 0)
942 return 0;
945 for(Counter = 0; Counter <= nCount; Counter++)
947 if(IsClipboardFormatAvailable32(*(lpPriorityList+sizeof(INT32)*Counter)))
948 return *(lpPriorityList+sizeof(INT32)*Counter);
951 return -1;