diff options
-rw-r--r-- | dix/devices.c | 32 | ||||
-rw-r--r-- | dix/dispatch.c | 2 | ||||
-rw-r--r-- | dix/events.c | 181 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Xinput.c | 6 | ||||
-rw-r--r-- | include/dix.h | 6 | ||||
-rw-r--r-- | include/dixstruct.h | 2 | ||||
-rw-r--r-- | include/input.h | 2 |
7 files changed, 152 insertions, 79 deletions
diff --git a/dix/devices.c b/dix/devices.c index 747d7822b..f053e3401 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -342,6 +342,7 @@ InitCoreDevices() dev->ActivateGrab = ActivateKeyboardGrab; dev->DeactivateGrab = DeactivateKeyboardGrab; dev->coreEvents = FALSE; + dev->spriteOwner = FALSE; if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex)) FatalError("Couldn't allocate keyboard devPrivates\n"); dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; @@ -369,12 +370,12 @@ InitCoreDevices() if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex)) FatalError("Couldn't allocate pointer devPrivates\n"); dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; - InitSprite(dev, TRUE); + InitializeSprite(dev, NullWindow); (void)ActivateDevice(dev); inputInfo.pointer = dev; /* the core keyboard is initialised by now. set the keyboard's sprite * to the core pointer's sprite. */ - InitSprite(inputInfo.keyboard, FALSE); + PairDevices(pairingClient, inputInfo.pointer, inputInfo.keyboard); } } @@ -421,6 +422,7 @@ CloseDevice(register DeviceIntPtr dev) StringFeedbackPtr s, snext; BellFeedbackPtr b, bnext; LedFeedbackPtr l, lnext; + int j; if (dev->inited) (void)(*dev->deviceProc)(dev, DEVICE_CLOSE); @@ -504,6 +506,13 @@ CloseDevice(register DeviceIntPtr dev) if (DevHasCursor(dev)) xfree((pointer)dev->pSprite); + /* a client may have the device set as client pointer */ + for (j = 0; j < currentMaxClients; j++) + { + if (clients[j]->clientPtr == dev) + PickPointer(clients[j]); + } + xfree(dev->sync.event); xfree(dev); } @@ -1955,6 +1964,25 @@ PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) return Success; } +/* Return the pointer that is paired with the given keyboard. If no pointer is + * paired, return the virtual core pointer + */ +DeviceIntPtr +GetPairedPointer(DeviceIntPtr kbd) +{ + DeviceIntPtr ptr = inputInfo.devices; + while(ptr) + { + if (ptr->pSprite == kbd->pSprite && ptr->spriteOwner) + { + return ptr; + } + ptr = ptr->next; + } + + return inputInfo.pointer; +} + /* * Register a client to be able to pair devices. */ diff --git a/dix/dispatch.c b/dix/dispatch.c index 98183cc65..54931a1d3 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -3730,6 +3730,8 @@ void InitClient(ClientPtr client, int i, pointer ospriv) client->smart_stop_tick = SmartScheduleTime; client->smart_check_tick = SmartScheduleTime; #endif + + client->clientPtr = NULL; } int diff --git a/dix/events.c b/dix/events.c index a1e72f187..5be923a27 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1508,8 +1508,8 @@ int ProcAllowEvents(register ClientPtr client) { TimeStamp time; - DeviceIntPtr mouse = inputInfo.pointer; - DeviceIntPtr keybd = inputInfo.keyboard; + DeviceIntPtr mouse = PickPointer(client); + DeviceIntPtr keybd = PickKeyboard(client); REQUEST(xAllowEventsReq); REQUEST_SIZE_MATCH(xAllowEventsReq); @@ -2103,7 +2103,7 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev) pSprite->win = XYToWindow(pSprite->hot.x, pSprite->hot.y); #ifdef notyet if (!(pSprite->win->deliverableEvents & - Motion_Filter(inputInfo.pointer->button)) + Motion_Filter(pDev->button)) !syncEvents.playingEvents) { /* XXX Do PointerNonInterestBox here */ @@ -2220,15 +2220,23 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) FatalError("InitializeSprite: failed to allocate sprite struct"); } - pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr)NULL; pSprite = pDev->pSprite; + pDev->spriteOwner = TRUE; + + pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr)NULL; + pSprite->hot.pScreen = pScreen; pSprite->hotPhys.pScreen = pScreen; - pSprite->hotPhys.x = pScreen->width / 2; - pSprite->hotPhys.y = pScreen->height / 2; + if (pScreen) + { + pSprite->hotPhys.x = pScreen->width / 2; + pSprite->hotPhys.y = pScreen->height / 2; + pSprite->hotLimits.x2 = pScreen->width; + pSprite->hotLimits.y2 = pScreen->height; + } + pSprite->hot = pSprite->hotPhys; - pSprite->hotLimits.x2 = pScreen->width; - pSprite->hotLimits.y2 = pScreen->height; pSprite->win = pWin; + if (pWin) { pSprite->current = wCursor(pWin); @@ -2236,16 +2244,19 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) } else pSprite->current = NullCursor; - (*pScreen->CursorLimits) ( pDev, pScreen, pSprite->current, - &pSprite->hotLimits, &pSprite->physLimits); - pSprite->confined = FALSE; + if (pScreen) + { + (*pScreen->CursorLimits) ( pDev, pScreen, pSprite->current, + &pSprite->hotLimits, &pSprite->physLimits); + pSprite->confined = FALSE; - (*pScreen->ConstrainCursor) (pDev, pScreen, - &pSprite->physLimits); - (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x, - pSprite->hot.y, - FALSE); - (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current); + (*pScreen->ConstrainCursor) (pDev, pScreen, + &pSprite->physLimits); + (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x, + pSprite->hot.y, + FALSE); + (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current); + } #ifdef PANORAMIX if(!noPanoramiXExtension) { pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x; @@ -2264,7 +2275,6 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) } #endif - pDev->spriteOwner = TRUE; } /* @@ -2370,7 +2380,7 @@ XineramaWarpPointer(ClientPtr client) { WindowPtr dest = NULL; int x, y, rc; - SpritePtr pSprite = inputInfo.pointer->pSprite; + SpritePtr pSprite = PickPointer(client)->pSprite; REQUEST(xWarpPointerReq); @@ -2429,9 +2439,9 @@ XineramaWarpPointer(ClientPtr client) else if (y >= pSprite->physLimits.y2) y = pSprite->physLimits.y2 - 1; if (pSprite->hotShape) - ConfineToShape(inputInfo.pointer, pSprite->hotShape, &x, &y); + ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); - XineramaSetCursorPosition(inputInfo.pointer, x, y, TRUE); + XineramaSetCursorPosition(PickPointer(client), x, y, TRUE); return Success; } @@ -2445,7 +2455,7 @@ ProcWarpPointer(ClientPtr client) WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; - SpritePtr pSprite = inputInfo.pointer->pSprite; + SpritePtr pSprite = PickPointer(client)->pSprite; REQUEST(xWarpPointerReq); @@ -2518,14 +2528,14 @@ ProcWarpPointer(ClientPtr client) y = pSprite->physLimits.y2 - 1; #if defined(SHAPE) if (pSprite->hotShape) - ConfineToShape(inputInfo.pointer, pSprite->hotShape, &x, &y); + ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); #endif - (*newScreen->SetCursorPosition)(inputInfo.pointer, newScreen, x, y, + (*newScreen->SetCursorPosition)(PickPointer(client), newScreen, x, y, TRUE); } - else if (!PointerConfinedToScreen(inputInfo.pointer)) + else if (!PointerConfinedToScreen(PickPointer(client))) { - NewCurrentScreen(inputInfo.pointer, newScreen, x, y); + NewCurrentScreen(PickPointer(client), newScreen, x, y); } return Success; } @@ -2892,7 +2902,7 @@ drawable.id:0; #endif ))) #endif - XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state); + XE_KBPTR.state = (keyc->state | GetPairedPointer(keybd)->button->state); XE_KBPTR.rootX = keybd->pSprite->hot.x; XE_KBPTR.rootY = keybd->pSprite->hot.y; key = xE->u.u.detail; @@ -2925,7 +2935,7 @@ drawable.id:0; } return; } - inputInfo.pointer->valuator->motionHintWindow = NullWindow; + GetPairedPointer(keybd)->valuator->motionHintWindow = NullWindow; *kptr |= bit; keyc->prev_state = keyc->state; for (i = 0, mask = 1; modifiers; i++, mask <<= 1) @@ -2947,7 +2957,7 @@ drawable.id:0; case KeyRelease: if (!(*kptr & bit)) /* guard against duplicates */ return; - inputInfo.pointer->valuator->motionHintWindow = NullWindow; + GetPairedPointer(keybd)->valuator->motionHintWindow = NullWindow; *kptr &= ~bit; keyc->prev_state = keyc->state; for (i = 0, mask = 1; modifiers; i++, mask <<= 1) @@ -3837,7 +3847,7 @@ int ProcGrabPointer(ClientPtr client) { xGrabPointerReply rep; - DeviceIntPtr device = inputInfo.pointer; + DeviceIntPtr device = PickPointer(client); GrabPtr grab; WindowPtr pWin, confineTo; CursorPtr cursor, oldCursor; @@ -3945,7 +3955,7 @@ ProcGrabPointer(ClientPtr client) int ProcChangeActivePointerGrab(ClientPtr client) { - DeviceIntPtr device = inputInfo.pointer; + DeviceIntPtr device = PickPointer(client); register GrabPtr grab = device->grab; CursorPtr newCursor, oldCursor; REQUEST(xChangeActivePointerGrabReq); @@ -3991,7 +4001,7 @@ ProcChangeActivePointerGrab(ClientPtr client) int ProcUngrabPointer(ClientPtr client) { - DeviceIntPtr device = inputInfo.pointer; + DeviceIntPtr device = PickPointer(client); GrabPtr grab; TimeStamp time; REQUEST(xResourceReq); @@ -4122,7 +4132,7 @@ ProcQueryPointer(ClientPtr client) { xQueryPointerReply rep; WindowPtr pWin, t; - DeviceIntPtr mouse = inputInfo.pointer; + DeviceIntPtr mouse = PickPointer(client); SpritePtr pSprite = mouse->pSprite; int rc; @@ -4224,37 +4234,6 @@ InitEvents() } -/** - * Initialize a sprite structure for the given device. If hasCursor is False, - * let the device use the core pointer's sprite structure. - */ -void -InitSprite(DeviceIntPtr pDev, Bool hasCursor) -{ - if (hasCursor) - { - SpritePtr pSprite = (SpritePtr)xalloc(sizeof(SpriteRec)); - if (!pSprite) - FatalError("failed to allocate sprite struct"); - memset(pSprite, 0, sizeof(SpriteRec)); - pSprite->hot.pScreen = pSprite->hotPhys.pScreen = (ScreenPtr)NULL; - pSprite->win = NullWindow; - pSprite->current = NullCursor; - pSprite->hotLimits.x1 = 0; - pSprite->hotLimits.y1 = 0; - pSprite->hotLimits.x2 = 0; - pSprite->hotLimits.y2 = 0; - pSprite->confined = FALSE; - - pDev->pSprite = pSprite; - pDev->spriteOwner = TRUE; - } else - { - pDev->pSprite = inputInfo.pointer->pSprite; - pDev->spriteOwner = FALSE; - } -} - void CloseDownEvents(void) { @@ -4268,7 +4247,7 @@ ProcSendEvent(ClientPtr client) { WindowPtr pWin; WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - SpritePtr pSprite = inputInfo.pointer->pSprite; + SpritePtr pSprite = PickPointer(client)->pSprite; REQUEST(xSendEventReq); REQUEST_SIZE_MATCH(xSendEventReq); @@ -4335,8 +4314,8 @@ ProcSendEvent(ClientPtr client) { for (;pWin; pWin = pWin->parent) { - if (DeliverEventsToWindow(inputInfo.pointer, pWin, &stuff->event, - 1, stuff->eventMask, NullGrab, 0)) + if (DeliverEventsToWindow(PickPointer(client), pWin, + &stuff->event, 1, stuff->eventMask, NullGrab, 0)) return Success; if (pWin == effectiveFocus) return Success; @@ -4346,8 +4325,8 @@ ProcSendEvent(ClientPtr client) } } else - (void)DeliverEventsToWindow(inputInfo.pointer, pWin, &stuff->event, 1, - stuff->eventMask, NullGrab, 0); + (void)DeliverEventsToWindow(PickPointer(client), pWin, &stuff->event, + 1, stuff->eventMask, NullGrab, 0); return Success; } @@ -4511,7 +4490,7 @@ ProcGrabButton(ClientPtr client) } - grab = CreateGrab(client->index, inputInfo.pointer, pWin, + grab = CreateGrab(client->index, PickPointer(client), pWin, (Mask)stuff->eventMask, (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode, (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers, ButtonPress, @@ -4540,7 +4519,7 @@ ProcUngrabButton(ClientPtr client) if (rc != Success) return rc; tempGrab.resource = client->clientAsMask; - tempGrab.device = inputInfo.pointer; + tempGrab.device = PickPointer(client); tempGrab.window = pWin; tempGrab.modifiersDetail.exact = stuff->modifiers; tempGrab.modifiersDetail.pMask = NULL; @@ -4694,7 +4673,7 @@ ProcRecolorCursor(ClientPtr client) int nscr; ScreenPtr pscr; Bool displayed; - SpritePtr pSprite = inputInfo.pointer->pSprite; + SpritePtr pSprite = PickPointer(client)->pSprite; REQUEST(xRecolorCursorReq); REQUEST_SIZE_MATCH(xRecolorCursorReq); @@ -4723,7 +4702,7 @@ ProcRecolorCursor(ClientPtr client) else #endif displayed = (pscr == pSprite->hotPhys.pScreen); - ( *pscr->RecolorCursor)(inputInfo.pointer, pscr, pCursor, + ( *pscr->RecolorCursor)(PickPointer(client), pscr, pCursor, (pCursor == pSprite->current) && displayed); } return (Success); @@ -4810,3 +4789,59 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events); } } + +/* PickPointer will pick an appropriate pointer for the given client. + * + * If a client pointer is set, it will pick the client pointer, otherwise the + * first available pointer in the list. If no physical device is attached, it + * will pick the core pointer. + */ +_X_EXPORT DeviceIntPtr +PickPointer(ClientPtr client) +{ + if (!client->clientPtr) + { + /* look if there is a real device attached */ + DeviceIntPtr it = inputInfo.devices; + while (it) + { + if (it != inputInfo.pointer && it->spriteOwner) + { + client->clientPtr = it; + break; + } + it = it->next; + } + + if (!it) + { + ErrorF("Picking VCP\n"); + client->clientPtr = inputInfo.pointer; + } + } + return client->clientPtr; +} + +/* PickKeyboard will pick an appropriate keyboard for the given client by + * searching the list of devices for the keyboard device that is paired with + * the client's pointer. + * If no pointer is paired with the keyboard, the virtual core keyboard is + * returned. + */ +_X_EXPORT DeviceIntPtr +PickKeyboard(ClientPtr client) +{ + DeviceIntPtr dev; + DeviceIntPtr ptr = inputInfo.devices; + ptr = PickPointer(client); + + while(dev) + { + if (ptr->pSprite == dev->pSprite) + return dev; + dev = dev->next; + } + + return inputInfo.keyboard; +} + diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 41118c043..31be1e36a 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -188,9 +188,9 @@ xf86ActivateDevice(LocalDevicePtr local) /* Only create a new sprite if it's a non-shared pointer */ if (IsPointerDevice(dev) && dev->isMPDev) - InitializeSprite(pDev, NullWindow); + InitializeSprite(dev, GetCurrentRootWindow()); else - PairDevices(pairingClient, inputInfo.pointer, pDev); + PairDevices(NULL, inputInfo.pointer, dev); RegisterOtherDevice(dev); @@ -425,8 +425,6 @@ NewInputDeviceRequest (InputOption *options) EnableDevice(dev); /* send enter/leave event, update sprite window */ - if (dev->spriteOwner) - InitializeSprite(dev, GetCurrentRootWindow()); CheckMotion(NULL, dev); return Success; diff --git a/include/dix.h b/include/dix.h index 1c6b16379..95c69f057 100644 --- a/include/dix.h +++ b/include/dix.h @@ -602,6 +602,12 @@ extern int TryClientEvents( extern void WindowsRestructured(void); +extern DeviceIntPtr PickPointer( + ClientPtr /* client */); + +extern DeviceIntPtr PickKeyboard( + ClientPtr /* client */); + #ifdef PANORAMIX extern void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff); #endif diff --git a/include/dixstruct.h b/include/dixstruct.h index b5ffcca49..530009a8b 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -140,6 +140,8 @@ typedef struct _Client { long smart_stop_tick; long smart_check_tick; #endif + + DeviceIntPtr clientPtr; } ClientRec; #ifdef SMART_SCHEDULE diff --git a/include/input.h b/include/input.h index a7b1e84d3..433cc9419 100644 --- a/include/input.h +++ b/include/input.h @@ -450,6 +450,8 @@ extern int PairDevices(ClientPtr client, DeviceIntPtr pointer, DeviceIntPtr keyboard); +extern DeviceIntPtr GetPairedPointer(DeviceIntPtr kbd); + extern Bool RegisterPairingClient(ClientPtr client); extern Bool UnregisterPairingClient(ClientPtr client); |