Jacek Caban : winex11: Reimplement EVENT_DropFromOffiX using get_dos_file_name.

Alexandre Julliard julliard at winehq.org
Tue May 3 15:39:24 CDT 2022


Module: wine
Branch: master
Commit: e02c2f82d49c98424f3743c50a32a47d23e15295
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e02c2f82d49c98424f3743c50a32a47d23e15295

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sun May  1 22:18:43 2022 +0200

winex11: Reimplement EVENT_DropFromOffiX using get_dos_file_name.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 )




More information about the wine-cvs mailing list