2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
10 #include <sys/types.h>
21 #include "clipboard.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 /**************************************************************************
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
)
69 if (lpFormat
== NULL
||
70 lpFormat
->wFormatID
== wID
) break;
71 lpFormat
= lpFormat
->NextFormat
;
77 /**************************************************************************
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 /**************************************************************************
92 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
94 if( hqClipLock
== hqCurrent
)
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
);
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
)
163 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
164 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
165 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
168 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
169 if( lpFormat
) return (lpFormat
->wDataPresent
);
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
)
192 TRACE(clipboard
,"(%04x)...\n", hWnd
);
196 hqClipLock
= GetFastQueue();
197 hWndClipWindow
= hWnd
;
198 bCBHasChanged
= FALSE
;
203 TRACE(clipboard
," returning %i\n", 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())
228 if (bCBHasChanged
&& hWndViewer
)
229 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
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 */
259 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
263 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
264 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
266 lpFormat
= lpFormat
->NextFormat
;
269 hWndClipOwner
= hWndClipWindow
;
271 CLIPBOARD_GetDriver()->pEmptyClipboard();
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
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
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);
403 WARN(clipboard
, "\thWndClipOwner (%04x) is lost!\n",
405 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
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
)
423 if (lpSource
->hData32
)
425 size
= GlobalSize32( lpSource
->hData32
);
426 lpstrS
= (LPSTR
)GlobalLock32(lpSource
->hData32
);
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
);
443 if( lpSource
->wFormatID
== CF_TEXT
)
444 CharToOemBuff32A(lpstrS
, lpstrT
, size
);
446 OemToCharBuff32A(lpstrS
, lpstrT
, size
);
447 TRACE(clipboard
,"\tgot %s\n", lpstrT
);
448 GlobalUnlock32(lpTarget
->hData32
);
449 if (lpSource
->hData32
)
450 GlobalUnlock32(lpSource
->hData32
);
452 GlobalUnlock16(lpSource
->hData16
);
456 lpTarget
->hData32
= 0;
457 if (lpSource
->hData32
)
458 GlobalUnlock32(lpSource
->hData32
);
460 GlobalUnlock16(lpSource
->hData16
);
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");
494 lpRender
= __lookup_format( ClipFormats
, wFormat
);
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
)
505 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
506 size
= sizeof( METAFILEPICT16
);
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
);
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
) );
525 memcpy( GlobalLock16(lpUpdate
->hData16
),
526 GlobalLock32(lpUpdate
->hData32
),
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");
570 lpRender
= __lookup_format( ClipFormats
, wFormat
);
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
)
581 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
582 size
= sizeof( METAFILEPICT32
);
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
) );
597 memcpy( GlobalLock32(lpUpdate
->hData32
),
598 GlobalLock16(lpUpdate
->hData16
),
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
);
637 if (lpFormat
== NULL
) break;
638 if (lpFormat
->wDataPresent
)
640 TRACE(clipboard
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
643 lpFormat
= lpFormat
->NextFormat
;
646 TRACE(clipboard
,"\ttotal %d\n", 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();
676 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
677 return lpFormat
->wFormatID
;
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
;
691 if (lpFormat
== NULL
) return 0;
692 if (lpFormat
->wDataPresent
|| (lpFormat
->wFormatID
== CF_OEMTEXT
&&
693 ClipFormats
[CF_TEXT
-1].wDataPresent
))
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 */
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
);
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
);
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
);
834 /**************************************************************************
835 * GetClipboardViewer16 (USER.148)
837 HWND16 WINAPI
GetClipboardViewer16(void)
843 /**************************************************************************
844 * GetClipboardViewer32 (USER32.226)
846 HWND32 WINAPI
GetClipboardViewer32(void)
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
)
867 FIXME(clipboard
, "(0x%04x, 0x%04x): stub?\n", hWnd
, hWndNext
);
870 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
871 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
873 WARN(clipboard
, "hWndViewer is lost\n");
875 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
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
);
933 /**************************************************************************
934 * GetPriorityClipboardFormat32 (USER32.279)
936 INT32 WINAPI
GetPriorityClipboardFormat32( UINT32
*lpPriorityList
, INT32 nCount
)
940 if(CountClipboardFormats32() == 0)
945 for(Counter
= 0; Counter
<= nCount
; Counter
++)
947 if(IsClipboardFormatAvailable32(*(lpPriorityList
+sizeof(INT32
)*Counter
)))
948 return *(lpPriorityList
+sizeof(INT32
)*Counter
);