2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
10 #include <sys/types.h>
21 #include "clipboard.h"
25 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver
;
27 #define CF_REGFORMATBASE 0xC000
29 /**************************************************************************
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
)
65 if (lpFormat
== NULL
||
66 lpFormat
->wFormatID
== wID
) break;
67 lpFormat
= lpFormat
->NextFormat
;
73 /**************************************************************************
76 CLIPBOARD_DRIVER
*CLIPBOARD_GetDriver()
78 return &X11DRV_CLIPBOARD_Driver
;
81 /**************************************************************************
84 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
86 if( hqClipLock
== hqCurrent
)
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
);
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
)
155 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
156 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
157 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
160 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
161 if( lpFormat
) return (lpFormat
->wDataPresent
);
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
)
184 TRACE(clipboard
,"(%04x)...\n", hWnd
);
188 hqClipLock
= GetFastQueue();
189 hWndClipWindow
= hWnd
;
190 bCBHasChanged
= FALSE
;
195 TRACE(clipboard
," returning %i\n", 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())
220 if (bCBHasChanged
&& hWndViewer
)
221 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
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 */
251 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
255 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
256 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
258 lpFormat
= lpFormat
->NextFormat
;
261 hWndClipOwner
= hWndClipWindow
;
263 CLIPBOARD_GetDriver()->pEmptyClipboard();
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
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
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);
395 WARN(clipboard
, "\thWndClipOwner (%04x) is lost!\n",
397 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
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
)
415 if (lpSource
->hData32
)
417 size
= GlobalSize32( lpSource
->hData32
);
418 lpstrS
= (LPSTR
)GlobalLock32(lpSource
->hData32
);
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
);
435 if( lpSource
->wFormatID
== CF_TEXT
)
436 CharToOemBuff32A(lpstrS
, lpstrT
, size
);
438 OemToCharBuff32A(lpstrS
, lpstrT
, size
);
439 TRACE(clipboard
,"\tgot %s\n", lpstrT
);
440 GlobalUnlock32(lpTarget
->hData32
);
441 if (lpSource
->hData32
)
442 GlobalUnlock32(lpSource
->hData32
);
444 GlobalUnlock16(lpSource
->hData16
);
448 lpTarget
->hData32
= 0;
449 if (lpSource
->hData32
)
450 GlobalUnlock32(lpSource
->hData32
);
452 GlobalUnlock16(lpSource
->hData16
);
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");
486 lpRender
= __lookup_format( ClipFormats
, wFormat
);
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
)
497 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
498 size
= sizeof( METAFILEPICT16
);
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
);
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
) );
517 memcpy( GlobalLock16(lpUpdate
->hData16
),
518 GlobalLock32(lpUpdate
->hData32
),
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");
562 lpRender
= __lookup_format( ClipFormats
, wFormat
);
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
)
573 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
574 size
= sizeof( METAFILEPICT32
);
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
) );
589 memcpy( GlobalLock32(lpUpdate
->hData32
),
590 GlobalLock16(lpUpdate
->hData16
),
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
);
629 if (lpFormat
== NULL
) break;
630 if (lpFormat
->wDataPresent
)
632 TRACE(clipboard
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
635 lpFormat
= lpFormat
->NextFormat
;
638 TRACE(clipboard
,"\ttotal %d\n", 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();
668 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
669 return lpFormat
->wFormatID
;
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
;
683 if (lpFormat
== NULL
) return 0;
684 if (lpFormat
->wDataPresent
|| (lpFormat
->wFormatID
== CF_OEMTEXT
&&
685 ClipFormats
[CF_TEXT
-1].wDataPresent
))
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 */
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
);
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
);
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
);
826 /**************************************************************************
827 * GetClipboardViewer16 (USER.148)
829 HWND16 WINAPI
GetClipboardViewer16(void)
835 /**************************************************************************
836 * GetClipboardViewer32 (USER32.226)
838 HWND32 WINAPI
GetClipboardViewer32(void)
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
)
859 FIXME(clipboard
, "(0x%04x, 0x%04x): stub?\n", hWnd
, hWndNext
);
862 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
863 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
865 WARN(clipboard
, "hWndViewer is lost\n");
867 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
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
);
925 /**************************************************************************
926 * GetPriorityClipboardFormat32 (USER32.279)
928 INT32 WINAPI
GetPriorityClipboardFormat32( UINT32
*lpPriorityList
, INT32 nCount
)
932 if(CountClipboardFormats32() == 0)
937 for(Counter
= 0; Counter
<= nCount
; Counter
++)
939 if(IsClipboardFormatAvailable32(*(lpPriorityList
+sizeof(INT32
)*Counter
)))
940 return *(lpPriorityList
+sizeof(INT32
)*Counter
);