diff options
-rw-r--r-- | hw/dmx/dmxdnd.c | 61 | ||||
-rw-r--r-- | hw/dmx/dmxgrab.c | 38 | ||||
-rw-r--r-- | hw/dmx/dmxgrab.h | 4 | ||||
-rw-r--r-- | hw/dmx/dmxinput.c | 84 | ||||
-rw-r--r-- | hw/dmx/dmxinput.h | 9 |
5 files changed, 148 insertions, 48 deletions
diff --git a/hw/dmx/dmxdnd.c b/hw/dmx/dmxdnd.c index dee70b934..6927e0435 100644 --- a/hw/dmx/dmxdnd.c +++ b/hw/dmx/dmxdnd.c @@ -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, diff --git a/hw/dmx/dmxgrab.c b/hw/dmx/dmxgrab.c index 17f24f3ed..2cfb72a8f 100644 --- a/hw/dmx/dmxgrab.c +++ b/hw/dmx/dmxgrab.c @@ -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) { diff --git a/hw/dmx/dmxgrab.h b/hw/dmx/dmxgrab.h index 4a2f96c3c..ed0de0a5a 100644 --- a/hw/dmx/dmxgrab.h +++ b/hw/dmx/dmxgrab.h @@ -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); diff --git a/hw/dmx/dmxinput.c b/hw/dmx/dmxinput.c index 3b35a7525..f1ba3e00d 100644 --- a/hw/dmx/dmxinput.c +++ b/hw/dmx/dmxinput.c @@ -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; diff --git a/hw/dmx/dmxinput.h b/hw/dmx/dmxinput.h index f412224ed..9dd1385c0 100644 --- a/hw/dmx/dmxinput.h +++ b/hw/dmx/dmxinput.h @@ -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); |