From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winex11.drv/clipboard.c | 167 ++++++++++++++++------------------- 1 file changed, 75 insertions(+), 92 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c index 02456ef3870..ec0392f3ec8 100644 --- a/dlls/winex11.drv/clipboard.c +++ b/dlls/winex11.drv/clipboard.c @@ -97,7 +97,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
#define SELECTION_UPDATE_DELAY 2000 /* delay between checks of the X11 selection */
-typedef BOOL (*EXPORTFUNC)( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); +typedef BOOL (*EXPORTFUNC)( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); typedef HANDLE (*IMPORTFUNC)( Atom type, const void *data, size_t size );
struct clipboard_format @@ -121,19 +121,18 @@ static HANDLE import_text_html( Atom type, const void *data, size_t size ); static HANDLE import_text_uri_list( Atom type, const void *data, size_t size ); static HANDLE import_targets( Atom type, const void *data, size_t size );
-static BOOL export_data( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_text( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_enhmetafile( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_text_html( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); -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 BOOL export_timestamp( Display *display, Window win, Atom prop, Atom target, HANDLE handle ); +static BOOL export_data( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_string( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_text( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_text_html( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_targets( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_multiple( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ); +static BOOL export_timestamp( Display *display, Window win, Atom prop, Atom target, void *data, size_t size );
static BOOL read_property( Display *display, Window w, Atom prop, Atom *type, unsigned char **data, unsigned long *datasize ); @@ -167,7 +166,7 @@ static const struct { 0, CF_PENDATA, XATOM_WCF_PENDATA, import_data, export_data }, { 0, CF_RIFF, XATOM_WCF_RIFF, import_data, export_data }, { 0, CF_WAVE, XATOM_WCF_WAVE, import_data, export_data }, - { 0, CF_ENHMETAFILE, XATOM_WCF_ENHMETAFILE, import_enhmetafile, export_enhmetafile }, + { 0, CF_ENHMETAFILE, XATOM_WCF_ENHMETAFILE, import_enhmetafile, export_data }, { 0, CF_HDROP, XATOM_text_uri_list, import_text_uri_list, export_hdrop }, { 0, CF_DIB, XATOM_image_bmp, import_image_bmp, export_image_bmp }, { RichTextFormatW, 0, XATOM_text_rtf, import_data, export_data }, @@ -1099,13 +1098,9 @@ static HANDLE render_format( UINT id ) * * Generic export clipboard data routine. */ -static BOOL export_data( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_data( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { - void *ptr = GlobalLock( handle ); - - if (!ptr) return FALSE; - put_property( display, win, prop, target, 8, ptr, GlobalSize( handle )); - GlobalUnlock( handle ); + put_property( display, win, prop, target, 8, data, size ); return TRUE; }
@@ -1115,18 +1110,19 @@ static BOOL export_data( Display *display, Window win, Atom prop, Atom target, H * * Convert CF_UNICODETEXT data to a string in the specified codepage. */ -static char *string_from_unicode_text( UINT codepage, HANDLE handle, UINT *size ) +static char *string_from_unicode_text( UINT codepage, const WCHAR *string, size_t string_size, size_t *size ) { UINT i, j; char *str; - WCHAR *strW = GlobalLock( handle ); - UINT lenW = GlobalSize( handle ) / sizeof(WCHAR); - DWORD len = WideCharToMultiByte( codepage, 0, strW, lenW, NULL, 0, NULL, NULL ); + UINT lenW = string_size / sizeof(WCHAR); + DWORD len; + + if (!string_size) return NULL;
+ len = WideCharToMultiByte( codepage, 0, string, lenW, NULL, 0, NULL, NULL ); if ((str = malloc( len ))) { - WideCharToMultiByte( codepage, 0, strW, lenW, str, len, NULL, NULL); - GlobalUnlock( handle ); + WideCharToMultiByte( codepage, 0, string, lenW, str, len, NULL, NULL);
/* remove carriage returns */ for (i = j = 0; i < len; i++) @@ -1138,7 +1134,6 @@ static char *string_from_unicode_text( UINT codepage, HANDLE handle, UINT *size *size = j; TRACE( "returning %s\n", debugstr_an( str, j )); } - GlobalUnlock( handle ); return str; }
@@ -1148,15 +1143,13 @@ static char *string_from_unicode_text( UINT codepage, HANDLE handle, UINT *size * * Export CF_UNICODETEXT converting the string to XA_STRING. */ -static BOOL export_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_string( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { - UINT size; - char *text = string_from_unicode_text( 28591, handle, &size ); + char *text = string_from_unicode_text( 28591, data, size, &size );
if (!text) return FALSE; put_property( display, win, prop, target, 8, text, size ); free( text ); - GlobalUnlock( handle ); return TRUE; }
@@ -1166,15 +1159,14 @@ static BOOL export_string( Display *display, Window win, Atom prop, Atom target, * * Export CF_UNICODE converting the string to UTF8. */ -static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom target, + void *data, size_t size ) { - UINT size; - char *text = string_from_unicode_text( CP_UTF8, handle, &size ); + char *text = string_from_unicode_text( CP_UTF8, data, size, &size );
if (!text) return FALSE; put_property( display, win, prop, target, 8, text, size ); free( text ); - GlobalUnlock( handle ); return TRUE; }
@@ -1184,9 +1176,9 @@ static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom ta * * Export CF_UNICODE to the polymorphic TEXT type, using UTF8. */ -static BOOL export_text( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_text( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { - return export_utf8_string( display, win, prop, x11drv_atom(UTF8_STRING), handle ); + return export_utf8_string( display, win, prop, x11drv_atom(UTF8_STRING), data, size ); }
@@ -1195,12 +1187,12 @@ static BOOL export_text( Display *display, Window win, Atom prop, Atom target, H * * Export CF_UNICODE to COMPOUND_TEXT */ -static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom target, + void *data, size_t size ) { XTextProperty textprop; XICCEncodingStyle style; - UINT size; - char *text = string_from_unicode_text( CP_UNIXCP, handle, &size ); + char *text = string_from_unicode_text( CP_UNIXCP, data, size, &size );
if (!text) return FALSE; if (target == x11drv_atom(COMPOUND_TEXT)) @@ -1225,18 +1217,16 @@ static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom * * Export CF_DIB to XA_PIXMAP. */ -static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { Pixmap pixmap; - BITMAPINFO *pbmi; + BITMAPINFO *pbmi = data; struct gdi_image_bits bits;
- pbmi = GlobalLock( handle ); bits.ptr = (LPBYTE)pbmi + bitmap_info_size( pbmi, DIB_RGB_COLORS ); bits.free = NULL; bits.is_copy = FALSE; pixmap = create_pixmap_from_image( 0, &default_visual, pbmi, &bits, DIB_RGB_COLORS ); - GlobalUnlock( handle );
put_property( display, win, prop, target, 32, &pixmap, 1 ); /* FIXME: free the pixmap when the property is deleted */ @@ -1249,13 +1239,13 @@ static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, * * Export CF_DIB to image/bmp. */ -static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { - LPBYTE dibdata = GlobalLock( handle ); + LPBYTE dibdata = data; UINT bmpsize; BITMAPFILEHEADER *bfh;
- bmpsize = sizeof(BITMAPFILEHEADER) + GlobalSize( handle ); + bmpsize = sizeof(BITMAPFILEHEADER) + size; bfh = malloc( bmpsize ); if (bfh) { @@ -1269,33 +1259,12 @@ static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom targ /* rest of bitmap is the same as the packed dib */ memcpy(bfh+1, dibdata, bmpsize-sizeof(BITMAPFILEHEADER)); } - GlobalUnlock( handle ); put_property( display, win, prop, target, 8, bfh, bmpsize ); free( bfh ); return TRUE; }
-/************************************************************************** - * export_enhmetafile - * - * Export EnhMetaFile. - */ -static BOOL export_enhmetafile( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) -{ - unsigned int size; - void *ptr; - - if (!(size = GetEnhMetaFileBits( handle, 0, NULL ))) return FALSE; - if (!(ptr = malloc( size ))) return FALSE; - - GetEnhMetaFileBits( handle, size, ptr ); - put_property( display, win, prop, target, 8, ptr, size ); - free( ptr ); - return TRUE; -} - - /************************************************************************** * export_text_html * @@ -1303,14 +1272,12 @@ static BOOL export_enhmetafile( Display *display, Window win, Atom prop, Atom ta * * FIXME: We should attempt to add an <a base> tag and convert windows paths. */ -static BOOL export_text_html( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_text_html( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { - const char *p, *data; + const char *p; UINT start = 0, end = 0; BOOL ret = TRUE;
- if (!(data = GlobalLock( handle ))) return FALSE; - p = data; while (*p && *p != '<') { @@ -1319,12 +1286,11 @@ static BOOL export_text_html( Display *display, Window win, Atom prop, Atom targ if (!(p = strpbrk( p, "\r\n" ))) break; while (*p == '\r' || *p == '\n') p++; } - if (start && start < end && end <= GlobalSize( handle )) - put_property( display, win, prop, target, 8, data + start, end - start ); + if (start && start < end && end <= size) + put_property( display, win, prop, target, 8, (char *)data + start, end - start ); else ret = FALSE;
- GlobalUnlock( handle ); return ret; }
@@ -1334,14 +1300,13 @@ static BOOL export_text_html( Display *display, Window win, Atom prop, Atom targ * * Export CF_HDROP format to text/uri-list. */ -static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { char *textUriList = NULL; UINT textUriListSize = 32; UINT next = 0; const WCHAR *ptr; WCHAR *unicode_data = NULL; - void *data = GlobalLock( handle ); DROPFILES *drop_files = data;
if (!drop_files->fWide) @@ -1406,7 +1371,6 @@ static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, return TRUE;
failed: - GlobalUnlock( handle ); free( unicode_data ); free( textUriList ); return FALSE; @@ -1454,7 +1418,7 @@ static BOOL is_format_available( UINT format, const UINT *ids, unsigned int coun * * Service a TARGETS selection request event */ -static BOOL export_targets( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_targets( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { struct clipboard_format *format; UINT pos, count, *formats; @@ -1493,9 +1457,10 @@ static BOOL export_targets( Display *display, Window win, Atom prop, Atom target */ static BOOL export_selection( Display *display, Window win, Atom prop, Atom target ) { + struct get_clipboard_params params = { .data_only = TRUE }; struct clipboard_format *format; - HANDLE handle = 0; BOOL open = FALSE, ret = FALSE; + size_t buffer_size = 0;
LIST_FOR_EACH_ENTRY( format, &format_list, struct clipboard_format, entry ) { @@ -1504,26 +1469,44 @@ static BOOL export_selection( Display *display, Window win, Atom prop, Atom targ if (!format->id) { TRACE( "win %lx prop %s target %s\n", win, debugstr_xatom( prop ), debugstr_xatom( target )); - ret = format->export( display, win, prop, target, 0 ); + ret = format->export( display, win, prop, target, NULL, 0 ); break; } - if (!open && !(open = OpenClipboard( clipboard_hwnd ))) + if (!open && !(open = NtUserOpenClipboard( clipboard_hwnd, 0 ))) { ERR( "failed to open clipboard for %s\n", debugstr_xatom( target )); return FALSE; } - if ((handle = GetClipboardData( format->id ))) + + if (!buffer_size) { - TRACE( "win %lx prop %s target %s exporting %s %p\n", - win, debugstr_xatom( prop ), debugstr_xatom( target ), - debugstr_format( format->id ), handle ); + buffer_size = 1024; + if (!(params.data = malloc( buffer_size ))) break; + }
- ret = format->export( display, win, prop, target, handle ); - break; + for (;;) + { + params.size = buffer_size; + if (NtUserGetClipboardData( format->id, ¶ms )) + { + TRACE( "win %lx prop %s target %s exporting %s\n", + win, debugstr_xatom( prop ), debugstr_xatom( target ), + debugstr_format( format->id ) ); + + ret = format->export( display, win, prop, target, params.data, params.size ); + goto done; + } + if (!params.data_size) break; + free( params.data ); + if (!(params.data = malloc( params.data_size ))) goto done; + buffer_size = params.data_size; + params.data_size = 0; } /* keep looking for another Win32 format mapping to the same target */ } - if (open) CloseClipboard(); +done: + free( params.data ); + if (open) NtUserCloseClipboard(); return ret; }
@@ -1541,7 +1524,7 @@ static BOOL export_selection( Display *display, Window win, Atom prop, Atom targ * 2. If we fail to convert the target named by an atom in the MULTIPLE property, * we replace the atom in the property by None. */ -static BOOL export_multiple( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_multiple( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { Atom atype; int aformat; @@ -1587,7 +1570,7 @@ static BOOL export_multiple( Display *display, Window win, Atom prop, Atom targe * * Export the timestamp that was used to acquire the selection */ -static BOOL export_timestamp( Display *display, Window win, Atom prop, Atom target, HANDLE handle ) +static BOOL export_timestamp( Display *display, Window win, Atom prop, Atom target, void *data, size_t size ) { Time time = CurrentTime; /* FIXME */ put_property( display, win, prop, XA_INTEGER, 32, &time, 1 );