winex11: Move XdndPosition event handler to event.c.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3b06509f46
commit
1d337249f1
|
@ -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( ¶ms );
|
||||
|
||||
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 }
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue