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 #ifndef X_DISPLAY_MISSING
25 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver
;
26 #else /* X_DISPLAY_MISSING */
27 extern CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver
;
28 #endif /* X_DISPLAY_MISSING */
30 #define CF_REGFORMATBASE 0xC000
32 /**************************************************************************
36 static HQUEUE16 hqClipLock
= 0;
37 static BOOL bCBHasChanged
= FALSE
;
39 HWND hWndClipOwner
= 0; /* current clipboard owner */
40 HWND hWndClipWindow
= 0; /* window that opened clipboard */
41 static HWND hWndViewer
= 0; /* start of viewers chain */
43 static WORD LastRegFormat
= CF_REGFORMATBASE
;
45 WINE_CLIPFORMAT ClipFormats
[16] = {
46 { CF_TEXT
, 1, 0, "Text", (HANDLE
)NULL
, 0, NULL
, &ClipFormats
[1] , (HANDLE16
)NULL
},
47 { CF_BITMAP
, 1, 0, "Bitmap", (HANDLE
)NULL
, 0, &ClipFormats
[0], &ClipFormats
[2] , (HANDLE16
)NULL
},
48 { CF_METAFILEPICT
, 1, 0, "MetaFile Picture", (HANDLE
)NULL
, 0, &ClipFormats
[1], &ClipFormats
[3] , (HANDLE16
)NULL
},
49 { CF_SYLK
, 1, 0, "Sylk", (HANDLE
)NULL
, 0, &ClipFormats
[2], &ClipFormats
[4] , (HANDLE16
)NULL
},
50 { CF_DIF
, 1, 0, "DIF", (HANDLE
)NULL
, 0, &ClipFormats
[3], &ClipFormats
[5] , (HANDLE16
)NULL
},
51 { CF_TIFF
, 1, 0, "TIFF", (HANDLE
)NULL
, 0, &ClipFormats
[4], &ClipFormats
[6] , (HANDLE16
)NULL
},
52 { CF_OEMTEXT
, 1, 0, "OEM Text", (HANDLE
)NULL
, 0, &ClipFormats
[5], &ClipFormats
[7] , (HANDLE16
)NULL
},
53 { CF_DIB
, 1, 0, "DIB", (HANDLE
)NULL
, 0, &ClipFormats
[6], &ClipFormats
[8] , (HANDLE16
)NULL
},
54 { CF_PALETTE
, 1, 0, "Palette", (HANDLE
)NULL
, 0, &ClipFormats
[7], &ClipFormats
[9] , (HANDLE16
)NULL
},
55 { CF_PENDATA
, 1, 0, "PenData", (HANDLE
)NULL
, 0, &ClipFormats
[8], &ClipFormats
[10] , (HANDLE16
)NULL
},
56 { CF_RIFF
, 1, 0, "RIFF", (HANDLE
)NULL
, 0, &ClipFormats
[9], &ClipFormats
[11] , (HANDLE16
)NULL
},
57 { CF_WAVE
, 1, 0, "Wave", (HANDLE
)NULL
, 0, &ClipFormats
[10], &ClipFormats
[12] , (HANDLE16
)NULL
},
58 { CF_OWNERDISPLAY
, 1, 0, "Owner Display", (HANDLE
)NULL
, 0, &ClipFormats
[11], &ClipFormats
[13] , (HANDLE16
)NULL
},
59 { CF_DSPTEXT
, 1, 0, "DSPText", (HANDLE
)NULL
, 0, &ClipFormats
[12], &ClipFormats
[14] , (HANDLE16
)NULL
},
60 { CF_DSPMETAFILEPICT
, 1, 0, "DSPMetaFile Picture", (HANDLE
)NULL
, 0, &ClipFormats
[13], &ClipFormats
[15] , (HANDLE16
)NULL
},
61 { CF_DSPBITMAP
, 1, 0, "DSPBitmap", (HANDLE
)NULL
, 0, &ClipFormats
[14], NULL
, (HANDLE16
)NULL
}
64 static LPWINE_CLIPFORMAT
__lookup_format( LPWINE_CLIPFORMAT lpFormat
, WORD wID
)
68 if (lpFormat
== NULL
||
69 lpFormat
->wFormatID
== wID
) break;
70 lpFormat
= lpFormat
->NextFormat
;
76 /**************************************************************************
79 CLIPBOARD_DRIVER
*CLIPBOARD_GetDriver()
81 #ifndef X_DISPLAY_MISSING
82 return &X11DRV_CLIPBOARD_Driver
;
83 #else /* X_DISPLAY_MISSING */
84 return &TTYDRV_CLIPBOARD_Driver
;
85 #endif /* X_DISPLAY_MISSING */
88 /**************************************************************************
91 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
93 if( hqClipLock
== hqCurrent
)
108 /**************************************************************************
109 * CLIPBOARD_DeleteRecord
111 void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat
, BOOL bChange
)
113 if( (lpFormat
->wFormatID
>= CF_GDIOBJFIRST
&&
114 lpFormat
->wFormatID
<= CF_GDIOBJLAST
) || lpFormat
->wFormatID
== CF_BITMAP
)
116 if (lpFormat
->hData32
)
117 DeleteObject(lpFormat
->hData32
);
118 if (lpFormat
->hData16
)
119 DeleteObject16(lpFormat
->hData16
);
121 else if( lpFormat
->wFormatID
== CF_METAFILEPICT
)
123 if (lpFormat
->hData32
)
125 DeleteMetaFile( ((METAFILEPICT
*)GlobalLock( lpFormat
->hData32
))->hMF
);
126 GlobalFree(lpFormat
->hData32
);
127 if (lpFormat
->hData16
)
128 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
129 and a shallow copy is enough to share a METAFILEPICT
130 structure between 16bit and 32bit clipboards. The MetaFile
131 should of course only be deleted once. */
132 GlobalFree16(lpFormat
->hData16
);
134 else if (lpFormat
->hData16
)
136 DeleteMetaFile16( ((METAFILEPICT16
*)GlobalLock16( lpFormat
->hData16
))->hMF
);
137 GlobalFree16(lpFormat
->hData16
);
142 if (lpFormat
->hData32
)
143 GlobalFree(lpFormat
->hData32
);
144 if (lpFormat
->hData16
)
145 GlobalFree16(lpFormat
->hData16
);
148 lpFormat
->wDataPresent
= 0;
149 lpFormat
->hData16
= 0;
150 lpFormat
->hData32
= 0;
152 if( bChange
) bCBHasChanged
= TRUE
;
155 /**************************************************************************
156 * CLIPBOARD_IsPresent
158 BOOL
CLIPBOARD_IsPresent(WORD wFormat
)
162 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
163 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
164 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
167 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
168 if( lpFormat
) return (lpFormat
->wDataPresent
);
173 /**************************************************************************
174 * OpenClipboard16 (USER.137)
176 BOOL16 WINAPI
OpenClipboard16( HWND16 hWnd
)
178 return OpenClipboard( hWnd
);
182 /**************************************************************************
183 * OpenClipboard32 (USER32.407)
185 * Note: Netscape uses NULL hWnd to open the clipboard.
187 BOOL WINAPI
OpenClipboard( HWND hWnd
)
191 TRACE(clipboard
,"(%04x)...\n", hWnd
);
195 hqClipLock
= GetFastQueue16();
196 hWndClipWindow
= hWnd
;
197 bCBHasChanged
= FALSE
;
202 TRACE(clipboard
," returning %i\n", bRet
);
207 /**************************************************************************
208 * CloseClipboard16 (USER.138)
210 BOOL16 WINAPI
CloseClipboard16(void)
212 return CloseClipboard();
216 /**************************************************************************
217 * CloseClipboard32 (USER32.54)
219 BOOL WINAPI
CloseClipboard(void)
221 TRACE(clipboard
,"!\n");
223 if (hqClipLock
== GetFastQueue16())
227 if (bCBHasChanged
&& hWndViewer
)
228 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
235 /**************************************************************************
236 * EmptyClipboard16 (USER.139)
238 BOOL16 WINAPI
EmptyClipboard16(void)
240 return EmptyClipboard();
244 /**************************************************************************
245 * EmptyClipboard32 (USER32.169)
247 BOOL WINAPI
EmptyClipboard(void)
249 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
251 TRACE(clipboard
,"(void)\n");
253 if (hqClipLock
!= GetFastQueue16()) return FALSE
;
255 /* destroy private objects */
258 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
262 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
263 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
265 lpFormat
= lpFormat
->NextFormat
;
268 hWndClipOwner
= hWndClipWindow
;
270 CLIPBOARD_GetDriver()->pEmptyClipboard();
276 /**************************************************************************
277 * GetClipboardOwner16 (USER.140)
279 HWND16 WINAPI
GetClipboardOwner16(void)
281 return hWndClipOwner
;
285 /**************************************************************************
286 * GetClipboardOwner32 (USER32.225)
288 HWND WINAPI
GetClipboardOwner(void)
290 return hWndClipOwner
;
294 /**************************************************************************
295 * SetClipboardData16 (USER.141)
297 HANDLE16 WINAPI
SetClipboardData16( UINT16 wFormat
, HANDLE16 hData
)
299 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
301 TRACE(clipboard
, "(%04X, %04x) !\n", wFormat
, hData
);
303 /* NOTE: If the hData is zero and current owner doesn't match
304 * the window that opened the clipboard then this application
305 * is screwed because WM_RENDERFORMAT will go to the owner
306 * (to become the owner it must call EmptyClipboard() before
310 if( (hqClipLock
!= GetFastQueue16()) || !lpFormat
||
311 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
313 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat
);
315 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
317 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
319 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
321 if( wFormat
== CF_TEXT
322 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
323 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
324 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
325 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
326 if( wFormat
== CF_OEMTEXT
327 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
328 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
329 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
330 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
333 bCBHasChanged
= TRUE
;
334 lpFormat
->wDataPresent
= 1;
335 lpFormat
->hData16
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
336 lpFormat
->hData32
= 0;
338 return lpFormat
->hData16
;
342 /**************************************************************************
343 * SetClipboardData32 (USER32.470)
345 HANDLE WINAPI
SetClipboardData( UINT wFormat
, HANDLE hData
)
347 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
349 TRACE(clipboard
, "(%08X, %08x) !\n", wFormat
, hData
);
351 /* NOTE: If the hData is zero and current owner doesn't match
352 * the window that opened the clipboard then this application
353 * is screwed because WM_RENDERFORMAT will go to the owner
354 * (to become the owner it must call EmptyClipboard() before
358 if( (hqClipLock
!= GetFastQueue16()) || !lpFormat
||
359 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
361 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat
);
363 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
365 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
367 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
369 if( wFormat
== CF_TEXT
370 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
371 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
372 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
373 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
374 if( wFormat
== CF_OEMTEXT
375 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
376 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
377 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
378 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
381 bCBHasChanged
= TRUE
;
382 lpFormat
->wDataPresent
= 1;
383 lpFormat
->hData32
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
384 lpFormat
->hData16
= 0;
386 return lpFormat
->hData32
;
390 /**************************************************************************
391 * CLIPBOARD_RenderFormat
393 static BOOL
CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat
)
395 if( lpFormat
->wDataPresent
&& !lpFormat
->hData16
&& !lpFormat
->hData32
)
397 if( IsWindow(hWndClipOwner
) )
398 SendMessage16(hWndClipOwner
,WM_RENDERFORMAT
,
399 (WPARAM16
)lpFormat
->wFormatID
,0L);
402 WARN(clipboard
, "\thWndClipOwner (%04x) is lost!\n",
404 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
408 return (lpFormat
->hData16
|| lpFormat
->hData32
) ? TRUE
: FALSE
;
411 /**************************************************************************
412 * CLIPBOARD_RenderText
414 * Convert text between UNIX and DOS formats.
416 static BOOL
CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget
, LPWINE_CLIPFORMAT lpSource
)
422 if (lpSource
->hData32
)
424 size
= GlobalSize( lpSource
->hData32
);
425 lpstrS
= (LPSTR
)GlobalLock(lpSource
->hData32
);
429 size
= GlobalSize16( lpSource
->hData16
);
430 lpstrS
= (LPSTR
)GlobalLock16(lpSource
->hData16
);
433 if( !lpstrS
) return FALSE
;
434 TRACE(clipboard
,"\tconverting from '%s' to '%s', %i chars\n",
435 lpSource
->Name
, lpTarget
->Name
, size
);
437 lpTarget
->hData32
= GlobalAlloc(GMEM_ZEROINIT
, size
);
438 lpstrT
= (LPSTR
)GlobalLock(lpTarget
->hData32
);
442 if( lpSource
->wFormatID
== CF_TEXT
)
443 CharToOemBuffA(lpstrS
, lpstrT
, size
);
445 OemToCharBuffA(lpstrS
, lpstrT
, size
);
446 TRACE(clipboard
,"\tgot %s\n", lpstrT
);
447 GlobalUnlock(lpTarget
->hData32
);
448 if (lpSource
->hData32
)
449 GlobalUnlock(lpSource
->hData32
);
451 GlobalUnlock16(lpSource
->hData16
);
455 lpTarget
->hData32
= 0;
456 if (lpSource
->hData32
)
457 GlobalUnlock(lpSource
->hData32
);
459 GlobalUnlock16(lpSource
->hData16
);
463 /**************************************************************************
464 * GetClipboardData16 (USER.142)
466 HANDLE16 WINAPI
GetClipboardData16( UINT16 wFormat
)
468 LPWINE_CLIPFORMAT lpRender
= ClipFormats
;
469 LPWINE_CLIPFORMAT lpUpdate
= NULL
;
471 if (hqClipLock
!= GetFastQueue16()) return 0;
473 TRACE(clipboard
,"(%04X)\n", wFormat
);
475 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
476 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
478 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
479 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
481 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
483 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
484 && lpRender
[CF_TEXT
-1].wDataPresent
)
486 lpRender
= &ClipFormats
[CF_TEXT
-1];
487 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
489 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
493 lpRender
= __lookup_format( ClipFormats
, wFormat
);
497 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
498 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
499 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
501 if( lpUpdate
->hData32
&& !lpUpdate
->hData16
)
504 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
505 size
= sizeof( METAFILEPICT16
);
507 size
= GlobalSize(lpUpdate
->hData32
);
508 lpUpdate
->hData16
= GlobalAlloc16(GMEM_ZEROINIT
, size
);
509 if( !lpUpdate
->hData16
)
510 ERR(clipboard
, "(%04X) -- not enough memory in 16b heap\n", wFormat
);
513 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
515 FIXME(clipboard
,"\timplement function CopyMetaFilePict32to16\n");
516 FIXME(clipboard
,"\tin the appropriate file.\n");
517 #ifdef SOMEONE_IMPLEMENTED_ME
518 CopyMetaFilePict32to16( GlobalLock16(lpUpdate
->hData16
),
519 GlobalLock(lpUpdate
->hData32
) );
524 memcpy( GlobalLock16(lpUpdate
->hData16
),
525 GlobalLock(lpUpdate
->hData32
),
528 GlobalUnlock16(lpUpdate
->hData16
);
529 GlobalUnlock(lpUpdate
->hData32
);
533 TRACE(clipboard
,"\treturning %04x (type %i)\n",
534 lpUpdate
->hData16
, lpUpdate
->wFormatID
);
535 return lpUpdate
->hData16
;
539 /**************************************************************************
540 * GetClipboardData32 (USER32.222)
542 HANDLE WINAPI
GetClipboardData( UINT wFormat
)
544 LPWINE_CLIPFORMAT lpRender
= ClipFormats
;
545 LPWINE_CLIPFORMAT lpUpdate
= NULL
;
547 if (hqClipLock
!= GetFastQueue16()) return 0;
549 TRACE(clipboard
,"(%08X)\n", wFormat
);
551 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
552 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
554 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
555 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
557 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
559 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
560 && lpRender
[CF_TEXT
-1].wDataPresent
)
562 lpRender
= &ClipFormats
[CF_TEXT
-1];
563 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
565 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
569 lpRender
= __lookup_format( ClipFormats
, wFormat
);
573 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
574 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
575 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
577 if( lpUpdate
->hData16
&& !lpUpdate
->hData32
)
580 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
581 size
= sizeof( METAFILEPICT
);
583 size
= GlobalSize16(lpUpdate
->hData16
);
584 lpUpdate
->hData32
= GlobalAlloc(GMEM_ZEROINIT
, size
);
585 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
587 FIXME(clipboard
,"\timplement function CopyMetaFilePict16to32\n");
588 FIXME(clipboard
,"\tin the appropriate file.\n");
589 #ifdef SOMEONE_IMPLEMENTED_ME
590 CopyMetaFilePict16to32( GlobalLock16(lpUpdate
->hData32
),
591 GlobalLock(lpUpdate
->hData16
) );
596 memcpy( GlobalLock(lpUpdate
->hData32
),
597 GlobalLock16(lpUpdate
->hData16
),
600 GlobalUnlock(lpUpdate
->hData32
);
601 GlobalUnlock16(lpUpdate
->hData16
);
604 TRACE(clipboard
,"\treturning %04x (type %i)\n",
605 lpUpdate
->hData32
, lpUpdate
->wFormatID
);
606 return lpUpdate
->hData32
;
609 /**************************************************************************
610 * CountClipboardFormats16 (USER.143)
612 INT16 WINAPI
CountClipboardFormats16(void)
614 return CountClipboardFormats();
618 /**************************************************************************
619 * CountClipboardFormats32 (USER32.63)
621 INT WINAPI
CountClipboardFormats(void)
624 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
626 TRACE(clipboard
,"(void)\n");
628 /* FIXME: Returns BOOL32 */
629 CLIPBOARD_GetDriver()->pRequestSelection();
631 FormatCount
+= abs(lpFormat
[CF_TEXT
-1].wDataPresent
-
632 lpFormat
[CF_OEMTEXT
-1].wDataPresent
);
636 if (lpFormat
== NULL
) break;
637 if (lpFormat
->wDataPresent
)
639 TRACE(clipboard
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
642 lpFormat
= lpFormat
->NextFormat
;
645 TRACE(clipboard
,"\ttotal %d\n", FormatCount
);
650 /**************************************************************************
651 * EnumClipboardFormats16 (USER.144)
653 UINT16 WINAPI
EnumClipboardFormats16( UINT16 wFormat
)
655 return EnumClipboardFormats( wFormat
);
659 /**************************************************************************
660 * EnumClipboardFormats32 (USER32.179)
662 UINT WINAPI
EnumClipboardFormats( UINT wFormat
)
664 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
666 TRACE(clipboard
,"(%04X)\n", wFormat
);
668 if( hqClipLock
!= GetFastQueue16() ) return 0;
670 if( (!wFormat
|| wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
671 CLIPBOARD_GetDriver()->pRequestSelection();
675 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
676 return lpFormat
->wFormatID
;
678 wFormat
= lpFormat
->wFormatID
; /* and CF_TEXT is not available */
681 /* walk up to the specified format record */
683 if( !(lpFormat
= __lookup_format( lpFormat
, wFormat
)) ) return 0;
685 /* find next format with available data */
687 lpFormat
= lpFormat
->NextFormat
;
690 if (lpFormat
== NULL
) return 0;
691 if (lpFormat
->wDataPresent
|| (lpFormat
->wFormatID
== CF_OEMTEXT
&&
692 ClipFormats
[CF_TEXT
-1].wDataPresent
))
694 lpFormat
= lpFormat
->NextFormat
;
697 return lpFormat
->wFormatID
;
701 /**************************************************************************
702 * RegisterClipboardFormat16 (USER.145)
704 UINT16 WINAPI
RegisterClipboardFormat16( LPCSTR FormatName
)
706 LPWINE_CLIPFORMAT lpNewFormat
;
707 LPWINE_CLIPFORMAT lpFormat
= ClipFormats
;
709 if (FormatName
== NULL
) return 0;
711 TRACE(clipboard
,"('%s') !\n", FormatName
);
713 /* walk format chain to see if it's already registered */
717 if ( !strcmp(lpFormat
->Name
,FormatName
) )
719 lpFormat
->wRefCount
++;
720 return lpFormat
->wFormatID
;
723 if ( lpFormat
->NextFormat
== NULL
) break;
725 lpFormat
= lpFormat
->NextFormat
;
728 /* allocate storage for new format entry */
730 lpNewFormat
= (LPWINE_CLIPFORMAT
)xmalloc(sizeof(WINE_CLIPFORMAT
));
731 lpFormat
->NextFormat
= lpNewFormat
;
732 lpNewFormat
->wFormatID
= LastRegFormat
;
733 lpNewFormat
->wRefCount
= 1;
735 lpNewFormat
->Name
= (LPSTR
)xmalloc(strlen(FormatName
) + 1);
736 strcpy(lpNewFormat
->Name
, FormatName
);
738 lpNewFormat
->wDataPresent
= 0;
739 lpNewFormat
->hData16
= 0;
740 lpNewFormat
->hData32
= 0;
741 lpNewFormat
->BufSize
= 0;
742 lpNewFormat
->PrevFormat
= lpFormat
;
743 lpNewFormat
->NextFormat
= NULL
;
745 return LastRegFormat
++;
749 /**************************************************************************
750 * RegisterClipboardFormat32A (USER32.431)
752 UINT WINAPI
RegisterClipboardFormatA( LPCSTR formatName
)
754 return RegisterClipboardFormat16( formatName
);
758 /**************************************************************************
759 * RegisterClipboardFormat32W (USER32.432)
761 UINT WINAPI
RegisterClipboardFormatW( LPCWSTR formatName
)
763 LPSTR aFormat
= HEAP_strdupWtoA( GetProcessHeap(), 0, formatName
);
764 UINT ret
= RegisterClipboardFormatA( aFormat
);
765 HeapFree( GetProcessHeap(), 0, aFormat
);
769 /**************************************************************************
770 * GetClipboardFormatName16 (USER.146)
772 INT16 WINAPI
GetClipboardFormatName16( UINT16 wFormat
, LPSTR retStr
, INT16 maxlen
)
774 return GetClipboardFormatNameA( wFormat
, retStr
, maxlen
);
778 /**************************************************************************
779 * GetClipboardFormatName32A (USER32.223)
781 INT WINAPI
GetClipboardFormatNameA( UINT wFormat
, LPSTR retStr
, INT maxlen
)
783 LPWINE_CLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
785 TRACE(clipboard
, "(%04X, %p, %d) !\n", wFormat
, retStr
, maxlen
);
787 if (lpFormat
== NULL
|| lpFormat
->Name
== NULL
||
788 lpFormat
->wFormatID
< CF_REGFORMATBASE
) return 0;
790 TRACE(clipboard
, "Name='%s' !\n", lpFormat
->Name
);
792 lstrcpynA( retStr
, lpFormat
->Name
, maxlen
);
793 return strlen(retStr
);
797 /**************************************************************************
798 * GetClipboardFormatName32W (USER32.224)
800 INT WINAPI
GetClipboardFormatNameW( UINT wFormat
, LPWSTR retStr
, INT maxlen
)
802 LPSTR p
= HEAP_xalloc( GetProcessHeap(), 0, maxlen
);
803 INT ret
= GetClipboardFormatNameA( wFormat
, p
, maxlen
);
804 lstrcpynAtoW( retStr
, p
, maxlen
);
805 HeapFree( GetProcessHeap(), 0, p
);
810 /**************************************************************************
811 * SetClipboardViewer16 (USER.147)
813 HWND16 WINAPI
SetClipboardViewer16( HWND16 hWnd
)
815 return SetClipboardViewer( hWnd
);
819 /**************************************************************************
820 * SetClipboardViewer32 (USER32.471)
822 HWND WINAPI
SetClipboardViewer( HWND hWnd
)
824 HWND hwndPrev
= hWndViewer
;
826 TRACE(clipboard
,"(%04x): returning %04x\n", hWnd
, hwndPrev
);
833 /**************************************************************************
834 * GetClipboardViewer16 (USER.148)
836 HWND16 WINAPI
GetClipboardViewer16(void)
842 /**************************************************************************
843 * GetClipboardViewer32 (USER32.226)
845 HWND WINAPI
GetClipboardViewer(void)
851 /**************************************************************************
852 * ChangeClipboardChain16 (USER.149)
854 BOOL16 WINAPI
ChangeClipboardChain16(HWND16 hWnd
, HWND16 hWndNext
)
856 return ChangeClipboardChain(hWnd
, hWndNext
);
859 /**************************************************************************
860 * ChangeClipboardChain32 (USER32.22)
862 BOOL WINAPI
ChangeClipboardChain(HWND hWnd
, HWND hWndNext
)
866 FIXME(clipboard
, "(0x%04x, 0x%04x): stub?\n", hWnd
, hWndNext
);
869 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
870 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
872 WARN(clipboard
, "hWndViewer is lost\n");
874 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
881 /**************************************************************************
882 * IsClipboardFormatAvailable16 (USER.193)
884 BOOL16 WINAPI
IsClipboardFormatAvailable16( UINT16 wFormat
)
886 return IsClipboardFormatAvailable( wFormat
);
890 /**************************************************************************
891 * IsClipboardFormatAvailable32 (USER32.340)
893 BOOL WINAPI
IsClipboardFormatAvailable( UINT wFormat
)
895 TRACE(clipboard
,"(%04X) !\n", wFormat
);
897 if( (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
898 CLIPBOARD_GetDriver()->pRequestSelection();
900 return CLIPBOARD_IsPresent(wFormat
);
904 /**************************************************************************
905 * GetOpenClipboardWindow16 (USER.248)
907 HWND16 WINAPI
GetOpenClipboardWindow16(void)
909 return hWndClipWindow
;
913 /**************************************************************************
914 * GetOpenClipboardWindow32 (USER32.277)
916 HWND WINAPI
GetOpenClipboardWindow(void)
918 return hWndClipWindow
;
922 /**************************************************************************
923 * GetPriorityClipboardFormat16 (USER.402)
925 INT16 WINAPI
GetPriorityClipboardFormat16( UINT16
*lpPriorityList
, INT16 nCount
)
927 FIXME(clipboard
, "(%p,%d): stub\n", lpPriorityList
, nCount
);
932 /**************************************************************************
933 * GetPriorityClipboardFormat32 (USER32.279)
935 INT WINAPI
GetPriorityClipboardFormat( UINT
*lpPriorityList
, INT nCount
)
939 if(CountClipboardFormats() == 0)
944 for(Counter
= 0; Counter
<= nCount
; Counter
++)
946 if(IsClipboardFormatAvailable(*(lpPriorityList
+sizeof(INT
)*Counter
)))
947 return *(lpPriorityList
+sizeof(INT
)*Counter
);