summaryrefslogtreecommitdiff
path: root/dix/events.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2008-04-11 08:29:52 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2008-04-11 08:29:52 +0930
commit90f491cf8eb869f27c4278b26c1bb84432b12d63 (patch)
treee55487aaef9d157a7d03f3f62b185c83f2eb4bb6 /dix/events.c
parentcbe01b3083eb65c9d4259b1071683febebf11600 (diff)
parentb4380d8030927c940ddaea83c4cf24e0b9eb7b96 (diff)
Merge whot@wombat:~/potoroo/xserver into mpx
Diffstat (limited to 'dix/events.c')
-rw-r--r--dix/events.c146
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;
+}
+