From: Jacek Caban jacek@codeweavers.com
Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winex11.drv/clipboard.c | 17 +++-- dlls/winex11.drv/event.c | 118 ++++++++++++----------------------- dlls/winex11.drv/x11drv.h | 1 + 3 files changed, 54 insertions(+), 82 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c index 506d1a81f0f..f2f93c9ee38 100644 --- a/dlls/winex11.drv/clipboard.c +++ b/dlls/winex11.drv/clipboard.c @@ -1043,11 +1043,9 @@ static void *import_text_html( Atom type, const void *data, size_t size, size_t
/************************************************************************** - * import_text_uri_list - * - * Import text/uri-list. + * uri_list_to_drop_files */ -static void *import_text_uri_list( Atom type, const void *data, size_t size, size_t *ret_size ) +void *uri_list_to_drop_files( const void *data, size_t size, size_t *ret_size ) { const char *uriList = data; char *uri; @@ -1121,6 +1119,17 @@ static void *import_text_uri_list( Atom type, const void *data, size_t size, siz }
+/************************************************************************** + * import_text_uri_list + * + * Import text/uri-list. + */ +static void *import_text_uri_list( Atom type, const void *data, size_t size, size_t *ret_size ) +{ + return uri_list_to_drop_files( data, size, ret_size ); +} + + /************************************************************************** * import_targets * diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 5a22464d594..cb0e91821e4 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1476,6 +1476,20 @@ static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt ) return hQueryWnd; }
+static void post_drop( HWND hwnd, DROPFILES *drop, ULONG size ) +{ + HDROP handle; + + if ((handle = GlobalAlloc( GMEM_SHARE, size ))) + { + DROPFILES *ptr = GlobalLock( handle ); + memcpy( ptr, drop, size ); + ptr->fWide = TRUE; + GlobalUnlock( handle ); + PostMessageW( hwnd, WM_DROPFILES, (WPARAM)handle, 0 ); + } +} + /********************************************************************** * EVENT_DropFromOffix * @@ -1573,14 +1587,11 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event ) { struct x11drv_win_data *win_data; unsigned long data_length; - unsigned long aux_long, drop_len = 0; + unsigned long aux_long; unsigned char *p_data = NULL; /* property data */ - char *p_drop = NULL; - char *p, *next; int x, y; - POINT pos; - DROPFILES *lpDrop; - HDROP hDrop; + DROPFILES *drop; + int format; union { Atom atom_aux; int i; @@ -1592,87 +1603,38 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
XGetWindowProperty( event->display, DefaultRootWindow(event->display), x11drv_atom(DndSelection), 0, 65535, FALSE, - AnyPropertyType, &u.atom_aux, &u.i, + AnyPropertyType, &u.atom_aux, &format, &data_length, &aux_long, &p_data); if (aux_long) WARN("property too large, truncated!\n"); TRACE("urls=%s\n", p_data);
- if( !aux_long && p_data) { /* don't bother if > 64K */ - /* calculate length */ - p = (char*) p_data; - next = strchr(p, '\n'); - while (p) { - if (next) *next=0; - if (strncmp(p,"file:",5) == 0 ) { - INT len = GetShortPathNameA( p+5, NULL, 0 ); - if (len) drop_len += len + 1; - } - if (next) { - *next = '\n'; - p = next + 1; - next = strchr(p, '\n'); - } else { - p = NULL; - } - } - - if( drop_len && drop_len < 65535 ) { - XQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux, - &x, &y, &u.i, &u.i, &u.u); - pos = root_to_virtual_screen( x, y ); - - drop_len += sizeof(DROPFILES) + 1; - hDrop = GlobalAlloc( GMEM_SHARE, drop_len ); - lpDrop = GlobalLock( hDrop ); + if (!aux_long && p_data) /* don't bother if > 64K */ + { + size_t drop_size; + drop = uri_list_to_drop_files( p_data, get_property_size( format, data_length ), &drop_size );
- if( lpDrop && (win_data = get_win_data( hWnd ))) + if (drop) { - lpDrop->pFiles = sizeof(DROPFILES); - lpDrop->pt = pos; - lpDrop->fNC = - (pos.x < (win_data->client_rect.left - win_data->whole_rect.left) || - pos.y < (win_data->client_rect.top - win_data->whole_rect.top) || - pos.x > (win_data->client_rect.right - win_data->whole_rect.left) || - pos.y > (win_data->client_rect.bottom - win_data->whole_rect.top) ); - lpDrop->fWide = FALSE; - p_drop = (char*)(lpDrop + 1); - release_win_data( win_data ); + XQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux, + &x, &y, &u.i, &u.i, &u.u); + drop->pt = root_to_virtual_screen( x, y ); + + if ((win_data = get_win_data( hWnd ))) + { + drop->fNC = + (drop->pt.x < (win_data->client_rect.left - win_data->whole_rect.left) || + drop->pt.y < (win_data->client_rect.top - win_data->whole_rect.top) || + drop->pt.x > (win_data->client_rect.right - win_data->whole_rect.left) || + drop->pt.y > (win_data->client_rect.bottom - win_data->whole_rect.top) ); + release_win_data( win_data ); + } + + post_drop( hWnd, drop, drop_size ); + free( drop ); } - - /* create message content */ - if (p_drop) { - p = (char*) p_data; - next = strchr(p, '\n'); - while (p) { - if (next) *next=0; - if (strncmp(p,"file:",5) == 0 ) { - INT len = GetShortPathNameA( p+5, p_drop, 65535 ); - if (len) { - TRACE("drop file %s as %s\n", p+5, p_drop); - p_drop += len+1; - } else { - WARN("can't convert file %s to dos name\n", p+5); - } - } else { - WARN("unknown mime type %s\n", p); - } - if (next) { - *next = '\n'; - p = next + 1; - next = strchr(p, '\n'); - } else { - p = NULL; - } - *p_drop = '\0'; - } - - GlobalUnlock(hDrop); - PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); - } - } } - if( p_data ) XFree(p_data); + if (p_data) XFree( p_data ); }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 2ff6bb00eb6..6b224f5426a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -661,6 +661,7 @@ extern void update_systray_balloon_position(void) DECLSPEC_HIDDEN; extern HWND create_foreign_window( Display *display, Window window ) DECLSPEC_HIDDEN; extern BOOL update_clipboard( HWND hwnd ) DECLSPEC_HIDDEN; extern void init_win_context(void) DECLSPEC_HIDDEN; +extern void *uri_list_to_drop_files( const void *data, size_t size, size_t *ret_size ) DECLSPEC_HIDDEN;
static inline void mirror_rect( const RECT *window_rect, RECT *rect ) {