Allow applications, under certain conditions, to set data into the
clipboard even if they are not the clipboard owners.
This commit is contained in:
parent
56193ecc36
commit
b41466b3b1
|
@ -117,7 +117,7 @@ static Window PrimarySelectionOwner = None; /* The window which owns the prim
|
||||||
static Window ClipboardSelectionOwner = None; /* The window which owns the clipboard selection */
|
static Window ClipboardSelectionOwner = None; /* The window which owns the clipboard selection */
|
||||||
|
|
||||||
INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName);
|
INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName);
|
||||||
void X11DRV_EmptyClipboard(void);
|
void X11DRV_EmptyClipboard(BOOL keepunowned);
|
||||||
void X11DRV_EndClipboardUpdate(void);
|
void X11DRV_EndClipboardUpdate(void);
|
||||||
HANDLE X11DRV_CLIPBOARD_ImportClipboardData(LPBYTE lpdata, UINT cBytes);
|
HANDLE X11DRV_CLIPBOARD_ImportClipboardData(LPBYTE lpdata, UINT cBytes);
|
||||||
HANDLE X11DRV_CLIPBOARD_ImportEnhMetaFile(LPBYTE lpdata, UINT cBytes);
|
HANDLE X11DRV_CLIPBOARD_ImportEnhMetaFile(LPBYTE lpdata, UINT cBytes);
|
||||||
|
@ -719,7 +719,7 @@ static BOOL X11DRV_CLIPBOARD_UpdateCache(LPCLIPBOARDINFO lpcbinfo)
|
||||||
}
|
}
|
||||||
else if (wSeqNo < lpcbinfo->seqno)
|
else if (wSeqNo < lpcbinfo->seqno)
|
||||||
{
|
{
|
||||||
X11DRV_EmptyClipboard();
|
X11DRV_EmptyClipboard(TRUE);
|
||||||
|
|
||||||
if (X11DRV_CLIPBOARD_QueryAvailableData(lpcbinfo) < 0)
|
if (X11DRV_CLIPBOARD_QueryAvailableData(lpcbinfo) < 0)
|
||||||
{
|
{
|
||||||
|
@ -1985,7 +1985,7 @@ void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd)
|
||||||
selectionWindow = None;
|
selectionWindow = None;
|
||||||
PrimarySelectionOwner = ClipboardSelectionOwner = 0;
|
PrimarySelectionOwner = ClipboardSelectionOwner = 0;
|
||||||
|
|
||||||
X11DRV_EmptyClipboard();
|
X11DRV_EmptyClipboard(FALSE);
|
||||||
|
|
||||||
/* Reset the selection flags now that we are done */
|
/* Reset the selection flags now that we are done */
|
||||||
selectionAcquired = S_NOSELECTION;
|
selectionAcquired = S_NOSELECTION;
|
||||||
|
@ -2135,29 +2135,41 @@ void X11DRV_AcquireClipboard(HWND hWndClipWindow)
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* X11DRV_EmptyClipboard
|
* X11DRV_EmptyClipboard
|
||||||
|
*
|
||||||
|
* Empty cached clipboard data.
|
||||||
*/
|
*/
|
||||||
void X11DRV_EmptyClipboard(void)
|
void X11DRV_EmptyClipboard(BOOL keepunowned)
|
||||||
{
|
{
|
||||||
if (ClipData)
|
if (ClipData)
|
||||||
{
|
{
|
||||||
LPWINE_CLIPDATA lpData;
|
LPWINE_CLIPDATA lpData, lpStart;
|
||||||
LPWINE_CLIPDATA lpNext = ClipData;
|
LPWINE_CLIPDATA lpNext = ClipData;
|
||||||
|
|
||||||
|
TRACE(" called with %d entries in cache.\n", ClipDataCount);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
lpStart = ClipData;
|
||||||
lpData = lpNext;
|
lpData = lpNext;
|
||||||
lpNext = lpData->NextData;
|
lpNext = lpData->NextData;
|
||||||
|
|
||||||
|
if (!keepunowned || !(lpData->wFlags & CF_FLAG_UNOWNED))
|
||||||
|
{
|
||||||
lpData->PrevData->NextData = lpData->NextData;
|
lpData->PrevData->NextData = lpData->NextData;
|
||||||
lpData->NextData->PrevData = lpData->PrevData;
|
lpData->NextData->PrevData = lpData->PrevData;
|
||||||
|
|
||||||
|
if (lpData == ClipData)
|
||||||
|
ClipData = lpNext != lpData ? lpNext : NULL;
|
||||||
|
|
||||||
X11DRV_CLIPBOARD_FreeData(lpData);
|
X11DRV_CLIPBOARD_FreeData(lpData);
|
||||||
HeapFree(GetProcessHeap(), 0, lpData);
|
HeapFree(GetProcessHeap(), 0, lpData);
|
||||||
} while (lpNext != lpData);
|
|
||||||
|
ClipDataCount--;
|
||||||
|
}
|
||||||
|
} while (lpNext != lpStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(" %d entries deleted from cache.\n", ClipDataCount);
|
TRACE(" %d entries remaining in cache.\n", ClipDataCount);
|
||||||
|
|
||||||
ClipData = NULL;
|
|
||||||
ClipDataCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2165,12 +2177,29 @@ void X11DRV_EmptyClipboard(void)
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* X11DRV_SetClipboardData
|
* X11DRV_SetClipboardData
|
||||||
*/
|
*/
|
||||||
BOOL X11DRV_SetClipboardData(UINT wFormat, HANDLE16 hData16, HANDLE hData32)
|
BOOL X11DRV_SetClipboardData(UINT wFormat, HANDLE16 hData16, HANDLE hData32, BOOL owner)
|
||||||
{
|
{
|
||||||
BOOL bResult = FALSE;
|
DWORD flags = 0;
|
||||||
|
BOOL bResult = TRUE;
|
||||||
|
|
||||||
if (X11DRV_CLIPBOARD_InsertClipboardData(wFormat, hData16, hData32, 0))
|
/* If it's not owned, data can only be set if the format data is not already owned
|
||||||
bResult = TRUE;
|
and its rendering is not delayed */
|
||||||
|
if (!owner)
|
||||||
|
{
|
||||||
|
CLIPBOARDINFO cbinfo;
|
||||||
|
LPWINE_CLIPDATA lpRender;
|
||||||
|
|
||||||
|
X11DRV_CLIPBOARD_UpdateCache(&cbinfo);
|
||||||
|
|
||||||
|
if ((!hData16 && !hData32) ||
|
||||||
|
((lpRender = X11DRV_CLIPBOARD_LookupData(wFormat)) &&
|
||||||
|
!(lpRender->wFlags & CF_FLAG_UNOWNED)))
|
||||||
|
bResult = FALSE;
|
||||||
|
else
|
||||||
|
flags = CF_FLAG_UNOWNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bResult &= X11DRV_CLIPBOARD_InsertClipboardData(wFormat, hData16, hData32, flags);
|
||||||
|
|
||||||
return bResult;
|
return bResult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,6 +474,7 @@ typedef struct tagWINE_CLIPFORMAT {
|
||||||
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
|
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
|
||||||
|
|
||||||
#define CF_FLAG_BUILTINFMT 1 /* Built-in windows format */
|
#define CF_FLAG_BUILTINFMT 1 /* Built-in windows format */
|
||||||
|
#define CF_FLAG_UNOWNED 2 /* cached data is not owned */
|
||||||
#define CF_FLAG_SYNTHESIZED 8 /* Implicitly converted data */
|
#define CF_FLAG_SYNTHESIZED 8 /* Implicitly converted data */
|
||||||
|
|
||||||
extern void X11DRV_InitClipboard(void);
|
extern void X11DRV_InitClipboard(void);
|
||||||
|
|
|
@ -94,7 +94,7 @@ typedef struct tagUSER_DRIVER {
|
||||||
/* clipboard functions */
|
/* clipboard functions */
|
||||||
void (*pAcquireClipboard)(HWND); /* Acquire selection */
|
void (*pAcquireClipboard)(HWND); /* Acquire selection */
|
||||||
BOOL (*pCountClipboardFormats)(void); /* Count available clipboard formats */
|
BOOL (*pCountClipboardFormats)(void); /* Count available clipboard formats */
|
||||||
void (*pEmptyClipboard)(void); /* Empty clipboard data */
|
void (*pEmptyClipboard)(BOOL); /* Empty clipboard data */
|
||||||
BOOL (*pEndClipboardUpdate)(void); /* End clipboard update */
|
BOOL (*pEndClipboardUpdate)(void); /* End clipboard update */
|
||||||
BOOL (*pEnumClipboardFormats)(UINT); /* Enumerate clipboard formats */
|
BOOL (*pEnumClipboardFormats)(UINT); /* Enumerate clipboard formats */
|
||||||
BOOL (*pGetClipboardData)(UINT, HANDLE16*, HANDLE*); /* Get specified selection data */
|
BOOL (*pGetClipboardData)(UINT, HANDLE16*, HANDLE*); /* Get specified selection data */
|
||||||
|
@ -102,7 +102,7 @@ typedef struct tagUSER_DRIVER {
|
||||||
BOOL (*pIsClipboardFormatAvailable)(UINT); /* Check if specified format is available */
|
BOOL (*pIsClipboardFormatAvailable)(UINT); /* Check if specified format is available */
|
||||||
INT (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
|
INT (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
|
||||||
void (*pResetSelectionOwner)(HWND, BOOL);
|
void (*pResetSelectionOwner)(HWND, BOOL);
|
||||||
BOOL (*pSetClipboardData)(UINT, HANDLE16, HANDLE); /* Set specified selection data */
|
BOOL (*pSetClipboardData)(UINT, HANDLE16, HANDLE, BOOL); /* Set specified selection data */
|
||||||
/* display modes */
|
/* display modes */
|
||||||
LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
|
LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
|
||||||
BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
|
BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
|
||||||
|
|
|
@ -427,7 +427,7 @@ BOOL WINAPI EmptyClipboard(void)
|
||||||
|
|
||||||
/* Empty the local cache */
|
/* Empty the local cache */
|
||||||
if (USER_Driver.pEmptyClipboard)
|
if (USER_Driver.pEmptyClipboard)
|
||||||
USER_Driver.pEmptyClipboard();
|
USER_Driver.pEmptyClipboard(FALSE);
|
||||||
|
|
||||||
bCBHasChanged = TRUE;
|
bCBHasChanged = TRUE;
|
||||||
|
|
||||||
|
@ -557,14 +557,22 @@ HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData)
|
||||||
|
|
||||||
TRACE("(%04X, %04x) !\n", wFormat, hData);
|
TRACE("(%04X, %04x) !\n", wFormat, hData);
|
||||||
|
|
||||||
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
|
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) || !(cbinfo.flags & CB_OPEN))
|
||||||
(~cbinfo.flags & CB_OPEN) ||
|
|
||||||
(~cbinfo.flags & CB_OWNER))
|
|
||||||
{
|
{
|
||||||
WARN("Clipboard not opened by calling task!\n");
|
WARN("Clipboard not opened by calling task. Operation failed.\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else if (USER_Driver.pSetClipboardData &&
|
|
||||||
USER_Driver.pSetClipboardData(wFormat, hData, 0))
|
/* If it's not owned, data can only be set if the format doesn't exists
|
||||||
|
and its rendering is not delayed */
|
||||||
|
if (!(cbinfo.flags & CB_OWNER) && !hData)
|
||||||
|
{
|
||||||
|
WARN("Clipboard not owned by calling task. Operation failed.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USER_Driver.pSetClipboardData &&
|
||||||
|
USER_Driver.pSetClipboardData(wFormat, hData, 0, cbinfo.flags & CB_OWNER))
|
||||||
{
|
{
|
||||||
hResult = hData;
|
hResult = hData;
|
||||||
bCBHasChanged = TRUE;
|
bCBHasChanged = TRUE;
|
||||||
|
@ -584,13 +592,22 @@ HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
|
||||||
|
|
||||||
TRACE("(%04X, %p) !\n", wFormat, hData);
|
TRACE("(%04X, %p) !\n", wFormat, hData);
|
||||||
|
|
||||||
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
|
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) || !(cbinfo.flags & CB_OPEN))
|
||||||
(~cbinfo.flags & CB_OWNER))
|
|
||||||
{
|
{
|
||||||
WARN("Clipboard not owned by calling task!\n");
|
WARN("Clipboard not opened by calling task. Operation failed.\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else if (USER_Driver.pSetClipboardData &&
|
|
||||||
USER_Driver.pSetClipboardData(wFormat, 0, hData))
|
/* If it's not owned, data can only be set if the format isn't
|
||||||
|
available and its rendering is not delayed */
|
||||||
|
if (!(cbinfo.flags & CB_OWNER) && !hData)
|
||||||
|
{
|
||||||
|
WARN("Clipboard not owned by calling task. Operation failed.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USER_Driver.pSetClipboardData &&
|
||||||
|
USER_Driver.pSetClipboardData(wFormat, 0, hData, cbinfo.flags & CB_OWNER))
|
||||||
{
|
{
|
||||||
hResult = hData;
|
hResult = hData;
|
||||||
bCBHasChanged = TRUE;
|
bCBHasChanged = TRUE;
|
||||||
|
|
Loading…
Reference in New Issue