diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2008-04-11 08:29:52 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2008-04-11 08:29:52 +0930 |
commit | 90f491cf8eb869f27c4278b26c1bb84432b12d63 (patch) | |
tree | e55487aaef9d157a7d03f3f62b185c83f2eb4bb6 /dix/events.c | |
parent | cbe01b3083eb65c9d4259b1071683febebf11600 (diff) | |
parent | b4380d8030927c940ddaea83c4cf24e0b9eb7b96 (diff) |
Merge whot@wombat:~/potoroo/xserver into mpx
Diffstat (limited to 'dix/events.c')
-rw-r--r-- | dix/events.c | 146 |
1 files changed, 86 insertions, 60 deletions
diff --git a/dix/events.c b/dix/events.c index 42ae3f1cb..2775bb2e7 100644 --- a/dix/events.c +++ b/dix/events.c @@ -331,11 +331,14 @@ IsPointerDevice(DeviceIntPtr dev) /* * Return true if a device is a keyboard, check is the same as used by XI to * fill the 'use' field. + * + * Some pointer devices have keys as well (e.g. multimedia keys). Try to not + * count them as keyboard devices. */ _X_EXPORT Bool IsKeyboardDevice(DeviceIntPtr dev) { - return (dev->key && dev->kbdfeed); + return (dev->key && dev->kbdfeed) && !IsPointerDevice(dev);; } #ifdef XEVIE @@ -1394,7 +1397,7 @@ ComputeFreezes(void) replayDev->spriteInfo->sprite->spriteTrace[i]) { if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) { - if (replayDev->focus) + if (replayDev->focus && !IsPointerEvent(xE)) DeliverFocusedEvent(replayDev, xE, w, count); else DeliverDeviceEvents(w, xE, NullGrab, NullWindow, @@ -1404,7 +1407,7 @@ ComputeFreezes(void) } } /* must not still be in the same stack */ - if (replayDev->focus) + if (replayDev->focus && !IsPointerEvent(xE)) DeliverFocusedEvent(replayDev, xE, w, count); else DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count); @@ -3688,7 +3691,18 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, { WindowPtr focus; - if (thisDev->focus) + /* Hack: Some pointer device have a focus class. So we need to check + * for the type of event, to see if we really want to deliver it to + * the focus window. For pointer events, the answer is no. + */ + if (xE->u.u.type == DeviceButtonPress || + xE->u.u.type == DeviceButtonRelease || + xE->u.u.type == DeviceMotionNotify || + xE->u.u.type == ProximityIn || + xE->u.u.type == ProximityOut) + { + focus = PointerRootWin; + } else if (thisDev->focus) { focus = thisDev->focus->win; if (focus == FollowKeyboardWin) @@ -4383,7 +4397,7 @@ EnterLeaveEvent( GrabPtr grab = mouse->deviceGrab.grab; GrabPtr devgrab = mouse->deviceGrab.grab; Mask mask; - int* inWindow; /* no of sprites inside pWin */ + int inWindow; /* zero if no sprites are in window */ Bool sendevent = FALSE; deviceEnterNotify *devEnterLeave; @@ -4436,7 +4450,6 @@ EnterLeaveEvent( IsParent(focus, pWin))) event.u.enterLeave.flags |= ELFlagFocus; - inWindow = &((FocusSemaphoresPtr)dixLookupPrivate(&pWin->devPrivates, FocusPrivatesKey))->enterleave; /* * Sending multiple core enter/leave events to the same window confuse the @@ -4462,16 +4475,15 @@ EnterLeaveEvent( * NotifyNonlinearVirtual to C and nothing to B. */ - if (event.u.u.detail != NotifyVirtual && - event.u.u.detail != NotifyNonlinearVirtual) - { - if (((*inWindow) == (LeaveNotify - type))) - sendevent = TRUE; - } else - { - if (!(*inWindow)) - sendevent = TRUE; - } + /* Clear bit for device, but don't worry about SDs. */ + if (mouse->isMaster && type == LeaveNotify && + (mode != NotifyVirtual && mode != NotifyNonlinearVirtual)) + ENTER_LEAVE_SEMAPHORE_UNSET(pWin, mouse); + + inWindow = EnterLeaveSemaphoresIsset(pWin); + + if (!inWindow) + sendevent = TRUE; if ((mask & filters[mouse->id][type]) && sendevent) { @@ -4483,6 +4495,10 @@ EnterLeaveEvent( filters[mouse->id][type], NullGrab, 0); } + if (mouse->isMaster && type == EnterNotify && + (mode != NotifyVirtual && mode != NotifyNonlinearVirtual)) + ENTER_LEAVE_SEMAPHORE_SET(pWin, mouse); + /* we don't have enough bytes, so we squash flags and mode into one byte, and use the last byte for the deviceid. */ devEnterLeave = (deviceEnterNotify*)&event; @@ -4572,25 +4588,6 @@ LeaveNotifies(DeviceIntPtr pDev, } } -/* welcome to insanity */ -#define FOCUS_SEMAPHORE_MODIFY(win, field, mode, val) \ -{ \ - FocusSemaphoresPtr sem;\ - sem = (FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey); \ - if (mode != NotifyGrab && mode != NotifyUngrab) { \ - sem->field += val; \ - } else if (mode == NotifyUngrab) { \ - if (sem->field == 0 && val > 0) \ - sem->field += val; \ - else if (sem->field == 1 && val < 0) \ - sem->field += val; \ - } \ -} -#define ENTER_LEAVE_SEMAPHORE_UP(win, mode) \ - FOCUS_SEMAPHORE_MODIFY(win, enterleave, mode, 1); - -#define ENTER_LEAVE_SEMAPHORE_DOWN(win, mode) \ - FOCUS_SEMAPHORE_MODIFY(win, enterleave, mode, -1); /** @@ -4610,33 +4607,27 @@ DoEnterLeaveEvents(DeviceIntPtr pDev, return; if (IsParent(fromWin, toWin)) { - ENTER_LEAVE_SEMAPHORE_DOWN(fromWin, mode); EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyInferior, fromWin, None); EnterNotifies(pDev, fromWin, toWin, mode, NotifyVirtual); - ENTER_LEAVE_SEMAPHORE_UP(toWin, mode); EnterLeaveEvent(pDev, EnterNotify, mode, NotifyAncestor, toWin, None); } else if (IsParent(toWin, fromWin)) { - ENTER_LEAVE_SEMAPHORE_DOWN(fromWin, mode); EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyAncestor, fromWin, None); LeaveNotifies(pDev, fromWin, toWin, mode, NotifyVirtual); - ENTER_LEAVE_SEMAPHORE_UP(toWin, mode); EnterLeaveEvent(pDev, EnterNotify, mode, NotifyInferior, toWin, None); } else { /* neither fromWin nor toWin is descendent of the other */ WindowPtr common = CommonAncestor(toWin, fromWin); /* common == NullWindow ==> different screens */ - ENTER_LEAVE_SEMAPHORE_DOWN(fromWin, mode); EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyNonlinear, fromWin, None); LeaveNotifies(pDev, fromWin, common, mode, NotifyNonlinearVirtual); EnterNotifies(pDev, common, toWin, mode, NotifyNonlinearVirtual); - ENTER_LEAVE_SEMAPHORE_UP(toWin, mode); EnterLeaveEvent(pDev, EnterNotify, mode, NotifyNonlinear, toWin, None); } @@ -4646,7 +4637,7 @@ static void FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) { xEvent event; - int* numFoci; /* no of foci the window has already */ + int numFoci; /* zero if no device has focus on window */ Bool sendevent = FALSE; if (dev != inputInfo.keyboard) @@ -4680,25 +4671,18 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) * NotifyNonlinearVirtual to C and nothing to B. */ - numFoci = - &((FocusSemaphoresPtr)dixLookupPrivate(&pWin->devPrivates, - FocusPrivatesKey))->focusinout; - if (mode == NotifyGrab || mode == NotifyUngrab) + if (dev->isMaster && type == FocusOut && + (detail != NotifyVirtual && + detail != NotifyNonlinearVirtual && + detail != NotifyPointer && + detail != NotifyPointerRoot && + detail != NotifyDetailNone)) + FOCUS_SEMAPHORE_UNSET(pWin, dev); + + numFoci = FocusSemaphoresIsset(pWin); + + if (!numFoci) sendevent = TRUE; - else if (detail != NotifyVirtual && - detail != NotifyNonlinearVirtual && - detail != NotifyPointer && - detail != NotifyPointerRoot && - detail != NotifyDetailNone) - { - (type == FocusIn) ? (*numFoci)++ : (*numFoci)--; - if (((*numFoci) == (FocusOut - type))) - sendevent = TRUE; - } else - { - if (!(*numFoci)) - sendevent = TRUE; - } if (sendevent) { @@ -4723,6 +4707,14 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) KeymapStateMask, NullGrab, 0); } } + + if (dev->isMaster && type == FocusIn && + (detail != NotifyVirtual && + detail != NotifyNonlinearVirtual && + detail != NotifyPointer && + detail != NotifyPointerRoot && + detail != NotifyDetailNone)) + FOCUS_SEMAPHORE_SET(pWin, dev); } /* @@ -6606,3 +6598,37 @@ ExtGrabDevice(ClientPtr client, return GrabSuccess; } +/* + * @return Zero if no device is currently in window, non-zero otherwise. + */ +int +EnterLeaveSemaphoresIsset(WindowPtr win) +{ + FocusSemaphoresPtr sem; + int set = 0; + int i; + + sem = (FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey); + for (i = 0; i < (MAX_DEVICES + 7)/8; i++) + set += sem->enterleave[i]; + + return set; +} + +/* + * @return Zero if no devices has focus on the window, non-zero otherwise. + */ +int +FocusSemaphoresIsset(WindowPtr win) +{ + FocusSemaphoresPtr sem; + int set = 0; + int i; + + sem = (FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey); + for (i = 0; i < (MAX_DEVICES + 7)/8; i++) + set += sem->focusinout[i]; + + return set; +} + |