2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
10 #include <sys/types.h>
19 #include "clipboard.h"
23 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver
;
25 #define CF_REGFORMATBASE 0xC000
27 /**************************************************************************
31 static HQUEUE16 hqClipLock
= 0;
32 static BOOL32 bCBHasChanged
= FALSE
;
34 HWND32 hWndClipOwner
= 0; /* current clipboard owner */
35 HWND32 hWndClipWindow
= 0; /* window that opened clipboard */
36 static HWND32 hWndViewer
= 0; /* start of viewers chain */
38 static WORD LastRegFormat
= CF_REGFORMATBASE
;
40 CLIPFORMAT ClipFormats
[16] = {
41 { CF_TEXT
, 1, 0, "Text", (HANDLE32
)NULL
, 0, NULL
, &ClipFormats
[1] , (HANDLE16
)NULL
},
42 { CF_BITMAP
, 1, 0, "Bitmap", (HANDLE32
)NULL
, 0, &ClipFormats
[0], &ClipFormats
[2] , (HANDLE16
)NULL
},
43 { CF_METAFILEPICT
, 1, 0, "MetaFile Picture", (HANDLE32
)NULL
, 0, &ClipFormats
[1], &ClipFormats
[3] , (HANDLE16
)NULL
},
44 { CF_SYLK
, 1, 0, "Sylk", (HANDLE32
)NULL
, 0, &ClipFormats
[2], &ClipFormats
[4] , (HANDLE16
)NULL
},
45 { CF_DIF
, 1, 0, "DIF", (HANDLE32
)NULL
, 0, &ClipFormats
[3], &ClipFormats
[5] , (HANDLE16
)NULL
},
46 { CF_TIFF
, 1, 0, "TIFF", (HANDLE32
)NULL
, 0, &ClipFormats
[4], &ClipFormats
[6] , (HANDLE16
)NULL
},
47 { CF_OEMTEXT
, 1, 0, "OEM Text", (HANDLE32
)NULL
, 0, &ClipFormats
[5], &ClipFormats
[7] , (HANDLE16
)NULL
},
48 { CF_DIB
, 1, 0, "DIB", (HANDLE32
)NULL
, 0, &ClipFormats
[6], &ClipFormats
[8] , (HANDLE16
)NULL
},
49 { CF_PALETTE
, 1, 0, "Palette", (HANDLE32
)NULL
, 0, &ClipFormats
[7], &ClipFormats
[9] , (HANDLE16
)NULL
},
50 { CF_PENDATA
, 1, 0, "PenData", (HANDLE32
)NULL
, 0, &ClipFormats
[8], &ClipFormats
[10] , (HANDLE16
)NULL
},
51 { CF_RIFF
, 1, 0, "RIFF", (HANDLE32
)NULL
, 0, &ClipFormats
[9], &ClipFormats
[11] , (HANDLE16
)NULL
},
52 { CF_WAVE
, 1, 0, "Wave", (HANDLE32
)NULL
, 0, &ClipFormats
[10], &ClipFormats
[12] , (HANDLE16
)NULL
},
53 { CF_OWNERDISPLAY
, 1, 0, "Owner Display", (HANDLE32
)NULL
, 0, &ClipFormats
[11], &ClipFormats
[13] , (HANDLE16
)NULL
},
54 { CF_DSPTEXT
, 1, 0, "DSPText", (HANDLE32
)NULL
, 0, &ClipFormats
[12], &ClipFormats
[14] , (HANDLE16
)NULL
},
55 { CF_DSPMETAFILEPICT
, 1, 0, "DSPMetaFile Picture", (HANDLE32
)NULL
, 0, &ClipFormats
[13], &ClipFormats
[15] , (HANDLE16
)NULL
},
56 { CF_DSPBITMAP
, 1, 0, "DSPBitmap", (HANDLE32
)NULL
, 0, &ClipFormats
[14], NULL
, (HANDLE16
)NULL
}
59 static LPCLIPFORMAT
__lookup_format( LPCLIPFORMAT lpFormat
, WORD wID
)
63 if (lpFormat
== NULL
||
64 lpFormat
->wFormatID
== wID
) break;
65 lpFormat
= lpFormat
->NextFormat
;
71 /**************************************************************************
74 CLIPBOARD_DRIVER
*CLIPBOARD_GetDriver()
76 return &X11DRV_CLIPBOARD_Driver
;
79 /**************************************************************************
82 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
84 if( hqClipLock
== hqCurrent
)
99 /**************************************************************************
100 * CLIPBOARD_DeleteRecord
102 void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat
, BOOL32 bChange
)
104 if( (lpFormat
->wFormatID
>= CF_GDIOBJFIRST
&&
105 lpFormat
->wFormatID
<= CF_GDIOBJLAST
) || lpFormat
->wFormatID
== CF_BITMAP
)
107 if (lpFormat
->hData32
)
108 DeleteObject32(lpFormat
->hData32
);
109 if (lpFormat
->hData16
)
110 DeleteObject16(lpFormat
->hData16
);
112 else if( lpFormat
->wFormatID
== CF_METAFILEPICT
)
114 if (lpFormat
->hData32
)
116 DeleteMetaFile32( ((METAFILEPICT32
*)GlobalLock32( lpFormat
->hData32
))->hMF
);
117 GlobalFree32(lpFormat
->hData32
);
118 if (lpFormat
->hData16
)
119 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
120 and a shallow copy is enough to share a METAFILEPICT
121 structure between 16bit and 32bit clipboards. The MetaFile
122 should of course only be deleted once. */
123 GlobalFree16(lpFormat
->hData16
);
125 else if (lpFormat
->hData16
)
127 DeleteMetaFile16( ((METAFILEPICT16
*)GlobalLock16( lpFormat
->hData16
))->hMF
);
128 GlobalFree16(lpFormat
->hData16
);
133 if (lpFormat
->hData32
)
134 GlobalFree32(lpFormat
->hData32
);
135 if (lpFormat
->hData16
)
136 GlobalFree16(lpFormat
->hData16
);
139 lpFormat
->wDataPresent
= 0;
140 lpFormat
->hData16
= 0;
141 lpFormat
->hData32
= 0;
143 if( bChange
) bCBHasChanged
= TRUE
;
146 /**************************************************************************
147 * CLIPBOARD_IsPresent
149 BOOL32
CLIPBOARD_IsPresent(WORD wFormat
)
153 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
154 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
155 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
158 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
159 if( lpFormat
) return (lpFormat
->wDataPresent
);
164 /**************************************************************************
165 * OpenClipboard16 (USER.137)
167 BOOL16 WINAPI
OpenClipboard16( HWND16 hWnd
)
169 return OpenClipboard32( hWnd
);
173 /**************************************************************************
174 * OpenClipboard32 (USER32.407)
176 * Note: Netscape uses NULL hWnd to open the clipboard.
178 BOOL32 WINAPI
OpenClipboard32( HWND32 hWnd
)
182 TRACE(clipboard
,"(%04x)...\n", hWnd
);
186 hqClipLock
= GetTaskQueue(0);
187 hWndClipWindow
= hWnd
;
188 bCBHasChanged
= FALSE
;
193 TRACE(clipboard
," returning %i\n", bRet
);
198 /**************************************************************************
199 * CloseClipboard16 (USER.138)
201 BOOL16 WINAPI
CloseClipboard16(void)
203 return CloseClipboard32();
207 /**************************************************************************
208 * CloseClipboard32 (USER32.54)
210 BOOL32 WINAPI
CloseClipboard32(void)
212 TRACE(clipboard
,"!\n");
214 if (hqClipLock
== GetTaskQueue(0))
218 if (bCBHasChanged
&& hWndViewer
)
219 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
226 /**************************************************************************
227 * EmptyClipboard16 (USER.139)
229 BOOL16 WINAPI
EmptyClipboard16(void)
231 return EmptyClipboard32();
235 /**************************************************************************
236 * EmptyClipboard32 (USER32.169)
238 BOOL32 WINAPI
EmptyClipboard32(void)
240 LPCLIPFORMAT lpFormat
= ClipFormats
;
242 TRACE(clipboard
,"(void)\n");
244 if (hqClipLock
!= GetTaskQueue(0)) return FALSE
;
246 /* destroy private objects */
249 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
253 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
254 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
256 lpFormat
= lpFormat
->NextFormat
;
259 hWndClipOwner
= hWndClipWindow
;
261 CLIPBOARD_GetDriver()->pEmptyClipboard();
267 /**************************************************************************
268 * GetClipboardOwner16 (USER.140)
270 HWND16 WINAPI
GetClipboardOwner16(void)
272 return hWndClipOwner
;
276 /**************************************************************************
277 * GetClipboardOwner32 (USER32.225)
279 HWND32 WINAPI
GetClipboardOwner32(void)
281 return hWndClipOwner
;
285 /**************************************************************************
286 * SetClipboardData16 (USER.141)
288 HANDLE16 WINAPI
SetClipboardData16( UINT16 wFormat
, HANDLE16 hData
)
290 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
292 TRACE(clipboard
, "(%04X, %04x) !\n", wFormat
, hData
);
294 /* NOTE: If the hData is zero and current owner doesn't match
295 * the window that opened the clipboard then this application
296 * is screwed because WM_RENDERFORMAT will go to the owner
297 * (to become the owner it must call EmptyClipboard() before
301 if( (hqClipLock
!= GetTaskQueue(0)) || !lpFormat
||
302 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
304 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat
);
306 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
308 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
310 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
312 if( wFormat
== CF_TEXT
313 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
314 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
315 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
316 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
317 if( wFormat
== CF_OEMTEXT
318 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
319 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
320 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
321 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
324 bCBHasChanged
= TRUE
;
325 lpFormat
->wDataPresent
= 1;
326 lpFormat
->hData16
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
327 lpFormat
->hData32
= 0;
329 return lpFormat
->hData16
;
333 /**************************************************************************
334 * SetClipboardData32 (USER32.470)
336 HANDLE32 WINAPI
SetClipboardData32( UINT32 wFormat
, HANDLE32 hData
)
338 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
340 TRACE(clipboard
, "(%08X, %08x) !\n", wFormat
, hData
);
342 /* NOTE: If the hData is zero and current owner doesn't match
343 * the window that opened the clipboard then this application
344 * is screwed because WM_RENDERFORMAT will go to the owner
345 * (to become the owner it must call EmptyClipboard() before
349 if( (hqClipLock
!= GetTaskQueue(0)) || !lpFormat
||
350 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
352 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat
);
354 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
356 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
358 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
360 if( wFormat
== CF_TEXT
361 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
362 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
363 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
364 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
365 if( wFormat
== CF_OEMTEXT
366 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
367 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
368 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
369 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
372 bCBHasChanged
= TRUE
;
373 lpFormat
->wDataPresent
= 1;
374 lpFormat
->hData32
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
375 lpFormat
->hData16
= 0;
377 return lpFormat
->hData32
;
381 /**************************************************************************
382 * CLIPBOARD_RenderFormat
384 static BOOL32
CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat
)
386 if( lpFormat
->wDataPresent
&& !lpFormat
->hData16
&& !lpFormat
->hData32
)
388 if( IsWindow32(hWndClipOwner
) )
389 SendMessage16(hWndClipOwner
,WM_RENDERFORMAT
,
390 (WPARAM16
)lpFormat
->wFormatID
,0L);
393 WARN(clipboard
, "\thWndClipOwner (%04x) is lost!\n",
395 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
399 return (lpFormat
->hData16
|| lpFormat
->hData32
) ? TRUE
: FALSE
;
402 /**************************************************************************
403 * CLIPBOARD_RenderText
405 * Convert text between UNIX and DOS formats.
407 static BOOL32
CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget
, LPCLIPFORMAT lpSource
)
413 if (lpSource
->hData32
)
415 size
= GlobalSize32( lpSource
->hData32
);
416 lpstrS
= (LPSTR
)GlobalLock32(lpSource
->hData32
);
420 size
= GlobalSize16( lpSource
->hData16
);
421 lpstrS
= (LPSTR
)GlobalLock16(lpSource
->hData16
);
424 if( !lpstrS
) return FALSE
;
425 TRACE(clipboard
,"\tconverting from '%s' to '%s', %i chars\n",
426 lpSource
->Name
, lpTarget
->Name
, size
);
428 lpTarget
->hData32
= GlobalAlloc32(GMEM_ZEROINIT
, size
);
429 lpstrT
= (LPSTR
)GlobalLock32(lpTarget
->hData32
);
433 if( lpSource
->wFormatID
== CF_TEXT
)
434 CharToOemBuff32A(lpstrS
, lpstrT
, size
);
436 OemToCharBuff32A(lpstrS
, lpstrT
, size
);
437 TRACE(clipboard
,"\tgot %s\n", lpstrT
);
438 GlobalUnlock32(lpTarget
->hData32
);
439 if (lpSource
->hData32
)
440 GlobalUnlock32(lpSource
->hData32
);
442 GlobalUnlock16(lpSource
->hData16
);
446 lpTarget
->hData32
= 0;
447 if (lpSource
->hData32
)
448 GlobalUnlock32(lpSource
->hData32
);
450 GlobalUnlock16(lpSource
->hData16
);
454 /**************************************************************************
455 * GetClipboardData16 (USER.142)
457 HANDLE16 WINAPI
GetClipboardData16( UINT16 wFormat
)
459 LPCLIPFORMAT lpRender
= ClipFormats
;
460 LPCLIPFORMAT lpUpdate
= NULL
;
462 if (hqClipLock
!= GetTaskQueue(0)) return 0;
464 TRACE(clipboard
,"(%04X)\n", wFormat
);
466 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
467 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
469 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
470 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
472 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
474 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
475 && lpRender
[CF_TEXT
-1].wDataPresent
)
477 lpRender
= &ClipFormats
[CF_TEXT
-1];
478 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
480 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
484 lpRender
= __lookup_format( ClipFormats
, wFormat
);
488 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
489 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
490 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
492 if( lpUpdate
->hData32
&& !lpUpdate
->hData16
)
495 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
496 size
= sizeof( METAFILEPICT16
);
498 size
= GlobalSize32(lpUpdate
->hData32
);
499 lpUpdate
->hData16
= GlobalAlloc16(GMEM_ZEROINIT
, size
);
500 if( !lpUpdate
->hData16
)
501 ERR(clipboard
, "(%04X) -- not enough memory in 16b heap\n", wFormat
);
504 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
506 FIXME(clipboard
,"\timplement function CopyMetaFilePict32to16\n");
507 FIXME(clipboard
,"\tin the appropriate file.\n");
508 #ifdef SOMEONE_IMPLEMENTED_ME
509 CopyMetaFilePict32to16( GlobalLock16(lpUpdate
->hData16
),
510 GlobalLock32(lpUpdate
->hData32
) );
515 memcpy( GlobalLock16(lpUpdate
->hData16
),
516 GlobalLock32(lpUpdate
->hData32
),
519 GlobalUnlock16(lpUpdate
->hData16
);
520 GlobalUnlock32(lpUpdate
->hData32
);
524 TRACE(clipboard
,"\treturning %04x (type %i)\n",
525 lpUpdate
->hData16
, lpUpdate
->wFormatID
);
526 return lpUpdate
->hData16
;
530 /**************************************************************************
531 * GetClipboardData32 (USER32.222)
533 HANDLE32 WINAPI
GetClipboardData32( UINT32 wFormat
)
535 LPCLIPFORMAT lpRender
= ClipFormats
;
536 LPCLIPFORMAT lpUpdate
= NULL
;
538 if (hqClipLock
!= GetTaskQueue(0)) return 0;
540 TRACE(clipboard
,"(%08X)\n", wFormat
);
542 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
543 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
545 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
546 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
548 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
550 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
551 && lpRender
[CF_TEXT
-1].wDataPresent
)
553 lpRender
= &ClipFormats
[CF_TEXT
-1];
554 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
556 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
560 lpRender
= __lookup_format( ClipFormats
, wFormat
);
564 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
565 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
566 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
568 if( lpUpdate
->hData16
&& !lpUpdate
->hData32
)
571 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
572 size
= sizeof( METAFILEPICT32
);
574 size
= GlobalSize16(lpUpdate
->hData16
);
575 lpUpdate
->hData32
= GlobalAlloc32(GMEM_ZEROINIT
, size
);
576 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
578 FIXME(clipboard
,"\timplement function CopyMetaFilePict16to32\n");
579 FIXME(clipboard
,"\tin the appropriate file.\n");
580 #ifdef SOMEONE_IMPLEMENTED_ME
581 CopyMetaFilePict16to32( GlobalLock16(lpUpdate
->hData32
),
582 GlobalLock32(lpUpdate
->hData16
) );
587 memcpy( GlobalLock32(lpUpdate
->hData32
),
588 GlobalLock16(lpUpdate
->hData16
),
591 GlobalUnlock32(lpUpdate
->hData32
);
592 GlobalUnlock16(lpUpdate
->hData16
);
595 TRACE(clipboard
,"\treturning %04x (type %i)\n",
596 lpUpdate
->hData32
, lpUpdate
->wFormatID
);
597 return lpUpdate
->hData32
;
600 /**************************************************************************
601 * CountClipboardFormats16 (USER.143)
603 INT16 WINAPI
CountClipboardFormats16(void)
605 return CountClipboardFormats32();
609 /**************************************************************************
610 * CountClipboardFormats32 (USER32.63)
612 INT32 WINAPI
CountClipboardFormats32(void)
614 INT32 FormatCount
= 0;
615 LPCLIPFORMAT lpFormat
= ClipFormats
;
617 TRACE(clipboard
,"(void)\n");
619 /* FIXME: Returns BOOL32 */
620 CLIPBOARD_GetDriver()->pRequestSelection();
622 FormatCount
+= abs(lpFormat
[CF_TEXT
-1].wDataPresent
-
623 lpFormat
[CF_OEMTEXT
-1].wDataPresent
);
627 if (lpFormat
== NULL
) break;
628 if (lpFormat
->wDataPresent
)
630 TRACE(clipboard
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
633 lpFormat
= lpFormat
->NextFormat
;
636 TRACE(clipboard
,"\ttotal %d\n", FormatCount
);
641 /**************************************************************************
642 * EnumClipboardFormats16 (USER.144)
644 UINT16 WINAPI
EnumClipboardFormats16( UINT16 wFormat
)
646 return EnumClipboardFormats32( wFormat
);
650 /**************************************************************************
651 * EnumClipboardFormats32 (USER32.179)
653 UINT32 WINAPI
EnumClipboardFormats32( UINT32 wFormat
)
655 LPCLIPFORMAT lpFormat
= ClipFormats
;
657 TRACE(clipboard
,"(%04X)\n", wFormat
);
659 if( hqClipLock
!= GetTaskQueue(0) ) return 0;
661 if( (!wFormat
|| wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
662 CLIPBOARD_GetDriver()->pRequestSelection();
666 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
667 return lpFormat
->wFormatID
;
669 wFormat
= lpFormat
->wFormatID
; /* and CF_TEXT is not available */
672 /* walk up to the specified format record */
674 if( !(lpFormat
= __lookup_format( lpFormat
, wFormat
)) ) return 0;
676 /* find next format with available data */
678 lpFormat
= lpFormat
->NextFormat
;
681 if (lpFormat
== NULL
) return 0;
682 if (lpFormat
->wDataPresent
|| (lpFormat
->wFormatID
== CF_OEMTEXT
&&
683 ClipFormats
[CF_TEXT
-1].wDataPresent
))
685 lpFormat
= lpFormat
->NextFormat
;
688 return lpFormat
->wFormatID
;
692 /**************************************************************************
693 * RegisterClipboardFormat16 (USER.145)
695 UINT16 WINAPI
RegisterClipboardFormat16( LPCSTR FormatName
)
697 LPCLIPFORMAT lpNewFormat
;
698 LPCLIPFORMAT lpFormat
= ClipFormats
;
700 if (FormatName
== NULL
) return 0;
702 TRACE(clipboard
,"('%s') !\n", FormatName
);
704 /* walk format chain to see if it's already registered */
708 if ( !strcmp(lpFormat
->Name
,FormatName
) )
710 lpFormat
->wRefCount
++;
711 return lpFormat
->wFormatID
;
714 if ( lpFormat
->NextFormat
== NULL
) break;
716 lpFormat
= lpFormat
->NextFormat
;
719 /* allocate storage for new format entry */
721 lpNewFormat
= (LPCLIPFORMAT
)xmalloc(sizeof(CLIPFORMAT
));
722 lpFormat
->NextFormat
= lpNewFormat
;
723 lpNewFormat
->wFormatID
= LastRegFormat
;
724 lpNewFormat
->wRefCount
= 1;
726 lpNewFormat
->Name
= (LPSTR
)xmalloc(strlen(FormatName
) + 1);
727 strcpy(lpNewFormat
->Name
, FormatName
);
729 lpNewFormat
->wDataPresent
= 0;
730 lpNewFormat
->hData16
= 0;
731 lpNewFormat
->hData32
= 0;
732 lpNewFormat
->BufSize
= 0;
733 lpNewFormat
->PrevFormat
= lpFormat
;
734 lpNewFormat
->NextFormat
= NULL
;
736 return LastRegFormat
++;
740 /**************************************************************************
741 * RegisterClipboardFormat32A (USER32.431)
743 UINT32 WINAPI
RegisterClipboardFormat32A( LPCSTR formatName
)
745 return RegisterClipboardFormat16( formatName
);
749 /**************************************************************************
750 * RegisterClipboardFormat32W (USER32.432)
752 UINT32 WINAPI
RegisterClipboardFormat32W( LPCWSTR formatName
)
754 LPSTR aFormat
= HEAP_strdupWtoA( GetProcessHeap(), 0, formatName
);
755 UINT32 ret
= RegisterClipboardFormat32A( aFormat
);
756 HeapFree( GetProcessHeap(), 0, aFormat
);
760 /**************************************************************************
761 * GetClipboardFormatName16 (USER.146)
763 INT16 WINAPI
GetClipboardFormatName16( UINT16 wFormat
, LPSTR retStr
, INT16 maxlen
)
765 return GetClipboardFormatName32A( wFormat
, retStr
, maxlen
);
769 /**************************************************************************
770 * GetClipboardFormatName32A (USER32.223)
772 INT32 WINAPI
GetClipboardFormatName32A( UINT32 wFormat
, LPSTR retStr
, INT32 maxlen
)
774 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
776 TRACE(clipboard
, "(%04X, %p, %d) !\n", wFormat
, retStr
, maxlen
);
778 if (lpFormat
== NULL
|| lpFormat
->Name
== NULL
||
779 lpFormat
->wFormatID
< CF_REGFORMATBASE
) return 0;
781 TRACE(clipboard
, "Name='%s' !\n", lpFormat
->Name
);
783 lstrcpyn32A( retStr
, lpFormat
->Name
, maxlen
);
784 return strlen(retStr
);
788 /**************************************************************************
789 * GetClipboardFormatName32W (USER32.224)
791 INT32 WINAPI
GetClipboardFormatName32W( UINT32 wFormat
, LPWSTR retStr
, INT32 maxlen
)
793 LPSTR p
= HEAP_xalloc( GetProcessHeap(), 0, maxlen
);
794 INT32 ret
= GetClipboardFormatName32A( wFormat
, p
, maxlen
);
795 lstrcpynAtoW( retStr
, p
, maxlen
);
796 HeapFree( GetProcessHeap(), 0, p
);
801 /**************************************************************************
802 * SetClipboardViewer16 (USER.147)
804 HWND16 WINAPI
SetClipboardViewer16( HWND16 hWnd
)
806 return SetClipboardViewer32( hWnd
);
810 /**************************************************************************
811 * SetClipboardViewer32 (USER32.471)
813 HWND32 WINAPI
SetClipboardViewer32( HWND32 hWnd
)
815 HWND32 hwndPrev
= hWndViewer
;
817 TRACE(clipboard
,"(%04x): returning %04x\n", hWnd
, hwndPrev
);
824 /**************************************************************************
825 * GetClipboardViewer16 (USER.148)
827 HWND16 WINAPI
GetClipboardViewer16(void)
833 /**************************************************************************
834 * GetClipboardViewer32 (USER32.226)
836 HWND32 WINAPI
GetClipboardViewer32(void)
842 /**************************************************************************
843 * ChangeClipboardChain16 (USER.149)
845 BOOL16 WINAPI
ChangeClipboardChain16(HWND16 hWnd
, HWND16 hWndNext
)
847 return ChangeClipboardChain32(hWnd
, hWndNext
);
850 /**************************************************************************
851 * ChangeClipboardChain32 (USER32.22)
853 BOOL32 WINAPI
ChangeClipboardChain32(HWND32 hWnd
, HWND32 hWndNext
)
857 FIXME(clipboard
, "(0x%04x, 0x%04x): stub?\n", hWnd
, hWndNext
);
860 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
861 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
863 WARN(clipboard
, "hWndViewer is lost\n");
865 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
872 /**************************************************************************
873 * IsClipboardFormatAvailable16 (USER.193)
875 BOOL16 WINAPI
IsClipboardFormatAvailable16( UINT16 wFormat
)
877 return IsClipboardFormatAvailable32( wFormat
);
881 /**************************************************************************
882 * IsClipboardFormatAvailable32 (USER32.340)
884 BOOL32 WINAPI
IsClipboardFormatAvailable32( UINT32 wFormat
)
886 TRACE(clipboard
,"(%04X) !\n", wFormat
);
888 if( (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
889 CLIPBOARD_GetDriver()->pRequestSelection();
891 return CLIPBOARD_IsPresent(wFormat
);
895 /**************************************************************************
896 * GetOpenClipboardWindow16 (USER.248)
898 HWND16 WINAPI
GetOpenClipboardWindow16(void)
900 return hWndClipWindow
;
904 /**************************************************************************
905 * GetOpenClipboardWindow32 (USER32.277)
907 HWND32 WINAPI
GetOpenClipboardWindow32(void)
909 return hWndClipWindow
;
913 /**************************************************************************
914 * GetPriorityClipboardFormat16 (USER.402)
916 INT16 WINAPI
GetPriorityClipboardFormat16( UINT16
*lpPriorityList
, INT16 nCount
)
918 FIXME(clipboard
, "(%p,%d): stub\n", lpPriorityList
, nCount
);
923 /**************************************************************************
924 * GetPriorityClipboardFormat32 (USER32.279)
926 INT32 WINAPI
GetPriorityClipboardFormat32( UINT32
*lpPriorityList
, INT32 nCount
)
930 if(CountClipboardFormats32() == 0)
935 for(Counter
= 0; Counter
<= nCount
; Counter
++)
937 if(IsClipboardFormatAvailable32(*(lpPriorityList
+sizeof(INT32
)*Counter
)))
938 return *(lpPriorityList
+sizeof(INT32
)*Counter
);