Fixed CHECK_STRING display.
[wine/multimedia.git] / windows / clipboard.c
blobf6332478d58f2d011be16dfec159558a2daa6954
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 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
27 #define CF_REGFORMATBASE 0xC000
29 /**************************************************************************
30 * internal variables
33 static HQUEUE16 hqClipLock = 0;
34 static BOOL32 bCBHasChanged = FALSE;
36 HWND32 hWndClipOwner = 0; /* current clipboard owner */
37 HWND32 hWndClipWindow = 0; /* window that opened clipboard */
38 static HWND32 hWndViewer = 0; /* start of viewers chain */
40 static WORD LastRegFormat = CF_REGFORMATBASE;
42 CLIPFORMAT ClipFormats[16] = {
43 { CF_TEXT, 1, 0, "Text", (HANDLE32)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
44 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE32)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
45 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
46 { CF_SYLK, 1, 0, "Sylk", (HANDLE32)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
47 { CF_DIF, 1, 0, "DIF", (HANDLE32)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
48 { CF_TIFF, 1, 0, "TIFF", (HANDLE32)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
49 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE32)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
50 { CF_DIB, 1, 0, "DIB", (HANDLE32)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
51 { CF_PALETTE, 1, 0, "Palette", (HANDLE32)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
52 { CF_PENDATA, 1, 0, "PenData", (HANDLE32)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
53 { CF_RIFF, 1, 0, "RIFF", (HANDLE32)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
54 { CF_WAVE, 1, 0, "Wave", (HANDLE32)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
55 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE32)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
56 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE32)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
57 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
58 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE32)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
61 static LPCLIPFORMAT __lookup_format( LPCLIPFORMAT lpFormat, WORD wID )
63 while(TRUE)
65 if (lpFormat == NULL ||
66 lpFormat->wFormatID == wID) break;
67 lpFormat = lpFormat->NextFormat;
69 return lpFormat;
73 /**************************************************************************
74 * CLIPBOARD_GetDriver
76 CLIPBOARD_DRIVER *CLIPBOARD_GetDriver()
78 return &X11DRV_CLIPBOARD_Driver;
81 /**************************************************************************
82 * CLIPBOARD_ResetLock
84 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
86 if( hqClipLock == hqCurrent )
88 if( hqNew )
89 hqClipLock = hqNew;
90 else
92 hWndClipOwner = 0;
93 hWndClipWindow = 0;
94 EmptyClipboard32();
95 hqClipLock = 0;
101 /**************************************************************************
102 * CLIPBOARD_DeleteRecord
104 void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat, BOOL32 bChange)
106 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
107 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
109 if (lpFormat->hData32)
110 DeleteObject32(lpFormat->hData32);
111 if (lpFormat->hData16)
112 DeleteObject16(lpFormat->hData16);
114 else if( lpFormat->wFormatID == CF_METAFILEPICT )
116 if (lpFormat->hData32)
118 DeleteMetaFile32( ((METAFILEPICT32 *)GlobalLock32( lpFormat->hData32 ))->hMF );
119 GlobalFree32(lpFormat->hData32);
120 if (lpFormat->hData16)
121 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
122 and a shallow copy is enough to share a METAFILEPICT
123 structure between 16bit and 32bit clipboards. The MetaFile
124 should of course only be deleted once. */
125 GlobalFree16(lpFormat->hData16);
127 else if (lpFormat->hData16)
129 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
130 GlobalFree16(lpFormat->hData16);
133 else
135 if (lpFormat->hData32)
136 GlobalFree32(lpFormat->hData32);
137 if (lpFormat->hData16)
138 GlobalFree16(lpFormat->hData16);
141 lpFormat->wDataPresent = 0;
142 lpFormat->hData16 = 0;
143 lpFormat->hData32 = 0;
145 if( bChange ) bCBHasChanged = TRUE;
148 /**************************************************************************
149 * CLIPBOARD_IsPresent
151 BOOL32 CLIPBOARD_IsPresent(WORD wFormat)
153 /* special case */
155 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
156 return ClipFormats[CF_TEXT-1].wDataPresent ||
157 ClipFormats[CF_OEMTEXT-1].wDataPresent;
158 else
160 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
161 if( lpFormat ) return (lpFormat->wDataPresent);
163 return FALSE;
166 /**************************************************************************
167 * OpenClipboard16 (USER.137)
169 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
171 return OpenClipboard32( hWnd );
175 /**************************************************************************
176 * OpenClipboard32 (USER32.407)
178 * Note: Netscape uses NULL hWnd to open the clipboard.
180 BOOL32 WINAPI OpenClipboard32( HWND32 hWnd )
182 BOOL32 bRet;
184 TRACE(clipboard,"(%04x)...\n", hWnd);
186 if (!hqClipLock)
188 hqClipLock = GetFastQueue();
189 hWndClipWindow = hWnd;
190 bCBHasChanged = FALSE;
191 bRet = TRUE;
193 else bRet = FALSE;
195 TRACE(clipboard," returning %i\n", bRet);
196 return bRet;
200 /**************************************************************************
201 * CloseClipboard16 (USER.138)
203 BOOL16 WINAPI CloseClipboard16(void)
205 return CloseClipboard32();
209 /**************************************************************************
210 * CloseClipboard32 (USER32.54)
212 BOOL32 WINAPI CloseClipboard32(void)
214 TRACE(clipboard,"!\n");
216 if (hqClipLock == GetFastQueue())
218 hWndClipWindow = 0;
220 if (bCBHasChanged && hWndViewer)
221 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
222 hqClipLock = 0;
224 return TRUE;
228 /**************************************************************************
229 * EmptyClipboard16 (USER.139)
231 BOOL16 WINAPI EmptyClipboard16(void)
233 return EmptyClipboard32();
237 /**************************************************************************
238 * EmptyClipboard32 (USER32.169)
240 BOOL32 WINAPI EmptyClipboard32(void)
242 LPCLIPFORMAT lpFormat = ClipFormats;
244 TRACE(clipboard,"(void)\n");
246 if (hqClipLock != GetFastQueue()) return FALSE;
248 /* destroy private objects */
250 if (hWndClipOwner)
251 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
253 while(lpFormat)
255 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
256 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
258 lpFormat = lpFormat->NextFormat;
261 hWndClipOwner = hWndClipWindow;
263 CLIPBOARD_GetDriver()->pEmptyClipboard();
265 return TRUE;
269 /**************************************************************************
270 * GetClipboardOwner16 (USER.140)
272 HWND16 WINAPI GetClipboardOwner16(void)
274 return hWndClipOwner;
278 /**************************************************************************
279 * GetClipboardOwner32 (USER32.225)
281 HWND32 WINAPI GetClipboardOwner32(void)
283 return hWndClipOwner;
287 /**************************************************************************
288 * SetClipboardData16 (USER.141)
290 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
292 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
294 TRACE(clipboard, "(%04X, %04x) !\n", wFormat, hData);
296 /* NOTE: If the hData is zero and current owner doesn't match
297 * the window that opened the clipboard then this application
298 * is screwed because WM_RENDERFORMAT will go to the owner
299 * (to become the owner it must call EmptyClipboard() before
300 * adding new data).
303 if( (hqClipLock != GetFastQueue()) || !lpFormat ||
304 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
306 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
308 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
310 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
312 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
314 if( wFormat == CF_TEXT
315 && ( ClipFormats[CF_OEMTEXT-1].hData16
316 || ClipFormats[CF_OEMTEXT-1].hData32 )
317 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
318 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
319 if( wFormat == CF_OEMTEXT
320 && ( ClipFormats[CF_OEMTEXT-1].hData16
321 || ClipFormats[CF_OEMTEXT-1].hData32 )
322 && !ClipFormats[CF_TEXT-1].wDataPresent )
323 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
326 bCBHasChanged = TRUE;
327 lpFormat->wDataPresent = 1;
328 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
329 lpFormat->hData32 = 0;
331 return lpFormat->hData16;
335 /**************************************************************************
336 * SetClipboardData32 (USER32.470)
338 HANDLE32 WINAPI SetClipboardData32( UINT32 wFormat, HANDLE32 hData )
340 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
342 TRACE(clipboard, "(%08X, %08x) !\n", wFormat, hData);
344 /* NOTE: If the hData is zero and current owner doesn't match
345 * the window that opened the clipboard then this application
346 * is screwed because WM_RENDERFORMAT will go to the owner
347 * (to become the owner it must call EmptyClipboard() before
348 * adding new data).
351 if( (hqClipLock != GetFastQueue()) || !lpFormat ||
352 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
354 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
356 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
358 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
360 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
362 if( wFormat == CF_TEXT
363 && ( ClipFormats[CF_OEMTEXT-1].hData16
364 || ClipFormats[CF_OEMTEXT-1].hData32 )
365 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
366 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
367 if( wFormat == CF_OEMTEXT
368 && ( ClipFormats[CF_OEMTEXT-1].hData16
369 || ClipFormats[CF_OEMTEXT-1].hData32 )
370 && !ClipFormats[CF_TEXT-1].wDataPresent )
371 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
374 bCBHasChanged = TRUE;
375 lpFormat->wDataPresent = 1;
376 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
377 lpFormat->hData16 = 0;
379 return lpFormat->hData32;
383 /**************************************************************************
384 * CLIPBOARD_RenderFormat
386 static BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
388 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
390 if( IsWindow32(hWndClipOwner) )
391 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
392 (WPARAM16)lpFormat->wFormatID,0L);
393 else
395 WARN(clipboard, "\thWndClipOwner (%04x) is lost!\n",
396 hWndClipOwner);
397 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
398 return FALSE;
401 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
404 /**************************************************************************
405 * CLIPBOARD_RenderText
407 * Convert text between UNIX and DOS formats.
409 static BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
411 UINT16 size;
412 LPCSTR lpstrS;
413 LPSTR lpstrT;
415 if (lpSource->hData32)
417 size = GlobalSize32( lpSource->hData32 );
418 lpstrS = (LPSTR)GlobalLock32(lpSource->hData32);
420 else
422 size = GlobalSize16( lpSource->hData16 );
423 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
426 if( !lpstrS ) return FALSE;
427 TRACE(clipboard,"\tconverting from '%s' to '%s', %i chars\n",
428 lpSource->Name, lpTarget->Name, size);
430 lpTarget->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
431 lpstrT = (LPSTR)GlobalLock32(lpTarget->hData32);
433 if( lpstrT )
435 if( lpSource->wFormatID == CF_TEXT )
436 CharToOemBuff32A(lpstrS, lpstrT, size);
437 else
438 OemToCharBuff32A(lpstrS, lpstrT, size);
439 TRACE(clipboard,"\tgot %s\n", lpstrT);
440 GlobalUnlock32(lpTarget->hData32);
441 if (lpSource->hData32)
442 GlobalUnlock32(lpSource->hData32);
443 else
444 GlobalUnlock16(lpSource->hData16);
445 return TRUE;
448 lpTarget->hData32 = 0;
449 if (lpSource->hData32)
450 GlobalUnlock32(lpSource->hData32);
451 else
452 GlobalUnlock16(lpSource->hData16);
453 return FALSE;
456 /**************************************************************************
457 * GetClipboardData16 (USER.142)
459 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
461 LPCLIPFORMAT lpRender = ClipFormats;
462 LPCLIPFORMAT lpUpdate = NULL;
464 if (hqClipLock != GetFastQueue()) return 0;
466 TRACE(clipboard,"(%04X)\n", wFormat);
468 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
469 && lpRender[CF_OEMTEXT-1].wDataPresent )
471 lpRender = &ClipFormats[CF_OEMTEXT-1];
472 lpUpdate = &ClipFormats[CF_TEXT-1];
474 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
476 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
477 && lpRender[CF_TEXT-1].wDataPresent )
479 lpRender = &ClipFormats[CF_TEXT-1];
480 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
482 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
484 else
486 lpRender = __lookup_format( ClipFormats, wFormat );
487 lpUpdate = lpRender;
490 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
491 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
492 CLIPBOARD_RenderText(lpUpdate, lpRender);
494 if( lpUpdate->hData32 && !lpUpdate->hData16 )
496 int size;
497 if( lpUpdate->wFormatID == CF_METAFILEPICT )
498 size = sizeof( METAFILEPICT16 );
499 else
500 size = GlobalSize32(lpUpdate->hData32);
501 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
502 if( !lpUpdate->hData16 )
503 ERR(clipboard, "(%04X) -- not enough memory in 16b heap\n", wFormat);
504 else
506 if( lpUpdate->wFormatID == CF_METAFILEPICT )
508 FIXME(clipboard,"\timplement function CopyMetaFilePict32to16\n");
509 FIXME(clipboard,"\tin the appropriate file.\n");
510 #ifdef SOMEONE_IMPLEMENTED_ME
511 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
512 GlobalLock32(lpUpdate->hData32) );
513 #endif
515 else
517 memcpy( GlobalLock16(lpUpdate->hData16),
518 GlobalLock32(lpUpdate->hData32),
519 size );
521 GlobalUnlock16(lpUpdate->hData16);
522 GlobalUnlock32(lpUpdate->hData32);
526 TRACE(clipboard,"\treturning %04x (type %i)\n",
527 lpUpdate->hData16, lpUpdate->wFormatID);
528 return lpUpdate->hData16;
532 /**************************************************************************
533 * GetClipboardData32 (USER32.222)
535 HANDLE32 WINAPI GetClipboardData32( UINT32 wFormat )
537 LPCLIPFORMAT lpRender = ClipFormats;
538 LPCLIPFORMAT lpUpdate = NULL;
540 if (hqClipLock != GetFastQueue()) return 0;
542 TRACE(clipboard,"(%08X)\n", wFormat);
544 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
545 && lpRender[CF_OEMTEXT-1].wDataPresent )
547 lpRender = &ClipFormats[CF_OEMTEXT-1];
548 lpUpdate = &ClipFormats[CF_TEXT-1];
550 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
552 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
553 && lpRender[CF_TEXT-1].wDataPresent )
555 lpRender = &ClipFormats[CF_TEXT-1];
556 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
558 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
560 else
562 lpRender = __lookup_format( ClipFormats, wFormat );
563 lpUpdate = lpRender;
566 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
567 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
568 CLIPBOARD_RenderText(lpUpdate, lpRender);
570 if( lpUpdate->hData16 && !lpUpdate->hData32 )
572 int size;
573 if( lpUpdate->wFormatID == CF_METAFILEPICT )
574 size = sizeof( METAFILEPICT32 );
575 else
576 size = GlobalSize16(lpUpdate->hData16);
577 lpUpdate->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
578 if( lpUpdate->wFormatID == CF_METAFILEPICT )
580 FIXME(clipboard,"\timplement function CopyMetaFilePict16to32\n");
581 FIXME(clipboard,"\tin the appropriate file.\n");
582 #ifdef SOMEONE_IMPLEMENTED_ME
583 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
584 GlobalLock32(lpUpdate->hData16) );
585 #endif
587 else
589 memcpy( GlobalLock32(lpUpdate->hData32),
590 GlobalLock16(lpUpdate->hData16),
591 size );
593 GlobalUnlock32(lpUpdate->hData32);
594 GlobalUnlock16(lpUpdate->hData16);
597 TRACE(clipboard,"\treturning %04x (type %i)\n",
598 lpUpdate->hData32, lpUpdate->wFormatID);
599 return lpUpdate->hData32;
602 /**************************************************************************
603 * CountClipboardFormats16 (USER.143)
605 INT16 WINAPI CountClipboardFormats16(void)
607 return CountClipboardFormats32();
611 /**************************************************************************
612 * CountClipboardFormats32 (USER32.63)
614 INT32 WINAPI CountClipboardFormats32(void)
616 INT32 FormatCount = 0;
617 LPCLIPFORMAT lpFormat = ClipFormats;
619 TRACE(clipboard,"(void)\n");
621 /* FIXME: Returns BOOL32 */
622 CLIPBOARD_GetDriver()->pRequestSelection();
624 FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
625 lpFormat[CF_OEMTEXT-1].wDataPresent);
627 while(TRUE)
629 if (lpFormat == NULL) break;
630 if (lpFormat->wDataPresent)
632 TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
633 FormatCount++;
635 lpFormat = lpFormat->NextFormat;
638 TRACE(clipboard,"\ttotal %d\n", FormatCount);
639 return FormatCount;
643 /**************************************************************************
644 * EnumClipboardFormats16 (USER.144)
646 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
648 return EnumClipboardFormats32( wFormat );
652 /**************************************************************************
653 * EnumClipboardFormats32 (USER32.179)
655 UINT32 WINAPI EnumClipboardFormats32( UINT32 wFormat )
657 LPCLIPFORMAT lpFormat = ClipFormats;
659 TRACE(clipboard,"(%04X)\n", wFormat);
661 if( hqClipLock != GetFastQueue() ) return 0;
663 if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
664 CLIPBOARD_GetDriver()->pRequestSelection();
666 if (wFormat == 0)
668 if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent)
669 return lpFormat->wFormatID;
670 else
671 wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
674 /* walk up to the specified format record */
676 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
678 /* find next format with available data */
680 lpFormat = lpFormat->NextFormat;
681 while(TRUE)
683 if (lpFormat == NULL) return 0;
684 if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT &&
685 ClipFormats[CF_TEXT-1].wDataPresent))
686 break;
687 lpFormat = lpFormat->NextFormat;
690 return lpFormat->wFormatID;
694 /**************************************************************************
695 * RegisterClipboardFormat16 (USER.145)
697 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
699 LPCLIPFORMAT lpNewFormat;
700 LPCLIPFORMAT lpFormat = ClipFormats;
702 if (FormatName == NULL) return 0;
704 TRACE(clipboard,"('%s') !\n", FormatName);
706 /* walk format chain to see if it's already registered */
708 while(TRUE)
710 if ( !strcmp(lpFormat->Name,FormatName) )
712 lpFormat->wRefCount++;
713 return lpFormat->wFormatID;
716 if ( lpFormat->NextFormat == NULL ) break;
718 lpFormat = lpFormat->NextFormat;
721 /* allocate storage for new format entry */
723 lpNewFormat = (LPCLIPFORMAT)xmalloc(sizeof(CLIPFORMAT));
724 lpFormat->NextFormat = lpNewFormat;
725 lpNewFormat->wFormatID = LastRegFormat;
726 lpNewFormat->wRefCount = 1;
728 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
729 strcpy(lpNewFormat->Name, FormatName);
731 lpNewFormat->wDataPresent = 0;
732 lpNewFormat->hData16 = 0;
733 lpNewFormat->hData32 = 0;
734 lpNewFormat->BufSize = 0;
735 lpNewFormat->PrevFormat = lpFormat;
736 lpNewFormat->NextFormat = NULL;
738 return LastRegFormat++;
742 /**************************************************************************
743 * RegisterClipboardFormat32A (USER32.431)
745 UINT32 WINAPI RegisterClipboardFormat32A( LPCSTR formatName )
747 return RegisterClipboardFormat16( formatName );
751 /**************************************************************************
752 * RegisterClipboardFormat32W (USER32.432)
754 UINT32 WINAPI RegisterClipboardFormat32W( LPCWSTR formatName )
756 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
757 UINT32 ret = RegisterClipboardFormat32A( aFormat );
758 HeapFree( GetProcessHeap(), 0, aFormat );
759 return ret;
762 /**************************************************************************
763 * GetClipboardFormatName16 (USER.146)
765 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
767 return GetClipboardFormatName32A( wFormat, retStr, maxlen );
771 /**************************************************************************
772 * GetClipboardFormatName32A (USER32.223)
774 INT32 WINAPI GetClipboardFormatName32A( UINT32 wFormat, LPSTR retStr, INT32 maxlen )
776 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
778 TRACE(clipboard, "(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
780 if (lpFormat == NULL || lpFormat->Name == NULL ||
781 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
783 TRACE(clipboard, "Name='%s' !\n", lpFormat->Name);
785 lstrcpyn32A( retStr, lpFormat->Name, maxlen );
786 return strlen(retStr);
790 /**************************************************************************
791 * GetClipboardFormatName32W (USER32.224)
793 INT32 WINAPI GetClipboardFormatName32W( UINT32 wFormat, LPWSTR retStr, INT32 maxlen )
795 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
796 INT32 ret = GetClipboardFormatName32A( wFormat, p, maxlen );
797 lstrcpynAtoW( retStr, p, maxlen );
798 HeapFree( GetProcessHeap(), 0, p );
799 return ret;
803 /**************************************************************************
804 * SetClipboardViewer16 (USER.147)
806 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
808 return SetClipboardViewer32( hWnd );
812 /**************************************************************************
813 * SetClipboardViewer32 (USER32.471)
815 HWND32 WINAPI SetClipboardViewer32( HWND32 hWnd )
817 HWND32 hwndPrev = hWndViewer;
819 TRACE(clipboard,"(%04x): returning %04x\n", hWnd, hwndPrev);
821 hWndViewer = hWnd;
822 return hwndPrev;
826 /**************************************************************************
827 * GetClipboardViewer16 (USER.148)
829 HWND16 WINAPI GetClipboardViewer16(void)
831 return hWndViewer;
835 /**************************************************************************
836 * GetClipboardViewer32 (USER32.226)
838 HWND32 WINAPI GetClipboardViewer32(void)
840 return hWndViewer;
844 /**************************************************************************
845 * ChangeClipboardChain16 (USER.149)
847 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
849 return ChangeClipboardChain32(hWnd, hWndNext);
852 /**************************************************************************
853 * ChangeClipboardChain32 (USER32.22)
855 BOOL32 WINAPI ChangeClipboardChain32(HWND32 hWnd, HWND32 hWndNext)
857 BOOL32 bRet = 0;
859 FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
861 if( hWndViewer )
862 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
863 (WPARAM16)hWnd, (LPARAM)hWndNext);
864 else
865 WARN(clipboard, "hWndViewer is lost\n");
867 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
869 return bRet;
874 /**************************************************************************
875 * IsClipboardFormatAvailable16 (USER.193)
877 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
879 return IsClipboardFormatAvailable32( wFormat );
883 /**************************************************************************
884 * IsClipboardFormatAvailable32 (USER32.340)
886 BOOL32 WINAPI IsClipboardFormatAvailable32( UINT32 wFormat )
888 TRACE(clipboard,"(%04X) !\n", wFormat);
890 if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
891 CLIPBOARD_GetDriver()->pRequestSelection();
893 return CLIPBOARD_IsPresent(wFormat);
897 /**************************************************************************
898 * GetOpenClipboardWindow16 (USER.248)
900 HWND16 WINAPI GetOpenClipboardWindow16(void)
902 return hWndClipWindow;
906 /**************************************************************************
907 * GetOpenClipboardWindow32 (USER32.277)
909 HWND32 WINAPI GetOpenClipboardWindow32(void)
911 return hWndClipWindow;
915 /**************************************************************************
916 * GetPriorityClipboardFormat16 (USER.402)
918 INT16 WINAPI GetPriorityClipboardFormat16( UINT16 *lpPriorityList, INT16 nCount)
920 FIXME(clipboard, "(%p,%d): stub\n", lpPriorityList, nCount );
921 return 0;
925 /**************************************************************************
926 * GetPriorityClipboardFormat32 (USER32.279)
928 INT32 WINAPI GetPriorityClipboardFormat32( UINT32 *lpPriorityList, INT32 nCount )
930 int Counter;
932 if(CountClipboardFormats32() == 0)
934 return 0;
937 for(Counter = 0; Counter <= nCount; Counter++)
939 if(IsClipboardFormatAvailable32(*(lpPriorityList+sizeof(INT32)*Counter)))
940 return *(lpPriorityList+sizeof(INT32)*Counter);
943 return -1;