Alexandre Julliard : winex11: Add helper functions to find and register X11 clipboard formats.
Alexandre Julliard
julliard at winehq.org
Thu Sep 22 10:00:02 CDT 2016
Module: wine
Branch: master
Commit: 242673589b792f8eda1bf2d621000238e6d87ff2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=242673589b792f8eda1bf2d621000238e6d87ff2
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Sep 22 15:04:33 2016 +0900
winex11: Add helper functions to find and register X11 clipboard formats.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winex11.drv/clipboard.c | 135 +++++++++++++++++++++++--------------------
1 file changed, 73 insertions(+), 62 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 34ca1bd..caa0348 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -305,6 +305,17 @@ static const char *debugstr_xatom( Atom atom )
}
+static int is_atom_error( Display *display, XErrorEvent *event, void *arg )
+{
+ return (event->error_code == BadAtom);
+}
+
+static int is_window_error( Display *display, XErrorEvent *event, void *arg )
+{
+ return (event->error_code == BadWindow);
+}
+
+
/**************************************************************************
* find_win32_format
*/
@@ -319,6 +330,19 @@ static struct clipboard_format *find_win32_format( UINT id )
/**************************************************************************
+ * find_x11_format
+ */
+static struct clipboard_format *find_x11_format( Atom atom )
+{
+ struct clipboard_format *format;
+
+ LIST_FOR_EACH_ENTRY( format, &format_list, struct clipboard_format, entry )
+ if (format->atom == atom) return format;
+ return NULL;
+}
+
+
+/**************************************************************************
* register_formats
*/
static void register_formats( const UINT *ids, const Atom *atoms, unsigned int count )
@@ -374,6 +398,47 @@ static void register_win32_formats( const UINT *ids, UINT size )
/**************************************************************************
+ * register_x11_formats
+ *
+ * Register X11 atom formats the first time we encounter them.
+ */
+static void register_x11_formats( const Atom *atoms, UINT size )
+{
+ Display *display = thread_display();
+ unsigned int i, pos, count;
+ char *names[256];
+ UINT ids[256];
+ Atom new_atoms[256];
+ WCHAR buffer[256];
+
+ while (size)
+ {
+ for (count = 0; count < 256 && size; atoms++, size--)
+ if (!find_x11_format( *atoms )) new_atoms[count++] = *atoms;
+
+ if (!count) return;
+
+ X11DRV_expect_error( display, is_atom_error, NULL );
+ if (!XGetAtomNames( display, new_atoms, count, names )) count = 0;
+ if (X11DRV_check_error())
+ {
+ WARN( "got some bad atoms, ignoring\n" );
+ count = 0;
+ }
+
+ for (i = pos = 0; i < count; i++)
+ {
+ if (MultiByteToWideChar( CP_UNIXCP, 0, names[i], -1, buffer, 256 ) &&
+ (ids[pos] = RegisterClipboardFormatW( buffer )))
+ new_atoms[pos++] = new_atoms[i];
+ XFree( names[i] );
+ }
+ register_formats( ids, new_atoms, pos );
+ }
+}
+
+
+/**************************************************************************
* X11DRV_InitClipboard
*/
void X11DRV_InitClipboard(void)
@@ -1342,9 +1407,11 @@ void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom select
HANDLE handle;
struct clipboard_format *format;
+ register_x11_formats( targets, count );
+
for (i = 0; i < count; i++)
{
- if (!(format = X11DRV_CLIPBOARD_LookupProperty( NULL, targets[i] ))) continue;
+ if (!(format = find_x11_format( targets[i] ))) continue;
if (!format->id) continue;
if (!(handle = import_selection( display, win, selection, format ))) continue;
callback( targets[i], format->id, handle );
@@ -1898,16 +1965,6 @@ static BOOL export_multiple( Display *display, Window win, Atom prop, Atom targe
}
-static int is_atom_error( Display *display, XErrorEvent *event, void *arg )
-{
- return (event->error_code == BadAtom);
-}
-
-static int is_window_error( Display *display, XErrorEvent *event, void *arg )
-{
- return (event->error_code == BadWindow);
-}
-
/**************************************************************************
* import_targets
*
@@ -1915,13 +1972,13 @@ static int is_window_error( Display *display, XErrorEvent *event, void *arg )
*/
static HANDLE import_targets( Atom type, const void *data, size_t size )
{
- UINT count = size / sizeof(Atom);
+ UINT i, count = size / sizeof(Atom);
const Atom *properties = data;
- UINT i, nb_atoms = 0;
- Atom *atoms = NULL;
if (type != XA_ATOM && type != x11drv_atom(TARGETS)) return 0;
+ register_x11_formats( properties, count );
+
/* Cache these formats in the clipboard cache */
for (i = 0; i < count; i++)
{
@@ -1944,54 +2001,8 @@ static HANDLE import_targets( Atom type, const void *data, size_t size )
lpFormat = X11DRV_CLIPBOARD_LookupProperty(lpFormat, properties[i]);
}
}
- else if (properties[i])
- {
- /* add it to the list of atoms that we don't know about yet */
- if (!atoms) atoms = HeapAlloc( GetProcessHeap(), 0,
- (count - i) * sizeof(*atoms) );
- if (atoms) atoms[nb_atoms++] = properties[i];
- }
}
- /* query all unknown atoms in one go */
- if (atoms)
- {
- char **names = HeapAlloc( GetProcessHeap(), 0, nb_atoms * sizeof(*names) );
- if (names)
- {
- Display *display = thread_display();
-
- X11DRV_expect_error( display, is_atom_error, NULL );
- if (!XGetAtomNames( display, atoms, nb_atoms, names )) nb_atoms = 0;
- if (X11DRV_check_error())
- {
- WARN( "got some bad atoms, ignoring\n" );
- nb_atoms = 0;
- }
- for (i = 0; i < nb_atoms; i++)
- {
- WINE_CLIPFORMAT *lpFormat;
- LPWSTR wname;
- int len = MultiByteToWideChar(CP_UNIXCP, 0, names[i], -1, NULL, 0);
- wname = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
- MultiByteToWideChar(CP_UNIXCP, 0, names[i], -1, wname, len);
-
- lpFormat = register_format( RegisterClipboardFormatW(wname), atoms[i] );
- HeapFree(GetProcessHeap(), 0, wname);
- if (!lpFormat)
- {
- ERR("Failed to register %s property. Type will not be cached.\n", names[i]);
- continue;
- }
- TRACE( "property %s -> format %s\n",
- debugstr_xatom( lpFormat->atom ), debugstr_format( lpFormat->id ));
- X11DRV_CLIPBOARD_InsertClipboardData( lpFormat->id, 0, lpFormat, FALSE );
- }
- for (i = 0; i < nb_atoms; i++) XFree( names[i] );
- HeapFree( GetProcessHeap(), 0, names );
- }
- HeapFree( GetProcessHeap(), 0, atoms );
- }
return (HANDLE)1;
}
@@ -2027,7 +2038,7 @@ static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display)
if ((use_primary_selection && XGetSelectionOwner(display,XA_PRIMARY)) ||
XGetSelectionOwner(display,x11drv_atom(CLIPBOARD)))
{
- struct clipboard_format *format = X11DRV_CLIPBOARD_LookupProperty( NULL, x11drv_atom(TARGETS) );
+ struct clipboard_format *format = find_x11_format( x11drv_atom(TARGETS) );
assert( format );
if (use_primary_selection && import_selection( display, w, XA_PRIMARY, format ))
@@ -2038,7 +2049,7 @@ static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display)
{
HANDLE handle;
- format = X11DRV_CLIPBOARD_LookupProperty( NULL, XA_STRING );
+ 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 )))
More information about the wine-cvs
mailing list