winex11: Remove the driver-side clipboard data storage.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-09-26 20:24:47 +09:00
parent e9461b4567
commit a46d736012
2 changed files with 3 additions and 415 deletions

View File

@ -102,8 +102,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
#define S_PRIMARY 1
#define S_CLIPBOARD 2
struct tagWINE_CLIPDATA; /* Forward */
typedef BOOL (*EXPORTFUNC)( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
typedef HANDLE (*IMPORTFUNC)( Atom type, const void *data, size_t size );
@ -116,15 +114,8 @@ typedef struct clipboard_format
EXPORTFUNC export;
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
typedef struct tagWINE_CLIPDATA {
struct list entry;
UINT wFormatID;
HANDLE hData;
} WINE_CLIPDATA, *LPWINE_CLIPDATA;
static int selectionAcquired = 0; /* Contains the current selection masks */
static Window selectionWindow = None; /* The top level X window which owns the selection */
static Atom selectionCacheSrc = XA_PRIMARY; /* The selection source from which the clipboard cache was filled */
static HANDLE import_data( Atom type, const void *data, size_t size );
static HANDLE import_enhmetafile( Atom type, const void *data, size_t size );
@ -150,13 +141,8 @@ static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target,
static BOOL export_targets( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static BOOL export_multiple( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display);
static BOOL X11DRV_CLIPBOARD_ReadSelectionData(Display *display, LPWINE_CLIPDATA lpData);
static BOOL X11DRV_CLIPBOARD_ReadProperty( Display *display, Window w, Atom prop,
Atom *type, unsigned char **data, unsigned long *datasize );
static BOOL X11DRV_CLIPBOARD_RenderFormat(Display *display, LPWINE_CLIPDATA lpData);
static void empty_clipboard(void);
/* Clipboard formats */
@ -220,13 +206,6 @@ static struct clipboard_format **current_x11_formats;
static unsigned int nb_current_x11_formats;
/*
* Cached clipboard data.
*/
static struct list data_list = LIST_INIT( data_list );
static UINT ClipDataCount = 0;
/**************************************************************************
* Internal Clipboard implementation methods
**************************************************************************/
@ -475,173 +454,6 @@ void X11DRV_InitClipboard(void)
}
/**************************************************************************
* X11DRV_CLIPBOARD_LookupData
*/
static LPWINE_CLIPDATA X11DRV_CLIPBOARD_LookupData(DWORD wID)
{
WINE_CLIPDATA *data;
LIST_FOR_EACH_ENTRY( data, &data_list, WINE_CLIPDATA, entry )
if (data->wFormatID == wID) return data;
return NULL;
}
/**************************************************************************
* X11DRV_CLIPBOARD_IsProcessOwner
*/
static BOOL X11DRV_CLIPBOARD_IsProcessOwner( HWND *owner )
{
BOOL ret = FALSE;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = 0;
if (!wine_server_call_err( req ))
{
*owner = wine_server_ptr_handle( reply->old_owner );
ret = (reply->flags & CB_PROCESS);
}
}
SERVER_END_REQ;
return ret;
}
/**************************************************************************
* X11DRV_CLIPBOARD_ReleaseOwnership
*/
static BOOL X11DRV_CLIPBOARD_ReleaseOwnership(void)
{
BOOL ret;
SERVER_START_REQ( set_clipboard_info )
{
req->flags = SET_CB_RELOWNER | SET_CB_SEQNO;
ret = !wine_server_call_err( req );
}
SERVER_END_REQ;
return ret;
}
/**************************************************************************
* X11DRV_CLIPBOARD_InsertClipboardData
*
* Caller *must* have the clipboard open and be the owner.
*/
static BOOL X11DRV_CLIPBOARD_InsertClipboardData( UINT wFormatID, HANDLE hData )
{
LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(wFormatID);
TRACE("format=%04x lpData=%p hData=%p\n", wFormatID, lpData, hData);
if (lpData)
{
X11DRV_CLIPBOARD_FreeData(lpData);
lpData->hData = hData;
}
else
{
lpData = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_CLIPDATA));
lpData->wFormatID = wFormatID;
lpData->hData = hData;
list_add_tail( &data_list, &lpData->entry );
ClipDataCount++;
}
return TRUE;
}
/**************************************************************************
* X11DRV_CLIPBOARD_FreeData
*
* Free clipboard data handle.
*/
static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData)
{
TRACE("%04x\n", lpData->wFormatID);
if (!lpData->hData) return;
switch (lpData->wFormatID)
{
case CF_BITMAP:
case CF_DSPBITMAP:
case CF_PALETTE:
DeleteObject(lpData->hData);
break;
case CF_METAFILEPICT:
case CF_DSPMETAFILEPICT:
DeleteMetaFile(((METAFILEPICT *)GlobalLock( lpData->hData ))->hMF );
GlobalFree(lpData->hData);
break;
case CF_ENHMETAFILE:
case CF_DSPENHMETAFILE:
DeleteEnhMetaFile(lpData->hData);
break;
default:
GlobalFree(lpData->hData);
break;
}
lpData->hData = 0;
}
/**************************************************************************
* X11DRV_CLIPBOARD_RenderFormat
*/
static BOOL X11DRV_CLIPBOARD_RenderFormat(Display *display, LPWINE_CLIPDATA lpData)
{
BOOL bret = TRUE;
TRACE(" 0x%04x hData(%p)\n", lpData->wFormatID, lpData->hData);
if (lpData->hData) return bret; /* Already rendered */
if (!selectionAcquired)
{
if (!X11DRV_CLIPBOARD_ReadSelectionData(display, lpData))
{
ERR("Failed to cache clipboard data owned by another process. Format=%04x\n",
lpData->wFormatID);
bret = FALSE;
}
}
else
{
HWND owner = GetClipboardOwner();
if (owner)
{
/* Send a WM_RENDERFORMAT message to notify the owner to render the
* data requested into the clipboard.
*/
TRACE("Sending WM_RENDERFORMAT message to hwnd(%p)\n", owner);
SendMessageW(owner, WM_RENDERFORMAT, lpData->wFormatID, 0);
if (!lpData->hData) bret = FALSE;
}
else
{
ERR("hWndClipOwner is lost!\n");
bret = FALSE;
}
}
return bret;
}
/**************************************************************************
* put_property
*
@ -1233,7 +1045,7 @@ static HANDLE import_targets( Atom type, const void *data, size_t size )
{
TRACE( "property %s -> format %s\n",
debugstr_xatom( properties[i] ), debugstr_format( format->id ));
X11DRV_CLIPBOARD_InsertClipboardData( format->id, 0 );
SetClipboardData( format->id, 0 );
formats[pos++] = format;
}
else TRACE( "property %s (ignoring)\n", debugstr_xatom( properties[i] ));
@ -1323,7 +1135,7 @@ void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom select
/**************************************************************************
* render_format
*/
static BOOL render_format( Display *display, Window win, Atom selection, UINT id )
BOOL render_format( Display *display, Window win, Atom selection, UINT id )
{
unsigned int i;
HANDLE handle = 0;
@ -1332,9 +1144,9 @@ static BOOL render_format( Display *display, Window win, Atom selection, UINT id
{
if (current_x11_formats[i]->id != id) continue;
handle = import_selection( display, win, selection, current_x11_formats[i] );
if (handle) SetClipboardData( id, handle );
break;
}
if (handle) X11DRV_CLIPBOARD_InsertClipboardData( id, handle );
return handle != 0;
}
@ -1893,94 +1705,6 @@ static BOOL export_multiple( Display *display, Window win, Atom prop, Atom targe
}
/**************************************************************************
* X11DRV_CLIPBOARD_QueryAvailableData
*
* Caches the list of data formats available from the current selection.
* This queries the selection owner for the TARGETS property and saves all
* reported property types.
*/
static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display)
{
Window w;
if (selectionAcquired & (S_PRIMARY | S_CLIPBOARD))
{
ERR("Received request to cache selection but process is owner=(%08x)\n",
(unsigned) selectionWindow);
return -1; /* Prevent self request */
}
w = thread_selection_wnd();
if (!w)
{
ERR("No window available to retrieve selection!\n");
return -1;
}
/*
* Query the selection owner for the TARGETS property
*/
if ((use_primary_selection && XGetSelectionOwner(display,XA_PRIMARY)) ||
XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)))
{
struct clipboard_format *format = find_x11_format( x11drv_atom(TARGETS) );
assert( format );
if (use_primary_selection && import_selection( display, w, XA_PRIMARY, format ))
selectionCacheSrc = XA_PRIMARY;
else if (import_selection( display, w, x11drv_atom(CLIPBOARD), format ))
selectionCacheSrc = x11drv_atom(CLIPBOARD);
else
{
HANDLE handle;
format = find_x11_format( XA_STRING );
assert( format );
/* Selection Owner doesn't understand TARGETS, try retrieving XA_STRING */
if (use_primary_selection && (handle = import_selection( display, w, XA_PRIMARY, format )))
{
X11DRV_CLIPBOARD_InsertClipboardData( format->id, handle );
selectionCacheSrc = XA_PRIMARY;
}
else if ((handle = import_selection( display, w, x11drv_atom(CLIPBOARD), format )))
{
X11DRV_CLIPBOARD_InsertClipboardData( format->id, handle );
selectionCacheSrc = x11drv_atom(CLIPBOARD);
}
else
{
WARN("Failed to query selection owner for available data.\n");
return -1;
}
}
return 1;
}
else return 0; /* No selection owner so report 0 targets available */
}
/**************************************************************************
* X11DRV_CLIPBOARD_ReadSelectionData
*
* This method is invoked only when we DO NOT own the X selection
*
* We always get the data from the selection client each time,
* since we have no way of determining if the data in our cache is stale.
*/
static BOOL X11DRV_CLIPBOARD_ReadSelectionData(Display *display, LPWINE_CLIPDATA lpData)
{
Window w = thread_selection_wnd();
if (!w)
{
ERR("No window available to read selection data!\n");
return FALSE;
}
return render_format( display, w, selectionCacheSrc, lpData->wFormatID );
}
/**************************************************************************
* X11DRV_CLIPBOARD_GetProperty
* Gets type, data and size.
@ -2164,26 +1888,9 @@ static void X11DRV_CLIPBOARD_ReleaseSelection(Display *display, Atom selType, Wi
if (selectionAcquired && (w == selectionWindow))
{
HWND owner;
/* completely give up the selection */
TRACE("Lost CLIPBOARD (+PRIMARY) selection\n");
if (X11DRV_CLIPBOARD_IsProcessOwner( &owner ))
{
/* Since we're still the owner, this wasn't initiated by
another Wine process */
if (OpenClipboard(hwnd))
{
/* Destroy private objects */
SendMessageW(owner, WM_DESTROYCLIPBOARD, 0, 0);
/* Give up ownership of the windows clipboard */
X11DRV_CLIPBOARD_ReleaseOwnership();
CloseClipboard();
}
}
if ((selType == x11drv_atom(CLIPBOARD)) && (selectionAcquired & S_PRIMARY))
{
TRACE("Lost clipboard. Check if we need to release PRIMARY\n");
@ -2211,8 +1918,6 @@ static void X11DRV_CLIPBOARD_ReleaseSelection(Display *display, Atom selType, Wi
selectionWindow = None;
empty_clipboard();
/* Reset the selection flags now that we are done */
selectionAcquired = S_NOSELECTION;
}
@ -2326,110 +2031,6 @@ void X11DRV_AcquireClipboard(HWND hWndClipWindow)
}
static void empty_clipboard(void)
{
WINE_CLIPDATA *data, *next;
LIST_FOR_EACH_ENTRY_SAFE( data, next, &data_list, WINE_CLIPDATA, entry )
{
list_remove( &data->entry );
X11DRV_CLIPBOARD_FreeData( data );
HeapFree( GetProcessHeap(), 0, data );
ClipDataCount--;
}
TRACE(" %d entries remaining in cache.\n", ClipDataCount);
}
/**************************************************************************
* X11DRV_EmptyClipboard
*
* Empty cached clipboard data.
*/
void CDECL X11DRV_EmptyClipboard(void)
{
X11DRV_AcquireClipboard( GetOpenClipboardWindow() );
empty_clipboard();
}
/**************************************************************************
* X11DRV_SetClipboardData
*/
BOOL CDECL X11DRV_SetClipboardData(UINT wFormat, HANDLE hData, BOOL owner)
{
return X11DRV_CLIPBOARD_InsertClipboardData( wFormat, hData );
}
/**************************************************************************
* CountClipboardFormats
*/
INT CDECL X11DRV_CountClipboardFormats(void)
{
return ClipDataCount;
}
/**************************************************************************
* X11DRV_EnumClipboardFormats
*/
UINT CDECL X11DRV_EnumClipboardFormats(UINT wFormat)
{
struct list *ptr = NULL;
if (!wFormat)
{
ptr = list_head( &data_list );
}
else
{
LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(wFormat);
if (lpData) ptr = list_next( &data_list, &lpData->entry );
}
if (!ptr) return 0;
return LIST_ENTRY( ptr, WINE_CLIPDATA, entry )->wFormatID;
}
/**************************************************************************
* X11DRV_IsClipboardFormatAvailable
*/
BOOL CDECL X11DRV_IsClipboardFormatAvailable(UINT wFormat)
{
BOOL bRet = FALSE;
if (wFormat != 0 && X11DRV_CLIPBOARD_LookupData(wFormat))
bRet = TRUE;
TRACE("(%04X)- ret(%d)\n", wFormat, bRet);
return bRet;
}
/**************************************************************************
* GetClipboardData (USER.142)
*/
HANDLE CDECL X11DRV_GetClipboardData(UINT wFormat)
{
LPWINE_CLIPDATA lpRender;
TRACE("(%04X)\n", wFormat);
if ((lpRender = X11DRV_CLIPBOARD_LookupData(wFormat)))
{
if ( !lpRender->hData )
X11DRV_CLIPBOARD_RenderFormat(thread_init_display(), lpRender);
TRACE(" returning %p (type %04x)\n", lpRender->hData, lpRender->wFormatID);
return lpRender->hData;
}
return 0;
}
/**************************************************************************
* X11DRV_UpdateClipboard
*/
@ -2442,10 +2043,6 @@ void CDECL X11DRV_UpdateClipboard(void)
now = GetTickCount();
if ((int)(now - last_update) <= SELECTION_UPDATE_DELAY) return;
last_update = now;
empty_clipboard();
if (X11DRV_CLIPBOARD_QueryAvailableData(thread_init_display()) < 0)
ERR("Failed to cache clipboard data owned by another process.\n");
}
@ -2483,9 +2080,6 @@ void X11DRV_ResetSelectionOwner(void)
} while ((hwnd = GetWindow(hwnd, GW_HWNDNEXT)) != NULL);
WARN("Failed to find another thread to take selection ownership. Clipboard data will be lost.\n");
X11DRV_CLIPBOARD_ReleaseOwnership();
empty_clipboard();
}

View File

@ -23,20 +23,14 @@
@ cdecl EnumDisplayMonitors(long ptr ptr long) X11DRV_EnumDisplayMonitors
@ cdecl EnumDisplaySettingsEx(ptr long ptr long) X11DRV_EnumDisplaySettingsEx
@ cdecl GetMonitorInfo(long ptr) X11DRV_GetMonitorInfo
@ cdecl CountClipboardFormats() X11DRV_CountClipboardFormats
@ cdecl CreateDesktopWindow(long) X11DRV_CreateDesktopWindow
@ cdecl CreateWindow(long) X11DRV_CreateWindow
@ cdecl DestroyWindow(long) X11DRV_DestroyWindow
@ cdecl EmptyClipboard() X11DRV_EmptyClipboard
@ cdecl EnumClipboardFormats(long) X11DRV_EnumClipboardFormats
@ cdecl FlashWindowEx(ptr) X11DRV_FlashWindowEx
@ cdecl GetClipboardData(long) X11DRV_GetClipboardData
@ cdecl GetDC(long long long ptr ptr long) X11DRV_GetDC
@ cdecl IsClipboardFormatAvailable(long) X11DRV_IsClipboardFormatAvailable
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) X11DRV_MsgWaitForMultipleObjectsEx
@ cdecl ReleaseDC(long long) X11DRV_ReleaseDC
@ cdecl ScrollDC(long long long long) X11DRV_ScrollDC
@ cdecl SetClipboardData(long long long) X11DRV_SetClipboardData
@ cdecl SetCapture(long long) X11DRV_SetCapture
@ cdecl SetFocus(long) X11DRV_SetFocus
@ cdecl SetLayeredWindowAttributes(long long long long) X11DRV_SetLayeredWindowAttributes