mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-25 01:20:05 +01:00
Add more appropriate system for dealing with pointer motion when
forwarding XDND.
This commit is contained in:
parent
f30d46a9b9
commit
4c5cb82302
5 changed files with 148 additions and 48 deletions
|
|
@ -81,6 +81,16 @@ dmxDnDUpdatePosition (DMXScreenInfo *dmxScreen,
|
|||
|
||||
event.u.clientMessage.u.l.longs0 = dmxScreens[0].selectionProxyWid[0];
|
||||
|
||||
if (pWin)
|
||||
{
|
||||
if (!dmxFakeMotion (&dmxScreen->input, x, y))
|
||||
pWin = NullWindow;
|
||||
}
|
||||
else
|
||||
{
|
||||
dmxEndFakeMotion (&dmxScreen->input);
|
||||
}
|
||||
|
||||
while (pWin)
|
||||
{
|
||||
if ((pWin->mapped) &&
|
||||
|
|
@ -246,50 +256,6 @@ dmxDnDUpdatePosition (DMXScreenInfo *dmxScreen,
|
|||
}
|
||||
}
|
||||
|
||||
/* version 5 of the XDND protocol doesn't provide information about
|
||||
the pointer device that is used so we'll simply update all devices */
|
||||
static void
|
||||
dmxDnDUpdatePointerDevice (ScreenPtr pScreen,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
DMXInputInfo *dmxInput = &dmxScreens[pScreen->myNum].input;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dmxInput->numDevs; i++)
|
||||
{
|
||||
DeviceIntPtr pDevice = dmxInput->devs[i];
|
||||
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDevice);
|
||||
xcb_generic_event_t xevent;
|
||||
|
||||
/* extension device */
|
||||
if (pDevPriv->deviceId >= 0)
|
||||
{
|
||||
xcb_input_device_motion_notify_event_t *xmotion =
|
||||
(xcb_input_device_motion_notify_event_t *) &xevent;
|
||||
|
||||
xmotion->response_type = dmxInput->eventBase +
|
||||
XCB_INPUT_DEVICE_MOTION_NOTIFY;
|
||||
xmotion->device_id = pDevPriv->deviceId;
|
||||
|
||||
xmotion->event_x = x;
|
||||
xmotion->event_y = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
xcb_motion_notify_event_t *xmotion =
|
||||
(xcb_motion_notify_event_t *) &xevent;
|
||||
|
||||
xmotion->response_type = XCB_MOTION_NOTIFY;
|
||||
|
||||
xmotion->event_x = x;
|
||||
xmotion->event_y = y;
|
||||
}
|
||||
|
||||
(*pDevPriv->EventCheck) (pDevice, &xevent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dmxDnDTranslateCoordinatesReply (ScreenPtr pScreen,
|
||||
unsigned int sequence,
|
||||
|
|
@ -312,8 +278,6 @@ dmxDnDTranslateCoordinatesReply (ScreenPtr pScreen,
|
|||
WindowPtr pWin = WindowTable[pScreen->myNum];
|
||||
xcb_client_message_event_t xevent;
|
||||
|
||||
dmxDnDUpdatePointerDevice (pScreen, xcoord->dst_x, xcoord->dst_y);
|
||||
|
||||
#ifdef PANORAMIX
|
||||
if (!noPanoramiXExtension)
|
||||
pWin = WindowTable[0];
|
||||
|
|
@ -596,6 +560,8 @@ dmxDnDDropMessage (ScreenPtr pScreen,
|
|||
{
|
||||
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
||||
|
||||
dmxEndFakeMotion (&dmxScreen->input);
|
||||
|
||||
if (dmxScreen->dndWindow)
|
||||
{
|
||||
WindowPtr pWin;
|
||||
|
|
@ -760,7 +726,8 @@ dmxDnDClientMessageEvent (xEvent *event)
|
|||
if (dmxScreen->dndAcceptedAction &&
|
||||
ValidAtom (dmxScreen->dndAcceptedAction))
|
||||
xevent.data.data32[4] =
|
||||
dmxBEAtom (dmxScreen, dmxScreen->dndAcceptedAction);
|
||||
dmxBEAtom (dmxScreen,
|
||||
dmxScreen->dndAcceptedAction);
|
||||
|
||||
xcb_send_event (dmxScreen->connection,
|
||||
FALSE,
|
||||
|
|
|
|||
|
|
@ -285,6 +285,44 @@ dmxDeactivatePointerGrab (DeviceIntPtr pDev)
|
|||
&pDev->deviceGrab);
|
||||
}
|
||||
|
||||
Bool
|
||||
dmxActivateFakePointerGrab (DeviceIntPtr pDev,
|
||||
GrabPtr pGrab)
|
||||
{
|
||||
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
|
||||
|
||||
if (pDevPriv->fakeGrab)
|
||||
return TRUE;
|
||||
|
||||
if (pDev->deviceGrab.grab)
|
||||
return FALSE;
|
||||
|
||||
pDevPriv->fakeGrab = TRUE;
|
||||
|
||||
DMX_UNWRAP (ActivateGrab, pDevPriv, &pDev->deviceGrab);
|
||||
(*pDev->deviceGrab.ActivateGrab) (pDev, pGrab, currentTime, FALSE);
|
||||
DMX_WRAP (ActivateGrab, dmxActivatePointerGrab, pDevPriv,
|
||||
&pDev->deviceGrab);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dmxDeactivateFakePointerGrab (DeviceIntPtr pDev)
|
||||
{
|
||||
dmxDevicePrivPtr pDevPriv = DMX_GET_DEVICE_PRIV (pDev);
|
||||
|
||||
if (!pDevPriv->fakeGrab)
|
||||
return;
|
||||
|
||||
pDevPriv->fakeGrab = FALSE;
|
||||
|
||||
DMX_UNWRAP (DeactivateGrab, pDevPriv, &pDev->deviceGrab);
|
||||
(*pDev->deviceGrab.DeactivateGrab) (pDev);
|
||||
DMX_WRAP (DeactivateGrab, dmxDeactivatePointerGrab, pDevPriv,
|
||||
&pDev->deviceGrab);
|
||||
}
|
||||
|
||||
static int
|
||||
dmxProcGrabButton (ClientPtr client)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ extern void dmxActivatePointerGrab (DeviceIntPtr pDev,
|
|||
Bool autoGrab);
|
||||
extern void dmxDeactivatePointerGrab (DeviceIntPtr pDev);
|
||||
|
||||
extern Bool dmxActivateFakePointerGrab (DeviceIntPtr pDev,
|
||||
GrabPtr pGrab);
|
||||
extern void dmxDeactivateFakePointerGrab (DeviceIntPtr pDev);
|
||||
|
||||
extern void dmxInitGrabs (void);
|
||||
extern void dmxResetGrabs (void);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "dmx.h"
|
||||
#include "dmxlog.h"
|
||||
#include "dmxinput.h"
|
||||
#include "dmxgrab.h"
|
||||
#include "dmxwindow.h"
|
||||
#include "dmxcursor.h"
|
||||
#include "dmxscrinit.h"
|
||||
|
|
@ -426,6 +427,82 @@ dmxUpdateSpritePosition (DeviceIntPtr pDevice,
|
|||
return dmxButtonEvent (pDevice, 0, x, y, XCB_MOTION_NOTIFY);
|
||||
}
|
||||
|
||||
Bool
|
||||
dmxFakeMotion (DMXInputInfo *dmxInput,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
DMXScreenInfo *dmxScreen = (DMXScreenInfo *) dmxInput;
|
||||
WindowPtr pWin = WindowTable[dmxScreen->index];
|
||||
GrabRec newGrab;
|
||||
int i;
|
||||
|
||||
#ifdef PANORAMIX
|
||||
if (!noPanoramiXExtension)
|
||||
pWin = WindowTable[0];
|
||||
#endif
|
||||
|
||||
memset (&newGrab, 0, sizeof (GrabRec));
|
||||
|
||||
newGrab.window = pWin;
|
||||
newGrab.resource = 0;
|
||||
newGrab.ownerEvents = xFalse;
|
||||
newGrab.cursor = NULL;
|
||||
newGrab.confineTo = NullWindow;
|
||||
newGrab.eventMask = NoEventMask;
|
||||
newGrab.genericMasks = NULL;
|
||||
newGrab.next = NULL;
|
||||
newGrab.keyboardMode = GrabModeAsync;
|
||||
newGrab.pointerMode = GrabModeAsync;
|
||||
|
||||
for (i = 0; i < dmxInput->numDevs; i++)
|
||||
{
|
||||
DeviceIntPtr pDevice = dmxInput->devs[i];
|
||||
|
||||
if (!pDevice->isMaster && pDevice->u.master)
|
||||
pDevice = pDevice->u.master;
|
||||
|
||||
if (!pDevice->button)
|
||||
continue;
|
||||
|
||||
newGrab.device = pDevice;
|
||||
|
||||
if (!dmxActivateFakePointerGrab (pDevice, &newGrab))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < dmxInput->numDevs; i++)
|
||||
{
|
||||
DeviceIntPtr pDevice = dmxInput->devs[i];
|
||||
|
||||
if (!pDevice->button)
|
||||
continue;
|
||||
|
||||
dmxUpdateSpritePosition (pDevice, x, y);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dmxEndFakeMotion (DMXInputInfo *dmxInput)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dmxInput->numDevs; i++)
|
||||
{
|
||||
DeviceIntPtr pDevice = dmxInput->devs[i];
|
||||
|
||||
if (!pDevice->isMaster && pDevice->u.master)
|
||||
pDevice = pDevice->u.master;
|
||||
|
||||
if (!pDevice->button)
|
||||
continue;
|
||||
|
||||
dmxDeactivateFakePointerGrab (pDevice);
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
||||
xcb_generic_event_t *event)
|
||||
|
|
@ -440,7 +517,8 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
|||
case XCB_MOTION_NOTIFY: {
|
||||
xcb_motion_notify_event_t *xmotion =
|
||||
(xcb_motion_notify_event_t *) event;
|
||||
|
||||
|
||||
dmxEndFakeMotion (dmxInput);
|
||||
dmxUpdateSpritePosition (pButtonDev,
|
||||
xmotion->event_x,
|
||||
xmotion->event_y);
|
||||
|
|
@ -450,6 +528,7 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
|||
xcb_button_press_event_t *xbutton =
|
||||
(xcb_button_press_event_t *) event;
|
||||
|
||||
dmxEndFakeMotion (dmxInput);
|
||||
dmxUpdateSpritePosition (pButtonDev,
|
||||
xbutton->event_x,
|
||||
xbutton->event_y);
|
||||
|
|
@ -480,6 +559,7 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
|||
if (id != (xmotion->device_id & DEVICE_BITS))
|
||||
return FALSE;
|
||||
|
||||
dmxEndFakeMotion (dmxInput);
|
||||
dmxUpdateSpritePosition (pButtonDev,
|
||||
xmotion->event_x,
|
||||
xmotion->event_y);
|
||||
|
|
@ -492,6 +572,7 @@ dmxDevicePointerEventCheck (DeviceIntPtr pDevice,
|
|||
if (id != (xbutton->device_id & DEVICE_BITS))
|
||||
return FALSE;
|
||||
|
||||
dmxEndFakeMotion (dmxInput);
|
||||
dmxUpdateSpritePosition (pButtonDev,
|
||||
xbutton->event_x,
|
||||
xbutton->event_y);
|
||||
|
|
@ -1466,6 +1547,7 @@ dmxAddInputDevice (DMXInputInfo *dmxInput,
|
|||
pDevPriv->deviceId = deviceId;
|
||||
pDevPriv->masterId = masterId;
|
||||
pDevPriv->device = NULL;
|
||||
pDevPriv->fakeGrab = xFalse;
|
||||
pDevPriv->EventCheck = EventCheck;
|
||||
pDevPriv->ReplyCheck = ReplyCheck;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ typedef struct _dmxDevicePriv {
|
|||
KeySymsRec keySyms;
|
||||
KeyCode *keycode;
|
||||
xcb_void_cookie_t grab;
|
||||
Bool fakeGrab;
|
||||
|
||||
Bool (*EventCheck) (DeviceIntPtr, xcb_generic_event_t *);
|
||||
Bool (*ReplyCheck) (DeviceIntPtr, unsigned int, xcb_generic_reply_t *);
|
||||
|
|
@ -91,6 +92,14 @@ dmxInputUngrabPointer (DMXInputInfo *dmxInput,
|
|||
DeviceIntPtr pDevice,
|
||||
WindowPtr pWindow);
|
||||
|
||||
Bool
|
||||
dmxFakeMotion (DMXInputInfo *dmxInput,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void
|
||||
dmxEndFakeMotion (DMXInputInfo *dmxInput);
|
||||
|
||||
int
|
||||
dmxInputEnable (DMXInputInfo *dmxInput);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue