2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
11 #include <sys/types.h>
17 #include <X11/Xatom.h>
22 #include "clipboard.h"
27 #define CF_REGFORMATBASE 0xC000
29 typedef struct tagCLIPFORMAT
{
36 struct tagCLIPFORMAT
*PrevFormat
;
37 struct tagCLIPFORMAT
*NextFormat
;
38 } CLIPFORMAT
, *LPCLIPFORMAT
;
40 /* *************************************************************************
44 static HQUEUE16 hqClipLock
= 0;
45 static BOOL32 bCBHasChanged
= FALSE
;
47 static HWND32 hWndClipOwner
= 0; /* current clipboard owner */
48 static HWND32 hWndClipWindow
= 0; /* window that opened clipboard */
49 static HWND32 hWndViewer
= 0; /* start of viewers chain */
51 static WORD LastRegFormat
= CF_REGFORMATBASE
;
53 static Bool selectionWait
= False
;
54 static Bool selectionAcquired
= False
;
55 static Window selectionWindow
= None
;
56 static Window selectionPrevWindow
= None
;
58 static CLIPFORMAT ClipFormats
[16] = {
59 { CF_TEXT
, 1, 0, "Text", (HANDLE16
)NULL
, 0, NULL
, &ClipFormats
[1] },
60 { CF_BITMAP
, 1, 0, "Bitmap", (HANDLE16
)NULL
, 0, &ClipFormats
[0], &ClipFormats
[2] },
61 { CF_METAFILEPICT
, 1, 0, "MetaFile Picture", (HANDLE16
)NULL
, 0, &ClipFormats
[1], &ClipFormats
[3] },
62 { CF_SYLK
, 1, 0, "Sylk", (HANDLE16
)NULL
, 0, &ClipFormats
[2], &ClipFormats
[4] },
63 { CF_DIF
, 1, 0, "DIF", (HANDLE16
)NULL
, 0, &ClipFormats
[3], &ClipFormats
[5] },
64 { CF_TIFF
, 1, 0, "TIFF", (HANDLE16
)NULL
, 0, &ClipFormats
[4], &ClipFormats
[6] },
65 { CF_OEMTEXT
, 1, 0, "OEM Text", (HANDLE16
)NULL
, 0, &ClipFormats
[5], &ClipFormats
[7] },
66 { CF_DIB
, 1, 0, "DIB", (HANDLE16
)NULL
, 0, &ClipFormats
[6], &ClipFormats
[8] },
67 { CF_PALETTE
, 1, 0, "Palette", (HANDLE16
)NULL
, 0, &ClipFormats
[7], &ClipFormats
[9] },
68 { CF_PENDATA
, 1, 0, "PenData", (HANDLE16
)NULL
, 0, &ClipFormats
[8], &ClipFormats
[10] },
69 { CF_RIFF
, 1, 0, "RIFF", (HANDLE16
)NULL
, 0, &ClipFormats
[9], &ClipFormats
[11] },
70 { CF_WAVE
, 1, 0, "Wave", (HANDLE16
)NULL
, 0, &ClipFormats
[10], &ClipFormats
[12] },
71 { CF_OWNERDISPLAY
, 1, 0, "Owner Display", (HANDLE16
)NULL
, 0, &ClipFormats
[11], &ClipFormats
[13] },
72 { CF_DSPTEXT
, 1, 0, "DSPText", (HANDLE16
)NULL
, 0, &ClipFormats
[12], &ClipFormats
[14] },
73 { CF_DSPMETAFILEPICT
, 1, 0, "DSPMetaFile Picture", (HANDLE16
)NULL
, 0, &ClipFormats
[13], &ClipFormats
[15] },
74 { CF_DSPBITMAP
, 1, 0, "DSPBitmap", (HANDLE16
)NULL
, 0, &ClipFormats
[14], NULL
}
77 static LPCLIPFORMAT
__lookup_format( LPCLIPFORMAT lpFormat
, WORD wID
)
81 if (lpFormat
== NULL
||
82 lpFormat
->wFormatID
== wID
) break;
83 lpFormat
= lpFormat
->NextFormat
;
88 /**************************************************************************
89 * CLIPBOARD_CheckSelection
91 * Prevent X selection from being lost when a top level window is
94 static void CLIPBOARD_CheckSelection(WND
* pWnd
)
96 dprintf_clipboard(stddeb
,"\tchecking %08x\n", (unsigned)pWnd
->window
);
98 if( selectionAcquired
&& selectionWindow
!= None
&&
99 pWnd
->window
== selectionWindow
)
101 selectionPrevWindow
= selectionWindow
;
102 selectionWindow
= None
;
105 selectionWindow
= pWnd
->next
->window
;
106 else if( pWnd
->parent
)
107 if( pWnd
->parent
->child
!= pWnd
)
108 selectionWindow
= pWnd
->parent
->child
->window
;
110 dprintf_clipboard(stddeb
,"\tswitching selection from %08x to %08x\n",
111 (unsigned)selectionPrevWindow
, (unsigned)selectionWindow
);
113 if( selectionWindow
!= None
)
115 TSXSetSelectionOwner(display
, XA_PRIMARY
, selectionWindow
, CurrentTime
);
116 if( TSXGetSelectionOwner(display
, XA_PRIMARY
) != selectionWindow
)
117 selectionWindow
= None
;
122 /**************************************************************************
123 * CLIPBOARD_ResetLock
125 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent
, HQUEUE16 hqNew
)
127 if( hqClipLock
== hqCurrent
)
141 /**************************************************************************
142 * CLIPBOARD_ResetOwner
144 * Called from DestroyWindow().
146 void CLIPBOARD_ResetOwner(WND
* pWnd
)
148 LPCLIPFORMAT lpFormat
= ClipFormats
;
150 dprintf_clipboard(stddeb
,"DisOwn: clipboard owner = %04x, selection = %08x\n",
151 hWndClipOwner
, (unsigned)selectionWindow
);
153 if( pWnd
->hwndSelf
== hWndClipOwner
)
155 SendMessage16(hWndClipOwner
,WM_RENDERALLFORMATS
,0,0L);
157 /* check if all formats were rendered */
161 if( lpFormat
->wDataPresent
&& !lpFormat
->hData
)
163 dprintf_clipboard( stddeb
,"\tdata missing for clipboard format %i\n",
164 lpFormat
->wFormatID
);
165 lpFormat
->wDataPresent
= 0;
167 lpFormat
= lpFormat
->NextFormat
;
172 /* now try to salvage current selection from being destroyed by X */
174 if( pWnd
->window
) CLIPBOARD_CheckSelection(pWnd
);
177 /**************************************************************************
178 * CLIPBOARD_DeleteRecord
180 static void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat
, BOOL32 bChange
)
182 if( (lpFormat
->wFormatID
>= CF_GDIOBJFIRST
&&
183 lpFormat
->wFormatID
<= CF_GDIOBJLAST
) || lpFormat
->wFormatID
== CF_BITMAP
)
184 DeleteObject32(lpFormat
->hData
);
185 else if( lpFormat
->wFormatID
== CF_METAFILEPICT
&& lpFormat
->hData
)
187 DeleteMetaFile16( ((METAFILEPICT16
*)GlobalLock16( lpFormat
->hData
))->hMF
);
188 GlobalFree16(lpFormat
->hData
);
190 else if( lpFormat
->hData
)
191 GlobalFree16(lpFormat
->hData
);
193 lpFormat
->wDataPresent
= 0;
196 if( bChange
) bCBHasChanged
= TRUE
;
199 /**************************************************************************
200 * CLIPBOARD_RequestXSelection
202 static BOOL32
CLIPBOARD_RequestXSelection()
204 HWND32 hWnd
= (hWndClipWindow
) ? hWndClipWindow
: GetActiveWindow32();
206 if( !hWnd
) return FALSE
;
208 dprintf_clipboard(stddeb
,"Requesting selection...\n");
210 /* request data type XA_STRING, later
211 * CLIPBOARD_ReadSelection() will be invoked
212 * from the SelectionNotify event handler */
214 TSXConvertSelection(display
,XA_PRIMARY
,XA_STRING
,
215 TSXInternAtom(display
,"PRIMARY_TEXT",False
),
216 WIN_GetXWindow(hWnd
),CurrentTime
);
218 /* wait until SelectionNotify is processed
220 * FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the
221 * CLIPBOARD_CheckSelection() ).
225 while(selectionWait
) EVENT_WaitNetEvent( TRUE
, FALSE
);
227 /* we treat Unix text as CF_OEMTEXT */
228 dprintf_clipboard(stddeb
,"\tgot CF_OEMTEXT = %i\n",
229 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
);
231 return (BOOL32
)ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
234 /**************************************************************************
235 * CLIPBOARD_IsPresent
237 BOOL32
CLIPBOARD_IsPresent(WORD wFormat
)
241 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
242 return ClipFormats
[CF_TEXT
-1].wDataPresent
||
243 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
246 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
247 if( lpFormat
) return (lpFormat
->wDataPresent
);
252 /**************************************************************************
253 * OpenClipboard16 (USER.137)
255 BOOL16 WINAPI
OpenClipboard16( HWND16 hWnd
)
257 return OpenClipboard32( hWnd
);
261 /**************************************************************************
262 * OpenClipboard32 (USER32.406)
264 * Note: Netscape uses NULL hWnd to open the clipboard.
266 BOOL32 WINAPI
OpenClipboard32( HWND32 hWnd
)
270 dprintf_clipboard(stddeb
,"OpenClipboard(%04x) = ", hWnd
);
274 hqClipLock
= GetTaskQueue(0);
275 hWndClipWindow
= hWnd
;
276 bCBHasChanged
= FALSE
;
281 dprintf_clipboard(stddeb
,"%i\n", bRet
);
286 /**************************************************************************
287 * CloseClipboard16 (USER.138)
289 BOOL16 WINAPI
CloseClipboard16(void)
291 return CloseClipboard32();
295 /**************************************************************************
296 * CloseClipboard32 (USER32.53)
298 BOOL32 WINAPI
CloseClipboard32(void)
300 dprintf_clipboard(stddeb
,"CloseClipboard(); !\n");
302 if (hqClipLock
== GetTaskQueue(0))
306 if (bCBHasChanged
&& hWndViewer
)
307 SendMessage16(hWndViewer
, WM_DRAWCLIPBOARD
, 0, 0L);
314 /**************************************************************************
315 * EmptyClipboard16 (USER.139)
317 BOOL16 WINAPI
EmptyClipboard16(void)
319 return EmptyClipboard32();
323 /**************************************************************************
324 * EmptyClipboard32 (USER32.168)
326 BOOL32 WINAPI
EmptyClipboard32(void)
328 LPCLIPFORMAT lpFormat
= ClipFormats
;
330 dprintf_clipboard(stddeb
,"EmptyClipboard()\n");
332 if (hqClipLock
!= GetTaskQueue(0)) return FALSE
;
334 /* destroy private objects */
337 SendMessage16(hWndClipOwner
, WM_DESTROYCLIPBOARD
, 0, 0L);
341 if ( lpFormat
->wDataPresent
|| lpFormat
->hData
)
342 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
344 lpFormat
= lpFormat
->NextFormat
;
347 hWndClipOwner
= hWndClipWindow
;
349 if(selectionAcquired
)
351 selectionAcquired
= False
;
352 selectionPrevWindow
= selectionWindow
;
353 selectionWindow
= None
;
355 dprintf_clipboard(stddeb
, "\tgiving up selection (spw = %08x)\n",
356 (unsigned)selectionPrevWindow
);
358 TSXSetSelectionOwner(display
, XA_PRIMARY
, None
, CurrentTime
);
364 /**************************************************************************
365 * GetClipboardOwner16 (USER.140)
367 HWND16 WINAPI
GetClipboardOwner16(void)
369 return hWndClipOwner
;
373 /**************************************************************************
374 * GetClipboardOwner32 (USER32.224)
376 HWND32 WINAPI
GetClipboardOwner32(void)
378 return hWndClipOwner
;
382 /**************************************************************************
383 * SetClipboardData16 (USER.141)
385 HANDLE16 WINAPI
SetClipboardData16( UINT16 wFormat
, HANDLE16 hData
)
387 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
390 dprintf_clipboard(stddeb
,
391 "SetClipboardData(%04X, %04x) !\n", wFormat
, hData
);
393 /* NOTE: If the hData is zero and current owner doesn't match
394 * the window that opened the clipboard then this application
395 * is screwed because WM_RENDERFORMAT will go to the owner
396 * (to become the owner it must call EmptyClipboard() before
400 if( (hqClipLock
!= GetTaskQueue(0)) || !lpFormat
||
401 (!hData
&& (!hWndClipOwner
|| (hWndClipOwner
!= hWndClipWindow
))) ) return 0;
403 /* Acquire X selection if text format */
405 if( !selectionAcquired
&&
406 (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
408 owner
= WIN_GetXWindow( hWndClipWindow
? hWndClipWindow
: AnyPopup32() );
409 TSXSetSelectionOwner(display
,XA_PRIMARY
,owner
,CurrentTime
);
410 if( TSXGetSelectionOwner(display
,XA_PRIMARY
) == owner
)
412 selectionAcquired
= True
;
413 selectionWindow
= owner
;
415 dprintf_clipboard(stddeb
,"Grabbed X selection, owner=(%08x)\n",
420 if ( lpFormat
->wDataPresent
|| lpFormat
->hData
)
422 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
424 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
426 if( wFormat
== CF_TEXT
&& ClipFormats
[CF_OEMTEXT
-1].hData
427 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
428 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
429 if( wFormat
== CF_OEMTEXT
&& ClipFormats
[CF_TEXT
-1].hData
430 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
431 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
434 bCBHasChanged
= TRUE
;
435 lpFormat
->wDataPresent
= 1;
436 lpFormat
->hData
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
438 return lpFormat
->hData
;
442 /**************************************************************************
443 * SetClipboardData32 (USER32.469)
445 HANDLE32 WINAPI
SetClipboardData32( UINT32 wFormat
, HANDLE32 hData
)
447 fprintf( stderr
, "SetClipboardData: empty stub\n" );
452 /**************************************************************************
453 * CLIPBOARD_RenderFormat
455 static BOOL32
CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat
)
457 if( lpFormat
->wDataPresent
&& !lpFormat
->hData
)
458 if( IsWindow32(hWndClipOwner
) )
459 SendMessage16(hWndClipOwner
,WM_RENDERFORMAT
,
460 (WPARAM16
)lpFormat
->wFormatID
,0L);
463 dprintf_clipboard(stddeb
,"\thWndClipOwner (%04x) is lost!\n",
465 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
468 return (lpFormat
->hData
) ? TRUE
: FALSE
;
471 /**************************************************************************
472 * CLIPBOARD_RenderText
474 * Convert text between UNIX and DOS formats.
476 static BOOL32
CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget
, LPCLIPFORMAT lpSource
)
478 UINT16 size
= GlobalSize16( lpSource
->hData
);
479 LPCSTR lpstrS
= (LPSTR
)GlobalLock16(lpSource
->hData
);
482 if( !lpstrS
) return FALSE
;
483 dprintf_clipboard(stddeb
,"\tconverting from '%s' to '%s', %i chars\n",
484 lpSource
->Name
, lpTarget
->Name
, size
);
486 lpTarget
->hData
= GlobalAlloc16(GMEM_ZEROINIT
, size
);
487 lpstrT
= (LPSTR
)GlobalLock16(lpTarget
->hData
);
491 if( lpSource
->wFormatID
== CF_TEXT
)
492 CharToOemBuff32A(lpstrS
, lpstrT
, size
);
494 OemToCharBuff32A(lpstrS
, lpstrT
, size
);
495 dprintf_clipboard(stddeb
,"\tgot %s\n", lpstrT
);
503 /**************************************************************************
504 * GetClipboardData16 (USER.142)
506 HANDLE16 WINAPI
GetClipboardData16( UINT16 wFormat
)
508 LPCLIPFORMAT lpRender
= ClipFormats
;
509 LPCLIPFORMAT lpUpdate
= NULL
;
511 if (hqClipLock
!= GetTaskQueue(0)) return 0;
513 dprintf_clipboard(stddeb
,"GetClipboardData(%04X)\n", wFormat
);
515 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
516 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
518 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
519 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
521 dprintf_clipboard(stddeb
,"\tOEMTEXT -> TEXT\n");
523 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
524 && lpRender
[CF_TEXT
-1].wDataPresent
)
526 lpRender
= &ClipFormats
[CF_TEXT
-1];
527 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
529 dprintf_clipboard(stddeb
,"\tTEXT -> OEMTEXT\n");
533 lpRender
= __lookup_format( ClipFormats
, wFormat
);
537 if( !lpRender
|| !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
538 if( lpUpdate
!= lpRender
&& !lpUpdate
->hData
)
539 CLIPBOARD_RenderText(lpUpdate
, lpRender
);
541 dprintf_clipboard(stddeb
,"\treturning %04x (type %i)\n",
542 lpUpdate
->hData
, lpUpdate
->wFormatID
);
543 return lpUpdate
->hData
;
547 /**************************************************************************
548 * GetClipboardData32 (USER32.221)
550 HANDLE32 WINAPI
GetClipboardData32( UINT32 wFormat
)
552 fprintf( stderr
, "GetClipboardData32: empty stub\n" );
556 /**************************************************************************
557 * CountClipboardFormats16 (USER.143)
559 INT16 WINAPI
CountClipboardFormats16(void)
561 return CountClipboardFormats32();
565 /**************************************************************************
566 * CountClipboardFormats32 (USER32.62)
568 INT32 WINAPI
CountClipboardFormats32(void)
570 INT32 FormatCount
= 0;
571 LPCLIPFORMAT lpFormat
= ClipFormats
;
573 dprintf_clipboard(stddeb
,"CountClipboardFormats()\n");
575 if( !selectionAcquired
) CLIPBOARD_RequestXSelection();
577 FormatCount
+= abs(lpFormat
[CF_TEXT
-1].wDataPresent
-
578 lpFormat
[CF_OEMTEXT
-1].wDataPresent
);
582 if (lpFormat
== NULL
) break;
583 if (lpFormat
->wDataPresent
)
585 dprintf_clipboard(stddeb
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
588 lpFormat
= lpFormat
->NextFormat
;
591 dprintf_clipboard(stddeb
,"\ttotal %d\n", FormatCount
);
596 /**************************************************************************
597 * EnumClipboardFormats16 (USER.144)
599 UINT16 WINAPI
EnumClipboardFormats16( UINT16 wFormat
)
601 return EnumClipboardFormats32( wFormat
);
605 /**************************************************************************
606 * EnumClipboardFormats32 (USER32.178)
608 UINT32 WINAPI
EnumClipboardFormats32( UINT32 wFormat
)
610 LPCLIPFORMAT lpFormat
= ClipFormats
;
612 dprintf_clipboard(stddeb
,"EnumClipboardFormats(%04X)\n", wFormat
);
614 if( hqClipLock
!= GetTaskQueue(0) ) return 0;
616 if( (!wFormat
|| wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
617 && !selectionAcquired
) CLIPBOARD_RequestXSelection();
620 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
621 return lpFormat
->wFormatID
;
623 wFormat
= lpFormat
->wFormatID
; /* and CF_TEXT is not available */
625 /* walk up to the specified format record */
627 if( !(lpFormat
= __lookup_format( lpFormat
, wFormat
)) ) return 0;
629 /* find next format with available data */
631 lpFormat
= lpFormat
->NextFormat
;
634 if (lpFormat
== NULL
) return 0;
635 if (lpFormat
->wDataPresent
|| (lpFormat
->wFormatID
== CF_OEMTEXT
&&
636 ClipFormats
[CF_TEXT
-1].wDataPresent
))
638 lpFormat
= lpFormat
->NextFormat
;
641 return lpFormat
->wFormatID
;
645 /**************************************************************************
646 * RegisterClipboardFormat16 (USER.145)
648 UINT16 WINAPI
RegisterClipboardFormat16( LPCSTR FormatName
)
650 LPCLIPFORMAT lpNewFormat
;
651 LPCLIPFORMAT lpFormat
= ClipFormats
;
653 if (FormatName
== NULL
) return 0;
655 dprintf_clipboard(stddeb
,"RegisterClipboardFormat('%s') !\n", FormatName
);
657 /* walk format chain to see if it's already registered */
661 if ( !strcmp(lpFormat
->Name
,FormatName
) )
663 lpFormat
->wRefCount
++;
664 return lpFormat
->wFormatID
;
667 if ( lpFormat
->NextFormat
== NULL
) break;
669 lpFormat
= lpFormat
->NextFormat
;
672 /* allocate storage for new format entry */
674 lpNewFormat
= (LPCLIPFORMAT
)xmalloc(sizeof(CLIPFORMAT
));
675 lpFormat
->NextFormat
= lpNewFormat
;
676 lpNewFormat
->wFormatID
= LastRegFormat
;
677 lpNewFormat
->wRefCount
= 1;
679 lpNewFormat
->Name
= (LPSTR
)xmalloc(strlen(FormatName
) + 1);
680 strcpy(lpNewFormat
->Name
, FormatName
);
682 lpNewFormat
->wDataPresent
= 0;
683 lpNewFormat
->hData
= 0;
684 lpNewFormat
->BufSize
= 0;
685 lpNewFormat
->PrevFormat
= lpFormat
;
686 lpNewFormat
->NextFormat
= NULL
;
688 return LastRegFormat
++;
692 /**************************************************************************
693 * RegisterClipboardFormat32A (USER32.430)
695 UINT32 WINAPI
RegisterClipboardFormat32A( LPCSTR formatName
)
697 return RegisterClipboardFormat16( formatName
);
701 /**************************************************************************
702 * RegisterClipboardFormat32W (USER32.431)
704 UINT32 WINAPI
RegisterClipboardFormat32W( LPCWSTR formatName
)
706 LPSTR aFormat
= HEAP_strdupWtoA( GetProcessHeap(), 0, formatName
);
707 UINT32 ret
= RegisterClipboardFormat32A( aFormat
);
708 HeapFree( GetProcessHeap(), 0, aFormat
);
712 /**************************************************************************
713 * GetClipboardFormatName16 (USER.146)
715 INT16 WINAPI
GetClipboardFormatName16( UINT16 wFormat
, LPSTR retStr
, INT16 maxlen
)
717 return GetClipboardFormatName32A( wFormat
, retStr
, maxlen
);
721 /**************************************************************************
722 * GetClipboardFormatName32A (USER32.222)
724 INT32 WINAPI
GetClipboardFormatName32A( UINT32 wFormat
, LPSTR retStr
, INT32 maxlen
)
726 LPCLIPFORMAT lpFormat
= __lookup_format( ClipFormats
, wFormat
);
728 dprintf_clipboard(stddeb
,
729 "GetClipboardFormatName(%04X, %p, %d) !\n", wFormat
, retStr
, maxlen
);
731 if (lpFormat
== NULL
|| lpFormat
->Name
== NULL
||
732 lpFormat
->wFormatID
< CF_REGFORMATBASE
) return 0;
734 dprintf_clipboard(stddeb
,
735 "GetClipboardFormat // Name='%s' !\n", lpFormat
->Name
);
737 lstrcpyn32A( retStr
, lpFormat
->Name
, maxlen
);
738 return strlen(retStr
);
742 /**************************************************************************
743 * GetClipboardFormatName32W (USER32.223)
745 INT32 WINAPI
GetClipboardFormatName32W( UINT32 wFormat
, LPWSTR retStr
, INT32 maxlen
)
747 LPSTR p
= HEAP_xalloc( GetProcessHeap(), 0, maxlen
);
748 INT32 ret
= GetClipboardFormatName32A( wFormat
, p
, maxlen
);
749 lstrcpynAtoW( retStr
, p
, maxlen
);
750 HeapFree( GetProcessHeap(), 0, p
);
755 /**************************************************************************
756 * SetClipboardViewer16 (USER.147)
758 HWND16 WINAPI
SetClipboardViewer16( HWND16 hWnd
)
760 return SetClipboardViewer32( hWnd
);
764 /**************************************************************************
765 * SetClipboardViewer32 (USER32.470)
767 HWND32 WINAPI
SetClipboardViewer32( HWND32 hWnd
)
769 HWND32 hwndPrev
= hWndViewer
;
771 dprintf_clipboard(stddeb
,"SetClipboardViewer(%04x): returning %04x\n", hWnd
, hwndPrev
);
778 /**************************************************************************
779 * GetClipboardViewer16 (USER.148)
781 HWND16 WINAPI
GetClipboardViewer16(void)
787 /**************************************************************************
788 * GetClipboardViewer32 (USER32.225)
790 HWND32 WINAPI
GetClipboardViewer32(void)
796 /**************************************************************************
797 * ChangeClipboardChain16 (USER.149)
799 BOOL16 WINAPI
ChangeClipboardChain16(HWND16 hWnd
, HWND16 hWndNext
)
801 return ChangeClipboardChain32(hWnd
, hWndNext
);
804 /**************************************************************************
805 * ChangeClipboardChain32 (USER32.21)
807 BOOL32 WINAPI
ChangeClipboardChain32(HWND32 hWnd
, HWND32 hWndNext
)
811 dprintf_clipboard(stdnimp
, "ChangeClipboardChain(%04x, %04x)\n", hWnd
, hWndNext
);
814 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
815 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
817 dprintf_clipboard(stddeb
,"ChangeClipboardChain: hWndViewer is lost\n");
819 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
826 /**************************************************************************
827 * IsClipboardFormatAvailable16 (USER.193)
829 BOOL16 WINAPI
IsClipboardFormatAvailable16( UINT16 wFormat
)
831 return IsClipboardFormatAvailable32( wFormat
);
835 /**************************************************************************
836 * IsClipboardFormatAvailable32 (USER32.339)
838 BOOL32 WINAPI
IsClipboardFormatAvailable32( UINT32 wFormat
)
840 dprintf_clipboard(stddeb
,"IsClipboardFormatAvailable(%04X) !\n", wFormat
);
842 if( (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) &&
843 !selectionAcquired
) CLIPBOARD_RequestXSelection();
845 return CLIPBOARD_IsPresent(wFormat
);
849 /**************************************************************************
850 * GetOpenClipboardWindow16 (USER.248)
852 HWND16 WINAPI
GetOpenClipboardWindow16(void)
854 return hWndClipWindow
;
858 /**************************************************************************
859 * GetOpenClipboardWindow32 (USER32.276)
861 HWND32 WINAPI
GetOpenClipboardWindow32(void)
863 return hWndClipWindow
;
867 /**************************************************************************
868 * GetPriorityClipboardFormat16 (USER.402)
870 INT16 WINAPI
GetPriorityClipboardFormat16( UINT16
*lpPriorityList
, INT16 nCount
)
872 fprintf( stderr
, "GetPriorityClipboardFormat16(%p, %d): stub\n",
873 lpPriorityList
, nCount
);
878 /**************************************************************************
879 * GetPriorityClipboardFormat32 (USER32.279)
881 INT32 WINAPI
GetPriorityClipboardFormat32( UINT32
*lpPriorityList
, INT32 nCount
)
885 if(CountClipboardFormats32() == 0)
890 for(Counter
= 0; Counter
<= nCount
; Counter
++)
892 if(IsClipboardFormatAvailable32(*(lpPriorityList
+sizeof(INT32
)*Counter
)))
893 return *(lpPriorityList
+sizeof(INT32
)*Counter
);
900 /**************************************************************************
901 * CLIPBOARD_ReadSelection
903 * Called from the SelectionNotify event handler.
905 void CLIPBOARD_ReadSelection(Window w
,Atom prop
)
908 LPCLIPFORMAT lpFormat
= ClipFormats
;
910 dprintf_clipboard(stddeb
,"ReadSelection callback\n");
914 Atom atype
=AnyPropertyType
;
916 unsigned long nitems
,remain
;
917 unsigned char* val
=NULL
;
919 dprintf_clipboard(stddeb
,"\tgot property %s\n",TSXGetAtomName(display
,prop
));
921 /* TODO: Properties longer than 64K */
923 if(TSXGetWindowProperty(display
,w
,prop
,0,0x3FFF,True
,XA_STRING
,
924 &atype
, &aformat
, &nitems
, &remain
, &val
) != Success
)
925 dprintf_clipboard(stddeb
,"\tcouldn't read property\n");
928 dprintf_clipboard(stddeb
,"\tType %s,Format %d,nitems %ld,value %s\n",
929 TSXGetAtomName(display
,atype
),aformat
,nitems
,val
);
931 if(atype
== XA_STRING
&& aformat
== 8)
936 dprintf_clipboard(stddeb
,"\tselection is '%s'\n",val
);
938 for(i
=0; i
<= nitems
; i
++)
939 if( val
[i
] == '\n' ) inlcount
++;
943 hText
=GlobalAlloc16(GMEM_MOVEABLE
, nitems
+ inlcount
+ 1);
944 if( (lpstr
= (char*)GlobalLock16(hText
)) )
945 for(i
=0,inlcount
=0; i
<= nitems
; i
++)
947 if( val
[i
] == '\n' ) lpstr
[inlcount
++]='\r';
948 lpstr
[inlcount
++]=val
[i
];
957 /* delete previous CF_TEXT and CF_OEMTEXT data */
961 lpFormat
= &ClipFormats
[CF_TEXT
-1];
962 if (lpFormat
->wDataPresent
|| lpFormat
->hData
)
963 CLIPBOARD_DeleteRecord(lpFormat
, !(hWndClipWindow
));
964 lpFormat
= &ClipFormats
[CF_OEMTEXT
-1];
965 if (lpFormat
->wDataPresent
|| lpFormat
->hData
)
966 CLIPBOARD_DeleteRecord(lpFormat
, !(hWndClipWindow
));
968 lpFormat
->wDataPresent
= 1;
969 lpFormat
->hData
= hText
;
975 /**************************************************************************
976 * CLIPBOARD_ReleaseSelection
978 * Wine might have lost XA_PRIMARY selection because of
979 * EmptyClipboard() or other client.
981 void CLIPBOARD_ReleaseSelection(Window w
, HWND32 hwnd
)
983 /* w is the window that lost selection,
985 * selectionPrevWindow is nonzero if CheckSelection() was called.
988 dprintf_clipboard(stddeb
,"\tevent->window = %08x (sw = %08x, spw=%08x)\n",
989 (unsigned)w
, (unsigned)selectionWindow
, (unsigned)selectionPrevWindow
);
991 if( selectionAcquired
)
992 if( w
== selectionWindow
|| selectionPrevWindow
== None
)
994 /* alright, we really lost it */
996 selectionAcquired
= False
;
997 selectionWindow
= None
;
999 /* but we'll keep existing data for internal use */
1001 else if( w
== selectionPrevWindow
)
1003 w
= TSXGetSelectionOwner(display
, XA_PRIMARY
);
1005 TSXSetSelectionOwner(display
, XA_PRIMARY
, selectionWindow
, CurrentTime
);
1008 selectionPrevWindow
= None
;