2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
10 #include <sys/types.h>
19 #include "clipboard.h"
23 #ifndef X_DISPLAY_MISSING
24 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver
;
25 #else /* X_DISPLAY_MISSING */
26 extern CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver
;
27 #endif /* X_DISPLAY_MISSING */
29 #define CF_REGFORMATBASE 0xC000
31 /**************************************************************************
35 static HQUEUE16 hqClipLock
= 0;
36 static BOOL32 bCBHasChanged
= FALSE
;
38 HWND32 hWndClipOwner
= 0; /* current clipboard owner */
39 HWND32 hWndClipWindow
= 0; /* window that opened clipboard */
40 static HWND32 hWndViewer
= 0; /* start of viewers chain */
42 static WORD LastRegFormat
= CF_REGFORMATBASE
;
44 CLIPFORMAT ClipFormats
[16] = {
45 { CF_TEXT
, 1, 0, "Text", (HANDLE32
)NULL
, 0, NULL
, &ClipFormats
[1] , (HANDLE16
)NULL
},
46 { CF_BITMAP
, 1, 0, "Bitmap", (HANDLE32
)NULL
, 0, &ClipFormats
[0], &ClipFormats
[2] , (HANDLE16
)NULL
},
47 { CF_METAFILEPICT
, 1, 0, "MetaFile Picture", (HANDLE32
)NULL
, 0, &ClipFormats
[1], &ClipFormats
[3] , (HANDLE16
)NULL
},
48 { CF_SYLK
, 1, 0, "Sylk", (HANDLE32
)NULL
, 0, &ClipFormats
[2], &ClipFormats
[4] , (HANDLE16
)NULL
},
49 { CF_DIF
, 1, 0, "DIF", (HANDLE32
)NULL
, 0, &ClipFormats
[3], &ClipFormats
[5] , (HANDLE16
)NULL
},
50 { CF_TIFF
, 1, 0, "TIFF", (HANDLE32
)NULL
, 0, &ClipFormats
[4], &ClipFormats
[6] , (HANDLE16
)NULL
},
51 { CF_OEMTEXT
, 1, 0, "OEM Text", (HANDLE32
)NULL
, 0, &ClipFormats
[5], &ClipFormats
[7] , (HANDLE16
)NULL
},
52 { CF_DIB
, 1, 0, "DIB", (HANDLE32
)NULL
, 0, &ClipFormats
[6], &ClipFormats
[8] , (HANDLE16
)NULL
},
53 { CF_PALETTE
, 1, 0, "Palette", (HANDLE32
)NULL
, 0, &ClipFormats
[7], &ClipFormats
[9] , (HANDLE16
)NULL
},
54 { CF_PENDATA
, 1, 0, "PenData", (HANDLE32
)NULL
, 0, &ClipFormats
[8], &ClipFormats
[10] , (HANDLE16
)NULL
},
55 { CF_RIFF
, 1, 0, "RIFF", (HANDLE32
)NULL
, 0, &ClipFormats
[9], &ClipFormats
[11] , (HANDLE16
)NULL
},
56 { CF_WAVE
, 1, 0, "Wave", (HANDLE32
)NULL
, 0, &ClipFormats
[10], &ClipFormats
[12] , (HANDLE16
)NULL
},
57 { CF_OWNERDISPLAY
, 1, 0, "Owner Display", (HANDLE32
)NULL
, 0, &ClipFormats
[11], &ClipFormats
[13] , (HANDLE16
)NULL
},
58 { CF_DSPTEXT
, 1, 0, "DSPText", (HANDLE32
)NULL
, 0, &ClipFormats
[12], &ClipFormats
[14] , (HANDLE16
)NULL
},
59 { CF_DSPMETAFILEPICT
, 1, 0, "DSPMetaFile Picture", (HANDLE32
)NULL
, 0, &ClipFormats
[13], &ClipFormats
[15] , (HANDLE16
)NULL
},
60 { CF_DSPBITMAP
, 1, 0, "DSPBitmap", (HANDLE32
)NULL
, 0, &ClipFormats
[14], NULL
, (HANDLE16
)NULL
}
63 static LPCLIPFORMAT
__lookup_format( LPCLIPFORMAT lpFormat
, WORD wID
)
67 if (lpFormat
== NULL
||
68 lpFormat
->wFormatID
== wID
) break;
69 lpFormat
= lpFormat
->NextFormat
;
75 /**************************************************************************
78 CLIPBOARD_DRIVER
*CLIPBOARD_GetDriver()
80 #ifndef X_DISPLAY_MISSING
81 return &X11DRV_CLIPBOARD_Driver
;
82 #else /* X_DISPLAY_MISSING */
83 return &TTYDRV_CLIPBOARD_Driver
;
84 #endif /* X_DISPLAY_MISSING */
87 /**************************************************************************
90 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
92 if( hqClipLock
== hqCurrent
)
107 /**************************************************************************
108 * CLIPBOARD_DeleteRecord
110 void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat
, BOOL32 bChange
)
112 if( (lpFormat
->wFormatID
>= CF_GDIOBJFIRST
&&
113 lpFormat
->wFormatID
<= CF_GDIOBJLAST
) || lpFormat
->wFormatID
== CF_BITMAP
)
115 if (lpFormat
->hData32
)
116 DeleteObject32(lpFormat
->hData32
);
117 if (lpFormat
->hData16
)
118 DeleteObject16(lpFormat
->hData16
);
120 else if( lpFormat
->wFormatID
== CF_METAFILEPICT
)
122 if (lpFormat
->hData32
)
124 DeleteMetaFile32( ((METAFILEPICT32
*)GlobalLock32( lpFormat
->hData32
))->hMF
);
125 GlobalFree32(lpFormat
->hData32
);
126 if (lpFormat
->hData16
)
127 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
128 and a shallow copy is enough to share a METAFILEPICT
129 structure between 16bit and 32bit clipboards. The MetaFile
130 should of course only be deleted once. */
131 GlobalFree16(lpFormat
->hData16
);
133 else if (lpFormat
->hData16
)
135 DeleteMetaFile16( ((METAFILEPICT16
*)GlobalLock16( lpFormat
->hData16
))->hMF
);
136 GlobalFree16(lpFormat
->hData16
);
141 if (lpFormat
->hData32
)
142 GlobalFree32(lpFormat
->hData32
);
143 if (lpFormat
->hData16
)
144 GlobalFree16(lpFormat
->hData16
);
147 lpFormat
->wDataPresent
= 0;
148 lpFormat
->hData16
= 0;
149 lpFormat
->hData32
= 0;
151 if( bChange
) bCBHasChanged
= TRUE
;
154 /**************************************************************************
155 * CLIPBOARD_IsPresent
157 BOOL32
CLIPBOARD_IsPresent(WORD wFormat
)
161 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
162 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
163 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
166 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
167 if( lpFormat
) return (lpFormat
->wDataPresent
);
172 /**************************************************************************
173 * OpenClipboard16 (USER.137)
175 BOOL16 WINAPI
OpenClipboard16( HWND16 hWnd
)
177 return OpenClipboard32( hWnd
);
181 /**************************************************************************
182 * OpenClipboard32 (USER32.407)
184 * Note: Netscape uses NULL hWnd to open the clipboard.
186 BOOL32 WINAPI
OpenClipboard32( HWND32 hWnd
)
190 TRACE(clipboard
,"(%04x)...\n", hWnd
);
194 hqClipLock
= GetFastQueue();
195 hWndClipWindow
= hWnd
;
196 bCBHasChanged
= FALSE
;
201 TRACE(clipboard
," returning %i\n", bRet
);
206 /**************************************************************************
207 * CloseClipboard16 (USER.138)
209 BOOL16 WINAPI
CloseClipboard16(void)
211 return CloseClipboard32();
215 /**************************************************************************
216 * CloseClipboard32 (USER32.54)
218 BOOL32 WINAPI
CloseClipboard32(void)
220 TRACE(clipboard
,"!\n");
222 if (hqClipLock
== GetFastQueue())
226 if (bCBHasChanged
&& hWndViewer
)
227 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
234 /**************************************************************************
235 * EmptyClipboard16 (USER.139)
237 BOOL16 WINAPI
EmptyClipboard16(void)
239 return EmptyClipboard32();
243 /**************************************************************************
244 * EmptyClipboard32 (USER32.169)
246 BOOL32 WINAPI
EmptyClipboard32(void)
248 LPCLIPFORMAT lpFormat
= ClipFormats
;
250 TRACE(clipboard
,"(void)\n");
252 if (hqClipLock
!= GetFastQueue()) return FALSE
;
254 /* destroy private objects */
257 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
261 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
262 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
264 lpFormat
= lpFormat
->NextFormat
;
267 hWndClipOwner
= hWndClipWindow
;
269 CLIPBOARD_GetDriver()->pEmptyClipboard();
275 /**************************************************************************
276 * GetClipboardOwner16 (USER.140)
278 HWND16 WINAPI
GetClipboardOwner16(void)
280 return hWndClipOwner
;
284 /**************************************************************************
285 * GetClipboardOwner32 (USER32.225)
287 HWND32 WINAPI
GetClipboardOwner32(void)
289 return hWndClipOwner
;
293 /**************************************************************************
294 * SetClipboardData16 (USER.141)
296 HANDLE16 WINAPI
SetClipboardData16( UINT16 wFormat
, HANDLE16 hData
)
298 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
300 TRACE(clipboard
, "(%04X, %04x) !\n", wFormat
, hData
);
302 /* NOTE: If the hData is zero and current owner doesn't match
303 * the window that opened the clipboard then this application
304 * is screwed because WM_RENDERFORMAT will go to the owner
305 * (to become the owner it must call EmptyClipboard() before
309 if( (hqClipLock
!= GetFastQueue()) || !lpFormat
||
310 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
312 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat
);
314 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
316 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
318 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
320 if( wFormat
== CF_TEXT
321 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
322 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
323 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
324 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
325 if( wFormat
== CF_OEMTEXT
326 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
327 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
328 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
329 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
332 bCBHasChanged
= TRUE
;
333 lpFormat
->wDataPresent
= 1;
334 lpFormat
->hData16
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
335 lpFormat
->hData32
= 0;
337 return lpFormat
->hData16
;
341 /**************************************************************************
342 * SetClipboardData32 (USER32.470)
344 HANDLE32 WINAPI
SetClipboardData32( UINT32 wFormat
, HANDLE32 hData
)
346 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
348 TRACE(clipboard
, "(%08X, %08x) !\n", wFormat
, hData
);
350 /* NOTE: If the hData is zero and current owner doesn't match
351 * the window that opened the clipboard then this application
352 * is screwed because WM_RENDERFORMAT will go to the owner
353 * (to become the owner it must call EmptyClipboard() before
357 if( (hqClipLock
!= GetFastQueue()) || !lpFormat
||
358 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
360 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat
);
362 if ( lpFormat
->wDataPresent
|| lpFormat
->hData16
|| lpFormat
->hData32
)
364 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
366 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
368 if( wFormat
== CF_TEXT
369 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
370 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
371 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
372 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
373 if( wFormat
== CF_OEMTEXT
374 && ( ClipFormats
[CF_OEMTEXT
-1].hData16
375 || ClipFormats
[CF_OEMTEXT
-1].hData32
)
376 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
377 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
380 bCBHasChanged
= TRUE
;
381 lpFormat
->wDataPresent
= 1;
382 lpFormat
->hData32
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
383 lpFormat
->hData16
= 0;
385 return lpFormat
->hData32
;
389 /**************************************************************************
390 * CLIPBOARD_RenderFormat
392 static BOOL32
CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat
)
394 if( lpFormat
->wDataPresent
&& !lpFormat
->hData16
&& !lpFormat
->hData32
)
396 if( IsWindow32(hWndClipOwner
) )
397 SendMessage16(hWndClipOwner
,WM_RENDERFORMAT
,
398 (WPARAM16
)lpFormat
->wFormatID
,0L);
401 WARN(clipboard
, "\thWndClipOwner (%04x) is lost!\n",
403 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
407 return (lpFormat
->hData16
|| lpFormat
->hData32
) ? TRUE
: FALSE
;
410 /**************************************************************************
411 * CLIPBOARD_RenderText
413 * Convert text between UNIX and DOS formats.
415 static BOOL32
CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget
, LPCLIPFORMAT lpSource
)
421 if (lpSource
->hData32
)
423 size
= GlobalSize32( lpSource
->hData32
);
424 lpstrS
= (LPSTR
)GlobalLock32(lpSource
->hData32
);
428 size
= GlobalSize16( lpSource
->hData16
);
429 lpstrS
= (LPSTR
)GlobalLock16(lpSource
->hData16
);
432 if( !lpstrS
) return FALSE
;
433 TRACE(clipboard
,"\tconverting from '%s' to '%s', %i chars\n",
434 lpSource
->Name
, lpTarget
->Name
, size
);
436 lpTarget
->hData32
= GlobalAlloc32(GMEM_ZEROINIT
, size
);
437 lpstrT
= (LPSTR
)GlobalLock32(lpTarget
->hData32
);
441 if( lpSource
->wFormatID
== CF_TEXT
)
442 CharToOemBuff32A(lpstrS
, lpstrT
, size
);
444 OemToCharBuff32A(lpstrS
, lpstrT
, size
);
445 TRACE(clipboard
,"\tgot %s\n", lpstrT
);
446 GlobalUnlock32(lpTarget
->hData32
);
447 if (lpSource
->hData32
)
448 GlobalUnlock32(lpSource
->hData32
);
450 GlobalUnlock16(lpSource
->hData16
);
454 lpTarget
->hData32
= 0;
455 if (lpSource
->hData32
)
456 GlobalUnlock32(lpSource
->hData32
);
458 GlobalUnlock16(lpSource
->hData16
);
462 /**************************************************************************
463 * GetClipboardData16 (USER.142)
465 HANDLE16 WINAPI
GetClipboardData16( UINT16 wFormat
)
467 LPCLIPFORMAT lpRender
= ClipFormats
;
468 LPCLIPFORMAT lpUpdate
= NULL
;
470 if (hqClipLock
!= GetFastQueue()) return 0;
472 TRACE(clipboard
,"(%04X)\n", wFormat
);
474 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
475 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
477 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
478 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
480 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
482 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
483 && lpRender
[CF_TEXT
-1].wDataPresent
)
485 lpRender
= &ClipFormats
[CF_TEXT
-1];
486 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
488 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
492 lpRender
= __lookup_format( ClipFormats
, wFormat
);
496 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
497 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
498 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
500 if( lpUpdate
->hData32
&& !lpUpdate
->hData16
)
503 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
504 size
= sizeof( METAFILEPICT16
);
506 size
= GlobalSize32(lpUpdate
->hData32
);
507 lpUpdate
->hData16
= GlobalAlloc16(GMEM_ZEROINIT
, size
);
508 if( !lpUpdate
->hData16
)
509 ERR(clipboard
, "(%04X) -- not enough memory in 16b heap\n", wFormat
);
512 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
514 FIXME(clipboard
,"\timplement function CopyMetaFilePict32to16\n");
515 FIXME(clipboard
,"\tin the appropriate file.\n");
516 #ifdef SOMEONE_IMPLEMENTED_ME
517 CopyMetaFilePict32to16( GlobalLock16(lpUpdate
->hData16
),
518 GlobalLock32(lpUpdate
->hData32
) );
523 memcpy( GlobalLock16(lpUpdate
->hData16
),
524 GlobalLock32(lpUpdate
->hData32
),
527 GlobalUnlock16(lpUpdate
->hData16
);
528 GlobalUnlock32(lpUpdate
->hData32
);
532 TRACE(clipboard
,"\treturning %04x (type %i)\n",
533 lpUpdate
->hData16
, lpUpdate
->wFormatID
);
534 return lpUpdate
->hData16
;
538 /**************************************************************************
539 * GetClipboardData32 (USER32.222)
541 HANDLE32 WINAPI
GetClipboardData32( UINT32 wFormat
)
543 LPCLIPFORMAT lpRender
= ClipFormats
;
544 LPCLIPFORMAT lpUpdate
= NULL
;
546 if (hqClipLock
!= GetFastQueue()) return 0;
548 TRACE(clipboard
,"(%08X)\n", wFormat
);
550 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
551 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
553 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
554 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
556 TRACE(clipboard
,"\tOEMTEXT -> TEXT\n");
558 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
559 && lpRender
[CF_TEXT
-1].wDataPresent
)
561 lpRender
= &ClipFormats
[CF_TEXT
-1];
562 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
564 TRACE(clipboard
,"\tTEXT -> OEMTEXT\n");
568 lpRender
= __lookup_format( ClipFormats
, wFormat
);
572 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
573 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData16
&& !lpUpdate
->hData32
)
574 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
576 if( lpUpdate
->hData16
&& !lpUpdate
->hData32
)
579 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
580 size
= sizeof( METAFILEPICT32
);
582 size
= GlobalSize16(lpUpdate
->hData16
);
583 lpUpdate
->hData32
= GlobalAlloc32(GMEM_ZEROINIT
, size
);
584 if( lpUpdate
->wFormatID
== CF_METAFILEPICT
)
586 FIXME(clipboard
,"\timplement function CopyMetaFilePict16to32\n");
587 FIXME(clipboard
,"\tin the appropriate file.\n");
588 #ifdef SOMEONE_IMPLEMENTED_ME
589 CopyMetaFilePict16to32( GlobalLock16(lpUpdate
->hData32
),
590 GlobalLock32(lpUpdate
->hData16
) );
595 memcpy( GlobalLock32(lpUpdate
->hData32
),
596 GlobalLock16(lpUpdate
->hData16
),
599 GlobalUnlock32(lpUpdate
->hData32
);
600 GlobalUnlock16(lpUpdate
->hData16
);
603 TRACE(clipboard
,"\treturning %04x (type %i)\n",
604 lpUpdate
->hData32
, lpUpdate
->wFormatID
);
605 return lpUpdate
->hData32
;
608 /**************************************************************************
609 * CountClipboardFormats16 (USER.143)
611 INT16 WINAPI
CountClipboardFormats16(void)
613 return CountClipboardFormats32();
617 /**************************************************************************
618 * CountClipboardFormats32 (USER32.63)
620 INT32 WINAPI
CountClipboardFormats32(void)
622 INT32 FormatCount
= 0;
623 LPCLIPFORMAT lpFormat
= ClipFormats
;
625 TRACE(clipboard
,"(void)\n");
627 /* FIXME: Returns BOOL32 */
628 CLIPBOARD_GetDriver()->pRequestSelection();
630 FormatCount
+= abs(lpFormat
[CF_TEXT
-1].wDataPresent
-
631 lpFormat
[CF_OEMTEXT
-1].wDataPresent
);
635 if (lpFormat
== NULL
) break;
636 if (lpFormat
->wDataPresent
)
638 TRACE(clipboard
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
641 lpFormat
= lpFormat
->NextFormat
;
644 TRACE(clipboard
,"\ttotal %d\n", FormatCount
);
649 /**************************************************************************
650 * EnumClipboardFormats16 (USER.144)
652 UINT16 WINAPI
EnumClipboardFormats16( UINT16 wFormat
)
654 return EnumClipboardFormats32( wFormat
);
658 /**************************************************************************
659 * EnumClipboardFormats32 (USER32.179)
661 UINT32 WINAPI
EnumClipboardFormats32( UINT32 wFormat
)
663 LPCLIPFORMAT lpFormat
= ClipFormats
;
665 TRACE(clipboard
,"(%04X)\n", wFormat
);
667 if( hqClipLock
!= GetFastQueue() ) return 0;
669 if( (!wFormat
|| wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
670 CLIPBOARD_GetDriver()->pRequestSelection();
674 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
675 return lpFormat
->wFormatID
;
677 wFormat
= lpFormat
->wFormatID
; /* and CF_TEXT is not available */
680 /* walk up to the specified format record */
682 if( !(lpFormat
= __lookup_format( lpFormat
, wFormat
)) ) return 0;
684 /* find next format with available data */
686 lpFormat
= lpFormat
->NextFormat
;
689 if (lpFormat
== NULL
) return 0;
690 if (lpFormat
->wDataPresent
|| (lpFormat
->wFormatID
== CF_OEMTEXT
&&
691 ClipFormats
[CF_TEXT
-1].wDataPresent
))
693 lpFormat
= lpFormat
->NextFormat
;
696 return lpFormat
->wFormatID
;
700 /**************************************************************************
701 * RegisterClipboardFormat16 (USER.145)
703 UINT16 WINAPI
RegisterClipboardFormat16( LPCSTR FormatName
)
705 LPCLIPFORMAT lpNewFormat
;
706 LPCLIPFORMAT lpFormat
= ClipFormats
;
708 if (FormatName
== NULL
) return 0;
710 TRACE(clipboard
,"('%s') !\n", FormatName
);
712 /* walk format chain to see if it's already registered */
716 if ( !strcmp(lpFormat
->Name
,FormatName
) )
718 lpFormat
->wRefCount
++;
719 return lpFormat
->wFormatID
;
722 if ( lpFormat
->NextFormat
== NULL
) break;
724 lpFormat
= lpFormat
->NextFormat
;
727 /* allocate storage for new format entry */
729 lpNewFormat
= (LPCLIPFORMAT
)xmalloc(sizeof(CLIPFORMAT
));
730 lpFormat
->NextFormat
= lpNewFormat
;
731 lpNewFormat
->wFormatID
= LastRegFormat
;
732 lpNewFormat
->wRefCount
= 1;
734 lpNewFormat
->Name
= (LPSTR
)xmalloc(strlen(FormatName
) + 1);
735 strcpy(lpNewFormat
->Name
, FormatName
);
737 lpNewFormat
->wDataPresent
= 0;
738 lpNewFormat
->hData16
= 0;
739 lpNewFormat
->hData32
= 0;
740 lpNewFormat
->BufSize
= 0;
741 lpNewFormat
->PrevFormat
= lpFormat
;
742 lpNewFormat
->NextFormat
= NULL
;
744 return LastRegFormat
++;
748 /**************************************************************************
749 * RegisterClipboardFormat32A (USER32.431)
751 UINT32 WINAPI
RegisterClipboardFormat32A( LPCSTR formatName
)
753 return RegisterClipboardFormat16( formatName
);
757 /**************************************************************************
758 * RegisterClipboardFormat32W (USER32.432)
760 UINT32 WINAPI
RegisterClipboardFormat32W( LPCWSTR formatName
)
762 LPSTR aFormat
= HEAP_strdupWtoA( GetProcessHeap(), 0, formatName
);
763 UINT32 ret
= RegisterClipboardFormat32A( aFormat
);
764 HeapFree( GetProcessHeap(), 0, aFormat
);
768 /**************************************************************************
769 * GetClipboardFormatName16 (USER.146)
771 INT16 WINAPI
GetClipboardFormatName16( UINT16 wFormat
, LPSTR retStr
, INT16 maxlen
)
773 return GetClipboardFormatName32A( wFormat
, retStr
, maxlen
);
777 /**************************************************************************
778 * GetClipboardFormatName32A (USER32.223)
780 INT32 WINAPI
GetClipboardFormatName32A( UINT32 wFormat
, LPSTR retStr
, INT32 maxlen
)
782 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
784 TRACE(clipboard
, "(%04X, %p, %d) !\n", wFormat
, retStr
, maxlen
);
786 if (lpFormat
== NULL
|| lpFormat
->Name
== NULL
||
787 lpFormat
->wFormatID
< CF_REGFORMATBASE
) return 0;
789 TRACE(clipboard
, "Name='%s' !\n", lpFormat
->Name
);
791 lstrcpyn32A( retStr
, lpFormat
->Name
, maxlen
);
792 return strlen(retStr
);
796 /**************************************************************************
797 * GetClipboardFormatName32W (USER32.224)
799 INT32 WINAPI
GetClipboardFormatName32W( UINT32 wFormat
, LPWSTR retStr
, INT32 maxlen
)
801 LPSTR p
= HEAP_xalloc( GetProcessHeap(), 0, maxlen
);
802 INT32 ret
= GetClipboardFormatName32A( wFormat
, p
, maxlen
);
803 lstrcpynAtoW( retStr
, p
, maxlen
);
804 HeapFree( GetProcessHeap(), 0, p
);
809 /**************************************************************************
810 * SetClipboardViewer16 (USER.147)
812 HWND16 WINAPI
SetClipboardViewer16( HWND16 hWnd
)
814 return SetClipboardViewer32( hWnd
);
818 /**************************************************************************
819 * SetClipboardViewer32 (USER32.471)
821 HWND32 WINAPI
SetClipboardViewer32( HWND32 hWnd
)
823 HWND32 hwndPrev
= hWndViewer
;
825 TRACE(clipboard
,"(%04x): returning %04x\n", hWnd
, hwndPrev
);
832 /**************************************************************************
833 * GetClipboardViewer16 (USER.148)
835 HWND16 WINAPI
GetClipboardViewer16(void)
841 /**************************************************************************
842 * GetClipboardViewer32 (USER32.226)
844 HWND32 WINAPI
GetClipboardViewer32(void)
850 /**************************************************************************
851 * ChangeClipboardChain16 (USER.149)
853 BOOL16 WINAPI
ChangeClipboardChain16(HWND16 hWnd
, HWND16 hWndNext
)
855 return ChangeClipboardChain32(hWnd
, hWndNext
);
858 /**************************************************************************
859 * ChangeClipboardChain32 (USER32.22)
861 BOOL32 WINAPI
ChangeClipboardChain32(HWND32 hWnd
, HWND32 hWndNext
)
865 FIXME(clipboard
, "(0x%04x, 0x%04x): stub?\n", hWnd
, hWndNext
);
868 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
869 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
871 WARN(clipboard
, "hWndViewer is lost\n");
873 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
880 /**************************************************************************
881 * IsClipboardFormatAvailable16 (USER.193)
883 BOOL16 WINAPI
IsClipboardFormatAvailable16( UINT16 wFormat
)
885 return IsClipboardFormatAvailable32( wFormat
);
889 /**************************************************************************
890 * IsClipboardFormatAvailable32 (USER32.340)
892 BOOL32 WINAPI
IsClipboardFormatAvailable32( UINT32 wFormat
)
894 TRACE(clipboard
,"(%04X) !\n", wFormat
);
896 if( (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
897 CLIPBOARD_GetDriver()->pRequestSelection();
899 return CLIPBOARD_IsPresent(wFormat
);
903 /**************************************************************************
904 * GetOpenClipboardWindow16 (USER.248)
906 HWND16 WINAPI
GetOpenClipboardWindow16(void)
908 return hWndClipWindow
;
912 /**************************************************************************
913 * GetOpenClipboardWindow32 (USER32.277)
915 HWND32 WINAPI
GetOpenClipboardWindow32(void)
917 return hWndClipWindow
;
921 /**************************************************************************
922 * GetPriorityClipboardFormat16 (USER.402)
924 INT16 WINAPI
GetPriorityClipboardFormat16( UINT16
*lpPriorityList
, INT16 nCount
)
926 FIXME(clipboard
, "(%p,%d): stub\n", lpPriorityList
, nCount
);
931 /**************************************************************************
932 * GetPriorityClipboardFormat32 (USER32.279)
934 INT32 WINAPI
GetPriorityClipboardFormat32( UINT32
*lpPriorityList
, INT32 nCount
)
938 if(CountClipboardFormats32() == 0)
943 for(Counter
= 0; Counter
<= nCount
; Counter
++)
945 if(IsClipboardFormatAvailable32(*(lpPriorityList
+sizeof(INT32
)*Counter
)))
946 return *(lpPriorityList
+sizeof(INT32
)*Counter
);