From e02c2f82d49c98424f3743c50a32a47d23e15295 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sun, 1 May 2022 22:18:43 +0200 Subject: [PATCH] winex11: Reimplement EVENT_DropFromOffiX using get_dos_file_name. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/winex11.drv/clipboard.c | 52 ++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/event.c | 49 ++++++++------------------------- dlls/winex11.drv/x11drv.h | 1 + 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c index f2f93c9ee38..4ba36239595 100644 --- a/dlls/winex11.drv/clipboard.c +++ b/dlls/winex11.drv/clipboard.c @@ -1042,6 +1042,58 @@ static void *import_text_html( Atom type, const void *data, size_t size, size_t } +/************************************************************************** + * file_list_to_drop_files + */ +void *file_list_to_drop_files( const void *data, size_t size, size_t *ret_size ) +{ + size_t buf_size = 4096, path_size; + DROPFILES *drop = NULL; + const char *ptr; + WCHAR *path; + + for (ptr = data; ptr < (const char *)data + size; ptr += strlen( ptr ) + 1) + { + path = get_dos_file_name( ptr ); + + TRACE( "converted URI %s to DOS path %s\n", debugstr_a(ptr), debugstr_w(path) ); + + if (!path) continue; + + if (!drop) + { + if (!(drop = malloc( buf_size ))) return NULL; + drop->pFiles = sizeof(*drop); + drop->pt.x = drop->pt.y = 0; + drop->fNC = FALSE; + drop->fWide = TRUE; + *ret_size = sizeof(*drop); + } + + path_size = (lstrlenW( path ) + 1) * sizeof(WCHAR); + if (*ret_size + path_size > buf_size - sizeof(WCHAR)) + { + void *new_buf; + if (!(new_buf = realloc( drop, buf_size * 2 + path_size ))) + { + free( path ); + continue; + } + buf_size = buf_size * 2 + path_size; + drop = new_buf; + } + + memcpy( (char *)drop + *ret_size, path, path_size ); + *ret_size += path_size; + } + + if (!drop) return NULL; + *(WCHAR *)((char *)drop + *ret_size) = 0; + *ret_size += sizeof(WCHAR); + return drop; +} + + /************************************************************************** * uri_list_to_drop_files */ diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index cb0e91821e4..3bd771fa4fd 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1503,7 +1503,7 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) unsigned long aux_long; unsigned char* p_data = NULL; Atom atom_aux; - int x, y, cx, cy, dummy; + int x, y, cx, cy, dummy, format; Window win, w_aux_root, w_aux_child; if (!(data = get_win_data( hWnd ))) return; @@ -1529,50 +1529,23 @@ static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event ) XGetWindowProperty( event->display, DefaultRootWindow(event->display), x11drv_atom(DndSelection), 0, 65535, FALSE, - AnyPropertyType, &atom_aux, &dummy, + AnyPropertyType, &atom_aux, &format, &data_length, &aux_long, &p_data); - if( !aux_long && p_data) /* don't bother if > 64K */ + if (!aux_long && p_data) /* don't bother if > 64K */ { - char *p = (char *)p_data; - char *p_drop; + DROPFILES *drop; + size_t drop_size; - aux_long = 0; - while( *p ) /* calculate buffer size */ + drop = file_list_to_drop_files( p_data, get_property_size( format, data_length ), &drop_size ); + if (drop) { - INT len = GetShortPathNameA( p, NULL, 0 ); - if (len) aux_long += len + 1; - p += strlen(p) + 1; - } - if( aux_long && aux_long < 65535 ) - { - HDROP hDrop; - DROPFILES *lpDrop; - - aux_long += sizeof(DROPFILES) + 1; - hDrop = GlobalAlloc( GMEM_SHARE, aux_long ); - lpDrop = GlobalLock( hDrop ); - - if( lpDrop ) - { - lpDrop->pFiles = sizeof(DROPFILES); - lpDrop->pt = pt; - lpDrop->fNC = FALSE; - lpDrop->fWide = FALSE; - p_drop = (char *)(lpDrop + 1); - p = (char *)p_data; - while(*p) - { - if (GetShortPathNameA( p, p_drop, aux_long - (p_drop - (char *)lpDrop) )) - p_drop += strlen( p_drop ) + 1; - p += strlen(p) + 1; - } - *p_drop = '\0'; - PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L ); - } + post_drop( hWnd, drop, drop_size ); + free( drop ); } } - 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 6b224f5426a..957ef6ea667 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 *file_list_to_drop_files( const void *data, size_t size, size_t *ret_size ) 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 )