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

clipboard even if they are not the clipboard owners.
This commit is contained in:
Ulrich Czekalla 2004-05-06 23:40:30 +00:00 committed by Alexandre Julliard
parent 56193ecc36
commit b41466b3b1
4 changed files with 75 additions and 28 deletions

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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;