summaryrefslogtreecommitdiff
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
parentcbe01b3083eb65c9d4259b1071683febebf11600 (diff)
parentb4380d8030927c940ddaea83c4cf24e0b9eb7b96 (diff)
Merge whot@wombat:~/potoroo/xserver into mpx
-rw-r--r--Xi/chdevhier.c6
-rw-r--r--Xi/exevents.c56
-rw-r--r--dix/devices.c121
-rw-r--r--dix/events.c146
-rw-r--r--dix/window.c2
-rw-r--r--hw/xfree86/common/xf86Xinput.c5
-rw-r--r--include/dix.h1
-rw-r--r--include/input.h35
-rw-r--r--include/windowstr.h12
9 files changed, 204 insertions, 180 deletions
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index e9a5076a9..36797d90c 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -272,10 +272,10 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
goto unwind;
}
- if ((IsPointerDevice(newmaster) &&
- !IsPointerDevice(ptr)) ||
+ if (!((IsPointerDevice(newmaster) &&
+ IsPointerDevice(ptr)) ||
(IsKeyboardDevice(newmaster) &&
- !IsKeyboardDevice(ptr)))
+ IsKeyboardDevice(ptr))))
{
rc = BadDevice;
goto unwind;
diff --git a/Xi/exevents.c b/Xi/exevents.c
index f28952fdc..a93fef452 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -104,6 +104,32 @@ RegisterOtherDevice(DeviceIntPtr device)
device->public.realInputProc = ProcessOtherEvent;
}
+_X_EXPORT Bool
+IsPointerEvent(xEvent* xE)
+{
+ switch(xE->u.u.type)
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ return TRUE;
+ default:
+ if (xE->u.u.type == DeviceButtonPress ||
+ xE->u.u.type == DeviceButtonRelease ||
+ xE->u.u.type == DeviceMotionNotify ||
+ xE->u.u.type == DeviceEnterNotify ||
+ xE->u.u.type == DeviceLeaveNotify ||
+ xE->u.u.type == ProximityIn ||
+ xE->u.u.type == ProximityOut)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/**
* Copy the device->key into master->key and send a mapping notify to the
* clients if appropriate.
@@ -459,11 +485,29 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
}
- ALLOC_COPY_CLASS_IF(focus, FocusClassRec);
- if (to->focus && !from->focus)
+ /* We can't just copy over the focus class. When an app sets the focus,
+ * it'll do so on the master device. Copying the SDs focus means losing
+ * the focus.
+ * So we only copy the focus class if the device didn't have one,
+ * otherwise we leave it as it is.
+ */
+ if (from->focus)
+ {
+ if (!to->focus)
+ {
+ to->focus = xcalloc(1, sizeof(FocusClassRec));
+ if (!to->focus)
+ FatalError("[Xi] no memory for class shift.\n");
+ memcpy(to->focus->trace, from->focus->trace,
+ from->focus->traceSize * sizeof(WindowPtr));
+ }
+ } else if (to->focus)
{
- FreeDeviceClass(FocusClass, (pointer)&to->focus);
+ /* properly freeing the class would also free the sprite trace, which
+ * is still in use by the SD. just xfree the struct. */
+ xfree(to->focus);
}
+
ALLOC_COPY_CLASS_IF(proximity, ProximityClassRec);
if (to->proximity && !from->proximity)
{
@@ -730,11 +774,15 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
{
kbd = GetPairedDevice(device);
mouse = device;
+ if (!kbd->key) /* can happen with floating SDs */
+ kbd = NULL;
}
else
{
mouse = GetPairedDevice(device);
kbd = device;
+ if (!mouse->valuator || !mouse->button) /* may be float. SDs */
+ mouse = NULL;
}
xE->u.keyButtonPointer.state = (kbd) ? (kbd->key->state) : 0;
xE->u.keyButtonPointer.state |= (mouse) ? (mouse->button->state) : 0;
@@ -808,7 +856,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
if (grab)
DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
- else if (device->focus)
+ else if (device->focus && !IsPointerEvent(xE))
DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count);
else
DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow,
diff --git a/dix/devices.c b/dix/devices.c
index c4cde2660..a78a1255d 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -88,8 +88,6 @@ SOFTWARE.
/* The client that is allowed to change pointer-keyboard pairings. */
static ClientPtr pairingClient = NULL;
-
-DevPrivateKey MasterDevClassesPrivateKey = &MasterDevClassesPrivateKey;
DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKey;
/**
@@ -224,8 +222,7 @@ EnableDevice(DeviceIntPtr dev)
if (dev->spriteInfo->spriteOwner)
{
InitializeSprite(dev, WindowTable[0]);
- ((FocusSemaphoresPtr)dixLookupPrivate(&(WindowTable[0])->devPrivates,
- FocusPrivatesKey))->enterleave++;
+ ENTER_LEAVE_SEMAPHORE_SET(WindowTable[0], dev);
}
else if ((other = NextFreePointerDevice()) == NULL)
{
@@ -410,7 +407,6 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
XkbComponentNamesRec names;
#endif
ClassesPtr classes;
- DeviceIntRec dummy;
switch (what) {
case DEVICE_INIT:
@@ -420,8 +416,6 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
return BadAlloc;
}
- dixSetPrivate(&pDev->devPrivates, MasterDevClassesPrivateKey, NULL);
-
keySyms.minKeyCode = 8;
keySyms.maxKeyCode = 255;
keySyms.mapWidth = 4;
@@ -460,53 +454,9 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
xfree(keySyms.map);
xfree(modMap);
-
- classes->key = pDev->key;
- classes->valuator = pDev->valuator;
- classes->button = pDev->button;
- classes->focus = pDev->focus;
- classes->proximity = pDev->proximity;
- classes->absolute = pDev->absolute;
- classes->kbdfeed = pDev->kbdfeed;
- classes->ptrfeed = pDev->ptrfeed;
- classes->intfeed = pDev->intfeed;
- classes->stringfeed = pDev->stringfeed;
- classes->bell = pDev->bell;
- classes->leds = pDev->leds;
-
- /* Each time we switch classes we free the MD's classes and copy the
- * SD's classes into the MD. We mustn't lose the first set of classes
- * though as we need it to restore them when the last SD disconnects.
- *
- * So we create a fake device, seem to copy from the fake to the real
- * one, thus ending up with a copy of the original ones in our MD.
- *
- * If we don't do that, we're in SIGABRT territory (double-frees, etc)
- */
- memcpy(&dummy, pDev, sizeof(DeviceIntRec));
- /* Need to set them to NULL. Otherwise, Xkb does some weird stuff and
- * the dev->key->xkbInfo->kbdProc starts calling itself. This can
- * probably be fixed in a better way, but I don't know how. (whot) */
- pDev->key = NULL;
- pDev->valuator = NULL;
- pDev->button = NULL;
- pDev->focus = NULL;
- pDev->proximity = NULL;
- pDev->absolute = NULL;
- pDev->kbdfeed = NULL;
- pDev->ptrfeed = NULL;
- pDev->intfeed = NULL;
- pDev->stringfeed = NULL;
- pDev->bell = NULL;
- pDev->leds = NULL;
- DeepCopyDeviceClasses(&dummy, pDev);
-
- dixSetPrivate(&pDev->devPrivates, MasterDevClassesPrivateKey,
- classes);
break;
case DEVICE_CLOSE:
- dixSetPrivate(&pDev->devPrivates, CoreDevicePrivateKey, NULL);
break;
default:
@@ -527,16 +477,12 @@ CorePointerProc(DeviceIntPtr pDev, int what)
BYTE map[33];
int i = 0;
ClassesPtr classes;
- DeviceIntRec dummy;
-
switch (what) {
case DEVICE_INIT:
if (!(classes = xcalloc(1, sizeof(ClassesRec))))
return BadAlloc;
- dixSetPrivate(&pDev->devPrivates, MasterDevClassesPrivateKey, NULL);
-
for (i = 1; i <= 32; i++)
map[i] = i;
InitPointerDeviceStruct((DevicePtr)pDev, map, 32,
@@ -546,43 +492,9 @@ CorePointerProc(DeviceIntPtr pDev, int what)
pDev->lastx = pDev->valuator->axisVal[0];
pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
pDev->lasty = pDev->valuator->axisVal[1];
-
- classes->key = pDev->key;
- classes->valuator = pDev->valuator;
- classes->button = pDev->button;
- classes->focus = pDev->focus;
- classes->proximity = pDev->proximity;
- classes->absolute = pDev->absolute;
- classes->kbdfeed = pDev->kbdfeed;
- classes->ptrfeed = pDev->ptrfeed;
- classes->intfeed = pDev->intfeed;
- classes->stringfeed = pDev->stringfeed;
- classes->bell = pDev->bell;
- classes->leds = pDev->leds;
-
- /* See comment in CoreKeyboardProc. */
- memcpy(&dummy, pDev, sizeof(DeviceIntRec));
- /* Need to set them to NULL for the VCK (see CoreKeyboardProc). Not
- * sure if also necessary for the VCP, but it doesn't seem to hurt */
- pDev->key = NULL;
- pDev->valuator = NULL;
- pDev->button = NULL;
- pDev->focus = NULL;
- pDev->proximity = NULL;
- pDev->absolute = NULL;
- pDev->kbdfeed = NULL;
- pDev->ptrfeed = NULL;
- pDev->intfeed = NULL;
- pDev->stringfeed = NULL;
- pDev->bell = NULL;
- pDev->leds = NULL;
- DeepCopyDeviceClasses(&dummy, pDev);
-
- dixSetPrivate(&pDev->devPrivates, MasterDevClassesPrivateKey, classes);
break;
case DEVICE_CLOSE:
- dixSetPrivate(&pDev->devPrivates, CoreDevicePrivateKey, NULL);
break;
default:
@@ -858,13 +770,6 @@ CloseDevice(DeviceIntPtr dev)
xfree(dev->name);
- if (dev->isMaster)
- {
- classes = (ClassesPtr)dixLookupPrivate(&dev->devPrivates,
- MasterDevClassesPrivateKey);
- FreeAllDeviceClasses(classes);
- }
-
classes = (ClassesPtr)&dev->key;
FreeAllDeviceClasses(classes);
@@ -2506,7 +2411,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
return Success;
/* free the existing sprite. */
- if (!dev->u.master && dev->spriteInfo->sprite)
+ if (!dev->u.master && dev->spriteInfo->paired == dev)
xfree(dev->spriteInfo->sprite);
oldmaster = dev->u.master;
@@ -2515,15 +2420,22 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
/* If device is set to floating, we need to create a sprite for it,
* otherwise things go bad. However, we don't want to render the cursor,
* so we reset spriteOwner.
+ * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
+ * alloc new memory but overwrite the previous one.
*/
if (!master)
{
- /* current root window */
- InitializeSprite(dev, dev->spriteInfo->sprite->spriteTrace[0]);
+ WindowPtr currentRoot = dev->spriteInfo->sprite->spriteTrace[0];
+ dev->spriteInfo->sprite = NULL;
+ InitializeSprite(dev, currentRoot);
dev->spriteInfo->spriteOwner = FALSE;
-
+ dev->spriteInfo->paired = dev;
} else
+ {
dev->spriteInfo->sprite = master->spriteInfo->sprite;
+ dev->spriteInfo->paired = master;
+ dev->spriteInfo->spriteOwner = FALSE;
+ }
/* If we were connected to master device before, this MD may need to
* change back to it's original classes.
@@ -2537,16 +2449,9 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
if (!it) /* no dev is paired with old master */
{
- ClassesPtr classes;
+ /* XXX: reset to defaults */
EventList event = { NULL, 0};
char* classbuf;
- DeviceIntRec dummy;
-
- FreeAllDeviceClasses((ClassesPtr)&oldmaster->key);
- classes = (ClassesPtr)dixLookupPrivate(&oldmaster->devPrivates,
- MasterDevClassesPrivateKey);
- memcpy(&dummy.key, classes, sizeof(ClassesRec));
- DeepCopyDeviceClasses(&dummy, oldmaster);
/* Send event to clients */
CreateClassesChangedEvent(&event, oldmaster, oldmaster);
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;
+}
+
diff --git a/dix/window.c b/dix/window.c
index ee4c75649..d3160c903 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -366,6 +366,7 @@ CreateRootWindow(ScreenPtr pScreen)
WindowPtr pWin;
BoxRec box;
PixmapFormatRec *format;
+ FocusSemaphoresPtr sem;
pWin = (WindowPtr)xalloc(sizeof(WindowRec));
if (!pWin)
@@ -484,6 +485,7 @@ CreateRootWindow(ScreenPtr pScreen)
if (disableSaveUnders)
pScreen->saveUnderSupport = NotUseful;
+
return TRUE;
}
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index d8e23ee8d..c2dd6004b 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -722,7 +722,10 @@ xf86PostKeyboardEvent(DeviceIntPtr device,
int index;
#if XFreeXDGA
- DeviceIntPtr pointer = GetPairedDevice(device);
+ DeviceIntPtr pointer;
+
+ /* Some pointers send key events, paired device is wrong then. */
+ pointer = IsPointerDevice(device) ? device : GetPairedDevice(device);
if (miPointerGetScreen(pointer)) {
index = miPointerGetScreen(pointer)->myNum;
diff --git a/include/dix.h b/include/dix.h
index e00df29a2..57ffee9b9 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -615,6 +615,7 @@ extern int XItoCoreType(int xi_type);
extern Bool DevHasCursor(DeviceIntPtr pDev);
extern Bool IsPointerDevice( DeviceIntPtr dev);
extern Bool IsKeyboardDevice(DeviceIntPtr dev);
+extern Bool IsPointerEvent(xEvent* xE);
/*
* These are deprecated compatibility functions and will be removed soon!
diff --git a/include/input.h b/include/input.h
index 9ba12db79..0c993eed0 100644
--- a/include/input.h
+++ b/include/input.h
@@ -80,6 +80,39 @@ SOFTWARE.
#define RevertToFollowKeyboard 3
#endif
+/* Used for enter/leave and focus in/out semaphores */
+#define SEMAPHORE_FIELD_SET(win, dev, field) \
+{ \
+ FocusSemaphoresPtr sem; \
+ sem = (FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey); \
+ sem->field[dev->id/8] |= (1 << (dev->id % 8)); \
+}
+
+#define SEMAPHORE_FIELD_UNSET(win, dev, field) \
+{ \
+ FocusSemaphoresPtr sem; \
+ sem = (FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey); \
+ sem->field[dev->id/8] &= ~(1 << (dev->id % 8)); \
+}
+
+#define ENTER_LEAVE_SEMAPHORE_SET(win, dev) \
+ SEMAPHORE_FIELD_SET(win, dev, enterleave);
+
+#define ENTER_LEAVE_SEMAPHORE_UNSET(win, dev) \
+ SEMAPHORE_FIELD_UNSET(win, dev, enterleave);
+
+#define ENTER_LEAVE_SEMAPHORE_ISSET(win, dev) \
+ ((FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey))->enterleave[dev->id/8] & (1 << (dev->id % 8))
+
+#define FOCUS_SEMAPHORE_SET(win, dev) \
+ SEMAPHORE_FIELD_SET(win, dev, focusinout);
+
+#define FOCUS_SEMAPHORE_UNSET(win, dev) \
+ SEMAPHORE_FIELD_UNSET(win, dev, focusinout);
+
+#define FOCUS_SEMAPHORE_ISSET(win, dev) \
+ ((FocusSemaphoresPtr)dixLookupPrivate(&win->devPrivates, FocusPrivatesKey))->focusinout[dev->id/8] & (1 << (dev->id % 8))
+
typedef unsigned long Leds;
typedef struct _OtherClients *OtherClientsPtr;
typedef struct _InputClients *InputClientsPtr;
@@ -488,6 +521,8 @@ extern void DeepCopyDeviceClasses(DeviceIntPtr from,
extern void FreeDeviceClass(int type, pointer* class);
extern void FreeFeedbackClass(int type, pointer* class);
extern void FreeAllDeviceClasses(ClassesPtr classes);
+extern int EnterLeaveSemaphoresIsset(WindowPtr win);
+extern int FocusSemaphoresIsset(WindowPtr win);
/* Window/device based access control */
extern Bool ACRegisterClient(ClientPtr client);
diff --git a/include/windowstr.h b/include/windowstr.h
index 406087e17..a36dc2972 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -59,6 +59,7 @@ SOFTWARE.
#include "miscstruct.h"
#include <X11/Xprotostr.h>
#include "opaque.h"
+#include "inputstr.h"
#define GuaranteeNothing 0
#define GuaranteeVisBack 1
@@ -257,11 +258,14 @@ extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
extern DevPrivateKey FocusPrivatesKey;
/* Used to maintain semantics of core protocol for Enter/LeaveNotifies and
- * FocusIn/Out events for multiple pointers/keyboards.
- */
+ * FocusIn/Out events for multiple pointers/keyboards.
+ *
+ * Each device ID corresponds to one bit. If set, the device is in the
+ * window/has focus.
+ */
typedef struct _FocusSemaphores {
- int enterleave;
- int focusinout;
+ char enterleave[(MAX_DEVICES + 7)/8];
+ char focusinout[(MAX_DEVICES + 7)/8];
} FocusSemaphoresRec, *FocusSemaphoresPtr;
/*