- use global atoms for the format ids
- add timeout when calling XCheckTypedWindowEvent - fix broken IsClipboardFormatAvailable; it tried to do a trick with EnumClipboardFormats by making incorrect assumptions - in X11DRV_IsClipboardFormatAvailable do a quick exit if no one owns the selection - add 1 second *minimum* time lapse between XSelectionOwner calls - sync clipboard ownership between different wine processes - prevents apps from getting into wierd state where they thought they didn't own the selection but they did and as a result queried themselves for available selection data
This commit is contained in:
parent
a3c10cf1e0
commit
b2df5f9f19
|
@ -715,12 +715,6 @@
|
|||
################################################################
|
||||
# Wine dll separation hacks, these will go away, don't use them
|
||||
#
|
||||
@ cdecl CLIPBOARD_DeleteRecord(ptr long)
|
||||
@ cdecl CLIPBOARD_EmptyCache(long)
|
||||
@ cdecl CLIPBOARD_GetFormatName(long ptr long)
|
||||
@ cdecl CLIPBOARD_IsPresent(long)
|
||||
@ cdecl CLIPBOARD_LookupFormat(long)
|
||||
@ cdecl CLIPBOARD_ReleaseOwner()
|
||||
@ cdecl DCE_InvalidateDCE(long ptr)
|
||||
@ cdecl HOOK_CallHooks(long long long long long)
|
||||
@ cdecl NC_GetInsideRect(long ptr)
|
||||
|
|
|
@ -89,13 +89,15 @@ static BOOL load_driver(void)
|
|||
GET_USER_FUNC(GetScreenSaveActive);
|
||||
GET_USER_FUNC(SetScreenSaveActive);
|
||||
GET_USER_FUNC(AcquireClipboard);
|
||||
GET_USER_FUNC(ReleaseClipboard);
|
||||
GET_USER_FUNC(EmptyClipboard);
|
||||
GET_USER_FUNC(SetClipboardData);
|
||||
GET_USER_FUNC(GetClipboardData);
|
||||
GET_USER_FUNC(CountClipboardFormats);
|
||||
GET_USER_FUNC(EnumClipboardFormats);
|
||||
GET_USER_FUNC(IsClipboardFormatAvailable);
|
||||
GET_USER_FUNC(RegisterClipboardFormat);
|
||||
GET_USER_FUNC(GetClipboardFormatName);
|
||||
GET_USER_FUNC(IsSelectionOwner);
|
||||
GET_USER_FUNC(EndClipboardUpdate);
|
||||
GET_USER_FUNC(ResetSelectionOwner);
|
||||
GET_USER_FUNC(ChangeDisplaySettingsExW);
|
||||
GET_USER_FUNC(EnumDisplaySettingsExW);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,6 +47,7 @@
|
|||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(event);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(clipboard);
|
||||
|
||||
/* X context to associate a hwnd to an X window */
|
||||
extern XContext winContext;
|
||||
|
@ -272,10 +273,9 @@ static void EVENT_ProcessEvent( XEvent *event )
|
|||
if (XFindContext( display, event->xany.window, winContext, (char **)&hWnd ) != 0)
|
||||
hWnd = 0; /* Not for a registered window */
|
||||
wine_tsx11_unlock();
|
||||
if (!hWnd && event->xany.window == root_window) hWnd = GetDesktopWindow();
|
||||
|
||||
if ( !hWnd && event->xany.window != root_window
|
||||
&& event->type != PropertyNotify
|
||||
&& event->type != MappingNotify)
|
||||
if (!hWnd && event->type != PropertyNotify && event->type != MappingNotify)
|
||||
WARN( "Got event %s for unknown Window %08lx\n",
|
||||
event_names[event->type], event->xany.window );
|
||||
else
|
||||
|
@ -575,45 +575,16 @@ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* EVENT_SelectionRequest_TARGETS
|
||||
* Service a TARGETS selection request event
|
||||
* EVENT_SelectionRequest_AddTARGETS
|
||||
* Utility function for EVENT_SelectionRequest_TARGETS.
|
||||
*/
|
||||
static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
|
||||
Atom target, Atom rprop )
|
||||
static void EVENT_SelectionRequest_AddTARGETS(Atom* targets, unsigned long* cTargets, Atom prop)
|
||||
{
|
||||
Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
|
||||
Atom* targets;
|
||||
Atom prop;
|
||||
UINT wFormat;
|
||||
unsigned long cTargets;
|
||||
BOOL bHavePixmap;
|
||||
int xRc;
|
||||
|
||||
TRACE("Request for %s\n", TSXGetAtomName(display, target));
|
||||
|
||||
/*
|
||||
* Count the number of items we wish to expose as selection targets.
|
||||
* We include the TARGETS item, and a PIXMAP if we have CF_DIB or CF_BITMAP
|
||||
*/
|
||||
cTargets = CountClipboardFormats() + 1;
|
||||
if ( CLIPBOARD_IsPresent(CF_DIB) || CLIPBOARD_IsPresent(CF_BITMAP) )
|
||||
cTargets++;
|
||||
|
||||
/* Allocate temp buffer */
|
||||
targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
|
||||
if(targets == NULL) return None;
|
||||
|
||||
/* Create TARGETS property list (First item in list is TARGETS itself) */
|
||||
|
||||
for ( targets[0] = xaTargets, cTargets = 1, wFormat = 0, bHavePixmap = FALSE;
|
||||
(wFormat = EnumClipboardFormats( wFormat )); )
|
||||
{
|
||||
if ( (prop = X11DRV_CLIPBOARD_MapFormatToProperty(wFormat)) != None )
|
||||
{
|
||||
/* Scan through what we have so far to avoid duplicates */
|
||||
int i;
|
||||
BOOL bExists;
|
||||
for (i = 0, bExists = FALSE; i < cTargets; i++)
|
||||
|
||||
/* Scan through what we have so far to avoid duplicates */
|
||||
for (i = 0, bExists = FALSE; i < *cTargets; i++)
|
||||
{
|
||||
if (targets[i] == prop)
|
||||
{
|
||||
|
@ -621,22 +592,59 @@ static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bExists)
|
||||
{
|
||||
targets[cTargets++] = prop;
|
||||
targets[(*cTargets)++] = prop;
|
||||
}
|
||||
|
||||
/* Add PIXMAP prop for bitmaps additionally */
|
||||
if ( (wFormat == CF_DIB || wFormat == CF_BITMAP )
|
||||
&& !bHavePixmap )
|
||||
|
||||
/***********************************************************************
|
||||
* EVENT_SelectionRequest_TARGETS
|
||||
* Service a TARGETS selection request event
|
||||
*/
|
||||
static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
|
||||
Atom target, Atom rprop )
|
||||
{
|
||||
Atom* targets;
|
||||
UINT wFormat;
|
||||
UINT alias;
|
||||
ULONG cTargets;
|
||||
|
||||
/*
|
||||
* Count the number of items we wish to expose as selection targets.
|
||||
* We include the TARGETS item, and propery aliases
|
||||
*/
|
||||
cTargets = X11DRV_CountClipboardFormats() + 1;
|
||||
|
||||
for (wFormat = 0; (wFormat = X11DRV_EnumClipboardFormats(wFormat));)
|
||||
{
|
||||
targets[cTargets++] = XA_PIXMAP;
|
||||
bHavePixmap = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
|
||||
if (lpFormat && X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData))
|
||||
cTargets++;
|
||||
}
|
||||
|
||||
if (TRACE_ON(event))
|
||||
TRACE_(clipboard)(" found %ld formats\n", cTargets);
|
||||
|
||||
/* Allocate temp buffer */
|
||||
targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
|
||||
if(targets == NULL)
|
||||
return None;
|
||||
|
||||
/* Create TARGETS property list (First item in list is TARGETS itself) */
|
||||
for (targets[0] = xaTargets, cTargets = 1, wFormat = 0;
|
||||
(wFormat = X11DRV_EnumClipboardFormats(wFormat));)
|
||||
{
|
||||
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupFormat(wFormat);
|
||||
|
||||
EVENT_SelectionRequest_AddTARGETS(targets, &cTargets, lpFormat->drvData);
|
||||
|
||||
/* Check if any alias should be listed */
|
||||
alias = X11DRV_CLIPBOARD_LookupPropertyAlias(lpFormat->drvData);
|
||||
if (alias)
|
||||
EVENT_SelectionRequest_AddTARGETS(targets, &cTargets, alias);
|
||||
}
|
||||
|
||||
if (TRACE_ON(clipboard))
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < cTargets; i++)
|
||||
|
@ -644,260 +652,18 @@ static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
|
|||
if (targets[i])
|
||||
{
|
||||
char *itemFmtName = TSXGetAtomName(display, targets[i]);
|
||||
TRACE("\tAtom# %d: Type %s\n", i, itemFmtName);
|
||||
TRACE_(clipboard)("\tAtom# %d: Property %ld Type %s\n", i, targets[i], itemFmtName);
|
||||
TSXFree(itemFmtName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the X property */
|
||||
TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
|
||||
|
||||
/* We may want to consider setting the type to xaTargets instead,
|
||||
* in case some apps expect this instead of XA_ATOM */
|
||||
xRc = TSXChangeProperty(display, requestor, rprop,
|
||||
XA_ATOM, 32, PropModeReplace,
|
||||
(unsigned char *)targets, cTargets);
|
||||
TRACE("(Rc=%d)\n", xRc);
|
||||
TSXChangeProperty(display, requestor, rprop, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char *)targets, cTargets);
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, targets );
|
||||
|
||||
return rprop;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* EVENT_SelectionRequest_STRING
|
||||
* Service a STRING selection request event
|
||||
*/
|
||||
static Atom EVENT_SelectionRequest_STRING( Display *display, Window requestor,
|
||||
Atom target, Atom rprop )
|
||||
{
|
||||
static UINT text_cp = (UINT)-1;
|
||||
HANDLE hUnicodeText;
|
||||
LPWSTR uni_text;
|
||||
LPSTR text;
|
||||
int size,i,j;
|
||||
char* lpstr = 0;
|
||||
char *itemFmtName;
|
||||
int xRc;
|
||||
|
||||
if(text_cp == (UINT)-1)
|
||||
{
|
||||
HKEY hkey;
|
||||
/* default value */
|
||||
text_cp = CP_ACP;
|
||||
if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\x11drv", &hkey))
|
||||
{
|
||||
char buf[20];
|
||||
DWORD type, count = sizeof(buf);
|
||||
if(!RegQueryValueExA(hkey, "TextCP", 0, &type, buf, &count))
|
||||
text_cp = atoi(buf);
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the requested X selection property type atom name to a
|
||||
* windows clipboard format ID.
|
||||
*/
|
||||
itemFmtName = TSXGetAtomName(display, target);
|
||||
TRACE("Request for %s (wFormat=%x %s)\n",
|
||||
itemFmtName, CF_UNICODETEXT, CLIPBOARD_GetFormatName(CF_UNICODETEXT, NULL, 0));
|
||||
TSXFree(itemFmtName);
|
||||
|
||||
hUnicodeText = GetClipboardData(CF_UNICODETEXT);
|
||||
if(!hUnicodeText)
|
||||
return None;
|
||||
uni_text = GlobalLock(hUnicodeText);
|
||||
if(!uni_text)
|
||||
return None;
|
||||
|
||||
size = WideCharToMultiByte(text_cp, 0, uni_text, -1, NULL, 0, NULL, NULL);
|
||||
text = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
if (!text)
|
||||
return None;
|
||||
WideCharToMultiByte(text_cp, 0, uni_text, -1, text, size, NULL, NULL);
|
||||
|
||||
/* remove carriage returns */
|
||||
|
||||
lpstr = (char*)HeapAlloc( GetProcessHeap(), 0, size-- );
|
||||
if(lpstr == NULL) return None;
|
||||
for(i=0,j=0; i < size && text[i]; i++ )
|
||||
{
|
||||
if( text[i] == '\r' &&
|
||||
(text[i+1] == '\n' || text[i+1] == '\0') ) continue;
|
||||
lpstr[j++] = text[i];
|
||||
}
|
||||
lpstr[j]='\0';
|
||||
|
||||
/* Update the X property */
|
||||
TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
|
||||
xRc = TSXChangeProperty(display, requestor, rprop,
|
||||
XA_STRING, 8, PropModeReplace,
|
||||
lpstr, j);
|
||||
TRACE("(Rc=%d)\n", xRc);
|
||||
|
||||
GlobalUnlock(hUnicodeText);
|
||||
HeapFree(GetProcessHeap(), 0, text);
|
||||
HeapFree( GetProcessHeap(), 0, lpstr );
|
||||
|
||||
return rprop;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EVENT_SelectionRequest_PIXMAP
|
||||
* Service a PIXMAP selection request event
|
||||
*/
|
||||
static Atom EVENT_SelectionRequest_PIXMAP( Display *display, Window requestor,
|
||||
Atom target, Atom rprop )
|
||||
{
|
||||
HANDLE hClipData = 0;
|
||||
Pixmap pixmap = 0;
|
||||
UINT wFormat;
|
||||
char * itemFmtName;
|
||||
int xRc;
|
||||
#if(0)
|
||||
XSetWindowAttributes win_attr;
|
||||
XWindowAttributes win_attr_src;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Map the requested X selection property type atom name to a
|
||||
* windows clipboard format ID.
|
||||
*/
|
||||
itemFmtName = TSXGetAtomName(display, target);
|
||||
wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
|
||||
TRACE("Request for %s (wFormat=%x %s)\n",
|
||||
itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat, NULL, 0 ));
|
||||
TSXFree(itemFmtName);
|
||||
|
||||
hClipData = GetClipboardData(wFormat);
|
||||
if ( !hClipData )
|
||||
{
|
||||
TRACE("Could not retrieve a Pixmap compatible format from clipboard!\n");
|
||||
rprop = None; /* Fail the request */
|
||||
goto END;
|
||||
}
|
||||
|
||||
if (wFormat == CF_DIB)
|
||||
{
|
||||
HWND hwnd = GetOpenClipboardWindow();
|
||||
HDC hdc = GetDC(hwnd);
|
||||
|
||||
/* For convert from packed DIB to Pixmap */
|
||||
pixmap = X11DRV_DIB_CreatePixmapFromDIB(hClipData, hdc);
|
||||
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
else if (wFormat == CF_BITMAP)
|
||||
{
|
||||
HWND hwnd = GetOpenClipboardWindow();
|
||||
HDC hdc = GetDC(hwnd);
|
||||
|
||||
pixmap = X11DRV_BITMAP_CreatePixmapFromBitmap(hClipData, hdc);
|
||||
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("%s to PIXMAP conversion not yet implemented!\n",
|
||||
CLIPBOARD_GetFormatName(wFormat, NULL, 0));
|
||||
rprop = None;
|
||||
goto END;
|
||||
}
|
||||
|
||||
TRACE("\tUpdating property %s on Window %ld with %s %ld...\n",
|
||||
TSXGetAtomName(display, rprop), (long)requestor,
|
||||
TSXGetAtomName(display, target), pixmap);
|
||||
|
||||
/* Store the Pixmap handle in the property */
|
||||
xRc = TSXChangeProperty(display, requestor, rprop, target,
|
||||
32, PropModeReplace,
|
||||
(unsigned char *)&pixmap, 1);
|
||||
TRACE("(Rc=%d)\n", xRc);
|
||||
|
||||
/* Enable the code below if you want to handle destroying Pixmap resources
|
||||
* in response to property notify events. Clients like XPaint don't
|
||||
* appear to be duplicating Pixmaps so they don't like us deleting,
|
||||
* the resource in response to the property being deleted.
|
||||
*/
|
||||
#if(0)
|
||||
/* Express interest in property notify events so that we can delete the
|
||||
* pixmap when the client deletes the property atom.
|
||||
*/
|
||||
xRc = TSXGetWindowAttributes(display, requestor, &win_attr_src);
|
||||
TRACE("Turning on PropertyChangeEvent notifications from window %ld\n",
|
||||
(long)requestor);
|
||||
win_attr.event_mask = win_attr_src.your_event_mask | PropertyChangeMask;
|
||||
TSXChangeWindowAttributes(display, requestor, CWEventMask, &win_attr);
|
||||
|
||||
/* Register the Pixmap we created with the request property Atom.
|
||||
* When this property is destroyed we also destroy the Pixmap in
|
||||
* response to the PropertyNotify event.
|
||||
*/
|
||||
X11DRV_CLIPBOARD_RegisterPixmapResource( rprop, pixmap );
|
||||
#endif
|
||||
|
||||
END:
|
||||
return rprop;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* EVENT_SelectionRequest_WCF
|
||||
* Service a Wine Clipboard Format selection request event.
|
||||
* For <WCF>* data types we simply copy the data to X without conversion.
|
||||
*/
|
||||
static Atom EVENT_SelectionRequest_WCF( Display *display, Window requestor,
|
||||
Atom target, Atom rprop )
|
||||
{
|
||||
HANDLE hClipData = 0;
|
||||
void* lpClipData;
|
||||
UINT wFormat;
|
||||
char * itemFmtName;
|
||||
int cBytes;
|
||||
int xRc;
|
||||
int bemf;
|
||||
|
||||
/*
|
||||
* Map the requested X selection property type atom name to a
|
||||
* windows clipboard format ID.
|
||||
*/
|
||||
itemFmtName = TSXGetAtomName(display, target);
|
||||
wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
|
||||
TRACE("Request for %s (wFormat=%x %s)\n",
|
||||
itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat, NULL, 0));
|
||||
TSXFree(itemFmtName);
|
||||
|
||||
hClipData = GetClipboardData(wFormat);
|
||||
|
||||
bemf = wFormat == CF_METAFILEPICT || wFormat == CF_ENHMETAFILE;
|
||||
if (bemf)
|
||||
hClipData = X11DRV_CLIPBOARD_SerializeMetafile(wFormat, hClipData, sizeof(hClipData), TRUE);
|
||||
|
||||
if( hClipData && (lpClipData = GlobalLock(hClipData)) )
|
||||
{
|
||||
cBytes = GlobalSize(hClipData);
|
||||
|
||||
TRACE("\tUpdating property %s, %d bytes...\n",
|
||||
TSXGetAtomName(display, rprop), cBytes);
|
||||
|
||||
xRc = TSXChangeProperty(display, requestor, rprop,
|
||||
target, 8, PropModeReplace,
|
||||
(unsigned char *)lpClipData, cBytes);
|
||||
TRACE("(Rc=%d)\n", xRc);
|
||||
|
||||
GlobalUnlock(hClipData);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("\tCould not retrieve native format!\n");
|
||||
rprop = None; /* Fail the request */
|
||||
}
|
||||
|
||||
if (bemf) /* We must free serialized metafile data */
|
||||
GlobalFree(hClipData);
|
||||
HeapFree(GetProcessHeap(), 0, targets);
|
||||
|
||||
return rprop;
|
||||
}
|
||||
|
@ -1016,10 +782,8 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
|
|||
XSelectionEvent result;
|
||||
Atom rprop = None;
|
||||
Window request = event->requestor;
|
||||
BOOL couldOpen = FALSE;
|
||||
Atom xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
|
||||
Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
|
||||
Atom xaMultiple = TSXInternAtom(display, "MULTIPLE", False);
|
||||
|
||||
TRACE_(clipboard)("\n");
|
||||
|
||||
/*
|
||||
* We can only handle the selection request if :
|
||||
|
@ -1029,8 +793,7 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
|
|||
*/
|
||||
if ( !bIsMultiple )
|
||||
{
|
||||
if ( ( (event->selection != XA_PRIMARY) && (event->selection != xaClipboard) )
|
||||
|| !(couldOpen = OpenClipboard(hWnd)) )
|
||||
if (((event->selection != XA_PRIMARY) && (event->selection != xaClipboard)))
|
||||
goto END;
|
||||
}
|
||||
|
||||
|
@ -1051,36 +814,48 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
|
|||
/* MULTIPLE selection request */
|
||||
rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
|
||||
}
|
||||
else if(event->target == XA_STRING) /* treat CF_TEXT as Unix text */
|
||||
else
|
||||
{
|
||||
/* XA_STRING selection request */
|
||||
rprop = EVENT_SelectionRequest_STRING( display, request, event->target, rprop );
|
||||
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupProperty(event->target);
|
||||
|
||||
if (!lpFormat)
|
||||
lpFormat = X11DRV_CLIPBOARD_LookupAliasProperty(event->target);
|
||||
|
||||
if (lpFormat)
|
||||
{
|
||||
LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(lpFormat->wFormatID);
|
||||
|
||||
if (lpData)
|
||||
{
|
||||
unsigned char* lpClipData;
|
||||
DWORD cBytes;
|
||||
HANDLE hClipData = lpFormat->lpDrvExportFunc(lpData, &cBytes);
|
||||
|
||||
if (hClipData && (lpClipData = GlobalLock(hClipData)))
|
||||
{
|
||||
|
||||
TRACE_(clipboard)("\tUpdating property %s, %ld bytes\n",
|
||||
lpFormat->Name, cBytes);
|
||||
|
||||
TSXChangeProperty(display, request, rprop, event->target,
|
||||
8, PropModeReplace, (unsigned char *)lpClipData, cBytes);
|
||||
|
||||
GlobalUnlock(hClipData);
|
||||
GlobalFree(hClipData);
|
||||
}
|
||||
else if(event->target == XA_PIXMAP) /* Convert DIB's to Pixmaps */
|
||||
{
|
||||
/* XA_PIXMAP selection request */
|
||||
rprop = EVENT_SelectionRequest_PIXMAP( display, request, event->target, rprop );
|
||||
}
|
||||
else if(event->target == XA_BITMAP) /* Convert DIB's to 1-bit Pixmaps */
|
||||
{
|
||||
/* XA_BITMAP selection request - TODO: create a monochrome Pixmap */
|
||||
rprop = EVENT_SelectionRequest_PIXMAP( display, request, XA_PIXMAP, rprop );
|
||||
}
|
||||
else if(X11DRV_CLIPBOARD_IsNativeProperty(event->target)) /* <WCF>* */
|
||||
{
|
||||
/* All <WCF> selection requests */
|
||||
rprop = EVENT_SelectionRequest_WCF( display, request, event->target, rprop );
|
||||
}
|
||||
else
|
||||
rprop = None; /* Don't support this format */
|
||||
{
|
||||
if (TRACE_ON(clipboard))
|
||||
{
|
||||
TRACE_(clipboard)("Request for property %s (%ld) failed\n",
|
||||
TSXGetAtomName(display, event->target), event->target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
/* close clipboard only if we opened before */
|
||||
if(couldOpen) CloseClipboard();
|
||||
|
||||
if( rprop == None)
|
||||
TRACE("\tRequest ignored\n");
|
||||
|
||||
/* reply to sender
|
||||
* SelectionNotify should be sent only at the end of a MULTIPLE request
|
||||
*/
|
||||
|
@ -1103,8 +878,6 @@ END:
|
|||
*/
|
||||
static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
|
||||
{
|
||||
Atom xaClipboard = TSXInternAtom(event->display, "CLIPBOARD", False);
|
||||
|
||||
if (event->selection == XA_PRIMARY || event->selection == xaClipboard)
|
||||
X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd );
|
||||
}
|
||||
|
@ -1125,9 +898,6 @@ static void EVENT_PropertyNotify( XPropertyEvent *event )
|
|||
{
|
||||
TRACE("\tPropertyDelete for atom %s on window %ld\n",
|
||||
TSXGetAtomName(event->display, event->atom), (long)event->window);
|
||||
|
||||
if (X11DRV_IsSelectionOwner())
|
||||
X11DRV_CLIPBOARD_FreeResources( event->atom );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -373,15 +373,59 @@ extern Atom _kde_net_wm_system_tray_window_for;
|
|||
|
||||
/* X11 clipboard driver */
|
||||
|
||||
extern void X11DRV_CLIPBOARD_FreeResources( Atom property );
|
||||
extern BOOL X11DRV_CLIPBOARD_RegisterPixmapResource( Atom property, Pixmap pixmap );
|
||||
extern BOOL X11DRV_CLIPBOARD_IsNativeProperty(Atom prop);
|
||||
extern UINT X11DRV_CLIPBOARD_MapPropertyToFormat(char *itemFmtName);
|
||||
extern Atom X11DRV_CLIPBOARD_MapFormatToProperty(UINT id);
|
||||
typedef struct tagPROPERTYFORMATMAP
|
||||
{
|
||||
LPCSTR lpszProperty;
|
||||
LPCSTR lpszFormat;
|
||||
} PROPERTYFORMATMAP;
|
||||
|
||||
typedef struct tagPROPERTYALIASMAP
|
||||
{
|
||||
LPCSTR lpszProperty;
|
||||
UINT drvDataProperty;
|
||||
LPCSTR lpszAlias;
|
||||
UINT drvDataAlias;
|
||||
} PROPERTYALIASMAP;
|
||||
|
||||
typedef struct tagWINE_CLIPDATA {
|
||||
UINT wFormatID;
|
||||
HANDLE16 hData16;
|
||||
HANDLE hData32;
|
||||
UINT wFlags;
|
||||
struct tagWINE_CLIPDATA *PrevData;
|
||||
struct tagWINE_CLIPDATA *NextData;
|
||||
} WINE_CLIPDATA, *LPWINE_CLIPDATA;
|
||||
|
||||
typedef HANDLE (*DRVEXPORTFUNC)(LPWINE_CLIPDATA lpData, LPDWORD lpBytes);
|
||||
typedef HANDLE (*DRVIMPORTFUNC)(LPBYTE hData, UINT cBytes);
|
||||
|
||||
typedef struct tagWINE_CLIPFORMAT {
|
||||
UINT wFormatID;
|
||||
LPSTR Name;
|
||||
UINT drvData;
|
||||
UINT wFlags;
|
||||
DRVIMPORTFUNC lpDrvImportFunc;
|
||||
DRVEXPORTFUNC lpDrvExportFunc;
|
||||
struct tagWINE_CLIPFORMAT *PrevFormat;
|
||||
struct tagWINE_CLIPFORMAT *NextFormat;
|
||||
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
|
||||
|
||||
#define CF_FLAG_BUILTINFMT 1 /* Built-in windows format */
|
||||
#define CF_FLAG_SYNTHESIZED 8 /* Implicitly converted data */
|
||||
|
||||
extern Atom xaClipboard;
|
||||
extern Atom xaTargets;
|
||||
extern Atom xaMultiple;
|
||||
|
||||
extern BOOL X11DRV_InitClipboard(Display *display);
|
||||
extern void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd);
|
||||
extern BOOL X11DRV_IsSelectionOwner(void);
|
||||
extern BOOL X11DRV_GetClipboardData(UINT wFormat);
|
||||
extern HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, INT cbytes, BOOL out);
|
||||
extern INT X11DRV_CountClipboardFormats(void);
|
||||
extern UINT X11DRV_EnumClipboardFormats(UINT wFormat);
|
||||
extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupFormat(WORD wID);
|
||||
extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupProperty(UINT drvData);
|
||||
extern LPWINE_CLIPDATA X11DRV_CLIPBOARD_LookupData(DWORD wID);
|
||||
extern UINT X11DRV_CLIPBOARD_LookupPropertyAlias(UINT drvDataProperty);
|
||||
extern LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupAliasProperty(UINT drvDataAlias);
|
||||
|
||||
/* X11 event driver */
|
||||
|
||||
|
|
|
@ -74,32 +74,34 @@
|
|||
@ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive
|
||||
@ cdecl ChangeDisplaySettingsExW (ptr ptr long long long) X11DRV_ChangeDisplaySettingsExW
|
||||
@ cdecl EnumDisplaySettingsExW (ptr long ptr long) X11DRV_EnumDisplaySettingsExW
|
||||
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
|
||||
@ cdecl CountClipboardFormats() X11DRV_CountClipboardFormats
|
||||
@ cdecl CreateWindow(long ptr long) X11DRV_CreateWindow
|
||||
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
|
||||
@ cdecl GetDC(long long long long) X11DRV_GetDC
|
||||
@ cdecl EmptyClipboard() X11DRV_EmptyClipboard
|
||||
@ cdecl EndClipboardUpdate(long) X11DRV_EndClipboardUpdate
|
||||
@ cdecl EnumClipboardFormats(long) X11DRV_EnumClipboardFormats
|
||||
@ cdecl ForceWindowRaise(long) X11DRV_ForceWindowRaise
|
||||
@ cdecl GetClipboardData(long ptr ptr) X11DRV_GetClipboardData
|
||||
@ cdecl GetClipboardFormatName(long str long) X11DRV_GetClipboardFormatName
|
||||
@ cdecl GetDC(long long long long) X11DRV_GetDC
|
||||
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
|
||||
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
|
||||
@ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat
|
||||
@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC
|
||||
@ cdecl ResetSelectionOwner(long long) X11DRV_ResetSelectionOwner
|
||||
@ cdecl ScrollDC(long long long ptr ptr long ptr) X11DRV_ScrollDC
|
||||
@ cdecl ScrollWindowEx(long long long ptr ptr long ptr long) X11DRV_ScrollWindowEx
|
||||
@ cdecl SetClipboardData(long long long) X11DRV_SetClipboardData
|
||||
@ cdecl SetFocus(long) X11DRV_SetFocus
|
||||
@ cdecl SetParent(long long) X11DRV_SetParent
|
||||
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
|
||||
@ cdecl SetWindowPos(ptr) X11DRV_SetWindowPos
|
||||
@ cdecl SetWindowRgn(long long long) X11DRV_SetWindowRgn
|
||||
@ cdecl SetWindowIcon(long long long) X11DRV_SetWindowIcon
|
||||
@ cdecl SetWindowStyle(ptr long) X11DRV_SetWindowStyle
|
||||
@ cdecl SetWindowText(long wstr) X11DRV_SetWindowText
|
||||
@ cdecl ShowWindow(long long) X11DRV_ShowWindow
|
||||
@ cdecl SysCommandSizeMove(long long) X11DRV_SysCommandSizeMove
|
||||
@ cdecl AcquireClipboard() X11DRV_AcquireClipboard
|
||||
@ cdecl ReleaseClipboard() X11DRV_ReleaseClipboard
|
||||
@ cdecl SetClipboardData(long) X11DRV_SetClipboardData
|
||||
@ cdecl GetClipboardData(long) X11DRV_GetClipboardData
|
||||
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
|
||||
@ cdecl RegisterClipboardFormat(str) X11DRV_RegisterClipboardFormat
|
||||
@ cdecl GetClipboardFormatName(long str long) X11DRV_GetClipboardFormatName
|
||||
@ cdecl IsSelectionOwner() X11DRV_IsSelectionOwner
|
||||
@ cdecl ResetSelectionOwner(ptr long) X11DRV_ResetSelectionOwner
|
||||
|
||||
# X11 locks
|
||||
@ cdecl -norelay wine_tsx11_lock()
|
||||
|
|
|
@ -362,6 +362,13 @@ static void process_attach(void)
|
|||
ExitProcess(1);
|
||||
}
|
||||
|
||||
/* Initialize clipboard */
|
||||
if (!X11DRV_InitClipboard( display ))
|
||||
{
|
||||
ERR( "Couldn't Initialize clipboard.\n" );
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBXXF86VM
|
||||
/* initialize XVidMode */
|
||||
X11DRV_XF86VM_Init();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1996 Alex Korobka
|
||||
* Copyright 1999 Noel Borthwick
|
||||
* Copyright 2003 Ulrich Czekalla for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -22,29 +23,14 @@
|
|||
#define __WINE_CLIPBOARD_H
|
||||
|
||||
#include "windef.h"
|
||||
#include "wine/windef16.h"
|
||||
|
||||
struct tagWND;
|
||||
|
||||
typedef struct tagWINE_CLIPFORMAT {
|
||||
UINT wFormatID;
|
||||
UINT wRefCount;
|
||||
BOOL wDataPresent;
|
||||
LPSTR Name;
|
||||
HANDLE16 hData16;
|
||||
HANDLE hDataSrc32;
|
||||
HANDLE hData32;
|
||||
ULONG drvData;
|
||||
struct tagWINE_CLIPFORMAT *PrevFormat;
|
||||
struct tagWINE_CLIPFORMAT *NextFormat;
|
||||
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
|
||||
|
||||
extern LPWINE_CLIPFORMAT CLIPBOARD_LookupFormat( WORD wID );
|
||||
extern BOOL CLIPBOARD_IsCacheRendered();
|
||||
extern void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange);
|
||||
extern void CLIPBOARD_EmptyCache( BOOL bChange );
|
||||
extern BOOL CLIPBOARD_IsPresent(WORD wFormat);
|
||||
extern char * CLIPBOARD_GetFormatName(UINT wFormat, LPSTR buf, INT size);
|
||||
extern void CLIPBOARD_ReleaseOwner();
|
||||
typedef struct tagCLIPBOARDINFO
|
||||
{
|
||||
HWND hWndOpen;
|
||||
HWND hWndOwner;
|
||||
HWND hWndViewer;
|
||||
UINT seqno;
|
||||
UINT flags;
|
||||
} CLIPBOARDINFO, *LPCLIPBOARDINFO;
|
||||
|
||||
#endif /* __WINE_CLIPBOARD_H */
|
||||
|
|
|
@ -82,15 +82,17 @@ typedef struct tagUSER_DRIVER {
|
|||
BOOL (*pGetScreenSaveActive)(void);
|
||||
void (*pSetScreenSaveActive)(BOOL);
|
||||
/* clipboard functions */
|
||||
void (*pAcquireClipboard)(void); /* Acquire selection */
|
||||
void (*pReleaseClipboard)(void); /* Release selection */
|
||||
void (*pSetClipboardData)(UINT); /* Set specified selection data */
|
||||
BOOL (*pGetClipboardData)(UINT); /* Get specified selection data */
|
||||
void (*pAcquireClipboard)(HWND); /* Acquire selection */
|
||||
BOOL (*pCountClipboardFormats)(void); /* Count available clipboard formats */
|
||||
void (*pEmptyClipboard)(void); /* Empty clipboard data */
|
||||
BOOL (*pEndClipboardUpdate)(void); /* End clipboard update */
|
||||
BOOL (*pEnumClipboardFormats)(UINT); /* Enumerate clipboard formats */
|
||||
BOOL (*pGetClipboardData)(UINT, HANDLE16*, HANDLE*); /* Get specified selection data */
|
||||
BOOL (*pGetClipboardFormatName)(UINT, LPSTR, UINT); /* Get a clipboard format name */
|
||||
BOOL (*pIsClipboardFormatAvailable)(UINT); /* Check if specified format is available */
|
||||
INT (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
|
||||
BOOL (*pGetClipboardFormatName)(UINT, LPSTR, UINT); /* Get a clipboard format name */
|
||||
BOOL (*pIsSelectionOwner)(void); /* Check if we own the selection */
|
||||
void (*pResetSelectionOwner)(HWND, BOOL);
|
||||
BOOL (*pSetClipboardData)(UINT, HANDLE16, HANDLE); /* Set specified selection data */
|
||||
/* display modes */
|
||||
LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
|
||||
BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
|
||||
|
@ -163,6 +165,8 @@ extern INT SYSPARAMS_GetMouseButtonSwap( void );
|
|||
|
||||
extern HPALETTE WINAPI SelectPalette( HDC hDC, HPALETTE hPal, BOOL bForceBackground );
|
||||
|
||||
extern BOOL CLIPBOARD_ReleaseOwner(void);
|
||||
|
||||
extern DWORD USER16_AlertableWait;
|
||||
|
||||
/* HANDLE16 <-> HANDLE conversions */
|
||||
|
|
|
@ -3041,6 +3041,36 @@ struct get_next_hook_reply
|
|||
};
|
||||
|
||||
|
||||
|
||||
struct set_clipboard_info_request
|
||||
{
|
||||
struct request_header __header;
|
||||
unsigned int flags;
|
||||
user_handle_t clipboard;
|
||||
user_handle_t owner;
|
||||
user_handle_t viewer;
|
||||
unsigned int seqno;
|
||||
};
|
||||
struct set_clipboard_info_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
unsigned int flags;
|
||||
user_handle_t old_clipboard;
|
||||
user_handle_t old_owner;
|
||||
user_handle_t old_viewer;
|
||||
unsigned int seqno;
|
||||
};
|
||||
|
||||
#define SET_CB_OPEN 0x001
|
||||
#define SET_CB_OWNER 0x002
|
||||
#define SET_CB_VIEWER 0x004
|
||||
#define SET_CB_SEQNO 0x008
|
||||
#define SET_CB_RELOWNER 0x010
|
||||
#define SET_CB_CLOSE 0x020
|
||||
#define CB_OPEN 0x040
|
||||
#define CB_OWNER 0x080
|
||||
|
||||
|
||||
enum request
|
||||
{
|
||||
REQ_new_process,
|
||||
|
@ -3218,6 +3248,7 @@ enum request
|
|||
REQ_start_hook_chain,
|
||||
REQ_finish_hook_chain,
|
||||
REQ_get_next_hook,
|
||||
REQ_set_clipboard_info,
|
||||
REQ_NB_REQUESTS
|
||||
};
|
||||
|
||||
|
@ -3400,6 +3431,7 @@ union generic_request
|
|||
struct start_hook_chain_request start_hook_chain_request;
|
||||
struct finish_hook_chain_request finish_hook_chain_request;
|
||||
struct get_next_hook_request get_next_hook_request;
|
||||
struct set_clipboard_info_request set_clipboard_info_request;
|
||||
};
|
||||
union generic_reply
|
||||
{
|
||||
|
@ -3580,8 +3612,9 @@ union generic_reply
|
|||
struct start_hook_chain_reply start_hook_chain_reply;
|
||||
struct finish_hook_chain_reply finish_hook_chain_reply;
|
||||
struct get_next_hook_reply get_next_hook_reply;
|
||||
struct set_clipboard_info_reply set_clipboard_info_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 111
|
||||
#define SERVER_PROTOCOL_VERSION 112
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -9,6 +9,7 @@ C_SRCS = \
|
|||
async.c \
|
||||
atom.c \
|
||||
change.c \
|
||||
clipboard.c \
|
||||
console.c \
|
||||
context_i386.c \
|
||||
context_powerpc.c \
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Server-side clipboard management
|
||||
*
|
||||
* Copyright (C) 2002 Ulrich Czekalla
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "request.h"
|
||||
#include "object.h"
|
||||
#include "user.h"
|
||||
|
||||
struct thread *cbthread; /* thread id that has clipboard open */
|
||||
static user_handle_t clipboard; /* window that has clipboard open */
|
||||
|
||||
struct thread *cbowner; /* thread id that owns the clipboard */
|
||||
static user_handle_t owner; /* window that owns the clipboard data */
|
||||
|
||||
static user_handle_t viewer; /* first window in clipboard viewer list */
|
||||
static unsigned int seqno; /* clipboard change sequence number */
|
||||
static time_t seqnots; /* time stamp of last seqno increment */
|
||||
|
||||
#define MINUPDATELAPSE 2
|
||||
|
||||
/* Called when thread terminates to allow release of clipboard */
|
||||
void cleanup_clipboard_thread(struct thread *thread)
|
||||
{
|
||||
if (thread == cbthread)
|
||||
{
|
||||
clipboard = 0;
|
||||
cbthread = NULL;
|
||||
}
|
||||
if (thread == cbowner)
|
||||
{
|
||||
owner = 0;
|
||||
cbowner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int set_clipboard_window(user_handle_t win, int clear)
|
||||
{
|
||||
if (cbthread && cbthread != current)
|
||||
{
|
||||
set_error(STATUS_WAS_LOCKED);
|
||||
return 0;
|
||||
}
|
||||
else if (!clear)
|
||||
{
|
||||
clipboard = win;
|
||||
cbthread = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbthread = NULL;
|
||||
clipboard = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int set_clipboard_owner(user_handle_t win, int clear)
|
||||
{
|
||||
if (cbthread == current)
|
||||
{
|
||||
if (!clear)
|
||||
{
|
||||
cbowner = current;
|
||||
owner = win;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbowner = 0;
|
||||
owner = 0;
|
||||
}
|
||||
seqno++;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_error(STATUS_WAS_LOCKED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int get_seqno(void)
|
||||
{
|
||||
time_t tm = time(NULL);
|
||||
|
||||
if (!cbowner && (tm > (seqnots + MINUPDATELAPSE)))
|
||||
{
|
||||
seqnots = tm;
|
||||
seqno++;
|
||||
}
|
||||
return seqno;
|
||||
}
|
||||
|
||||
|
||||
DECL_HANDLER(set_clipboard_info)
|
||||
{
|
||||
reply->old_clipboard = clipboard;
|
||||
reply->old_owner = owner;
|
||||
reply->old_viewer = viewer;
|
||||
|
||||
if (req->flags & SET_CB_OPEN)
|
||||
{
|
||||
if (!set_clipboard_window(req->clipboard, 0))
|
||||
return;
|
||||
}
|
||||
else if (req->flags & SET_CB_CLOSE)
|
||||
{
|
||||
if (!set_clipboard_window(0, 1))
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->flags & SET_CB_OWNER)
|
||||
{
|
||||
if (!set_clipboard_owner(req->owner, 0))
|
||||
return;
|
||||
}
|
||||
else if (req->flags & SET_CB_RELOWNER)
|
||||
{
|
||||
if (!set_clipboard_owner(0, 1))
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->flags & SET_CB_VIEWER)
|
||||
viewer = req->viewer;
|
||||
|
||||
if (req->flags & SET_CB_SEQNO)
|
||||
seqno++;
|
||||
|
||||
reply->seqno = get_seqno();
|
||||
|
||||
if (cbthread == current)
|
||||
reply->flags |= CB_OPEN;
|
||||
|
||||
if (cbowner == current)
|
||||
reply->flags |= CB_OWNER;
|
||||
}
|
|
@ -2124,3 +2124,28 @@ enum message_type
|
|||
int next_unicode; /* is the next a unicode hook? */
|
||||
VARARG(module,unicode_str); /* module name */
|
||||
@END
|
||||
|
||||
|
||||
/* Set/get clipboard information */
|
||||
@REQ(set_clipboard_info)
|
||||
unsigned int flags; /* flags for fields to set (see below) */
|
||||
user_handle_t clipboard; /* clipboard window */
|
||||
user_handle_t owner; /* clipboard owner */
|
||||
user_handle_t viewer; /* first clipboard viewer */
|
||||
unsigned int seqno; /* change sequence number */
|
||||
@REPLY
|
||||
unsigned int flags; /* status flags (see below) */
|
||||
user_handle_t old_clipboard; /* old clipboard window */
|
||||
user_handle_t old_owner; /* old clipboard owner */
|
||||
user_handle_t old_viewer; /* old clipboard viewer */
|
||||
unsigned int seqno; /* current sequence number */
|
||||
@END
|
||||
|
||||
#define SET_CB_OPEN 0x001
|
||||
#define SET_CB_OWNER 0x002
|
||||
#define SET_CB_VIEWER 0x004
|
||||
#define SET_CB_SEQNO 0x008
|
||||
#define SET_CB_RELOWNER 0x010
|
||||
#define SET_CB_CLOSE 0x020
|
||||
#define CB_OPEN 0x040
|
||||
#define CB_OWNER 0x080
|
||||
|
|
|
@ -278,6 +278,7 @@ DECL_HANDLER(remove_hook);
|
|||
DECL_HANDLER(start_hook_chain);
|
||||
DECL_HANDLER(finish_hook_chain);
|
||||
DECL_HANDLER(get_next_hook);
|
||||
DECL_HANDLER(set_clipboard_info);
|
||||
|
||||
#ifdef WANT_REQUEST_HANDLERS
|
||||
|
||||
|
@ -459,6 +460,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_start_hook_chain,
|
||||
(req_handler)req_finish_hook_chain,
|
||||
(req_handler)req_get_next_hook,
|
||||
(req_handler)req_set_clipboard_info,
|
||||
};
|
||||
#endif /* WANT_REQUEST_HANDLERS */
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ static void cleanup_thread( struct thread *thread )
|
|||
if (thread->wait_fd) release_object( thread->wait_fd );
|
||||
if (thread->hooks) release_object( thread->hooks );
|
||||
free_msg_queue( thread );
|
||||
cleanup_clipboard_thread(thread);
|
||||
destroy_thread_windows( thread );
|
||||
for (i = 0; i < MAX_INFLIGHT_FDS; i++)
|
||||
{
|
||||
|
|
|
@ -2458,6 +2458,24 @@ static void dump_get_next_hook_reply( const struct get_next_hook_reply *req )
|
|||
dump_varargs_unicode_str( cur_size );
|
||||
}
|
||||
|
||||
static void dump_set_clipboard_info_request( const struct set_clipboard_info_request *req )
|
||||
{
|
||||
fprintf( stderr, " flags=%08x,", req->flags );
|
||||
fprintf( stderr, " clipboard=%p,", req->clipboard );
|
||||
fprintf( stderr, " owner=%p,", req->owner );
|
||||
fprintf( stderr, " viewer=%p,", req->viewer );
|
||||
fprintf( stderr, " seqno=%08x", req->seqno );
|
||||
}
|
||||
|
||||
static void dump_set_clipboard_info_reply( const struct set_clipboard_info_reply *req )
|
||||
{
|
||||
fprintf( stderr, " flags=%08x,", req->flags );
|
||||
fprintf( stderr, " old_clipboard=%p,", req->old_clipboard );
|
||||
fprintf( stderr, " old_owner=%p,", req->old_owner );
|
||||
fprintf( stderr, " old_viewer=%p,", req->old_viewer );
|
||||
fprintf( stderr, " seqno=%08x", req->seqno );
|
||||
}
|
||||
|
||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_new_process_request,
|
||||
(dump_func)dump_get_new_process_info_request,
|
||||
|
@ -2634,6 +2652,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_start_hook_chain_request,
|
||||
(dump_func)dump_finish_hook_chain_request,
|
||||
(dump_func)dump_get_next_hook_request,
|
||||
(dump_func)dump_set_clipboard_info_request,
|
||||
};
|
||||
|
||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
|
@ -2812,6 +2831,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_start_hook_chain_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_get_next_hook_reply,
|
||||
(dump_func)dump_set_clipboard_info_reply,
|
||||
};
|
||||
|
||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
|
@ -2990,6 +3010,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"start_hook_chain",
|
||||
"finish_hook_chain",
|
||||
"get_next_hook",
|
||||
"set_clipboard_info",
|
||||
};
|
||||
|
||||
/* ### make_requests end ### */
|
||||
|
|
|
@ -42,6 +42,10 @@ extern user_handle_t get_user_full_handle( user_handle_t handle );
|
|||
extern void *free_user_handle( user_handle_t handle );
|
||||
extern void *next_user_handle( user_handle_t *handle, enum user_object type );
|
||||
|
||||
/* clipboard functions */
|
||||
|
||||
extern void cleanup_clipboard_thread( struct thread *thread );
|
||||
|
||||
/* hook functions */
|
||||
|
||||
extern void close_global_hooks(void);
|
||||
|
|
1558
windows/clipboard.c
1558
windows/clipboard.c
File diff suppressed because it is too large
Load Diff
|
@ -1515,6 +1515,9 @@ BOOL WINAPI DestroyWindow( HWND hwnd )
|
|||
WIN_SendDestroyMsg( hwnd );
|
||||
if (!IsWindow( hwnd )) return TRUE;
|
||||
|
||||
if (GetClipboardOwner() == hwnd)
|
||||
CLIPBOARD_ReleaseOwner();
|
||||
|
||||
/* Unlink now so we won't bother with the children later on */
|
||||
|
||||
WIN_UnlinkWindow( hwnd );
|
||||
|
|
Loading…
Reference in New Issue