Delay the creation of the X atoms until we really need them, to allow
getting more of them in one call. Use XGetAtomNames to retrieve all the selection atoms at once.
This commit is contained in:
parent
2496c08b76
commit
3f6cb0cc3f
|
@ -58,6 +58,7 @@
|
||||||
* and vice versa. If a native format is available in the selection, it takes
|
* and vice versa. If a native format is available in the selection, it takes
|
||||||
* precedence, in order to avoid unnecessary conversions.
|
* precedence, in order to avoid unnecessary conversions.
|
||||||
*
|
*
|
||||||
|
* FIXME: global format list needs a critical section
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -123,7 +124,7 @@ HANDLE X11DRV_CLIPBOARD_ExportMetaFilePict(Window requestor, Atom aTarget,
|
||||||
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
|
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
|
||||||
HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget,
|
HANDLE X11DRV_CLIPBOARD_ExportEnhMetaFile(Window requestor, Atom aTarget,
|
||||||
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
|
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
|
||||||
static UINT X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop);
|
static WINE_CLIPFORMAT *X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop);
|
||||||
static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, Atom prop);
|
static BOOL X11DRV_CLIPBOARD_ReadSelection(LPWINE_CLIPFORMAT lpData, Window w, Atom prop);
|
||||||
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID);
|
static BOOL X11DRV_CLIPBOARD_RenderSynthesizedText(UINT wFormatID);
|
||||||
static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
|
static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
|
||||||
|
@ -257,11 +258,10 @@ static UINT wSeqNo = 0;
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* X11DRV_InitClipboard
|
* X11DRV_InitClipboard
|
||||||
*/
|
*/
|
||||||
void X11DRV_InitClipboard(Display *display)
|
void X11DRV_InitClipboard(void)
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
LPWINE_CLIPFORMAT lpFormat = ClipFormats;
|
|
||||||
|
|
||||||
if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Clipboard", &hkey))
|
if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Clipboard", &hkey))
|
||||||
{
|
{
|
||||||
|
@ -272,18 +272,6 @@ void X11DRV_InitClipboard(Display *display)
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register known formats */
|
|
||||||
while (lpFormat)
|
|
||||||
{
|
|
||||||
if (!lpFormat->wFormatID)
|
|
||||||
lpFormat->wFormatID = GlobalAddAtomA(lpFormat->Name);
|
|
||||||
|
|
||||||
if (!lpFormat->drvData)
|
|
||||||
lpFormat->drvData = TSXInternAtom(display, lpFormat->Name, False);
|
|
||||||
|
|
||||||
lpFormat = lpFormat->NextFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register known mapping between window formats and X properties */
|
/* Register known mapping between window formats and X properties */
|
||||||
for (i = 0; i < sizeof(PropertyFormatMap)/sizeof(PropertyFormatMap[0]); i++)
|
for (i = 0; i < sizeof(PropertyFormatMap)/sizeof(PropertyFormatMap[0]); i++)
|
||||||
X11DRV_CLIPBOARD_InsertClipboardFormat(PropertyFormatMap[i].lpszFormat,
|
X11DRV_CLIPBOARD_InsertClipboardFormat(PropertyFormatMap[i].lpszFormat,
|
||||||
|
@ -291,6 +279,64 @@ void X11DRV_InitClipboard(Display *display)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* intern_atoms
|
||||||
|
*
|
||||||
|
* Intern atoms for formats that don't have one yet.
|
||||||
|
*/
|
||||||
|
static void intern_atoms(void)
|
||||||
|
{
|
||||||
|
LPWINE_CLIPFORMAT format;
|
||||||
|
int i, count;
|
||||||
|
char **names;
|
||||||
|
Atom *atoms;
|
||||||
|
|
||||||
|
for (format = ClipFormats, count = 0; format; format = format->NextFormat)
|
||||||
|
if (!format->drvData) count++;
|
||||||
|
if (!count) return;
|
||||||
|
|
||||||
|
names = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*names) );
|
||||||
|
atoms = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*atoms) );
|
||||||
|
|
||||||
|
for (format = ClipFormats, i = 0; format; format = format->NextFormat)
|
||||||
|
if (!format->drvData) names[i++] = format->Name;
|
||||||
|
|
||||||
|
wine_tsx11_lock();
|
||||||
|
XInternAtoms( thread_display(), names, count, False, atoms );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
|
||||||
|
for (format = ClipFormats, i = 0; format; format = format->NextFormat)
|
||||||
|
if (!format->drvData) format->drvData = atoms[i];
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, names );
|
||||||
|
HeapFree( GetProcessHeap(), 0, atoms );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* register_format
|
||||||
|
*
|
||||||
|
* Register a custom X clipboard format.
|
||||||
|
*/
|
||||||
|
static WINE_CLIPFORMAT *register_format( LPCSTR FormatName, Atom prop )
|
||||||
|
{
|
||||||
|
LPWINE_CLIPFORMAT lpFormat = ClipFormats;
|
||||||
|
|
||||||
|
TRACE("'%s'\n", FormatName);
|
||||||
|
|
||||||
|
/* walk format chain to see if it's already registered */
|
||||||
|
while (lpFormat)
|
||||||
|
{
|
||||||
|
if ( !strcasecmp(lpFormat->Name, FormatName) &&
|
||||||
|
(lpFormat->wFlags & CF_FLAG_BUILTINFMT) == 0)
|
||||||
|
return lpFormat;
|
||||||
|
lpFormat = lpFormat->NextFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return X11DRV_CLIPBOARD_InsertClipboardFormat(FormatName, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* X11DRV_CLIPBOARD_LookupFormat
|
* X11DRV_CLIPBOARD_LookupFormat
|
||||||
*/
|
*/
|
||||||
|
@ -305,7 +351,7 @@ LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupFormat(WORD wID)
|
||||||
|
|
||||||
lpFormat = lpFormat->NextFormat;
|
lpFormat = lpFormat->NextFormat;
|
||||||
}
|
}
|
||||||
|
if (!lpFormat->drvData) intern_atoms();
|
||||||
return lpFormat;
|
return lpFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,18 +360,22 @@ LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupFormat(WORD wID)
|
||||||
* X11DRV_CLIPBOARD_LookupProperty
|
* X11DRV_CLIPBOARD_LookupProperty
|
||||||
*/
|
*/
|
||||||
LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupProperty(UINT drvData)
|
LPWINE_CLIPFORMAT X11DRV_CLIPBOARD_LookupProperty(UINT drvData)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
LPWINE_CLIPFORMAT lpFormat = ClipFormats;
|
LPWINE_CLIPFORMAT lpFormat = ClipFormats;
|
||||||
|
BOOL need_intern = FALSE;
|
||||||
|
|
||||||
while(lpFormat)
|
while(lpFormat)
|
||||||
{
|
{
|
||||||
if (lpFormat->drvData == drvData)
|
if (lpFormat->drvData == drvData) return lpFormat;
|
||||||
break;
|
if (!lpFormat->drvData) need_intern = TRUE;
|
||||||
|
|
||||||
lpFormat = lpFormat->NextFormat;
|
lpFormat = lpFormat->NextFormat;
|
||||||
}
|
}
|
||||||
|
if (!need_intern) return NULL;
|
||||||
return lpFormat;
|
intern_atoms();
|
||||||
|
/* restart the search for the new atoms */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -400,7 +450,7 @@ LPWINE_CLIPDATA X11DRV_CLIPBOARD_LookupData(DWORD wID)
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* InsertClipboardFormat
|
* InsertClipboardFormat
|
||||||
*/
|
*/
|
||||||
static UINT X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop)
|
static WINE_CLIPFORMAT *X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop)
|
||||||
{
|
{
|
||||||
LPWINE_CLIPFORMAT lpFormat;
|
LPWINE_CLIPFORMAT lpFormat;
|
||||||
LPWINE_CLIPFORMAT lpNewFormat;
|
LPWINE_CLIPFORMAT lpNewFormat;
|
||||||
|
@ -412,14 +462,14 @@ static UINT X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop)
|
||||||
if(lpNewFormat == NULL)
|
if(lpNewFormat == NULL)
|
||||||
{
|
{
|
||||||
WARN("No more memory for a new format!\n");
|
WARN("No more memory for a new format!\n");
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(lpNewFormat->Name = HeapAlloc(GetProcessHeap(), 0, strlen(FormatName)+1)))
|
if (!(lpNewFormat->Name = HeapAlloc(GetProcessHeap(), 0, strlen(FormatName)+1)))
|
||||||
{
|
{
|
||||||
WARN("No more memory for the new format name!\n");
|
WARN("No more memory for the new format name!\n");
|
||||||
HeapFree(GetProcessHeap(), 0, lpNewFormat);
|
HeapFree(GetProcessHeap(), 0, lpNewFormat);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(lpNewFormat->Name, FormatName);
|
strcpy(lpNewFormat->Name, FormatName);
|
||||||
|
@ -442,7 +492,7 @@ static UINT X11DRV_CLIPBOARD_InsertClipboardFormat(LPCSTR FormatName, Atom prop)
|
||||||
TRACE("Registering format(%d): %s drvData %d\n",
|
TRACE("Registering format(%d): %s drvData %d\n",
|
||||||
lpNewFormat->wFormatID, FormatName, lpNewFormat->drvData);
|
lpNewFormat->wFormatID, FormatName, lpNewFormat->drvData);
|
||||||
|
|
||||||
return lpNewFormat->wFormatID;
|
return lpNewFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1358,15 +1408,16 @@ static int X11DRV_CLIPBOARD_QueryAvailableData(LPCLIPBOARDINFO lpcbinfo)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACE("Type %s,Format %d,nItems %ld, Remain %ld\n",
|
TRACE("Type %lx,Format %d,nItems %ld, Remain %ld\n",
|
||||||
TSXGetAtomName(display,atype),aformat,cSelectionTargets, remain);
|
atype, aformat, cSelectionTargets, remain);
|
||||||
/*
|
/*
|
||||||
* The TARGETS property should have returned us a list of atoms
|
* The TARGETS property should have returned us a list of atoms
|
||||||
* corresponding to each selection target format supported.
|
* corresponding to each selection target format supported.
|
||||||
*/
|
*/
|
||||||
if ((atype == XA_ATOM || atype == x11drv_atom(TARGETS)) && aformat == 32)
|
if ((atype == XA_ATOM || atype == x11drv_atom(TARGETS)) && aformat == 32)
|
||||||
{
|
{
|
||||||
INT i;
|
INT i, nb_atoms = 0;
|
||||||
|
Atom *atoms = NULL;
|
||||||
|
|
||||||
/* Cache these formats in the clipboard cache */
|
/* Cache these formats in the clipboard cache */
|
||||||
for (i = 0; i < cSelectionTargets; i++)
|
for (i = 0; i < cSelectionTargets; i++)
|
||||||
|
@ -1378,27 +1429,48 @@ static int X11DRV_CLIPBOARD_QueryAvailableData(LPCLIPBOARDINFO lpcbinfo)
|
||||||
|
|
||||||
if (!lpFormat)
|
if (!lpFormat)
|
||||||
{
|
{
|
||||||
LPSTR lpName = TSXGetAtomName(display, targetList[i]);
|
/* add it to the list of atoms that we don't know about yet */
|
||||||
X11DRV_RegisterClipboardFormat(lpName);
|
if (!atoms) atoms = HeapAlloc( GetProcessHeap(), 0,
|
||||||
|
(cSelectionTargets - i) * sizeof(*atoms) );
|
||||||
lpFormat = X11DRV_CLIPBOARD_LookupProperty(targetList[i]);
|
if (atoms) atoms[nb_atoms++] = targetList[i];
|
||||||
|
}
|
||||||
if (!lpFormat)
|
else
|
||||||
{
|
{
|
||||||
ERR("Failed to cache %s property\n", lpName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSXFree(lpName);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Atom#%d Property(%d): --> FormatID(%d) %s\n",
|
TRACE("Atom#%d Property(%d): --> FormatID(%d) %s\n",
|
||||||
i, lpFormat->drvData, lpFormat->wFormatID, lpFormat->Name);
|
i, lpFormat->drvData, lpFormat->wFormatID, lpFormat->Name);
|
||||||
|
|
||||||
X11DRV_CLIPBOARD_InsertClipboardData(lpFormat->wFormatID, 0, 0, 0);
|
X11DRV_CLIPBOARD_InsertClipboardData(lpFormat->wFormatID, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* query all unknown atoms in one go */
|
||||||
|
if (atoms)
|
||||||
|
{
|
||||||
|
char **names = HeapAlloc( GetProcessHeap(), 0, nb_atoms * sizeof(*names) );
|
||||||
|
if (names)
|
||||||
|
{
|
||||||
|
wine_tsx11_lock();
|
||||||
|
XGetAtomNames( display, atoms, nb_atoms, names );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
for (i = 0; i < nb_atoms; i++)
|
||||||
|
{
|
||||||
|
WINE_CLIPFORMAT *lpFormat = register_format( names[i], atoms[i] );
|
||||||
|
if (!lpFormat)
|
||||||
|
{
|
||||||
|
ERR("Failed to cache %s property\n", names[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TRACE("Atom#%d Property(%d): --> FormatID(%d) %s\n",
|
||||||
|
i, lpFormat->drvData, lpFormat->wFormatID, lpFormat->Name);
|
||||||
|
X11DRV_CLIPBOARD_InsertClipboardData(lpFormat->wFormatID, 0, 0, 0);
|
||||||
|
}
|
||||||
|
wine_tsx11_lock();
|
||||||
|
for (i = 0; i < nb_atoms; i++) XFree( names[i] );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
HeapFree( GetProcessHeap(), 0, names );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Free the list of targets */
|
/* Free the list of targets */
|
||||||
TSXFree(targetList);
|
TSXFree(targetList);
|
||||||
}
|
}
|
||||||
|
@ -1808,29 +1880,11 @@ static BOOL X11DRV_CLIPBOARD_IsSelectionOwner(void)
|
||||||
*/
|
*/
|
||||||
INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName)
|
INT X11DRV_RegisterClipboardFormat(LPCSTR FormatName)
|
||||||
{
|
{
|
||||||
LPWINE_CLIPFORMAT lpFormat = ClipFormats;
|
LPWINE_CLIPFORMAT lpFormat;
|
||||||
Atom prop;
|
|
||||||
|
|
||||||
if (FormatName == NULL)
|
if (FormatName == NULL) return 0;
|
||||||
return 0;
|
if (!(lpFormat = register_format( FormatName, 0 ))) return 0;
|
||||||
|
|
||||||
TRACE("('%s') !\n", FormatName);
|
|
||||||
|
|
||||||
/* walk format chain to see if it's already registered */
|
|
||||||
while(TRUE)
|
|
||||||
{
|
|
||||||
if ( !strcasecmp(lpFormat->Name, FormatName) &&
|
|
||||||
(lpFormat->wFlags & CF_FLAG_BUILTINFMT) == 0)
|
|
||||||
return lpFormat->wFormatID;
|
return lpFormat->wFormatID;
|
||||||
|
|
||||||
if (!lpFormat->NextFormat)
|
|
||||||
break;
|
|
||||||
|
|
||||||
lpFormat = lpFormat->NextFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
prop = TSXInternAtom( thread_display(), FormatName, False );
|
|
||||||
return X11DRV_CLIPBOARD_InsertClipboardFormat(FormatName, prop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -726,7 +726,7 @@ static void create_desktop( Display *display, WND *wndPtr )
|
||||||
SetPropA( wndPtr->hwndSelf, client_window_atom, (HANDLE)root_window );
|
SetPropA( wndPtr->hwndSelf, client_window_atom, (HANDLE)root_window );
|
||||||
SetPropA( wndPtr->hwndSelf, "__wine_x11_visual_id", (HANDLE)XVisualIDFromVisual(visual) );
|
SetPropA( wndPtr->hwndSelf, "__wine_x11_visual_id", (HANDLE)XVisualIDFromVisual(visual) );
|
||||||
|
|
||||||
X11DRV_InitClipboard( display );
|
X11DRV_InitClipboard();
|
||||||
|
|
||||||
if (root_window != DefaultRootWindow(display)) X11DRV_create_desktop_thread();
|
if (root_window != DefaultRootWindow(display)) X11DRV_create_desktop_thread();
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,7 +448,7 @@ typedef struct tagWINE_CLIPFORMAT {
|
||||||
#define CF_FLAG_BUILTINFMT 1 /* Built-in windows format */
|
#define CF_FLAG_BUILTINFMT 1 /* Built-in windows format */
|
||||||
#define CF_FLAG_SYNTHESIZED 8 /* Implicitly converted data */
|
#define CF_FLAG_SYNTHESIZED 8 /* Implicitly converted data */
|
||||||
|
|
||||||
extern void X11DRV_InitClipboard(Display *display);
|
extern void X11DRV_InitClipboard(void);
|
||||||
extern void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd);
|
extern void X11DRV_CLIPBOARD_ReleaseSelection(Atom selType, Window w, HWND hwnd);
|
||||||
extern INT X11DRV_CountClipboardFormats(void);
|
extern INT X11DRV_CountClipboardFormats(void);
|
||||||
extern UINT X11DRV_EnumClipboardFormats(UINT wFormat);
|
extern UINT X11DRV_EnumClipboardFormats(UINT wFormat);
|
||||||
|
|
Loading…
Reference in New Issue