Commit b41466b3 authored by Ulrich Czekalla's avatar Ulrich Czekalla Committed by Alexandre Julliard

Allow applications, under certain conditions, to set data into the

clipboard even if they are not the clipboard owners.
parent 56193ecc
......@@ -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 */
INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName);
void X11DRV_EmptyClipboard(void);
void X11DRV_EmptyClipboard(BOOL keepunowned);
void X11DRV_EndClipboardUpdate(void);
HANDLE X11DRV_CLIPBOARD_ImportClipboardData(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)
{
X11DRV_EmptyClipboard();
X11DRV_EmptyClipboard(TRUE);
if (X11DRV_CLIPBOARD_QueryAvailableData(lpcbinfo) < 0)
{
......@@ -1985,7 +1985,7 @@ void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd)
selectionWindow = None;
PrimarySelectionOwner = ClipboardSelectionOwner = 0;
X11DRV_EmptyClipboard();
X11DRV_EmptyClipboard(FALSE);
/* Reset the selection flags now that we are done */
selectionAcquired = S_NOSELECTION;
......@@ -2135,29 +2135,41 @@ void X11DRV_AcquireClipboard(HWND hWndClipWindow)
/**************************************************************************
* X11DRV_EmptyClipboard
*
* Empty cached clipboard data.
*/
void X11DRV_EmptyClipboard(void)
void X11DRV_EmptyClipboard(BOOL keepunowned)
{
if (ClipData)
{
LPWINE_CLIPDATA lpData;
LPWINE_CLIPDATA lpData, lpStart;
LPWINE_CLIPDATA lpNext = ClipData;
TRACE(" called with %d entries in cache.\n", ClipDataCount);
do
{
lpStart = ClipData;
lpData = lpNext;
lpNext = lpData->NextData;
if (!keepunowned || !(lpData->wFlags & CF_FLAG_UNOWNED))
{
lpData->PrevData->NextData = lpData->NextData;
lpData->NextData->PrevData = lpData->PrevData;
if (lpData == ClipData)
ClipData = lpNext != lpData ? lpNext : NULL;
X11DRV_CLIPBOARD_FreeData(lpData);
HeapFree(GetProcessHeap(), 0, lpData);
} while (lpNext != lpData);
}
TRACE(" %d entries deleted from cache.\n", ClipDataCount);
ClipDataCount--;
}
} while (lpNext != lpStart);
}
ClipData = NULL;
ClipDataCount = 0;
TRACE(" %d entries remaining in cache.\n", ClipDataCount);
}
......@@ -2165,12 +2177,29 @@ void X11DRV_EmptyClipboard(void)
/**************************************************************************
* X11DRV_SetClipboardData
*/
BOOL X11DRV_SetClipboardData(UINT wFormat, HANDLE16 hData16, HANDLE hData32)
BOOL X11DRV_SetClipboardData(UINT wFormat, HANDLE16 hData16, HANDLE hData32, BOOL owner)
{
DWORD flags = 0;
BOOL bResult = TRUE;
/* If it's not owned, data can only be set if the format data is not already owned
and its rendering is not delayed */
if (!owner)
{
BOOL bResult = FALSE;
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;
}
if (X11DRV_CLIPBOARD_InsertClipboardData(wFormat, hData16, hData32, 0))
bResult = TRUE;
bResult &= X11DRV_CLIPBOARD_InsertClipboardData(wFormat, hData16, hData32, flags);
return bResult;
}
......
......@@ -474,6 +474,7 @@ typedef struct tagWINE_CLIPFORMAT {
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
#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 */
extern void X11DRV_InitClipboard(void);
......
......@@ -94,7 +94,7 @@ typedef struct tagUSER_DRIVER {
/* clipboard functions */
void (*pAcquireClipboard)(HWND); /* Acquire selection */
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 (*pEnumClipboardFormats)(UINT); /* Enumerate clipboard formats */
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 */
INT (*pRegisterClipboardFormat)(LPCSTR); /* Register a clipboard format */
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 */
LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
......
......@@ -427,7 +427,7 @@ BOOL WINAPI EmptyClipboard(void)
/* Empty the local cache */
if (USER_Driver.pEmptyClipboard)
USER_Driver.pEmptyClipboard();
USER_Driver.pEmptyClipboard(FALSE);
bCBHasChanged = TRUE;
......@@ -557,14 +557,22 @@ HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData)
TRACE("(%04X, %04x) !\n", wFormat, hData);
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
(~cbinfo.flags & CB_OPEN) ||
(~cbinfo.flags & CB_OWNER))
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) || !(cbinfo.flags & CB_OPEN))
{
WARN("Clipboard not opened by calling task!\n");
WARN("Clipboard not opened by calling task. Operation failed.\n");
return 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;
}
else if (USER_Driver.pSetClipboardData &&
USER_Driver.pSetClipboardData(wFormat, hData, 0))
if (USER_Driver.pSetClipboardData &&
USER_Driver.pSetClipboardData(wFormat, hData, 0, cbinfo.flags & CB_OWNER))
{
hResult = hData;
bCBHasChanged = TRUE;
......@@ -584,13 +592,22 @@ HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
TRACE("(%04X, %p) !\n", wFormat, hData);
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
(~cbinfo.flags & CB_OWNER))
if (!CLIPBOARD_GetClipboardInfo(&cbinfo) || !(cbinfo.flags & CB_OPEN))
{
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;
bCBHasChanged = TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment