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 | 192 ++++++++++++++++++----------------- 1 file changed, 100 insertions(+), 92 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c index a0ccc3ebc96..7640308fadd 100644 --- a/dlls/winex11.drv/clipboard.c +++ b/dlls/winex11.drv/clipboard.c @@ -98,7 +98,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, void *data, size_t size ); -typedef HANDLE (*IMPORTFUNC)( Atom type, const void *data, size_t size ); +typedef void *(*IMPORTFUNC)( Atom type, const void *data, size_t size, size_t *ret_size );
struct clipboard_format { @@ -109,17 +109,16 @@ struct clipboard_format EXPORTFUNC export; };
-static HANDLE import_data( Atom type, const void *data, size_t size ); -static HANDLE import_enhmetafile( Atom type, const void *data, size_t size ); -static HANDLE import_pixmap( Atom type, const void *data, size_t size ); -static HANDLE import_image_bmp( Atom type, const void *data, size_t size ); -static HANDLE import_string( Atom type, const void *data, size_t size ); -static HANDLE import_utf8_string( Atom type, const void *data, size_t size ); -static HANDLE import_compound_text( Atom type, const void *data, size_t size ); -static HANDLE import_text( Atom type, const void *data, size_t size ); -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 void *import_data( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_pixmap( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_image_bmp( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_string( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_utf8_string( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_compound_text( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_text( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_text_html( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_text_uri_list( Atom type, const void *data, size_t size, size_t *ret_size ); +static void *import_targets( Atom type, const void *data, size_t size, size_t *ret_size );
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 ); @@ -135,7 +134,7 @@ static BOOL export_multiple( Display *display, Window win, Atom prop, Atom targe 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 ); + Atom *type, unsigned char **data, size_t *datasize );
/* Clipboard formats */
@@ -166,7 +165,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_data }, + { 0, CF_ENHMETAFILE, XATOM_WCF_ENHMETAFILE, import_data, 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 }, @@ -442,13 +441,12 @@ static void selection_sleep(void) NtDelayExecution( FALSE, &timeout ); }
- /************************************************************************** * convert_selection */ static BOOL convert_selection( Display *display, Window win, Atom selection, struct clipboard_format *format, Atom *type, - unsigned char **data, unsigned long *size ) + unsigned char **data, size_t *size ) { int i; XEvent event; @@ -504,15 +502,14 @@ static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) * * Allocates a packed DIB and copies the bitmap data into it. */ -static HGLOBAL create_dib_from_bitmap(HBITMAP hBmp) +static void *create_dib_from_bitmap( HBITMAP hBmp, size_t *size ) { BITMAP bmp; HDC hdc; - HGLOBAL hPackedDIB; - LPBYTE pPackedDIB; LPBITMAPINFOHEADER pbmiHeader; - unsigned int cDataSize, cPackedSize, OffsetBits; + unsigned int cDataSize, OffsetBits; int nLinesCopied; + char *ret;
if (!GetObjectW( hBmp, sizeof(bmp), &bmp )) return 0;
@@ -523,24 +520,22 @@ static HGLOBAL create_dib_from_bitmap(HBITMAP hBmp)
/* Calculate the size of the packed DIB */ cDataSize = abs( bmp.bmHeight ) * (((bmp.bmWidth * bmp.bmBitsPixel + 31) / 8) & ~3); - cPackedSize = sizeof(BITMAPINFOHEADER) + *size = sizeof(BITMAPINFOHEADER) + ( (bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0 ) + cDataSize; /* Get the offset to the bits */ - OffsetBits = cPackedSize - cDataSize; + OffsetBits = *size - cDataSize;
/* Allocate the packed DIB */ - TRACE("\tAllocating packed DIB of size %d\n", cPackedSize); - hPackedDIB = GlobalAlloc( GMEM_FIXED, cPackedSize ); - if ( !hPackedDIB ) + TRACE( "\tAllocating packed DIB\n" ); + if (!(ret = malloc( *size ))) { - WARN("Could not allocate packed DIB!\n"); + WARN( "Could not allocate packed DIB!\n" ); return 0; }
/* A packed DIB starts with a BITMAPINFOHEADER */ - pPackedDIB = GlobalLock(hPackedDIB); - pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB; + pbmiHeader = (LPBITMAPINFOHEADER)ret;
/* Init the BITMAPINFOHEADER */ pbmiHeader->biSize = sizeof(BITMAPINFOHEADER); @@ -561,20 +556,19 @@ static HGLOBAL create_dib_from_bitmap(HBITMAP hBmp) hBmp, /* Handle to bitmap */ 0, /* First scan line to set in dest bitmap */ bmp.bmHeight, /* Number of scan lines to copy */ - pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */ + ret + OffsetBits, /* [out] Address of array for bitmap bits */ (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */ 0); /* RGB or palette index */ - GlobalUnlock(hPackedDIB); ReleaseDC( 0, hdc );
/* Cleanup if GetDIBits failed */ if (nLinesCopied != bmp.bmHeight) { TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight); - GlobalFree(hPackedDIB); - hPackedDIB = 0; + free( ret ); + ret = NULL; } - return hPackedDIB; + return ret; }
@@ -690,14 +684,14 @@ static WCHAR* uri_to_dos(char *encodedURI) * * Convert a string in the specified encoding to CF_UNICODETEXT format. */ -static HANDLE unicode_text_from_string( UINT codepage, const void *data, size_t size ) +static WCHAR *unicode_text_from_string( UINT codepage, const void *data, size_t size, size_t *ret_size ) { DWORD i, j, count; WCHAR *strW;
count = MultiByteToWideChar( codepage, 0, data, size, NULL, 0);
- if (!(strW = GlobalAlloc( GMEM_FIXED, (count * 2 + 1) * sizeof(WCHAR) ))) return 0; + if (!(strW = malloc( (count * 2 + 1) * sizeof(WCHAR) ))) return 0;
MultiByteToWideChar( codepage, 0, data, size, strW + count, count ); for (i = j = 0; i < count; i++) @@ -706,7 +700,7 @@ static HANDLE unicode_text_from_string( UINT codepage, const void *data, size_t strW[j++] = strW[i + count]; } strW[j++] = 0; - GlobalReAlloc( strW, j * sizeof(WCHAR), GMEM_FIXED ); /* release unused space */ + *ret_size = j * sizeof(WCHAR); TRACE( "returning %s\n", debugstr_wn( strW, j - 1 )); return strW; } @@ -717,9 +711,9 @@ static HANDLE unicode_text_from_string( UINT codepage, const void *data, size_t * * Import XA_STRING, converting the string to CF_UNICODETEXT. */ -static HANDLE import_string( Atom type, const void *data, size_t size ) +static void *import_string( Atom type, const void *data, size_t size, size_t *ret_size ) { - return unicode_text_from_string( 28591, data, size ); + return unicode_text_from_string( 28591, data, size, ret_size ); }
@@ -728,9 +722,9 @@ static HANDLE import_string( Atom type, const void *data, size_t size ) * * Import XA_UTF8_STRING, converting the string to CF_UNICODETEXT. */ -static HANDLE import_utf8_string( Atom type, const void *data, size_t size ) +static void *import_utf8_string( Atom type, const void *data, size_t size, size_t *ret_size ) { - return unicode_text_from_string( CP_UTF8, data, size ); + return unicode_text_from_string( CP_UTF8, data, size, ret_size ); }
@@ -739,12 +733,12 @@ static HANDLE import_utf8_string( Atom type, const void *data, size_t size ) * * Import COMPOUND_TEXT to CF_UNICODETEXT. */ -static HANDLE import_compound_text( Atom type, const void *data, size_t size ) +static void *import_compound_text( Atom type, const void *data, size_t size, size_t *ret_size ) { char** srcstr; int count; - HANDLE ret; XTextProperty txtprop; + void *ret;
txtprop.value = (BYTE *)data; txtprop.nitems = size; @@ -753,7 +747,7 @@ static HANDLE import_compound_text( Atom type, const void *data, size_t size ) if (XmbTextPropertyToTextList( thread_display(), &txtprop, &srcstr, &count ) != Success) return 0; if (!count) return 0;
- ret = unicode_text_from_string( CP_UNIXCP, srcstr[0], strlen(srcstr[0]) + 1 ); + ret = unicode_text_from_string( CP_UNIXCP, srcstr[0], strlen(srcstr[0]) + 1, ret_size ); XFreeStringList(srcstr); return ret; } @@ -764,11 +758,11 @@ static HANDLE import_compound_text( Atom type, const void *data, size_t size ) * * Import XA_TEXT, converting the string to CF_UNICODETEXT. */ -static HANDLE import_text( Atom type, const void *data, size_t size ) +static void *import_text( Atom type, const void *data, size_t size, size_t *ret_size ) { - if (type == XA_STRING) return import_string( type, data, size ); - if (type == x11drv_atom(UTF8_STRING)) return import_utf8_string( type, data, size ); - if (type == x11drv_atom(COMPOUND_TEXT)) return import_compound_text( type, data, size ); + if (type == XA_STRING) return import_string( type, data, size, ret_size ); + if (type == x11drv_atom(UTF8_STRING)) return import_utf8_string( type, data, size, ret_size ); + if (type == x11drv_atom(COMPOUND_TEXT)) return import_compound_text( type, data, size, ret_size ); FIXME( "unsupported TEXT type %s\n", debugstr_xatom( type )); return 0; } @@ -779,7 +773,7 @@ static HANDLE import_text( Atom type, const void *data, size_t size ) * * Import XA_PIXMAP, converting the image to CF_DIB. */ -static HANDLE import_pixmap( Atom type, const void *data, size_t size ) +static void *import_pixmap( Atom type, const void *data, size_t size, size_t *ret_size ) { const Pixmap *pPixmap = (const Pixmap *)data; BYTE *ptr = NULL; @@ -824,11 +818,12 @@ static HANDLE import_pixmap( Atom type, const void *data, size_t size ) { DWORD info_size = bitmap_info_size( info, DIB_RGB_COLORS );
- ptr = GlobalAlloc( GMEM_FIXED, info_size + info->bmiHeader.biSizeImage ); + ptr = malloc( info_size + info->bmiHeader.biSizeImage ); if (ptr) { memcpy( ptr, info, info_size ); memcpy( ptr + info_size, bits.ptr, info->bmiHeader.biSizeImage ); + *ret_size = info_size + info->bmiHeader.biSizeImage; } if (bits.free) bits.free( &bits ); } @@ -841,10 +836,10 @@ static HANDLE import_pixmap( Atom type, const void *data, size_t size ) * * Import image/bmp, converting the image to CF_DIB. */ -static HANDLE import_image_bmp( Atom type, const void *data, size_t size ) +static void *import_image_bmp( Atom type, const void *data, size_t size, size_t *ret_size ) { - HANDLE hClipData = 0; const BITMAPFILEHEADER *bfh = data; + void *ret = NULL;
if (size >= sizeof(BITMAPFILEHEADER)+sizeof(BITMAPCOREHEADER) && bfh->bfType == 0x4d42 /* "BM" */) @@ -856,28 +851,19 @@ static HANDLE import_image_bmp( Atom type, const void *data, size_t size ) if ((hbmp = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT, (const BYTE *)data + bfh->bfOffBits, bmi, DIB_RGB_COLORS ))) { - hClipData = create_dib_from_bitmap( hbmp ); + ret = create_dib_from_bitmap( hbmp, ret_size ); DeleteObject(hbmp); } ReleaseDC(0, hdc); } - return hClipData; -} - - -/************************************************************************** - * import_enhmetafile - */ -static HANDLE import_enhmetafile( Atom type, const void *data, size_t size ) -{ - return SetEnhMetaFileBits( size, data ); + return ret; }
/************************************************************************** * import_text_html */ -static HANDLE import_text_html( Atom type, const void *data, size_t size ) +static void *import_text_html( Atom type, const void *data, size_t size, size_t *ret_size ) { static const char header[] = "Version:0.9\n" @@ -905,12 +891,13 @@ static HANDLE import_text_html( Atom type, const void *data, size_t size )
len = strlen( header ) + 12; /* 3 * 4 extra chars for %010lu */ total = len + size + sizeof(trailer); - if ((ret = GlobalAlloc( GMEM_FIXED, total ))) + if ((ret = malloc( total ))) { char *p = ret; p += sprintf( p, header, total - 1, len, len + size + 1 /* include the final \n in the data */ ); memcpy( p, data, size ); strcpy( p + size, trailer ); + *ret_size = total; TRACE( "returning %s\n", debugstr_a( ret )); } free( text ); @@ -923,7 +910,7 @@ static HANDLE import_text_html( Atom type, const void *data, size_t size ) * * Import text/uri-list. */ -static HANDLE import_text_uri_list( Atom type, const void *data, size_t size ) +static void *import_text_uri_list( Atom type, const void *data, size_t size, size_t *ret_size ) { const char *uriList = data; char *uri; @@ -980,7 +967,8 @@ static HANDLE import_text_uri_list( Atom type, const void *data, size_t size ) } if (out && end >= size) { - if ((dropFiles = GlobalAlloc( GMEM_FIXED, sizeof(DROPFILES) + (total + 1) * sizeof(WCHAR) ))) + *ret_size = sizeof(DROPFILES) + (total + 1) * sizeof(WCHAR); + if ((dropFiles = malloc( *ret_size ))) { dropFiles->pFiles = sizeof(DROPFILES); dropFiles->pt.x = 0; @@ -1001,7 +989,7 @@ static HANDLE import_text_uri_list( Atom type, const void *data, size_t size ) * * Import TARGETS and mark the corresponding clipboard formats as available. */ -static HANDLE import_targets( Atom type, const void *data, size_t size ) +static void *import_targets( Atom type, const void *data, size_t size, size_t *ret_size ) { UINT i, pos, count = size / sizeof(Atom); const Atom *properties = data; @@ -1022,9 +1010,12 @@ static HANDLE import_targets( Atom type, const void *data, size_t size ) if (i == count) continue; if (format->import && format->id) { + struct set_clipboard_params params = { .data = NULL }; + TRACE( "property %s -> format %s\n", debugstr_xatom( properties[i] ), debugstr_format( format->id )); - SetClipboardData( format->id, 0 ); + + NtUserSetClipboardData( format->id, 0, ¶ms ); formats[pos++] = format; } else TRACE( "property %s (ignoring)\n", debugstr_xatom( properties[i] )); @@ -1033,7 +1024,8 @@ static HANDLE import_targets( Atom type, const void *data, size_t size ) free( current_x11_formats ); current_x11_formats = formats; nb_current_x11_formats = pos; - return (HANDLE)1; + *ret_size = 0; + return (void *)1; }
@@ -1042,11 +1034,14 @@ static HANDLE import_targets( Atom type, const void *data, size_t size ) * * Generic import clipboard data routine. */ -static HANDLE import_data( Atom type, const void *data, size_t size ) +static void *import_data( Atom type, const void *data, size_t size, size_t *ret_size ) { - void *ret = GlobalAlloc( GMEM_FIXED, size ); - - if (ret) memcpy( ret, data, size ); + void *ret = malloc( size ); + if (ret) + { + memcpy( ret, data, size ); + *ret_size = size; + } return ret; }
@@ -1056,11 +1051,11 @@ static HANDLE import_data( Atom type, const void *data, size_t size ) * * Import the specified format from the selection and return a global handle to the data. */ -static HANDLE import_selection( Display *display, Window win, Atom selection, - struct clipboard_format *format ) +static void *import_selection( Display *display, Window win, Atom selection, + struct clipboard_format *format, size_t *ret_size ) { unsigned char *data; - unsigned long size; + size_t size; Atom type; HANDLE ret;
@@ -1071,7 +1066,7 @@ static HANDLE import_selection( Display *display, Window win, Atom selection, TRACE( "failed to convert selection\n" ); return 0; } - ret = format->import( type, data, size ); + ret = format->import( type, data, size, ret_size ); free( data ); return ret; } @@ -1088,6 +1083,8 @@ void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom select { UINT i; HANDLE handle; + void *data; + size_t size; struct clipboard_format *format;
register_x11_formats( targets, count ); @@ -1096,8 +1093,17 @@ void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom select { if (!(format = find_x11_format( targets[i] ))) continue; if (!format->id) continue; - if (!(handle = import_selection( display, win, selection, format ))) continue; - callback( format->id, handle ); + if (!(data = import_selection( display, win, selection, format, &size ))) continue; + + if ((handle = GlobalAlloc( GMEM_FIXED, size ))) + { + void *ptr; + ptr = GlobalLock( handle ); + memcpy( ptr, data, size ); + GlobalUnlock( handle ); + callback( format->id, handle ); + } + free( data ); } }
@@ -1105,23 +1111,25 @@ void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom select /************************************************************************** * render_format */ -static HANDLE render_format( UINT id ) +static BOOL render_format( UINT id ) { Display *display = thread_display(); unsigned int i; - HANDLE handle = 0;
if (!current_selection) return 0;
for (i = 0; i < nb_current_x11_formats; i++) { + struct set_clipboard_params params; if (current_x11_formats[i]->id != id) continue; - if (!(handle = import_selection( display, import_window, - current_selection, current_x11_formats[i] ))) continue; - SetClipboardData( id, handle ); - break; + if (!(params.data = import_selection( display, import_window, current_selection, + current_x11_formats[i], ¶ms.size ))) continue; + params.seqno = 0; + NtUserSetClipboardData( id, 0, ¶ms ); + if (params.size) free( params.data ); + return TRUE; } - return handle; + return FALSE; }
@@ -1615,7 +1623,7 @@ static BOOL export_timestamp( Display *display, Window win, Atom prop, Atom targ * Gets type, data and size. */ static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop, - Atom *atype, unsigned char** data, unsigned long* datasize) + Atom *atype, unsigned char **data, size_t *datasize) { int aformat; unsigned long pos = 0, nitems, remain, count; @@ -1652,7 +1660,7 @@ static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop, pos += count / sizeof(int); }
- TRACE( "got property %s type %s format %u len %lu from window %lx\n", + TRACE( "got property %s type %s format %u len %zu from window %lx\n", debugstr_xatom( prop ), debugstr_xatom( *atype ), aformat, *datasize, w );
/* Delete the property on the window now that we are done @@ -1674,7 +1682,7 @@ struct clipboard_data_packet { * Reads the contents of the X selection property. */ static BOOL read_property( Display *display, Window w, Atom prop, - Atom *type, unsigned char **data, unsigned long *datasize ) + Atom *type, unsigned char **data, size_t *datasize ) { XEvent xe;
@@ -1704,7 +1712,7 @@ static BOOL read_property( Display *display, Window w, Atom prop, { int i; unsigned char *prop_data; - unsigned long prop_size; + size_t prop_size;
/* Wait until PropertyNotify is received */ for (i = 0; i < SELECTION_RETRIES; i++) @@ -1830,7 +1838,7 @@ static BOOL request_selection_contents( Display *display, BOOL changed ) struct clipboard_format *format = NULL; Window owner = 0; unsigned char *data = NULL; - unsigned long size = 0; + size_t import_size, size = 0; Atom type = 0;
static Atom last_selection; @@ -1883,7 +1891,7 @@ static BOOL request_selection_contents( Display *display, BOOL changed ) is_clipboard_owner = TRUE; rendered_formats = 0;
- if (format) format->import( type, data, size ); + if (format) format->import( type, data, size, &import_size );
free( last_data ); last_selection = current_selection;