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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
}
TRACE(" %d entries deleted from cache.\n", ClipDataCount); ClipDataCount--;
}
} while (lpNext != lpStart);
}
ClipData = NULL; TRACE(" %d entries remaining in cache.\n", ClipDataCount);
ClipDataCount = 0;
} }
...@@ -2165,12 +2177,29 @@ void X11DRV_EmptyClipboard(void) ...@@ -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 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)
{
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 &= X11DRV_CLIPBOARD_InsertClipboardData(wFormat, hData16, hData32, flags);
bResult = TRUE;
return bResult; return bResult;
} }
......
...@@ -474,6 +474,7 @@ typedef struct tagWINE_CLIPFORMAT { ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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;
}
/* 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; hResult = hData;
bCBHasChanged = TRUE; bCBHasChanged = TRUE;
...@@ -584,13 +592,22 @@ HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData) ...@@ -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;
......
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