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) { - FreeDeviceClass(FocusClass, (pointer)&to->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) + { + /* 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 #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; /*