summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dix/devices.c32
-rw-r--r--dix/dispatch.c2
-rw-r--r--dix/events.c181
-rw-r--r--hw/xfree86/common/xf86Xinput.c6
-rw-r--r--include/dix.h6
-rw-r--r--include/dixstruct.h2
-rw-r--r--include/input.h2
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);