2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
10 #include <sys/types.h>
16 #include "wine/winuser16.h"
20 #include "clipboard.h"
24 DEFAULT_DEBUG_CHANNEL(clipboard
)
26 #define CF_REGFORMATBASE 0xC000
28 /**************************************************************************
32 CLIPBOARD_DRIVER
*CLIPBOARD_Driver
= NULL
;
34 static HQUEUE16 hqClipLock
= 0;
35 static BOOL bCBHasChanged
= FALSE
;
37 HWND hWndClipOwner
= 0; /* current clipboard owner */
38 HWND hWndClipWindow
= 0; /* window that opened clipboard */
39 static HWND hWndViewer
= 0; /* start of viewers chain */
41 static WORD LastRegFormat
= CF_REGFORMATBASE
;
43 WINE_CLIPFORMAT ClipFormats
[16] = {
44 { CF_TEXT
, 1, 0, "Text", (HANDLE
)NULL
, 0, NULL
, &ClipFormats
[1] , (HANDLE16
)NULL
},
45 { CF_BITMAP
, 1, 0, "Bitmap", (HANDLE
)NULL
, 0, &ClipFormats
[0], &ClipFormats
[2] , (HANDLE16
)NULL
},
46 { CF_METAFILEPICT
, 1, 0, "MetaFile Picture", (HANDLE
)NULL
, 0, &ClipFormats
[1], &ClipFormats
[3] , (HANDLE16
)NULL
},
47 { CF_SYLK
, 1, 0, "Sylk", (HANDLE
)NULL
, 0, &ClipFormats
[2], &ClipFormats
[4] , (HANDLE16
)NULL
},
48 { CF_DIF
, 1, 0, "DIF", (HANDLE
)NULL
, 0, &ClipFormats
[3], &ClipFormats
[5] , (HANDLE16
)NULL
},
49 { CF_TIFF
, 1, 0, "TIFF", (HANDLE
)NULL
, 0, &ClipFormats
[4], &ClipFormats
[6] , (HANDLE16
)NULL
},
50 { CF_OEMTEXT
, 1, 0, "OEM Text", (HANDLE
)NULL
, 0, &ClipFormats
[5], &ClipFormats
[7] , (HANDLE16
)NULL
},
51 { CF_DIB
, 1, 0, "DIB", (HANDLE
)NULL
, 0, &ClipFormats
[6], &ClipFormats
[8] , (HANDLE16
)NULL
},
52 { CF_PALETTE
, 1, 0, "Palette", (HANDLE
)NULL
, 0, &ClipFormats
[7], &ClipFormats
[9] , (HANDLE16
)NULL
},
53 { CF_PENDATA
, 1, 0, "PenData", (HANDLE
)NULL
, 0, &ClipFormats
[8], &ClipFormats
[10] , (HANDLE16
)NULL
},
54 { CF_RIFF
, 1, 0, "RIFF", (HANDLE
)NULL
, 0, &ClipFormats
[9], &ClipFormats
[11] , (HANDLE16
)NULL
},
55 { CF_WAVE
, 1, 0, "Wave", (HANDLE
)NULL
, 0, &ClipFormats
[10], &ClipFormats
[12] , (HANDLE16
)NULL
},
56 { CF_OWNERDISPLAY
, 1, 0, "Owner Display", (HANDLE
)NULL
, 0, &ClipFormats
[11], &ClipFormats
[13] , (HANDLE16
)NULL
},
57 { CF_DSPTEXT
, 1, 0, "DSPText", (HANDLE
)NULL
, 0, &ClipFormats
[12], &ClipFormats
[14] , (HANDLE16
)NULL
},
58 { CF_DSPMETAFILEPICT
, 1, 0, "DSPMetaFile Picture", (HANDLE
)NULL
, 0, &ClipFormats
[13], &ClipFormats
[15] , (HANDLE16
)NULL
},
59 { CF_DSPBITMAP
, 1, 0, "DSPBitmap", (HANDLE
)NULL
, 0, &ClipFormats
[14], NULL
, (HANDLE16
)NULL
}
62 static LPWINE_CLIPFORMAT
__lookup_format( LPWINE_CLIPFORMAT lpFormat
, WORD wID
)
66 if (lpFormat
== NULL
||
67 lpFormat
->wFormatID
== wID
) break;
68 lpFormat
= lpFormat
->NextFormat
;
73 /**************************************************************************
76 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
78 if( hqClipLock
== hqCurrent
)
93 /**************************************************************************
94 * CLIPBOARD_DeleteRecord
96 void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat
, BOOL bChange
)
98 if( (lpFormat
->wFormatID
>= CF_GDIOBJFIRST
&&
99 lpFormat
->wFormatID
<= CF_GDIOBJLAST
) || lpFormat
->wFormatID
== CF_BITMAP
)
101 if (lpFormat
->hData32
)
102 DeleteObject(lpFormat
->hData32
);
103 if (lpFormat
->hData16
)
104 DeleteObject16(lpFormat
->hData16
);
106 else if( lpFormat
->wFormatID
== CF_METAFILEPICT
)
108 if (lpFormat
->hData32
)
110 DeleteMetaFile( ((METAFILEPICT
*)GlobalLock( lpFormat
->hData32
))->hMF
);
111 GlobalFree(lpFormat
->hData32
);
112 if (lpFormat
->hData16
)
113 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
114 and a shallow copy is enough to share a METAFILEPICT
115 structure between 16bit and 32bit clipboards. The MetaFile
116 should of course only be deleted once. */
117 GlobalFree16(lpFormat
->hData16
);
119 else if (lpFormat
->hData16
)
121 DeleteMetaFile16( ((METAFILEPICT16
*)GlobalLock16( lpFormat
->hData16
))->hMF
);
122 GlobalFree16(lpFormat
->hData16
);
127 if (lpFormat
->hData32
)
128 GlobalFree(lpFormat
->hData32
);
129 if (lpFormat
->hData16
)
130 GlobalFree16(lpFormat
->hData16
);
133 lpFormat
->wDataPresent
= 0;
134 lpFormat
->hData16
= 0;
135 lpFormat
->hData32
= 0;
137 if( bChange
) bCBHasChanged
= TRUE
;
140 /**************************************************************************
141 * CLIPBOARD_IsPresent
143 BOOL
CLIPBOARD_IsPresent(WORD wFormat
)
147 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
148 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
149 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
152 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
153 if( lpFormat
) return (lpFormat
->wDataPresent
);
158 /**************************************************************************
159 * OpenClipboard16 (USER.137)
161 BOOL16 WINAPI
OpenClipboard16( HWND16 hWnd
)
163 return OpenClipboard( hWnd
);
167 /**************************************************************************
168 * OpenClipboard32 (USER32.407)
170 * Note: Netscape uses NULL hWnd to open the clipboard.
172 BOOL WINAPI
OpenClipboard( HWND hWnd
)
176 TRACE(clipboard
,"(%04x)...\n", hWnd
);
180 hqClipLock
= GetFastQueue16();
181 hWndClipWindow
= hWnd
;
182 bCBHasChanged
= FALSE
;
187 TRACE(clipboard
," returning %i\n", bRet
);
192 /**************************************************************************
193 * CloseClipboard16 (USER.138)
195 BOOL16 WINAPI
CloseClipboard16(void)
197 return CloseClipboard();
201 /**************************************************************************
202 * CloseClipboard32 (USER32.54)
204 BOOL WINAPI
CloseClipboard(void)
206 TRACE(clipboard
,"!\n");
208 if (hqClipLock
== GetFastQueue16())
212 if (bCBHasChanged
&& hWndViewer
)
213 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
220 /**************************************************************************
221 * EmptyClipboard16 (USER.139)
223 BOOL16 WINAPI
EmptyClipboard16(void)
225 return EmptyClipboard();
229 /**************************************************************************
230 * EmptyClipboard32 (USER32.169)
232 BOOL WINAPI
EmptyClipboard(void)
234 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
236 TRACE(clipboard
,"(void)\n");
238 if (hqClipLock
!= GetFastQueue16()) return FALSE
;
240 /* destroy private objects */
243 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
247 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
248 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
250 lpFormat
= lpFormat
->NextFormat
;
253 hWndClipOwner
= hWndClipWindow
;
255 CLIPBOARD_Driver
->pEmpty();
261 /**************************************************************************
262 * GetClipboardOwner16 (USER.140)
264 HWND16 WINAPI
GetClipboardOwner16(void)
266 return hWndClipOwner
;
270 /**************************************************************************
271 * GetClipboardOwner32 (USER32.225)
273 HWND WINAPI
GetClipboardOwner(void)
275 return hWndClipOwner
;
279 /**************************************************************************
280 * SetClipboardData16 (USER.141)
282 HANDLE16 WINAPI
SetClipboardData16( UINT16 wFormat
, HANDLE16 hData
)
284 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
286 TRACE(clipboard
, "(%04X, %04x) !\n", wFormat
, hData
);
288 /* NOTE: If the hData is zero and current owner doesn't match
289 * the window that opened the clipboard then this application
290 * is screwed because WM_RENDERFORMAT will go to the owner
291 * (to become the owner it must call EmptyClipboard() before
295 if( (hqClipLock
!= GetFastQueue16()) || !lpFormat
||
296 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
298 CLIPBOARD_Driver
->pSetData(wFormat
);
300 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
302 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
304 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
306 if( wFormat
== CF_TEXT
307 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
308 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
309 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
310 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
311 if( wFormat
== CF_OEMTEXT
312 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
313 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
314 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
315 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
318 bCBHasChanged
= TRUE
;
319 lpFormat
->wDataPresent
= 1;
320 lpFormat
->hData16
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
321 lpFormat
->hData32
= 0;
323 return lpFormat
->hData16
;
327 /**************************************************************************
328 * SetClipboardData (USER32.470)
330 HANDLE WINAPI
SetClipboardData( UINT wFormat
, HANDLE hData
)
332 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
334 TRACE(clipboard
, "(%08X, %08x) !\n", wFormat
, hData
);
336 /* NOTE: If the hData is zero and current owner doesn't match
337 * the window that opened the clipboard then this application
338 * is screwed because WM_RENDERFORMAT will go to the owner
339 * (to become the owner it must call EmptyClipboard() before
343 if( (hqClipLock
!= GetFastQueue16()) || !lpFormat
||
344 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
346 CLIPBOARD_Driver
->pSetData(wFormat
);
348 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
350 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
352 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
354 if( wFormat
== CF_TEXT
355 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
356 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
357 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
358 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
359 if( wFormat
== CF_OEMTEXT
360 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
361 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
362 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
363 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
366 bCBHasChanged
= TRUE
;
367 lpFormat
->wDataPresent
= 1;
368 lpFormat
->hData32
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
369 lpFormat
->hData16
= 0;
371 return lpFormat
->hData32
;
375 /**************************************************************************
376 * CLIPBOARD_RenderFormat
378 static BOOL
CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat
)
380 if( lpFormat
->wDataPresent
&& !lpFormat
->hData16
&& !lpFormat
->hData32
)
382 if( IsWindow(hWndClipOwner
) )
383 SendMessage16(hWndClipOwner
,WM_RENDERFORMAT
,
384 (WPARAM16
)lpFormat
->wFormatID
,0L);
387 WARN(clipboard
, "\thWndClipOwner (%04x) is lost!\n",
389 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
393 return (lpFormat
->hData16
|| lpFormat
->hData32
) ? TRUE
: FALSE
;
396 /**************************************************************************
397 * CLIPBOARD_RenderText
399 * Convert text between UNIX and DOS formats.
401 * FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
404 static BOOL
CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget
, LPWINE_CLIPFORMAT lpSource
)
410 if (lpSource
->hData32
)
412 size
= GlobalSize( lpSource
->hData32
);
413 lpstrS
= (LPSTR
)GlobalLock(lpSource
->hData32
);
417 size
= GlobalSize16( lpSource
->hData16
);
418 lpstrS
= (LPSTR
)GlobalLock16(lpSource
->hData16
);
421 if( !lpstrS
) return FALSE
;
422 TRACE(clipboard
,"\tconverting from '%s' to '%s', %i chars\n",
423 lpSource
->Name
, lpTarget
->Name
, size
);
425 lpTarget
->hData32
= GlobalAlloc(GMEM_ZEROINIT
, size
);
426 lpstrT
= (LPSTR
)GlobalLock(lpTarget
->hData32
);
430 if( lpSource
->wFormatID
== CF_TEXT
)
431 CharToOemBuffA(lpstrS
, lpstrT
, size
);
433 OemToCharBuffA(lpstrS
, lpstrT
, size
);
434 TRACE(clipboard
,"\tgot %s\n", lpstrT
);
435 GlobalUnlock(lpTarget
->hData32
);
436 if (lpSource
->hData32
)
437 GlobalUnlock(lpSource
->hData32
);
439 GlobalUnlock16(lpSource
->hData16
);
443 lpTarget
->hData32
= 0;
444 if (lpSource
->hData32
)
445 GlobalUnlock(lpSource
->hData32
);
447 GlobalUnlock16(lpSource
->hData16
);
451 /**************************************************************************
452 * GetClipboardData16 (USER.142)
454 HANDLE16 WINAPI
GetClipboardData16( UINT16 wFormat
)
456 LPWINE_CLIPFORMAT lpRender
= ClipFormats
;
457 LPWINE_CLIPFORMAT lpUpdate
= NULL
;
459 if (hqClipLock
!= GetFastQueue16()) return 0;
461 TRACE(clipboard
,"(%04X)\n", wFormat
);
463 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
464 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
466 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
467 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
469 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
471 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
472 && lpRender
[CF_TEXT
-1].wDataPresent
)
474 lpRender
= &ClipFormats
[CF_TEXT
-1];
475 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
477 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
481 lpRender
= __lookup_format( ClipFormats
, wFormat
);
485 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
486 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
487 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
489 if( lpUpdate
->hData32
&& !lpUpdate
->hData16
)
492 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
493 size
= sizeof( METAFILEPICT16
);
495 size
= GlobalSize(lpUpdate
->hData32
);
496 lpUpdate
->hData16
= GlobalAlloc16(GMEM_ZEROINIT
, size
);
497 if( !lpUpdate
->hData16
)
498 ERR(clipboard
, "(%04X) -- not enough memory in 16b heap\n", wFormat
);
501 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
503 FIXME(clipboard
,"\timplement function CopyMetaFilePict32to16\n");
504 FIXME(clipboard
,"\tin the appropriate file.\n");
505 #ifdef SOMEONE_IMPLEMENTED_ME
506 CopyMetaFilePict32to16( GlobalLock16(lpUpdate
->hData16
),
507 GlobalLock(lpUpdate
->hData32
) );
512 memcpy( GlobalLock16(lpUpdate
->hData16
),
513 GlobalLock(lpUpdate
->hData32
),
516 GlobalUnlock16(lpUpdate
->hData16
);
517 GlobalUnlock(lpUpdate
->hData32
);
521 TRACE(clipboard
,"\treturning %04x (type %i)\n",
522 lpUpdate
->hData16
, lpUpdate
->wFormatID
);
523 return lpUpdate
->hData16
;
527 /**************************************************************************
528 * GetClipboardData32 (USER32.222)
530 HANDLE WINAPI
GetClipboardData( UINT wFormat
)
532 LPWINE_CLIPFORMAT lpRender
= ClipFormats
;
533 LPWINE_CLIPFORMAT lpUpdate
= NULL
;
535 if (hqClipLock
!= GetFastQueue16()) return 0;
537 TRACE(clipboard
,"(%08X)\n", wFormat
);
539 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
540 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
542 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
543 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
545 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
547 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
548 && lpRender
[CF_TEXT
-1].wDataPresent
)
550 lpRender
= &ClipFormats
[CF_TEXT
-1];
551 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
553 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
557 lpRender
= __lookup_format( ClipFormats
, wFormat
);
561 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
562 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
563 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
565 if( lpUpdate
->hData16
&& !lpUpdate
->hData32
)
568 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
569 size
= sizeof( METAFILEPICT
);
571 size
= GlobalSize16(lpUpdate
->hData16
);
572 lpUpdate
->hData32
= GlobalAlloc(GMEM_ZEROINIT
, size
);
573 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
575 FIXME(clipboard
,"\timplement function CopyMetaFilePict16to32\n");
576 FIXME(clipboard
,"\tin the appropriate file.\n");
577 #ifdef SOMEONE_IMPLEMENTED_ME
578 CopyMetaFilePict16to32( GlobalLock16(lpUpdate
->hData32
),
579 GlobalLock(lpUpdate
->hData16
) );
584 memcpy( GlobalLock(lpUpdate
->hData32
),
585 GlobalLock16(lpUpdate
->hData16
),
588 GlobalUnlock(lpUpdate
->hData32
);
589 GlobalUnlock16(lpUpdate
->hData16
);
592 TRACE(clipboard
,"\treturning %04x (type %i)\n",
593 lpUpdate
->hData32
, lpUpdate
->wFormatID
);
594 return lpUpdate
->hData32
;
597 /**************************************************************************
598 * CountClipboardFormats16 (USER.143)
600 INT16 WINAPI
CountClipboardFormats16(void)
602 return CountClipboardFormats();
606 /**************************************************************************
607 * CountClipboardFormats32 (USER32.63)
609 INT WINAPI
CountClipboardFormats(void)
612 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
614 TRACE(clipboard
,"(void)\n");
618 if (lpFormat
== NULL
) break;
620 if( lpFormat
->wFormatID
!= CF_TEXT
)
621 CLIPBOARD_Driver
->pGetData( lpFormat
->wFormatID
);
623 if (lpFormat
->wDataPresent
)
625 TRACE(clipboard
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
628 lpFormat
= lpFormat
->NextFormat
;
631 /* these two are equivalent, adjust the total */
633 FormatCount
+= abs(ClipFormats
[CF_TEXT
-1].wDataPresent
-
634 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
);
636 TRACE(clipboard
,"\ttotal %d\n", FormatCount
);
641 /**************************************************************************
642 * EnumClipboardFormats16 (USER.144)
644 UINT16 WINAPI
EnumClipboardFormats16( UINT16 wFormat
)
646 return EnumClipboardFormats( wFormat
);
650 /**************************************************************************
651 * EnumClipboardFormats32 (USER32.179)
653 UINT WINAPI
EnumClipboardFormats( UINT wFormat
)
655 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
657 TRACE(clipboard
,"(%04X)\n", wFormat
);
659 if( hqClipLock
!= GetFastQueue16() ) return 0;
661 if( wFormat
< CF_OEMTEXT
)
662 CLIPBOARD_Driver
->pGetData( CF_OEMTEXT
);
664 if (wFormat
== 0) /* start from the beginning */
665 lpFormat
= ClipFormats
;
668 /* walk up to the specified format record */
670 if( !(lpFormat
= __lookup_format( lpFormat
, wFormat
)) )
672 lpFormat
= lpFormat
->NextFormat
; /* right */
677 if (lpFormat
== NULL
) return 0;
679 if( lpFormat
->wFormatID
!= CF_OEMTEXT
&& lpFormat
->wFormatID
!= CF_TEXT
)
680 CLIPBOARD_Driver
->pGetData( lpFormat
->wFormatID
);
682 if (lpFormat
->wDataPresent
||
683 (lpFormat
->wFormatID
== CF_OEMTEXT
&& ClipFormats
[CF_TEXT
-1].wDataPresent
) ||
684 (lpFormat
->wFormatID
== CF_TEXT
&& ClipFormats
[CF_OEMTEXT
-1].wDataPresent
) )
686 lpFormat
= lpFormat
->NextFormat
;
689 return lpFormat
->wFormatID
;
693 /**************************************************************************
694 * RegisterClipboardFormat16 (USER.145)
696 UINT16 WINAPI
RegisterClipboardFormat16( LPCSTR FormatName
)
698 LPWINE_CLIPFORMAT lpNewFormat
;
699 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
701 if (FormatName
== NULL
) return 0;
703 TRACE(clipboard
,"('%s') !\n", FormatName
);
705 /* walk format chain to see if it's already registered */
709 if ( !strcmp(lpFormat
->Name
,FormatName
) )
711 lpFormat
->wRefCount
++;
712 return lpFormat
->wFormatID
;
715 if ( lpFormat
->NextFormat
== NULL
) break;
717 lpFormat
= lpFormat
->NextFormat
;
720 /* allocate storage for new format entry */
722 lpNewFormat
= (LPWINE_CLIPFORMAT
)xmalloc(sizeof(WINE_CLIPFORMAT
));
723 lpFormat
->NextFormat
= lpNewFormat
;
724 lpNewFormat
->wFormatID
= LastRegFormat
;
725 lpNewFormat
->wRefCount
= 1;
727 lpNewFormat
->Name
= (LPSTR
)xmalloc(strlen(FormatName
) + 1);
728 strcpy(lpNewFormat
->Name
, FormatName
);
730 lpNewFormat
->wDataPresent
= 0;
731 lpNewFormat
->hData16
= 0;
732 lpNewFormat
->hData32
= 0;
733 lpNewFormat
->BufSize
= 0;
734 lpNewFormat
->PrevFormat
= lpFormat
;
735 lpNewFormat
->NextFormat
= NULL
;
737 return LastRegFormat
++;
741 /**************************************************************************
742 * RegisterClipboardFormat32A (USER32.431)
744 UINT WINAPI
RegisterClipboardFormatA( LPCSTR formatName
)
746 return RegisterClipboardFormat16( formatName
);
750 /**************************************************************************
751 * RegisterClipboardFormat32W (USER32.432)
753 UINT WINAPI
RegisterClipboardFormatW( LPCWSTR formatName
)
755 LPSTR aFormat
= HEAP_strdupWtoA( GetProcessHeap(), 0, formatName
);
756 UINT ret
= RegisterClipboardFormatA( aFormat
);
757 HeapFree( GetProcessHeap(), 0, aFormat
);
761 /**************************************************************************
762 * GetClipboardFormatName16 (USER.146)
764 INT16 WINAPI
GetClipboardFormatName16( UINT16 wFormat
, LPSTR retStr
, INT16 maxlen
)
766 return GetClipboardFormatNameA( wFormat
, retStr
, maxlen
);
770 /**************************************************************************
771 * GetClipboardFormatName32A (USER32.223)
773 INT WINAPI
GetClipboardFormatNameA( UINT wFormat
, LPSTR retStr
, INT maxlen
)
775 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
777 TRACE(clipboard
, "(%04X, %p, %d) !\n", wFormat
, retStr
, maxlen
);
779 if (lpFormat
== NULL
|| lpFormat
->Name
== NULL
||
780 lpFormat
->wFormatID
< CF_REGFORMATBASE
) return 0;
782 TRACE(clipboard
, "Name='%s' !\n", lpFormat
->Name
);
784 lstrcpynA( retStr
, lpFormat
->Name
, maxlen
);
785 return strlen(retStr
);
789 /**************************************************************************
790 * GetClipboardFormatName32W (USER32.224)
792 INT WINAPI
GetClipboardFormatNameW( UINT wFormat
, LPWSTR retStr
, INT maxlen
)
794 LPSTR p
= HEAP_xalloc( GetProcessHeap(), 0, maxlen
);
795 INT ret
= GetClipboardFormatNameA( wFormat
, p
, maxlen
);
796 lstrcpynAtoW( retStr
, p
, maxlen
);
797 HeapFree( GetProcessHeap(), 0, p
);
802 /**************************************************************************
803 * SetClipboardViewer16 (USER.147)
805 HWND16 WINAPI
SetClipboardViewer16( HWND16 hWnd
)
807 return SetClipboardViewer( hWnd
);
811 /**************************************************************************
812 * SetClipboardViewer32 (USER32.471)
814 HWND WINAPI
SetClipboardViewer( HWND hWnd
)
816 HWND hwndPrev
= hWndViewer
;
818 TRACE(clipboard
,"(%04x): returning %04x\n", hWnd
, hwndPrev
);
825 /**************************************************************************
826 * GetClipboardViewer16 (USER.148)
828 HWND16 WINAPI
GetClipboardViewer16(void)
834 /**************************************************************************
835 * GetClipboardViewer32 (USER32.226)
837 HWND WINAPI
GetClipboardViewer(void)
843 /**************************************************************************
844 * ChangeClipboardChain16 (USER.149)
846 BOOL16 WINAPI
ChangeClipboardChain16(HWND16 hWnd
, HWND16 hWndNext
)
848 return ChangeClipboardChain(hWnd
, hWndNext
);
851 /**************************************************************************
852 * ChangeClipboardChain32 (USER32.22)
854 BOOL WINAPI
ChangeClipboardChain(HWND hWnd
, HWND hWndNext
)
858 FIXME(clipboard
, "(0x%04x, 0x%04x): stub?\n", hWnd
, hWndNext
);
861 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
862 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
864 WARN(clipboard
, "hWndViewer is lost\n");
866 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
873 /**************************************************************************
874 * IsClipboardFormatAvailable16 (USER.193)
876 BOOL16 WINAPI
IsClipboardFormatAvailable16( UINT16 wFormat
)
878 return IsClipboardFormatAvailable( wFormat
);
882 /**************************************************************************
883 * IsClipboardFormatAvailable32 (USER32.340)
885 BOOL WINAPI
IsClipboardFormatAvailable( UINT wFormat
)
887 TRACE(clipboard
,"(%04X) !\n", wFormat
);
889 CLIPBOARD_Driver
->pGetData( (wFormat
== CF_TEXT
) ? CF_OEMTEXT
: wFormat
);
891 return CLIPBOARD_IsPresent(wFormat
);
895 /**************************************************************************
896 * GetOpenClipboardWindow16 (USER.248)
898 HWND16 WINAPI
GetOpenClipboardWindow16(void)
900 return hWndClipWindow
;
904 /**************************************************************************
905 * GetOpenClipboardWindow32 (USER32.277)
907 HWND WINAPI
GetOpenClipboardWindow(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 INT WINAPI
GetPriorityClipboardFormat( UINT
*lpPriorityList
, INT nCount
)
930 if(CountClipboardFormats() == 0)
935 for(Counter
= 0; Counter
<= nCount
; Counter
++)
937 if(IsClipboardFormatAvailable(*(lpPriorityList
+sizeof(INT
)*Counter
)))
938 return *(lpPriorityList
+sizeof(INT
)*Counter
);