[PATCH 2/8] winex11: Move XdndPosition event handler to event.c.

Jacek Caban wine at gitlab.winehq.org
Thu Apr 28 07:12:14 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

---
 dlls/winex11.drv/event.c   | 72 +++++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/unixlib.h | 43 +++++++++++++++++++++++
 dlls/winex11.drv/x11drv.h  | 10 ++----
 dlls/winex11.drv/xdnd.c    | 70 ++++++++++--------------------------
 4 files changed, 135 insertions(+), 60 deletions(-)
 create mode 100644 dlls/winex11.drv/unixlib.h

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index c8cd3fd5ef1..2bfcd3211ae 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -1826,6 +1826,76 @@ static void handle_xdnd_enter_event( HWND hWnd, XClientMessageEvent *event )
 }
 
 
+static DWORD xdnd_action_to_drop_effect( long action )
+{
+    /* In Windows, nothing but the given effects is allowed.
+     * In X the given action is just a hint, and you can always
+     * XdndActionCopy and XdndActionPrivate, so be more permissive. */
+    if (action == x11drv_atom(XdndActionCopy))
+        return DROPEFFECT_COPY;
+    else if (action == x11drv_atom(XdndActionMove))
+        return DROPEFFECT_MOVE | DROPEFFECT_COPY;
+    else if (action == x11drv_atom(XdndActionLink))
+        return DROPEFFECT_LINK | DROPEFFECT_COPY;
+    else if (action == x11drv_atom(XdndActionAsk))
+        /* FIXME: should we somehow ask the user what to do here? */
+        return DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK;
+
+    FIXME( "unknown action %ld, assuming DROPEFFECT_COPY\n", action );
+    return DROPEFFECT_COPY;
+}
+
+
+static long drop_effect_to_xdnd_action( DWORD effect )
+{
+    if (effect == DROPEFFECT_COPY)
+        return x11drv_atom(XdndActionCopy);
+    else if (effect == DROPEFFECT_MOVE)
+        return x11drv_atom(XdndActionMove);
+    else if (effect == DROPEFFECT_LINK)
+        return x11drv_atom(XdndActionLink);
+    else if (effect == DROPEFFECT_NONE)
+        return None;
+
+    FIXME( "unknown drop effect %u, assuming XdndActionCopy\n", effect );
+    return x11drv_atom(XdndActionCopy);
+}
+
+
+static void handle_xdnd_position_event( HWND hwnd, XClientMessageEvent *event )
+{
+    struct dnd_position_event_params params;
+    XClientMessageEvent e;
+    DWORD effect;
+
+    params.type = DND_POSITION_EVENT;
+    params.hwnd = hwnd;
+    params.point = root_to_virtual_screen( event->data.l[2] >> 16, event->data.l[2] & 0xFFFF );
+    params.effect = effect = xdnd_action_to_drop_effect( event->data.l[4] );
+
+    effect = handle_dnd_event( &params );
+
+    TRACE( "actionRequested(%ld) chosen(0x%x) at x(%d),y(%d)\n",
+           event->data.l[4], effect, params.point.x, params.point.y );
+
+    /*
+     * Let source know if we're accepting the drop by
+     * sending a status message.
+     */
+    e.type = ClientMessage;
+    e.display = event->display;
+    e.window = event->data.l[0];
+    e.message_type = x11drv_atom(XdndStatus);
+    e.format = 32;
+    e.data.l[0] = event->window;
+    e.data.l[1] = !!effect;
+    e.data.l[2] = 0; /* Empty Rect */
+    e.data.l[3] = 0; /* Empty Rect */
+    e.data.l[4] = drop_effect_to_xdnd_action( effect );
+    XSendEvent( event->display, event->data.l[0], False, NoEventMask, (XEvent *)&e );
+}
+
+
 struct client_message_handler
 {
     int    atom;                                  /* protocol atom */
@@ -1839,7 +1909,7 @@ static const struct client_message_handler client_messages[] =
     { XATOM__XEMBED,      handle_xembed_protocol },
     { XATOM_DndProtocol,  handle_dnd_protocol },
     { XATOM_XdndEnter,    handle_xdnd_enter_event },
-    { XATOM_XdndPosition, X11DRV_XDND_PositionEvent },
+    { XATOM_XdndPosition, handle_xdnd_position_event },
     { XATOM_XdndDrop,     X11DRV_XDND_DropEvent },
     { XATOM_XdndLeave,    X11DRV_XDND_LeaveEvent }
 };
diff --git a/dlls/winex11.drv/unixlib.h b/dlls/winex11.drv/unixlib.h
new file mode 100644
index 00000000000..7f8ec28b7cf
--- /dev/null
+++ b/dlls/winex11.drv/unixlib.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "ntuser.h"
+#include "wine/unixlib.h"
+
+/* DnD support */
+
+struct format_entry
+{
+    UINT format;
+    UINT size;
+    char data[1];
+};
+
+enum dnd_event_type
+{
+    DND_POSITION_EVENT,
+};
+
+/* DND_POSITION_EVENT params */
+struct dnd_position_event_params
+{
+    UINT  type;
+    HWND  hwnd;
+    POINT point;
+    DWORD effect;
+};
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 9339c1c08e6..d49643a890b 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -61,6 +61,7 @@ typedef int Status;
 #include "winbase.h"
 #include "ntgdi.h"
 #include "wine/gdi_driver.h"
+#include "unixlib.h"
 #include "wine/list.h"
 
 #define MAX_DASHLEN 16
@@ -293,18 +294,11 @@ extern BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp,
                                      DWORD dwReadLen) DECLSPEC_HIDDEN;
 extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultlen) DECLSPEC_HIDDEN;
 
-extern void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
 extern void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
 extern void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
 
-struct format_entry
-{
-    UINT format;
-    UINT size;
-    char data[1];
-};
-
 extern void handle_dnd_enter_event( struct format_entry *formats, ULONG size ) DECLSPEC_HIDDEN;
+extern UINT handle_dnd_event( void *params ) DECLSPEC_HIDDEN;
 
 extern struct format_entry *import_xdnd_selection( Display *display, Window win, Atom selection,
                                                    Atom *targets, UINT count,
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c
index e56fc964ada..7633738917f 100644
--- a/dlls/winex11.drv/xdnd.c
+++ b/dlls/winex11.drv/xdnd.c
@@ -142,27 +142,6 @@ static IDropTarget* get_droptarget_pointer(HWND hwnd)
     return droptarget;
 }
 
-/**************************************************************************
- * X11DRV_XDND_XdndActionToDROPEFFECT
- */
-static DWORD X11DRV_XDND_XdndActionToDROPEFFECT(long action)
-{
-    /* In Windows, nothing but the given effects is allowed.
-     * In X the given action is just a hint, and you can always
-     * XdndActionCopy and XdndActionPrivate, so be more permissive. */
-    if (action == x11drv_atom(XdndActionCopy))
-        return DROPEFFECT_COPY;
-    else if (action == x11drv_atom(XdndActionMove))
-        return DROPEFFECT_MOVE | DROPEFFECT_COPY;
-    else if (action == x11drv_atom(XdndActionLink))
-        return DROPEFFECT_LINK | DROPEFFECT_COPY;
-    else if (action == x11drv_atom(XdndActionAsk))
-        /* FIXME: should we somehow ask the user what to do here? */
-        return DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK;
-    FIXME("unknown action %ld, assuming DROPEFFECT_COPY\n", action);
-    return DROPEFFECT_COPY;
-}
-
 /**************************************************************************
  * X11DRV_XDND_DROPEFFECTToXdndAction
  */
@@ -215,22 +194,17 @@ static HWND window_accepting_files(HWND hwnd)
  *
  * Handle an XdndPosition event.
  */
-void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event )
+static BOOL handle_position_event( struct dnd_position_event_params *params )
 {
-    XClientMessageEvent e;
     int accept = 0; /* Assume we're not accepting */
     IDropTarget *dropTarget = NULL;
-    DWORD effect;
+    DWORD effect = params->effect;
     POINTL pointl;
     HWND targetWindow;
     HRESULT hr;
 
-    XDNDxy = root_to_virtual_screen( event->data.l[2] >> 16, event->data.l[2] & 0xFFFF );
-    targetWindow = window_from_point_dnd(hWnd, XDNDxy);
-
-    pointl.x = XDNDxy.x;
-    pointl.y = XDNDxy.y;
-    effect = X11DRV_XDND_XdndActionToDROPEFFECT(event->data.l[4]);
+    XDNDxy = params->point;
+    targetWindow = window_from_point_dnd( params->hwnd, XDNDxy );
 
     if (!XDNDAccepted || XDNDLastTargetWnd != targetWindow)
     {
@@ -301,27 +275,7 @@ void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event )
         }
     }
 
-    TRACE("actionRequested(%ld) accept(%d) chosen(0x%x) at x(%d),y(%d)\n",
-          event->data.l[4], accept, effect, XDNDxy.x, XDNDxy.y);
-
-    /*
-     * Let source know if we're accepting the drop by
-     * sending a status message.
-     */
-    e.type = ClientMessage;
-    e.display = event->display;
-    e.window = event->data.l[0];
-    e.message_type = x11drv_atom(XdndStatus);
-    e.format = 32;
-    e.data.l[0] = event->window;
-    e.data.l[1] = accept;
-    e.data.l[2] = 0; /* Empty Rect */
-    e.data.l[3] = 0; /* Empty Rect */
-    if (accept)
-        e.data.l[4] = X11DRV_XDND_DROPEFFECTToXdndAction(effect);
-    else
-        e.data.l[4] = None;
-    XSendEvent(event->display, event->data.l[0], False, NoEventMask, (XEvent*)&e);
+    return accept ? effect : 0;
 }
 
 /**************************************************************************
@@ -806,3 +760,17 @@ static IDataObjectVtbl xdndDataObjectVtbl =
 };
 
 static IDataObject XDNDDataObject = { &xdndDataObjectVtbl };
+
+UINT handle_dnd_event( void *params )
+{
+
+    switch (*(UINT *)params)
+    {
+    case DND_POSITION_EVENT:
+        return handle_position_event( params );
+
+    default:
+        ERR( "invalid event\n" );
+        return 0;
+    }
+}
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/11



More information about the wine-devel mailing list