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 HWND32 hWndClipOwner
= 0; /* current clipboard owner */
45 static HWND32 hWndClipWindow
= 0; /* window that opened clipboard */
46 static HWND32 hWndViewer
= 0; /* start of viewers chain */
48 static BOOL32 bClipChanged
= FALSE
;
49 static WORD LastRegFormat
= CF_REGFORMATBASE
;
51 static Bool selectionWait
= False
;
52 static Bool selectionAcquired
= False
;
53 static Window selectionWindow
= None
;
54 static Window selectionPrevWindow
= None
;
56 static CLIPFORMAT ClipFormats
[16] = {
57 { CF_TEXT
, 1, 0, "Text", (HANDLE16
)NULL
, 0, NULL
, &ClipFormats
[1] },
58 { CF_BITMAP
, 1, 0, "Bitmap", (HANDLE16
)NULL
, 0, &ClipFormats
[0], &ClipFormats
[2] },
59 { CF_METAFILEPICT
, 1, 0, "MetaFile Picture", (HANDLE16
)NULL
, 0, &ClipFormats
[1], &ClipFormats
[3] },
60 { CF_SYLK
, 1, 0, "Sylk", (HANDLE16
)NULL
, 0, &ClipFormats
[2], &ClipFormats
[4] },
61 { CF_DIF
, 1, 0, "DIF", (HANDLE16
)NULL
, 0, &ClipFormats
[3], &ClipFormats
[5] },
62 { CF_TIFF
, 1, 0, "TIFF", (HANDLE16
)NULL
, 0, &ClipFormats
[4], &ClipFormats
[6] },
63 { CF_OEMTEXT
, 1, 0, "OEM Text", (HANDLE16
)NULL
, 0, &ClipFormats
[5], &ClipFormats
[7] },
64 { CF_DIB
, 1, 0, "DIB", (HANDLE16
)NULL
, 0, &ClipFormats
[6], &ClipFormats
[8] },
65 { CF_PALETTE
, 1, 0, "Palette", (HANDLE16
)NULL
, 0, &ClipFormats
[7], &ClipFormats
[9] },
66 { CF_PENDATA
, 1, 0, "PenData", (HANDLE16
)NULL
, 0, &ClipFormats
[8], &ClipFormats
[10] },
67 { CF_RIFF
, 1, 0, "RIFF", (HANDLE16
)NULL
, 0, &ClipFormats
[9], &ClipFormats
[11] },
68 { CF_WAVE
, 1, 0, "Wave", (HANDLE16
)NULL
, 0, &ClipFormats
[10], &ClipFormats
[12] },
69 { CF_OWNERDISPLAY
, 1, 0, "Owner Display", (HANDLE16
)NULL
, 0, &ClipFormats
[11], &ClipFormats
[13] },
70 { CF_DSPTEXT
, 1, 0, "DSPText", (HANDLE16
)NULL
, 0, &ClipFormats
[12], &ClipFormats
[14] },
71 { CF_DSPMETAFILEPICT
, 1, 0, "DSPMetaFile Picture", (HANDLE16
)NULL
, 0, &ClipFormats
[13], &ClipFormats
[15] },
72 { CF_DSPBITMAP
, 1, 0, "DSPBitmap", (HANDLE16
)NULL
, 0, &ClipFormats
[14], NULL
}
75 /**************************************************************************
76 * CLIPBOARD_CheckSelection
78 static void CLIPBOARD_CheckSelection(WND
* pWnd
)
80 dprintf_clipboard(stddeb
,"\tchecking %08x\n", (unsigned)pWnd
->window
);
82 if( selectionAcquired
&& selectionWindow
!= None
&&
83 pWnd
->window
== selectionWindow
)
85 selectionPrevWindow
= selectionWindow
;
86 selectionWindow
= None
;
89 selectionWindow
= pWnd
->next
->window
;
90 else if( pWnd
->parent
)
91 if( pWnd
->parent
->child
!= pWnd
)
92 selectionWindow
= pWnd
->parent
->child
->window
;
94 dprintf_clipboard(stddeb
,"\tswitching selection from %08x to %08x\n",
95 (unsigned)selectionPrevWindow
, (unsigned)selectionWindow
);
97 if( selectionWindow
!= None
)
99 XSetSelectionOwner(display
, XA_PRIMARY
, selectionWindow
, CurrentTime
);
100 if( XGetSelectionOwner(display
, XA_PRIMARY
) != selectionWindow
)
101 selectionWindow
= None
;
106 /**************************************************************************
109 * Called from DestroyWindow().
111 void CLIPBOARD_DisOwn(WND
* pWnd
)
113 LPCLIPFORMAT lpFormat
= ClipFormats
;
115 dprintf_clipboard(stddeb
,"DisOwn: clipboard owner = %04x, sw = %08x\n",
116 hWndClipOwner
, (unsigned)selectionWindow
);
118 if( pWnd
->hwndSelf
== hWndClipOwner
)
120 SendMessage16(hWndClipOwner
,WM_RENDERALLFORMATS
,0,0L);
122 /* check if all formats were rendered */
126 if( lpFormat
->wDataPresent
&& !lpFormat
->hData
)
128 dprintf_clipboard(stddeb
,"\tdata missing for clipboard format %i\n", lpFormat
->wFormatID
);
129 lpFormat
->wDataPresent
= 0;
131 lpFormat
= lpFormat
->NextFormat
;
136 /* now try to salvage current selection from being destroyed by X */
138 CLIPBOARD_CheckSelection(pWnd
);
141 /**************************************************************************
142 * CLIPBOARD_DeleteRecord
144 static void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat
, BOOL32 bChange
)
146 if( lpFormat
->wFormatID
>= CF_GDIOBJFIRST
&&
147 lpFormat
->wFormatID
<= CF_GDIOBJLAST
)
148 DeleteObject32(lpFormat
->hData
);
149 else if( lpFormat
->hData
)
150 GlobalFree16(lpFormat
->hData
);
152 lpFormat
->wDataPresent
= 0;
155 if( bChange
) bClipChanged
= TRUE
;
158 /**************************************************************************
159 * CLIPBOARD_RequestXSelection
161 static BOOL32
CLIPBOARD_RequestXSelection()
163 HWND32 hWnd
= (hWndClipWindow
) ? hWndClipWindow
: GetActiveWindow32();
165 if( !hWnd
) return FALSE
;
167 dprintf_clipboard(stddeb
,"Requesting selection...\n");
169 /* request data type XA_STRING, later
170 * CLIPBOARD_ReadSelection() will be invoked
171 * from the SelectionNotify event handler */
173 XConvertSelection(display
,XA_PRIMARY
,XA_STRING
,
174 XInternAtom(display
,"PRIMARY_TEXT",False
),
175 WIN_GetXWindow(hWnd
),CurrentTime
);
177 /* wait until SelectionNotify is processed */
181 EVENT_WaitXEvent( TRUE
, FALSE
);
183 /* we treat Unix text as CF_OEMTEXT */
184 dprintf_clipboard(stddeb
,"\tgot CF_OEMTEXT = %i\n",
185 ClipFormats
[CF_OEMTEXT
-1].wDataPresent
);
187 return (BOOL32
)ClipFormats
[CF_OEMTEXT
-1].wDataPresent
;
190 /**************************************************************************
191 * CLIPBOARD_IsPresent
193 BOOL32
CLIPBOARD_IsPresent(WORD wFormat
)
195 LPCLIPFORMAT lpFormat
= ClipFormats
;
199 if( wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
200 return lpFormat
[CF_TEXT
-1].wDataPresent
||
201 lpFormat
[CF_OEMTEXT
-1].wDataPresent
;
204 if (lpFormat
== NULL
) return FALSE
;
205 if (lpFormat
->wFormatID
== wFormat
) break;
206 lpFormat
= lpFormat
->NextFormat
;
209 return (lpFormat
->wDataPresent
);
212 /**************************************************************************
213 * OpenClipboard16 (USER.137)
215 BOOL16
OpenClipboard16( HWND16 hWnd
)
217 return OpenClipboard32( hWnd
);
221 /**************************************************************************
222 * OpenClipboard32 (USER32.406)
224 BOOL32
OpenClipboard32( HWND32 hWnd
)
227 dprintf_clipboard(stddeb
,"OpenClipboard(%04x) = ", hWnd
);
231 hWndClipWindow
= hWnd
;
234 bClipChanged
= FALSE
;
236 dprintf_clipboard(stddeb
,"%i\n", bRet
);
241 /**************************************************************************
242 * CloseClipboard16 (USER.138)
244 BOOL16
CloseClipboard16(void)
246 return CloseClipboard32();
250 /**************************************************************************
251 * CloseClipboard32 (USER32.53)
253 BOOL32
CloseClipboard32(void)
255 dprintf_clipboard(stddeb
,"CloseClipboard(); !\n");
257 if (hWndClipWindow
== 0) return FALSE
;
260 if (bClipChanged
&& hWndViewer
) SendMessage16(hWndViewer
,WM_DRAWCLIPBOARD
,0,0L);
266 /**************************************************************************
267 * EmptyClipboard16 (USER.139)
269 BOOL16
EmptyClipboard16(void)
271 return EmptyClipboard32();
275 /**************************************************************************
276 * EmptyClipboard32 (USER32.168)
278 BOOL32
EmptyClipboard32(void)
280 LPCLIPFORMAT lpFormat
= ClipFormats
;
282 dprintf_clipboard(stddeb
,"EmptyClipboard()\n");
284 if (hWndClipWindow
== 0) return FALSE
;
286 /* destroy private objects */
289 SendMessage16(hWndClipOwner
,WM_DESTROYCLIPBOARD
,0,0L);
293 if ( lpFormat
->wDataPresent
|| lpFormat
->hData
)
294 CLIPBOARD_DeleteRecord( lpFormat
, TRUE
);
296 lpFormat
= lpFormat
->NextFormat
;
299 hWndClipOwner
= hWndClipWindow
;
301 if(selectionAcquired
)
303 selectionAcquired
= False
;
304 selectionPrevWindow
= selectionWindow
;
305 selectionWindow
= None
;
307 dprintf_clipboard(stddeb
, "\tgiving up selection (spw = %08x)\n",
308 (unsigned)selectionPrevWindow
);
310 XSetSelectionOwner(display
,XA_PRIMARY
,None
,CurrentTime
);
316 /**************************************************************************
317 * GetClipboardOwner16 (USER.140)
319 HWND16
GetClipboardOwner16(void)
321 return hWndClipOwner
;
325 /**************************************************************************
326 * GetClipboardOwner32 (USER32.224)
328 HWND32
GetClipboardOwner32(void)
330 return hWndClipOwner
;
334 /**************************************************************************
335 * SetClipboardData16 (USER.141)
337 HANDLE16
SetClipboardData16( UINT16 wFormat
, HANDLE16 hData
)
339 LPCLIPFORMAT lpFormat
= ClipFormats
;
342 dprintf_clipboard(stddeb
,
343 "SetClipboardData(%04X, %04x) !\n", wFormat
, hData
);
347 if (lpFormat
== NULL
) return 0;
348 if (lpFormat
->wFormatID
== wFormat
) break;
349 lpFormat
= lpFormat
->NextFormat
;
352 /* Acquire X selection if text format */
354 if( !selectionAcquired
&&
355 (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) )
357 owner
= WIN_GetXWindow(hWndClipWindow
);
358 XSetSelectionOwner(display
,XA_PRIMARY
,owner
,CurrentTime
);
359 if( XGetSelectionOwner(display
,XA_PRIMARY
) == owner
)
361 selectionAcquired
= True
;
362 selectionWindow
= owner
;
364 dprintf_clipboard(stddeb
,"Grabbed X selection, owner=(%08x)\n",
369 if ( lpFormat
->wDataPresent
|| lpFormat
->hData
)
371 CLIPBOARD_DeleteRecord(lpFormat
, TRUE
);
373 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
375 if( wFormat
== CF_TEXT
&& ClipFormats
[CF_OEMTEXT
-1].hData
376 && !ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
377 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_OEMTEXT
-1], TRUE
);
378 if( wFormat
== CF_OEMTEXT
&& ClipFormats
[CF_TEXT
-1].hData
379 && !ClipFormats
[CF_TEXT
-1].wDataPresent
)
380 CLIPBOARD_DeleteRecord(&ClipFormats
[CF_TEXT
-1], TRUE
);
384 lpFormat
->wDataPresent
= 1;
385 lpFormat
->hData
= hData
; /* 0 is legal, see WM_RENDERFORMAT */
387 return lpFormat
->hData
;
391 /**************************************************************************
392 * SetClipboardData32 (USER32.469)
394 HANDLE32
SetClipboardData32( UINT32 wFormat
, HANDLE32 hData
)
396 fprintf( stderr
, "SetClipboardData: empty stub\n" );
401 /**************************************************************************
402 * CLIPBOARD_RenderFormat
404 static BOOL32
CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat
)
406 if( lpFormat
->wDataPresent
&& !lpFormat
->hData
)
407 if( IsWindow32(hWndClipOwner
) )
408 SendMessage16(hWndClipOwner
,WM_RENDERFORMAT
,
409 (WPARAM16
)lpFormat
->wFormatID
,0L);
412 dprintf_clipboard(stddeb
,"\thWndClipOwner (%04x) is lost!\n",
414 hWndClipOwner
= 0; lpFormat
->wDataPresent
= 0;
417 return (lpFormat
->hData
) ? TRUE
: FALSE
;
420 /**************************************************************************
421 * CLIPBOARD_RenderText
423 static BOOL32
CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget
, LPCLIPFORMAT lpSource
)
425 UINT16 size
= GlobalSize16( lpSource
->hData
);
426 LPCSTR lpstrS
= (LPSTR
)GlobalLock16(lpSource
->hData
);
429 if( !lpstrS
) return FALSE
;
430 dprintf_clipboard(stddeb
,"\tconverting from '%s' to '%s', %i chars\n",
431 lpSource
->Name
, lpTarget
->Name
, size
);
433 lpTarget
->hData
= GlobalAlloc16(GMEM_ZEROINIT
, size
);
434 lpstrT
= (LPSTR
)GlobalLock16(lpTarget
->hData
);
438 if( lpSource
->wFormatID
== CF_TEXT
)
439 CharToOemBuff32A(lpstrS
, lpstrT
, size
);
441 OemToCharBuff32A(lpstrS
, lpstrT
, size
);
442 dprintf_clipboard(stddeb
,"\tgot %s\n", lpstrT
);
450 /**************************************************************************
451 * GetClipboardData16 (USER.142)
453 HANDLE16
GetClipboardData16( UINT16 wFormat
)
455 LPCLIPFORMAT lpRender
= ClipFormats
;
456 LPCLIPFORMAT lpUpdate
= NULL
;
458 if (!hWndClipWindow
) return 0;
460 dprintf_clipboard(stddeb
,"GetClipboardData(%04X)\n", wFormat
);
462 if( wFormat
== CF_TEXT
&& !lpRender
[CF_TEXT
-1].wDataPresent
463 && lpRender
[CF_OEMTEXT
-1].wDataPresent
)
465 lpRender
= &ClipFormats
[CF_OEMTEXT
-1];
466 lpUpdate
= &ClipFormats
[CF_TEXT
-1];
468 dprintf_clipboard(stddeb
,"\tOEMTEXT -> TEXT\n");
470 else if( wFormat
== CF_OEMTEXT
&& !lpRender
[CF_OEMTEXT
-1].wDataPresent
471 && lpRender
[CF_TEXT
-1].wDataPresent
)
473 lpRender
= &ClipFormats
[CF_TEXT
-1];
474 lpUpdate
= &ClipFormats
[CF_OEMTEXT
-1];
476 dprintf_clipboard(stddeb
,"\tTEXT -> OEMTEXT\n");
482 if (lpRender
== NULL
) return 0;
483 if (lpRender
->wFormatID
== wFormat
) break;
484 lpRender
= lpRender
->NextFormat
;
489 if( !CLIPBOARD_RenderFormat(lpRender
) ) return 0;
490 if( lpUpdate
!= lpRender
&&
491 !lpUpdate
->hData
) CLIPBOARD_RenderText(lpUpdate
, lpRender
);
493 dprintf_clipboard(stddeb
,"\treturning %04x (type %i)\n",
494 lpUpdate
->hData
, lpUpdate
->wFormatID
);
495 return lpUpdate
->hData
;
499 /**************************************************************************
500 * GetClipboardData32 (USER32.221)
502 HANDLE32
GetClipboardData32( UINT32 wFormat
)
504 fprintf( stderr
, "GetClipboardData32: empty stub\n" );
508 /**************************************************************************
509 * CountClipboardFormats16 (USER.143)
511 INT16
CountClipboardFormats16(void)
513 return CountClipboardFormats32();
517 /**************************************************************************
518 * CountClipboardFormats32 (USER32.62)
520 INT32
CountClipboardFormats32(void)
522 INT32 FormatCount
= 0;
523 LPCLIPFORMAT lpFormat
= ClipFormats
;
525 dprintf_clipboard(stddeb
,"CountClipboardFormats()\n");
527 if( !selectionAcquired
) CLIPBOARD_RequestXSelection();
529 FormatCount
+= abs(lpFormat
[CF_TEXT
-1].wDataPresent
-
530 lpFormat
[CF_OEMTEXT
-1].wDataPresent
);
533 if (lpFormat
== NULL
) break;
534 if (lpFormat
->wDataPresent
)
536 dprintf_clipboard(stddeb
, "\tdata found for format %i\n", lpFormat
->wFormatID
);
540 lpFormat
= lpFormat
->NextFormat
;
543 dprintf_clipboard(stddeb
,"\ttotal %d\n", FormatCount
);
548 /**************************************************************************
549 * EnumClipboardFormats16 (USER.144)
551 UINT16
EnumClipboardFormats16( UINT16 wFormat
)
553 return EnumClipboardFormats32( wFormat
);
557 /**************************************************************************
558 * EnumClipboardFormats32 (USER32.178)
560 UINT32
EnumClipboardFormats32( UINT32 wFormat
)
562 LPCLIPFORMAT lpFormat
= ClipFormats
;
564 dprintf_clipboard(stddeb
,"EnumClipboardFormats(%04X)\n", wFormat
);
566 if( !hWndClipWindow
) return 0;
568 if( (!wFormat
|| wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
)
569 && !selectionAcquired
) CLIPBOARD_RequestXSelection();
572 if (lpFormat
->wDataPresent
|| ClipFormats
[CF_OEMTEXT
-1].wDataPresent
)
573 return lpFormat
->wFormatID
;
575 wFormat
= lpFormat
->wFormatID
; /* and CF_TEXT is not available */
577 /* walk up to the specified format record */
580 if (lpFormat
== NULL
) return 0;
581 if (lpFormat
->wFormatID
== wFormat
) break;
582 lpFormat
= lpFormat
->NextFormat
;
585 /* find next format with available data */
587 lpFormat
= lpFormat
->NextFormat
;
589 if (lpFormat
== NULL
) return 0;
590 if (lpFormat
->wDataPresent
||
591 (lpFormat
->wFormatID
== CF_OEMTEXT
&&
592 ClipFormats
[CF_TEXT
-1].wDataPresent
)) break;
593 lpFormat
= lpFormat
->NextFormat
;
596 return lpFormat
->wFormatID
;
600 /**************************************************************************
601 * RegisterClipboardFormat16 (USER.145)
603 UINT16
RegisterClipboardFormat16( LPCSTR FormatName
)
605 LPCLIPFORMAT lpNewFormat
;
606 LPCLIPFORMAT lpFormat
= ClipFormats
;
608 if (FormatName
== NULL
) return 0;
610 dprintf_clipboard(stddeb
,"RegisterClipboardFormat('%s') !\n", FormatName
);
612 /* walk format chain to see if it's already registered */
615 if ( !strcmp(lpFormat
->Name
,FormatName
) )
617 lpFormat
->wRefCount
++;
618 return lpFormat
->wFormatID
;
621 if ( lpFormat
->NextFormat
== NULL
) break;
623 lpFormat
= lpFormat
->NextFormat
;
626 /* allocate storage for new format entry */
628 lpNewFormat
= (LPCLIPFORMAT
)xmalloc(sizeof(CLIPFORMAT
));
629 lpFormat
->NextFormat
= lpNewFormat
;
630 lpNewFormat
->wFormatID
= LastRegFormat
;
631 lpNewFormat
->wRefCount
= 1;
633 lpNewFormat
->Name
= (LPSTR
)xmalloc(strlen(FormatName
) + 1);
634 strcpy(lpNewFormat
->Name
, FormatName
);
636 lpNewFormat
->wDataPresent
= 0;
637 lpNewFormat
->hData
= 0;
638 lpNewFormat
->BufSize
= 0;
639 lpNewFormat
->PrevFormat
= lpFormat
;
640 lpNewFormat
->NextFormat
= NULL
;
642 return LastRegFormat
++;
646 /**************************************************************************
647 * RegisterClipboardFormat32A (USER32.430)
649 UINT32
RegisterClipboardFormat32A( LPCSTR formatName
)
651 return RegisterClipboardFormat16( formatName
);
655 /**************************************************************************
656 * RegisterClipboardFormat32W (USER32.431)
658 UINT32
RegisterClipboardFormat32W( LPCWSTR formatName
)
660 LPSTR aFormat
= HEAP_strdupWtoA( GetProcessHeap(), 0, formatName
);
661 UINT32 ret
= RegisterClipboardFormat32A( aFormat
);
662 HeapFree( GetProcessHeap(), 0, aFormat
);
666 /**************************************************************************
667 * GetClipboardFormatName16 (USER.146)
669 INT16
GetClipboardFormatName16( UINT16 wFormat
, LPSTR retStr
, INT16 maxlen
)
671 return GetClipboardFormatName32A( wFormat
, retStr
, maxlen
);
675 /**************************************************************************
676 * GetClipboardFormatName32A (USER32.222)
678 INT32
GetClipboardFormatName32A( UINT32 wFormat
, LPSTR retStr
, INT32 maxlen
)
680 LPCLIPFORMAT lpFormat
= ClipFormats
;
682 dprintf_clipboard(stddeb
,
683 "GetClipboardFormatName(%04X, %p, %d) !\n", wFormat
, retStr
, maxlen
);
686 if (lpFormat
== NULL
) return 0;
687 if (lpFormat
->wFormatID
== wFormat
) break;
688 lpFormat
= lpFormat
->NextFormat
;
691 if (lpFormat
->Name
== NULL
||
692 lpFormat
->wFormatID
< CF_REGFORMATBASE
) return 0;
694 dprintf_clipboard(stddeb
,
695 "GetClipboardFormat // Name='%s' !\n", lpFormat
->Name
);
697 lstrcpyn32A( retStr
, lpFormat
->Name
, maxlen
);
698 return strlen(retStr
);
702 /**************************************************************************
703 * GetClipboardFormatName32W (USER32.223)
705 INT32
GetClipboardFormatName32W( UINT32 wFormat
, LPWSTR retStr
, INT32 maxlen
)
707 LPSTR p
= HEAP_xalloc( GetProcessHeap(), 0, maxlen
);
708 INT32 ret
= GetClipboardFormatName32A( wFormat
, p
, maxlen
);
709 lstrcpynAtoW( retStr
, p
, maxlen
);
710 HeapFree( GetProcessHeap(), 0, p
);
715 /**************************************************************************
716 * SetClipboardViewer16 (USER.147)
718 HWND16
SetClipboardViewer16( HWND16 hWnd
)
720 return SetClipboardViewer32( hWnd
);
724 /**************************************************************************
725 * SetClipboardViewer32 (USER32.470)
727 HWND32
SetClipboardViewer32( HWND32 hWnd
)
729 HWND32 hwndPrev
= hWndViewer
;
731 dprintf_clipboard(stddeb
,"SetClipboardViewer(%04x)\n", hWnd
);
738 /**************************************************************************
739 * GetClipboardViewer16 (USER.148)
741 HWND16
GetClipboardViewer16(void)
747 /**************************************************************************
748 * GetClipboardViewer32 (USER32.225)
750 HWND32
GetClipboardViewer32(void)
756 /**************************************************************************
757 * ChangeClipboardChain16 (USER.149)
759 BOOL16
ChangeClipboardChain16(HWND16 hWnd
, HWND16 hWndNext
)
761 return ChangeClipboardChain32(hWnd
,hWndNext
);
764 /**************************************************************************
765 * ChangeClipboardChain32 (USER32.21)
767 BOOL32
ChangeClipboardChain32(HWND32 hWnd
, HWND32 hWndNext
)
771 dprintf_clipboard(stdnimp
, "ChangeClipboardChain(%04x, %04x)\n", hWnd
, hWndNext
);
774 bRet
= !SendMessage16( hWndViewer
, WM_CHANGECBCHAIN
,
775 (WPARAM16
)hWnd
, (LPARAM
)hWndNext
);
777 dprintf_clipboard(stddeb
,"ChangeClipboardChain: hWndViewer is lost\n");
779 if( hWnd
== hWndViewer
) hWndViewer
= hWndNext
;
786 /**************************************************************************
787 * IsClipboardFormatAvailable16 (USER.193)
789 BOOL16
IsClipboardFormatAvailable16( UINT16 wFormat
)
791 return IsClipboardFormatAvailable32( wFormat
);
795 /**************************************************************************
796 * IsClipboardFormatAvailable32 (USER32.339)
798 BOOL32
IsClipboardFormatAvailable32( UINT32 wFormat
)
800 dprintf_clipboard(stddeb
,"IsClipboardFormatAvailable(%04X) !\n", wFormat
);
802 if( (wFormat
== CF_TEXT
|| wFormat
== CF_OEMTEXT
) &&
803 !selectionAcquired
) CLIPBOARD_RequestXSelection();
805 return CLIPBOARD_IsPresent(wFormat
);
809 /**************************************************************************
810 * GetOpenClipboardWindow16 (USER.248)
812 HWND16
GetOpenClipboardWindow16(void)
814 return hWndClipWindow
;
818 /**************************************************************************
819 * GetOpenClipboardWindow32 (USER32.276)
821 HWND32
GetOpenClipboardWindow32(void)
823 return hWndClipWindow
;
827 /**************************************************************************
828 * GetPriorityClipboardFormat16 (USER.402)
830 INT16
GetPriorityClipboardFormat16( UINT16
*lpPriorityList
, INT16 nCount
)
832 fprintf( stderr
, "GetPriorityClipboardFormat16(%p, %d): stub\n",
833 lpPriorityList
, nCount
);
838 /**************************************************************************
839 * GetPriorityClipboardFormat32 (USER32
841 INT32
GetPriorityClipboardFormat32( UINT32
*lpPriorityList
, INT32 nCount
)
843 fprintf( stderr
, "GetPriorityClipboardFormat32(%p, %d): stub\n",
844 lpPriorityList
, nCount
);
849 /**************************************************************************
850 * CLIPBOARD_ReadSelection
852 * Called from the SelectionNotify event handler.
854 void CLIPBOARD_ReadSelection(Window w
,Atom prop
)
857 LPCLIPFORMAT lpFormat
= ClipFormats
;
859 dprintf_clipboard(stddeb
,"ReadSelection callback\n");
863 Atom atype
=AnyPropertyType
;
865 unsigned long nitems
,remain
;
866 unsigned char* val
=NULL
;
868 dprintf_clipboard(stddeb
,"\tgot property %s\n",XGetAtomName(display
,prop
));
870 /* TODO: Properties longer than 64K */
872 if(XGetWindowProperty(display
,w
,prop
,0,0x3FFF,True
,XA_STRING
,
873 &atype
, &aformat
, &nitems
, &remain
, &val
) != Success
)
874 dprintf_clipboard(stddeb
,"\tcouldn't read property\n");
877 dprintf_clipboard(stddeb
,"\tType %s,Format %d,nitems %ld,value %s\n",
878 XGetAtomName(display
,atype
),aformat
,nitems
,val
);
880 if(atype
== XA_STRING
&& aformat
== 8)
885 dprintf_clipboard(stddeb
,"\tselection is '%s'\n",val
);
887 for(i
=0; i
<= nitems
; i
++)
888 if( val
[i
] == '\n' ) inlcount
++;
892 hText
=GlobalAlloc16(GMEM_MOVEABLE
, nitems
+ inlcount
+ 1);
893 if( (lpstr
= (char*)GlobalLock16(hText
)) )
894 for(i
=0,inlcount
=0; i
<= nitems
; i
++)
896 if( val
[i
] == '\n' ) lpstr
[inlcount
++]='\r';
897 lpstr
[inlcount
++]=val
[i
];
906 /* delete previous CF_TEXT and CF_OEMTEXT data */
910 lpFormat
= &ClipFormats
[CF_TEXT
-1];
911 if (lpFormat
->wDataPresent
|| lpFormat
->hData
)
912 CLIPBOARD_DeleteRecord(lpFormat
, !(hWndClipWindow
));
913 lpFormat
= &ClipFormats
[CF_OEMTEXT
-1];
914 if (lpFormat
->wDataPresent
|| lpFormat
->hData
)
915 CLIPBOARD_DeleteRecord(lpFormat
, !(hWndClipWindow
));
917 lpFormat
->wDataPresent
= 1;
918 lpFormat
->hData
= hText
;
924 /**************************************************************************
925 * CLIPBOARD_ReleaseSelection
927 * Wine might have lost XA_PRIMARY selection because of
928 * EmptyClipboard() or other client.
930 void CLIPBOARD_ReleaseSelection(Window w
, HWND32 hwnd
)
932 /* w is the window that lost selection,
934 * selectionPrevWindow is nonzero if CheckSelection() was called.
937 dprintf_clipboard(stddeb
,"\tevent->window = %08x (sw = %08x, spw=%08x)\n",
938 (unsigned)w
, (unsigned)selectionWindow
, (unsigned)selectionPrevWindow
);
940 if( selectionAcquired
)
941 if( w
== selectionWindow
|| selectionPrevWindow
== None
)
943 /* alright, we really lost it */
945 selectionAcquired
= False
;
946 selectionWindow
= None
;
948 /* but we'll keep existing data for internal use */
950 else if( w
== selectionPrevWindow
)
952 w
= XGetSelectionOwner(display
, XA_PRIMARY
);
955 XSetSelectionOwner(display
, XA_PRIMARY
, selectionWindow
, CurrentTime
);
958 selectionPrevWindow
= None
;