winex11: Move common code out of the export functions and simplify their usage.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-09-20 11:50:21 +09:00
parent 7d0ddff2d8
commit fd41ddec0a
1 changed files with 161 additions and 361 deletions

View File

@ -101,8 +101,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipboard);
struct tagWINE_CLIPDATA; /* Forward */ struct tagWINE_CLIPDATA; /* Forward */
typedef HANDLE (*DRVEXPORTFUNC)(Display *display, Window requestor, Atom aTarget, Atom rprop, typedef BOOL (*EXPORTFUNC)( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
struct tagWINE_CLIPDATA* lpData, LPDWORD lpBytes);
typedef HANDLE (*DRVIMPORTFUNC)(Display *d, Window w, Atom prop); typedef HANDLE (*DRVIMPORTFUNC)(Display *d, Window w, Atom prop);
typedef struct clipboard_format typedef struct clipboard_format
@ -111,7 +110,7 @@ typedef struct clipboard_format
UINT id; UINT id;
Atom atom; Atom atom;
DRVIMPORTFUNC lpDrvImportFunc; DRVIMPORTFUNC lpDrvImportFunc;
DRVEXPORTFUNC lpDrvExportFunc; EXPORTFUNC export;
} WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT; } WINE_CLIPFORMAT, *LPWINE_CLIPFORMAT;
typedef struct tagWINE_CLIPDATA { typedef struct tagWINE_CLIPDATA {
@ -136,26 +135,16 @@ static HANDLE import_utf8_string(Display *d, Window w, Atom prop);
static HANDLE import_compound_text(Display *d, Window w, Atom prop); static HANDLE import_compound_text(Display *d, Window w, Atom prop);
static HANDLE import_text_uri_list(Display *display, Window w, Atom prop); static HANDLE import_text_uri_list(Display *display, Window w, Atom prop);
static HANDLE export_data(Display *display, Window requestor, Atom aTarget, static BOOL export_data( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes); static BOOL export_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static HANDLE export_string(Display *display, Window requestor, Atom aTarget, static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes); static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static HANDLE export_utf8_string(Display *display, Window requestor, Atom aTarget, static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes); static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static HANDLE export_compound_text(Display *display, Window requestor, Atom aTarget, static BOOL export_metafile( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes); static BOOL export_enhmetafile( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static HANDLE export_pixmap(Display *display, Window requestor, Atom aTarget, static BOOL export_text_html( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes); static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, HANDLE handle );
static HANDLE export_image_bmp(Display *display, Window requestor, Atom aTarget,
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
static HANDLE export_metafile(Display *display, Window requestor, Atom aTarget,
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
static HANDLE export_enhmetafile(Display *display, Window requestor, Atom aTarget,
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
static HANDLE export_text_html(Display *display, Window requestor, Atom aTarget,
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
static HANDLE export_hdrop(Display *display, Window requestor, Atom aTarget,
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes);
static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData); static void X11DRV_CLIPBOARD_FreeData(LPWINE_CLIPDATA lpData);
static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display); static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display);
@ -180,7 +169,7 @@ static const struct
UINT id; UINT id;
UINT data; UINT data;
DRVIMPORTFUNC import; DRVIMPORTFUNC import;
DRVEXPORTFUNC export; EXPORTFUNC export;
} builtin_formats[] = } builtin_formats[] =
{ {
{ 0, CF_TEXT, XA_STRING, import_string, export_string }, { 0, CF_TEXT, XA_STRING, import_string, export_string },
@ -268,6 +257,7 @@ static const char *debugstr_format( UINT id )
switch (id) switch (id)
{ {
case 0: return "(none)";
#define BUILTIN(id) case id: return #id; #define BUILTIN(id) case id: return #id;
BUILTIN(CF_TEXT) BUILTIN(CF_TEXT)
BUILTIN(CF_BITMAP) BUILTIN(CF_BITMAP)
@ -328,7 +318,7 @@ void X11DRV_InitClipboard(void)
formats[i].atom = GET_ATOM(builtin_formats[i].data); formats[i].atom = GET_ATOM(builtin_formats[i].data);
formats[i].lpDrvImportFunc = builtin_formats[i].import; formats[i].lpDrvImportFunc = builtin_formats[i].import;
formats[i].lpDrvExportFunc = builtin_formats[i].export; formats[i].export = builtin_formats[i].export;
list_add_tail( &format_list, &formats[i].entry ); list_add_tail( &format_list, &formats[i].entry );
} }
} }
@ -409,7 +399,7 @@ static struct clipboard_format *register_format( UINT id, Atom prop )
format->id = id; format->id = id;
format->atom = prop; format->atom = prop;
format->lpDrvImportFunc = import_data; format->lpDrvImportFunc = import_data;
format->lpDrvExportFunc = export_data; format->export = export_data;
list_add_tail( &format_list, &format->entry ); list_add_tail( &format_list, &format->entry );
TRACE( "Registering format %s atom %ld\n", debugstr_format(id), prop ); TRACE( "Registering format %s atom %ld\n", debugstr_format(id), prop );
@ -1392,40 +1382,14 @@ HANDLE X11DRV_CLIPBOARD_ImportSelection(Display *d, Atom target, Window w, Atom
* *
* Generic export clipboard data routine. * Generic export clipboard data routine.
*/ */
static HANDLE export_data(Display *display, Window requestor, Atom aTarget, static BOOL export_data( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
Atom rprop, LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
{ {
LPVOID lpClipData; void *ptr = GlobalLock( handle );
UINT datasize = 0;
HANDLE hClipData = 0;
*lpBytes = 0; /* Assume failure */ if (!ptr) return FALSE;
put_property( display, win, prop, target, 8, ptr, GlobalSize( handle ));
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpData)) GlobalUnlock( handle );
ERR("Failed to export %04x format\n", lpData->wFormatID); return TRUE;
else
{
datasize = GlobalSize(lpData->hData);
hClipData = GlobalAlloc(GMEM_FIXED, datasize);
if (hClipData == 0) return NULL;
if ((lpClipData = GlobalLock(hClipData)))
{
LPVOID lpdata = GlobalLock(lpData->hData);
memcpy(lpClipData, lpdata, datasize);
*lpBytes = datasize;
GlobalUnlock(lpData->hData);
GlobalUnlock(hClipData);
} else {
GlobalFree(hClipData);
hClipData = 0;
}
}
return hClipData;
} }
@ -1434,39 +1398,32 @@ static HANDLE export_data(Display *display, Window requestor, Atom aTarget,
* *
* Export CF_TEXT converting the string to XA_STRING. * Export CF_TEXT converting the string to XA_STRING.
*/ */
static HANDLE export_string(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
{ {
UINT i, j; UINT i, j;
UINT size; UINT size;
LPSTR text, lpstr = NULL; LPSTR text, lpstr = NULL;
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpData)) return 0; text = GlobalLock( handle );
*lpBytes = 0; /* Assume return has zero bytes */
text = GlobalLock(lpData->hData);
size = strlen(text); size = strlen(text);
/* remove carriage returns */ /* remove carriage returns */
lpstr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1); lpstr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
if (lpstr == NULL) if (lpstr == NULL)
goto done; {
GlobalUnlock( handle );
return FALSE;
}
for (i = 0,j = 0; i < size && text[i]; i++) for (i = 0,j = 0; i < size && text[i]; i++)
{ {
if (text[i] == '\r' && (text[i+1] == '\n' || text[i+1] == '\0')) if (text[i] == '\r' && (text[i+1] == '\n' || text[i+1] == '\0'))
continue; continue;
lpstr[j++] = text[i]; lpstr[j++] = text[i];
} }
put_property( display, win, prop, target, 8, lpstr, j );
lpstr[j]='\0'; HeapFree( GetProcessHeap(), 0, lpstr );
*lpBytes = j; /* Number of bytes in string */ GlobalUnlock( handle );
return TRUE;
done:
GlobalUnlock(lpData->hData);
return lpstr;
} }
@ -1475,74 +1432,66 @@ done:
* *
* Export CF_UNICODE converting the string to UTF8. * Export CF_UNICODE converting the string to UTF8.
*/ */
static HANDLE export_utf8_string(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_utf8_string( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
{ {
UINT i, j; UINT i, j;
UINT size; UINT size;
LPWSTR uni_text; LPSTR text, lpstr;
LPSTR text, lpstr = NULL; LPWSTR uni_text = GlobalLock( handle );
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpData)) return 0;
*lpBytes = 0; /* Assume return has zero bytes */
uni_text = GlobalLock(lpData->hData);
size = WideCharToMultiByte(CP_UTF8, 0, uni_text, -1, NULL, 0, NULL, NULL); size = WideCharToMultiByte(CP_UTF8, 0, uni_text, -1, NULL, 0, NULL, NULL);
text = HeapAlloc(GetProcessHeap(), 0, size); text = HeapAlloc(GetProcessHeap(), 0, size);
if (!text) if (!text)
goto done; {
GlobalUnlock( handle );
return FALSE;
}
WideCharToMultiByte(CP_UTF8, 0, uni_text, -1, text, size, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, uni_text, -1, text, size, NULL, NULL);
GlobalUnlock( handle );
/* remove carriage returns */ /* remove carriage returns */
lpstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size--); lpstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size--);
if (lpstr == NULL) if (lpstr == NULL)
goto done; {
HeapFree(GetProcessHeap(), 0, text);
return FALSE;
}
for (i = 0,j = 0; i < size && text[i]; i++) for (i = 0,j = 0; i < size && text[i]; i++)
{ {
if (text[i] == '\r' && (text[i+1] == '\n' || text[i+1] == '\0')) if (text[i] == '\r' && (text[i+1] == '\n' || text[i+1] == '\0'))
continue; continue;
lpstr[j++] = text[i]; lpstr[j++] = text[i];
} }
lpstr[j]='\0'; put_property( display, win, prop, target, 8, lpstr, j );
HeapFree(GetProcessHeap(), 0, lpstr);
*lpBytes = j; /* Number of bytes in string */
done:
HeapFree(GetProcessHeap(), 0, text); HeapFree(GetProcessHeap(), 0, text);
GlobalUnlock(lpData->hData); GlobalUnlock( handle );
return TRUE;
return lpstr;
} }
/************************************************************************** /**************************************************************************
* export_compound_text * export_compound_text
* *
* Export CF_UNICODE to COMPOUND_TEXT * Export CF_UNICODE to COMPOUND_TEXT
*/ */
static HANDLE export_compound_text(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_compound_text( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpData, LPDWORD lpBytes)
{ {
char* lpstr = 0; char* lpstr;
XTextProperty prop; XTextProperty textprop;
XICCEncodingStyle style; XICCEncodingStyle style;
UINT i, j; UINT i, j;
UINT size; UINT size;
LPWSTR uni_text; LPWSTR uni_text = GlobalLock( handle );
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpData)) return 0;
uni_text = GlobalLock(lpData->hData);
size = WideCharToMultiByte(CP_UNIXCP, 0, uni_text, -1, NULL, 0, NULL, NULL); size = WideCharToMultiByte(CP_UNIXCP, 0, uni_text, -1, NULL, 0, NULL, NULL);
lpstr = HeapAlloc(GetProcessHeap(), 0, size); lpstr = HeapAlloc(GetProcessHeap(), 0, size);
if (!lpstr) if (!lpstr)
return 0; {
GlobalUnlock( handle );
return FALSE;
}
WideCharToMultiByte(CP_UNIXCP, 0, uni_text, -1, lpstr, size, NULL, NULL); WideCharToMultiByte(CP_UNIXCP, 0, uni_text, -1, lpstr, size, NULL, NULL);
@ -1555,23 +1504,22 @@ static HANDLE export_compound_text(Display *display, Window requestor, Atom aTar
} }
lpstr[j]='\0'; lpstr[j]='\0';
GlobalUnlock(lpData->hData); GlobalUnlock( handle );
if (aTarget == x11drv_atom(COMPOUND_TEXT)) if (target == x11drv_atom(COMPOUND_TEXT))
style = XCompoundTextStyle; style = XCompoundTextStyle;
else else
style = XStdICCTextStyle; style = XStdICCTextStyle;
/* Update the X property */ /* Update the X property */
if (XmbTextListToTextProperty(display, &lpstr, 1, style, &prop) == Success) if (XmbTextListToTextProperty( display, &lpstr, 1, style, &textprop ) == Success)
{ {
XSetTextProperty(display, requestor, &prop, rprop); XSetTextProperty( display, win, &textprop, prop );
XFree(prop.value); XFree( textprop.value );
} }
HeapFree(GetProcessHeap(), 0, lpstr); HeapFree(GetProcessHeap(), 0, lpstr);
return TRUE;
return 0;
} }
@ -1580,42 +1528,22 @@ static HANDLE export_compound_text(Display *display, Window requestor, Atom aTar
* *
* Export CF_DIB to XA_PIXMAP. * Export CF_DIB to XA_PIXMAP.
*/ */
static HANDLE export_pixmap(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_pixmap( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
HANDLE hData; Pixmap pixmap;
unsigned char* lpData; BITMAPINFO *pbmi;
struct gdi_image_bits bits;
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata)) pbmi = GlobalLock( handle );
{ bits.ptr = (LPBYTE)pbmi + bitmap_info_size( pbmi, DIB_RGB_COLORS );
ERR("Failed to export %04x format\n", lpdata->wFormatID); bits.free = NULL;
return 0; bits.is_copy = FALSE;
} pixmap = create_pixmap_from_image( 0, &default_visual, pbmi, &bits, DIB_RGB_COLORS );
GlobalUnlock( handle );
if (!lpdata->drvData) /* If not already rendered */ put_property( display, win, prop, target, 32, &pixmap, 1 );
{ /* FIXME: free the pixmap when the property is deleted */
Pixmap pixmap; return TRUE;
LPBITMAPINFO pbmi;
struct gdi_image_bits bits;
pbmi = GlobalLock( lpdata->hData );
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( lpdata->hData );
lpdata->drvData = pixmap;
}
*lpBytes = sizeof(Pixmap); /* pixmap is a 32bit value */
/* Wrap pixmap so we can return a handle */
hData = GlobalAlloc(0, *lpBytes);
lpData = GlobalLock(hData);
memcpy(lpData, &lpdata->drvData, *lpBytes);
GlobalUnlock(hData);
return hData;
} }
@ -1624,50 +1552,17 @@ static HANDLE export_pixmap(Display *display, Window requestor, Atom aTarget, At
* *
* Export CF_DIB to image/bmp. * Export CF_DIB to image/bmp.
*/ */
static HANDLE export_image_bmp(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_image_bmp( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
HANDLE hpackeddib; LPBYTE dibdata = GlobalLock( handle );
LPBYTE dibdata;
UINT bmpsize; UINT bmpsize;
HANDLE hbmpdata;
LPBYTE bmpdata;
BITMAPFILEHEADER *bfh; BITMAPFILEHEADER *bfh;
*lpBytes = 0; bmpsize = sizeof(BITMAPFILEHEADER) + GlobalSize( handle );
bfh = HeapAlloc( GetProcessHeap(), 0, bmpsize );
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata)) if (bfh)
{ {
ERR("Failed to export %04x format\n", lpdata->wFormatID);
return 0;
}
hpackeddib = lpdata->hData;
dibdata = GlobalLock(hpackeddib);
if (!dibdata)
{
ERR("Failed to lock packed DIB\n");
return 0;
}
bmpsize = sizeof(BITMAPFILEHEADER) + GlobalSize(hpackeddib);
hbmpdata = GlobalAlloc(0, bmpsize);
if (hbmpdata)
{
bmpdata = GlobalLock(hbmpdata);
if (!bmpdata)
{
GlobalFree(hbmpdata);
GlobalUnlock(hpackeddib);
return 0;
}
/* bitmap file header */ /* bitmap file header */
bfh = (BITMAPFILEHEADER*)bmpdata;
bfh->bfType = 0x4d42; /* "BM" */ bfh->bfType = 0x4d42; /* "BM" */
bfh->bfSize = bmpsize; bfh->bfSize = bmpsize;
bfh->bfReserved1 = 0; bfh->bfReserved1 = 0;
@ -1676,15 +1571,11 @@ static HANDLE export_image_bmp(Display *display, Window requestor, Atom aTarget,
/* rest of bitmap is the same as the packed dib */ /* rest of bitmap is the same as the packed dib */
memcpy(bfh+1, dibdata, bmpsize-sizeof(BITMAPFILEHEADER)); memcpy(bfh+1, dibdata, bmpsize-sizeof(BITMAPFILEHEADER));
*lpBytes = bmpsize;
GlobalUnlock(hbmpdata);
} }
GlobalUnlock( handle );
GlobalUnlock(hpackeddib); put_property( display, win, prop, target, 8, bfh, bmpsize );
HeapFree( GetProcessHeap(), 0, bfh );
return hbmpdata; return TRUE;
} }
@ -1693,39 +1584,24 @@ static HANDLE export_image_bmp(Display *display, Window requestor, Atom aTarget,
* *
* Export MetaFilePict. * Export MetaFilePict.
*/ */
static HANDLE export_metafile(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_metafile( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
LPMETAFILEPICT lpmfp; METAFILEPICT *src, *dst;
unsigned int size; unsigned int size;
HANDLE h;
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata)) src = GlobalLock( handle );
size = GetMetaFileBitsEx(src->hMF, 0, NULL);
dst = HeapAlloc( GetProcessHeap(), 0, size + sizeof(*dst) );
if (dst)
{ {
ERR("Failed to export %04x format\n", lpdata->wFormatID); *dst = *src;
return 0; GetMetaFileBitsEx( src->hMF, size, dst + 1 );
} }
GlobalUnlock( handle );
*lpBytes = 0; /* Assume failure */ put_property( display, win, prop, target, 8, dst, size + sizeof(*dst) );
HeapFree( GetProcessHeap(), 0, dst );
lpmfp = GlobalLock(lpdata->hData); return TRUE;
size = GetMetaFileBitsEx(lpmfp->hMF, 0, NULL);
h = GlobalAlloc(0, size + sizeof(METAFILEPICT));
if (h)
{
char *pdata = GlobalLock(h);
memcpy(pdata, lpmfp, sizeof(METAFILEPICT));
GetMetaFileBitsEx(lpmfp->hMF, size, pdata + sizeof(METAFILEPICT));
*lpBytes = size + sizeof(METAFILEPICT);
GlobalUnlock(h);
}
GlobalUnlock(lpdata->hData);
return h;
} }
@ -1734,32 +1610,18 @@ static HANDLE export_metafile(Display *display, Window requestor, Atom aTarget,
* *
* Export EnhMetaFile. * Export EnhMetaFile.
*/ */
static HANDLE export_enhmetafile(Display *display, Window requestor, Atom aTarget, Atom rprop, static BOOL export_enhmetafile( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
unsigned int size; unsigned int size;
HANDLE h; void *ptr;
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata)) if (!(size = GetEnhMetaFileBits( handle, 0, NULL ))) return FALSE;
{ if (!(ptr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
ERR("Failed to export %04x format\n", lpdata->wFormatID);
return 0;
}
*lpBytes = 0; /* Assume failure */ GetEnhMetaFileBits( handle, size, ptr );
put_property( display, win, prop, target, 8, ptr, size );
size = GetEnhMetaFileBits(lpdata->hData, 0, NULL); HeapFree( GetProcessHeap(), 0, ptr );
h = GlobalAlloc(0, size); return TRUE;
if (h)
{
LPVOID pdata = GlobalLock(h);
GetEnhMetaFileBits(lpdata->hData, size, pdata);
*lpBytes = size;
GlobalUnlock(h);
}
return h;
} }
@ -1792,38 +1654,19 @@ static LPCSTR get_html_description_field(LPCSTR data, LPCSTR keyword)
* *
* FIXME: We should attempt to add an <a base> tag and convert windows paths. * FIXME: We should attempt to add an <a base> tag and convert windows paths.
*/ */
static HANDLE export_text_html(Display *display, Window requestor, Atom aTarget, static BOOL export_text_html( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
HANDLE hdata;
LPCSTR data, field_value; LPCSTR data, field_value;
UINT fragmentstart, fragmentend, htmlsize; UINT fragmentstart, fragmentend;
HANDLE hhtmldata=NULL;
LPSTR htmldata;
*lpBytes = 0; data = GlobalLock( handle );
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata))
{
ERR("Failed to export %04x format\n", lpdata->wFormatID);
return 0;
}
hdata = lpdata->hData;
data = GlobalLock(hdata);
if (!data)
{
ERR("Failed to lock HTML Format data\n");
return 0;
}
/* read the important fields */ /* read the important fields */
field_value = get_html_description_field(data, "StartFragment:"); field_value = get_html_description_field(data, "StartFragment:");
if (!field_value) if (!field_value)
{ {
ERR("Couldn't find StartFragment value\n"); ERR("Couldn't find StartFragment value\n");
goto end; goto failed;
} }
fragmentstart = atoi(field_value); fragmentstart = atoi(field_value);
@ -1831,39 +1674,18 @@ static HANDLE export_text_html(Display *display, Window requestor, Atom aTarget,
if (!field_value) if (!field_value)
{ {
ERR("Couldn't find EndFragment value\n"); ERR("Couldn't find EndFragment value\n");
goto end; goto failed;
} }
fragmentend = atoi(field_value); fragmentend = atoi(field_value);
/* export only the fragment */ /* export only the fragment */
htmlsize = fragmentend - fragmentstart + 1; put_property( display, win, prop, target, 8, &data[fragmentstart], fragmentend - fragmentstart );
GlobalUnlock( handle );
return TRUE;
hhtmldata = GlobalAlloc(0, htmlsize); failed:
GlobalUnlock( handle );
if (hhtmldata) return FALSE;
{
htmldata = GlobalLock(hhtmldata);
if (!htmldata)
{
GlobalFree(hhtmldata);
htmldata = NULL;
goto end;
}
memcpy(htmldata, &data[fragmentstart], fragmentend-fragmentstart);
htmldata[htmlsize-1] = '\0';
*lpBytes = htmlsize;
GlobalUnlock(htmldata);
}
end:
GlobalUnlock(hdata);
return hhtmldata;
} }
@ -1872,29 +1694,17 @@ end:
* *
* Export CF_HDROP format to text/uri-list. * Export CF_HDROP format to text/uri-list.
*/ */
static HANDLE export_hdrop(Display *display, Window requestor, Atom aTarget, static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target, HANDLE handle )
Atom rprop, LPWINE_CLIPDATA lpdata, LPDWORD lpBytes)
{ {
HDROP hDrop;
UINT i; UINT i;
UINT numFiles; UINT numFiles;
HGLOBAL hClipData = NULL; char *textUriList;
char *textUriList = NULL;
UINT textUriListSize = 32; UINT textUriListSize = 32;
UINT next = 0; UINT next = 0;
*lpBytes = 0; textUriList = HeapAlloc( GetProcessHeap(), 0, textUriListSize );
if (!textUriList) return FALSE;
if (!X11DRV_CLIPBOARD_RenderFormat(display, lpdata)) numFiles = DragQueryFileW( handle, 0xFFFFFFFF, NULL, 0 );
{
ERR("Failed to export %04x format\n", lpdata->wFormatID);
return 0;
}
hClipData = GlobalAlloc(GMEM_FIXED, textUriListSize);
if (hClipData == NULL)
return 0;
hDrop = (HDROP) lpdata->hData;
numFiles = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
for (i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
{ {
UINT dosFilenameSize; UINT dosFilenameSize;
@ -1903,10 +1713,10 @@ static HANDLE export_hdrop(Display *display, Window requestor, Atom aTarget,
UINT uriSize; UINT uriSize;
UINT u; UINT u;
dosFilenameSize = 1 + DragQueryFileW(hDrop, i, NULL, 0); dosFilenameSize = 1 + DragQueryFileW( handle, i, NULL, 0 );
dosFilename = HeapAlloc(GetProcessHeap(), 0, dosFilenameSize*sizeof(WCHAR)); dosFilename = HeapAlloc(GetProcessHeap(), 0, dosFilenameSize*sizeof(WCHAR));
if (dosFilename == NULL) goto failed; if (dosFilename == NULL) goto failed;
DragQueryFileW(hDrop, i, dosFilename, dosFilenameSize); DragQueryFileW( handle, i, dosFilename, dosFilenameSize );
unixFilename = wine_get_unix_file_name(dosFilename); unixFilename = wine_get_unix_file_name(dosFilename);
HeapFree(GetProcessHeap(), 0, dosFilename); HeapFree(GetProcessHeap(), 0, dosFilename);
if (unixFilename == NULL) goto failed; if (unixFilename == NULL) goto failed;
@ -1916,10 +1726,10 @@ static HANDLE export_hdrop(Display *display, Window requestor, Atom aTarget,
if ((next + uriSize) > textUriListSize) if ((next + uriSize) > textUriListSize)
{ {
UINT biggerSize = max( 2 * textUriListSize, next + uriSize ); UINT biggerSize = max( 2 * textUriListSize, next + uriSize );
HGLOBAL bigger = GlobalReAlloc(hClipData, biggerSize, 0); void *bigger = HeapReAlloc( GetProcessHeap(), 0, textUriList, biggerSize );
if (bigger) if (bigger)
{ {
hClipData = bigger; textUriList = bigger;
textUriListSize = biggerSize; textUriListSize = biggerSize;
} }
else else
@ -1928,7 +1738,6 @@ static HANDLE export_hdrop(Display *display, Window requestor, Atom aTarget,
goto failed; goto failed;
} }
} }
textUriList = GlobalLock(hClipData);
lstrcpyA(&textUriList[next], "file:///"); lstrcpyA(&textUriList[next], "file:///");
next += 8; next += 8;
/* URL encode everything - unnecessary, but easier/lighter than linking in shlwapi, and can't hurt */ /* URL encode everything - unnecessary, but easier/lighter than linking in shlwapi, and can't hurt */
@ -1941,17 +1750,41 @@ static HANDLE export_hdrop(Display *display, Window requestor, Atom aTarget,
} }
textUriList[next++] = '\r'; textUriList[next++] = '\r';
textUriList[next++] = '\n'; textUriList[next++] = '\n';
GlobalUnlock(hClipData);
HeapFree(GetProcessHeap(), 0, unixFilename); HeapFree(GetProcessHeap(), 0, unixFilename);
} }
put_property( display, win, prop, target, 8, textUriList, next );
*lpBytes = next; HeapFree( GetProcessHeap(), 0, textUriList );
return hClipData; return TRUE;
failed: failed:
GlobalFree(hClipData); HeapFree( GetProcessHeap(), 0, textUriList );
*lpBytes = 0; return FALSE;
return 0; }
/**************************************************************************
* export_selection
*
* Export selection data, depending on the target type.
*/
static BOOL export_selection( Display *display, Window win, Atom prop, Atom target )
{
struct clipboard_format *format = X11DRV_CLIPBOARD_LookupProperty( NULL, target );
HANDLE handle = 0;
if (!format || !format->export) return FALSE;
TRACE( "win %lx prop %s target %s exporting %s\n", win,
debugstr_xatom( prop ), debugstr_xatom( target ), debugstr_format( format->id ) );
if (format->id)
{
LPWINE_CLIPDATA data = X11DRV_CLIPBOARD_LookupData( format->id );
if (!data) return FALSE;
if (!X11DRV_CLIPBOARD_RenderFormat( display, data )) return FALSE;
handle = data->hData;
}
return format->export( display, win, prop, target, handle );
} }
@ -2748,8 +2581,7 @@ static Atom X11DRV_SelectionRequest_TARGETS( Display *display, Window requestor,
LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry ) LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry )
LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry ) LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry )
if ((format->id == lpData->wFormatID) && if (format->id == lpData->wFormatID && format->export && format->atom)
format->lpDrvExportFunc && format->atom)
cTargets++; cTargets++;
TRACE(" found %d formats\n", cTargets); TRACE(" found %d formats\n", cTargets);
@ -2764,8 +2596,7 @@ static Atom X11DRV_SelectionRequest_TARGETS( Display *display, Window requestor,
LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry ) LIST_FOR_EACH_ENTRY( lpData, &data_list, WINE_CLIPDATA, entry )
LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry ) LIST_FOR_EACH_ENTRY( format, &format_list, WINE_CLIPFORMAT, entry )
if ((format->id == lpData->wFormatID) && if (format->id == lpData->wFormatID && format->export && format->atom)
format->lpDrvExportFunc && format->atom)
{ {
TRACE( "%d: %s -> %s\n", i, debugstr_format( format->id ), TRACE( "%d: %s -> %s\n", i, debugstr_format( format->id ),
debugstr_xatom( format->atom )); debugstr_xatom( format->atom ));
@ -2920,39 +2751,8 @@ static void X11DRV_HandleSelectionRequest( HWND hWnd, XSelectionRequestEvent *ev
/* MULTIPLE selection request */ /* MULTIPLE selection request */
rprop = X11DRV_SelectionRequest_MULTIPLE( hWnd, event ); rprop = X11DRV_SelectionRequest_MULTIPLE( hWnd, event );
} }
else else if (!export_selection( display, event->requestor, rprop, event->target ))
{ rprop = None; /* report failure to client */
LPWINE_CLIPFORMAT lpFormat = X11DRV_CLIPBOARD_LookupProperty(NULL, event->target);
BOOL success = FALSE;
if (lpFormat && lpFormat->lpDrvExportFunc)
{
LPWINE_CLIPDATA lpData = X11DRV_CLIPBOARD_LookupData(lpFormat->id);
if (lpData)
{
unsigned char* lpClipData;
DWORD cBytes;
HANDLE hClipData = lpFormat->lpDrvExportFunc(display, request, event->target,
rprop, lpData, &cBytes);
if (hClipData && (lpClipData = GlobalLock(hClipData)))
{
TRACE("\tUpdating property %s, %d bytes\n",
debugstr_format(lpFormat->id), cBytes);
put_property( display, request, rprop, event->target, 8, lpClipData, cBytes );
GlobalUnlock(hClipData);
GlobalFree(hClipData);
success = TRUE;
}
}
}
if (!success)
rprop = None; /* report failure to client */
}
END: END:
/* reply to sender /* reply to sender