Add more appropriate system for dealing with pointer motion when

forwarding XDND.
This commit is contained in:
David Reveman 2008-10-13 11:53:21 -04:00
parent f30d46a9b9
commit 4c5cb82302
5 changed files with 148 additions and 48 deletions

View file

@ -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,

View file

@ -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)
{

View file

@ -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);

View file

@ -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;

View file

@ -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);