diff options
98 files changed, 5737 insertions, 1587 deletions
diff --git a/XTrap/xtrapddmi.c b/XTrap/xtrapddmi.c index 73a20c1f6..ec094ecf4 100644 --- a/XTrap/xtrapddmi.c +++ b/XTrap/xtrapddmi.c @@ -60,6 +60,7 @@ SOFTWARE. # include "extnsionst.h" /* Server ExtensionEntry definitions */ # include "scrnintstr.h" /* Screen struct */ #endif +#include "inputstr.h" #include <X11/extensions/xtrapdi.h> #include <X11/extensions/xtrapddmi.h> @@ -96,8 +97,8 @@ int XETrapSimulateXEvent(register xXTrapInputReq *request, xEvent xev; register int x = request->input.x; register int y = request->input.y; - DevicePtr keydev = LookupKeyboardDevice(); - DevicePtr ptrdev = LookupPointerDevice(); + DevicePtr keydev = (DevicePtr)PickKeyboard(client); + DevicePtr ptrdev = (DevicePtr)PickPointer(client); if (request->input.screen < screenInfo.numScreens) { @@ -130,8 +131,8 @@ int XETrapSimulateXEvent(register xXTrapInputReq *request, { /* Set new cursor position on screen */ XETrap_avail.data.cur_x = x; XETrap_avail.data.cur_y = y; - NewCurrentScreen (pScr, x, y); /* fix from amnonc@mercury.co.il */ - if (!(*pScr->SetCursorPosition)(pScr, x, y, xFalse)) + NewCurrentScreen (inputInfo.pointer, pScr, x, y); /* fix from amnonc@mercury.co.il */ + if (!(*pScr->SetCursorPosition)(inputInfo.pointer, pScr, x, y, xFalse)) { status = BadImplementation; } diff --git a/XTrap/xtrapdi.c b/XTrap/xtrapdi.c index 23d3bde7f..bc15bbd86 100644 --- a/XTrap/xtrapdi.c +++ b/XTrap/xtrapdi.c @@ -71,6 +71,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif #include "pixmapstr.h" /* DrawableRec */ #include "windowstr.h" /* Drawable Lookup structures */ +#include "inputstr.h" #include <X11/extensions/xtrapdi.h> #include <X11/extensions/xtrapddmi.h> #include <X11/extensions/xtrapproto.h> @@ -1564,7 +1565,7 @@ void XETrapStampAndMail(xEvent *x_event) data.u.event.u.u.type == ButtonRelease || data.u.event.u.u.type == KeyPress || data.u.event.u.u.type == KeyRelease)) { - int scr = XineramaGetCursorScreen(); + int scr = XineramaGetCursorScreen(inputInfo.pointer); data.u.event.u.keyButtonPointer.rootX += panoramiXdataPtr[scr].x - panoramiXdataPtr[0].x; data.u.event.u.keyButtonPointer.rootY += diff --git a/Xext/security.c b/Xext/security.c index c17a438b4..18ab496b9 100644 --- a/Xext/security.c +++ b/Xext/security.c @@ -745,12 +745,12 @@ SecurityDetermineEventPropogationLimits( if (pFocusWin == PointerRootWin) { /* focus follows the pointer */ - *ppWin = GetSpriteWindow(); + *ppWin = GetSpriteWindow(dev); *ppStopWin = NULL; /* propogate all the way to the root */ } else { /* a real window is set for the focus */ - WindowPtr pSpriteWin = GetSpriteWindow(); + WindowPtr pSpriteWin = GetSpriteWindow(dev); *ppStopWin = pFocusWin->parent; /* don't go past the focus window */ /* if the pointer is in a subwindow of the focus window, start @@ -822,10 +822,13 @@ CALLBACK(SecurityCheckDeviceAccess) untrusted_got_event = FALSE; found_event_window = FALSE; - if (dev->grab) + /* We can just use coreGrab as a comment a few lines above clearly states + "device security other than keyboard is not implemented yet". The core + kbd should never have a device grab set. */ + if (dev->coreGrab.grab) { untrusted_got_event = - (TRUSTLEVEL(rClient(dev->grab)) != XSecurityClientTrusted); + (TRUSTLEVEL(rClient(dev->coreGrab.grab)) != XSecurityClientTrusted); } else { diff --git a/Xext/xtest.c b/Xext/xtest.c index 94d8974b6..93e88c471 100644 --- a/Xext/xtest.c +++ b/Xext/xtest.c @@ -148,7 +148,7 @@ ProcXTestCompareCursor(client) if (stuff->cursor == None) pCursor = NullCursor; else if (stuff->cursor == XTestCurrentCursor) - pCursor = GetSpriteCursor(); + pCursor = GetSpriteCursor(inputInfo.pointer); else { pCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR); if (!pCursor) @@ -316,7 +316,7 @@ ProcXTestFakeInput(client) #ifdef XINPUT if (!extension) #endif /* XINPUT */ - dev = (DeviceIntPtr)LookupKeyboardDevice(); + dev = PickKeyboard(client); if (ev->u.u.detail < dev->key->curKeySyms.minKeyCode || ev->u.u.detail > dev->key->curKeySyms.maxKeyCode) { @@ -360,7 +360,8 @@ ProcXTestFakeInput(client) break; } #endif /* XINPUT */ - dev = (DeviceIntPtr)LookupPointerDevice(); + if (!dev) + dev = PickPointer(client); if (ev->u.keyButtonPointer.root == None) root = GetCurrentRootWindow(); else @@ -378,7 +379,7 @@ ProcXTestFakeInput(client) if (ev->u.u.detail == xTrue) { int x, y; - GetSpritePosition(&x, &y); + GetSpritePosition(dev, &x, &y); ev->u.keyButtonPointer.rootX += x; ev->u.keyButtonPointer.rootY += y; } @@ -425,20 +426,21 @@ ProcXTestFakeInput(client) #ifdef PANORAMIX if ((!noPanoramiXExtension - && root->drawable.pScreen->myNum != XineramaGetCursorScreen()) + && root->drawable.pScreen->myNum + != XineramaGetCursorScreen(dev)) || (noPanoramiXExtension && root != GetCurrentRootWindow())) #else if (root != GetCurrentRootWindow()) #endif { - NewCurrentScreen(root->drawable.pScreen, + NewCurrentScreen(dev, root->drawable.pScreen, ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootY); return client->noClientException; } (*root->drawable.pScreen->SetCursorPosition) - (root->drawable.pScreen, + (dev, root->drawable.pScreen, ev->u.keyButtonPointer.rootX, ev->u.keyButtonPointer.rootY, FALSE); dev->valuator->lastx = ev->u.keyButtonPointer.rootX; @@ -449,7 +451,7 @@ ProcXTestFakeInput(client) #ifdef XINPUT if (!extension) #endif /* XINPUT */ - dev = (DeviceIntPtr)LookupPointerDevice(); + dev = PickPointer(client); if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons) { client->errorValue = ev->u.u.detail; diff --git a/Xi/Makefile.am b/Xi/Makefile.am index fbe438543..9b1253e0b 100644 --- a/Xi/Makefile.am +++ b/Xi/Makefile.am @@ -5,6 +5,8 @@ AM_CFLAGS = $(DIX_CFLAGS) libXi_la_SOURCES = \ allowev.c \ allowev.h \ + chdevcur.c \ + chdevcur.h \ chgdctl.c \ chgdctl.h \ chgfctl.c \ @@ -17,6 +19,10 @@ libXi_la_SOURCES = \ chgprop.h \ chgptr.c \ chgptr.h \ + chpkpair.c \ + chpkpair.h \ + chaccess.c \ + chaccess.h \ closedev.c \ closedev.h \ devbell.c \ @@ -26,6 +32,8 @@ libXi_la_SOURCES = \ extinit.c \ getbmap.c \ getbmap.h \ + getcptr.c \ + getcptr.h \ getdctl.c \ getdctl.h \ getfctl.c \ @@ -36,12 +44,16 @@ libXi_la_SOURCES = \ getkmap.h \ getmmap.c \ getmmap.h \ + getpairp.c \ + getpairp.h \ getprop.c \ getprop.h \ getselev.c \ getselev.h \ getvers.c \ getvers.h \ + grabacc.c \ + grabacc.h \ grabdev.c \ grabdev.h \ grabdevb.c \ @@ -54,14 +66,22 @@ libXi_la_SOURCES = \ listdev.h \ opendev.c \ opendev.h \ + querydp.c \ + querydp.h \ queryst.c \ queryst.h \ + qryacces.c \ + qryacces.h \ + regpair.c \ + regpair.h \ selectev.c \ selectev.h \ sendexev.c \ sendexev.h \ setbmap.c \ setbmap.h \ + setcptr.c \ + setcptr.h \ setdval.c \ setdval.h \ setfocus.c \ @@ -75,6 +95,8 @@ libXi_la_SOURCES = \ ungrdevb.c \ ungrdevb.h \ ungrdevk.c \ - ungrdevk.h + ungrdevk.h \ + warpdevp.c \ + warpdevp.h EXTRA_DIST = stubs.c diff --git a/Xi/allowev.c b/Xi/allowev.c index 85b6eaf6b..449d8811a 100644 --- a/Xi/allowev.c +++ b/Xi/allowev.c @@ -111,22 +111,22 @@ ProcXAllowDeviceEvents(ClientPtr client) switch (stuff->mode) { case ReplayThisDevice: - AllowSome(client, time, thisdev, NOT_GRABBED); + AllowSome(client, time, thisdev, NOT_GRABBED, FALSE); break; case SyncThisDevice: - AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT); + AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT, FALSE); break; case AsyncThisDevice: - AllowSome(client, time, thisdev, THAWED); + AllowSome(client, time, thisdev, THAWED, FALSE); break; case AsyncOtherDevices: - AllowSome(client, time, thisdev, THAW_OTHERS); + AllowSome(client, time, thisdev, THAW_OTHERS, FALSE); break; case SyncAll: - AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT); + AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT, FALSE); break; case AsyncAll: - AllowSome(client, time, thisdev, THAWED_BOTH); + AllowSome(client, time, thisdev, THAWED_BOTH, FALSE); break; default: SendErrorToClient(client, IReqCode, X_AllowDeviceEvents, 0, BadValue); diff --git a/Xi/chaccess.c b/Xi/chaccess.c new file mode 100644 index 000000000..5005e9435 --- /dev/null +++ b/Xi/chaccess.c @@ -0,0 +1,177 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "chaccess.h" + +/*********************************************************************** + * This procedure allows a client to change window access control. + */ + +int +SProcXChangeWindowAccess(ClientPtr client) +{ + char n; + REQUEST(xChangeWindowAccessReq); + + swaps(&stuff->length, n); + swapl(&stuff->win, n); + return ProcXChangeWindowAccess(client); +} + +int +ProcXChangeWindowAccess(ClientPtr client) +{ + int padding, err, i; + CARD8* deviceids = NULL; + WindowPtr win; + DeviceIntPtr* perm_devices = NULL; + DeviceIntPtr* deny_devices = NULL; + REQUEST(xChangeWindowAccessReq); + REQUEST_AT_LEAST_SIZE(xChangeWindowAccessReq); + + + padding = (4 - ((stuff->npermit + stuff->ndeny) % 4)) % 4; + + if (stuff->length != ((sizeof(xChangeWindowAccessReq) + + (stuff->npermit + stuff->ndeny + padding)) >> 2)) + { + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + 0, BadLength); + return Success; + } + + + err = dixLookupWindow(&win, stuff->win, client, DixWriteAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + stuff->win, err); + return Success; + } + + /* Are we clearing? if so, ignore the rest */ + if (stuff->clear) + { + err = ACClearWindowAccess(client, win, stuff->clear); + if (err != Success) + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, err); + return Success; + } + + if (stuff->npermit || stuff->ndeny) + deviceids = (CARD8*)&stuff[1]; + + if (stuff->npermit) + { + perm_devices = + (DeviceIntPtr*)xalloc(stuff->npermit * sizeof(DeviceIntPtr)); + if (!perm_devices) + { + ErrorF("ProcXChangeWindowAccess: alloc failure.\n"); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, + BadImplementation); + return Success; + } + + /* if one of the devices cannot be accessed, we don't do anything.*/ + for (i = 0; i < stuff->npermit; i++) + { + perm_devices[i] = LookupDeviceIntRec(deviceids[i]); + if (!perm_devices[i]) + { + xfree(perm_devices); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + deviceids[i], BadDevice); + return Success; + } + } + } + + if (stuff->ndeny) + { + deny_devices = + (DeviceIntPtr*)xalloc(stuff->ndeny * sizeof(DeviceIntPtr)); + if (!deny_devices) + { + ErrorF("ProcXChangeWindowAccecss: alloc failure.\n"); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, + BadImplementation); + + xfree(perm_devices); + return Success; + } + + for (i = 0; i < stuff->ndeny; i++) + { + deny_devices[i] = + LookupDeviceIntRec(deviceids[i+stuff->npermit]); + + if (!deny_devices[i]) + { + xfree(perm_devices); + xfree(deny_devices); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + deviceids[i + stuff->npermit], BadDevice); + return Success; + } + } + } + + err = ACChangeWindowAccess(client, win, stuff->defaultRule, + perm_devices, stuff->npermit, + deny_devices, stuff->ndeny); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + stuff->win, err); + return Success; + } + + xfree(perm_devices); + xfree(deny_devices); + return Success; +} + diff --git a/Xi/chaccess.h b/Xi/chaccess.h new file mode 100644 index 000000000..8c2c6003e --- /dev/null +++ b/Xi/chaccess.h @@ -0,0 +1,39 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef CHACCESS_H +#define CHACCESS_H 1 + +int SProcXChangeWindowAccess(ClientPtr /* client */); +int ProcXChangeWindowAccess(ClientPtr /* client */); + +#endif /* CHACCESS_H */ diff --git a/Xi/chdevcur.c b/Xi/chdevcur.c new file mode 100644 index 000000000..e69a26613 --- /dev/null +++ b/Xi/chdevcur.c @@ -0,0 +1,123 @@ +/* + +Copyright 2006 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/*********************************************************************** + * + * Request to change a given device pointer's cursor. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "chdevcur.h" + +/*********************************************************************** + * + * This procedure allows a client to set one pointer's cursor. + * + */ + +int +SProcXChangeDeviceCursor(ClientPtr client) +{ + char n; + + REQUEST(xChangeDeviceCursorReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xChangeDeviceCursorReq); + return (ProcXChangeDeviceCursor(client)); +} + +int ProcXChangeDeviceCursor(ClientPtr client) +{ + int err; + WindowPtr pWin = NULL; + DeviceIntPtr pDev = NULL; + CursorPtr pCursor = NULL; + + REQUEST(xChangeDeviceCursorReq); + REQUEST_SIZE_MATCH(xChangeDeviceCursorReq); + + pDev = LookupDeviceIntRec(stuff->deviceid); + if (pDev == NULL) { + SendErrorToClient(client, IReqCode, X_ChangeDeviceCursor, 0, + BadDevice); + return Success; + } + + if (stuff->win != None) + { + err = dixLookupWindow(&pWin, stuff->win, client, DixReadWriteAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_ChangeDeviceCursor, + stuff->win, err); + return Success; + } + } + + if (stuff->cursor == None) + { + if (pWin == WindowTable[pWin->drawable.pScreen->myNum]) + pCursor = rootCursor; + else + pCursor = (CursorPtr)None; + } + else + { + pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor, + RT_CURSOR, DixReadAccess); + if (!pCursor) + { + SendErrorToClient(client, IReqCode, X_ChangeDeviceCursor, + stuff->cursor, BadCursor); + return Success; + } + } + + ChangeWindowDeviceCursor(pWin, pDev, pCursor); + + return Success; +} + diff --git a/Xi/chdevcur.h b/Xi/chdevcur.h new file mode 100644 index 000000000..92c8d4f0d --- /dev/null +++ b/Xi/chdevcur.h @@ -0,0 +1,39 @@ +/************************************************************ + +Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef CHDEVCUR_H +#define CHDEVCUR_H 1 + +int SProcXChangeDeviceCursor(ClientPtr /* client */ + ); + +int ProcXChangeDeviceCursor(ClientPtr /* client */ + ); + +#endif /* CHDEVCUR_H */ diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c index 9676fb747..def3b702d 100644 --- a/Xi/chgdctl.c +++ b/Xi/chgdctl.c @@ -138,7 +138,7 @@ ProcXChangeDeviceControl(ClientPtr client) ret = BadMatch; goto out; } - if ((dev->grab) && !SameClient(dev->grab, client)) { + if ((dev->deviceGrab.grab) && !SameClient(dev->deviceGrab.grab, client)) { rep.status = AlreadyGrabbed; ret = Success; goto out; diff --git a/Xi/chpkpair.c b/Xi/chpkpair.c new file mode 100644 index 000000000..fcbdcdf2e --- /dev/null +++ b/Xi/chpkpair.c @@ -0,0 +1,110 @@ +/* + +Copyright 2006 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/*********************************************************************** + * + * Request change pairing between pointer and keyboard device. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + + +#include "chpkpair.h" + +/*********************************************************************** + * + * This procedure allows a client to change the pairing of a pointer with a + * a keyboard. + * + */ + +int SProcXChangePointerKeyboardPairing(ClientPtr client) +{ + char n; + + REQUEST(xChangePointerKeyboardPairingReq); + swaps(&stuff->length, n); + return (ProcXChangePointerKeyboardPairing(client)); +} + +int +ProcXChangePointerKeyboardPairing(ClientPtr client) +{ + DeviceIntPtr pPointer, pKeyboard; + int ret; + + REQUEST(xChangePointerKeyboardPairingReq); + REQUEST_SIZE_MATCH(xChangePointerKeyboardPairingReq); + + /* check if client is registered */ + + pPointer = LookupDeviceIntRec(stuff->pointer); + if (pPointer == NULL) + { + SendErrorToClient(client, IReqCode, X_ChangePointerKeyboardPairing, + stuff->pointer, BadDevice); + return Success; + } + + pKeyboard = LookupDeviceIntRec(stuff->keyboard); + if (pKeyboard == NULL) + { + SendErrorToClient(client, IReqCode, X_ChangePointerKeyboardPairing, + stuff->keyboard, BadDevice); + return Success; + } + + ret = PairDevices(client, pPointer, pKeyboard); + if (ret != Success) + { + SendErrorToClient(client, IReqCode, X_ChangePointerKeyboardPairing, + 0, ret); + return Success; + } + + + /* TODO: generate event here... */ + return Success; +} diff --git a/Xi/chpkpair.h b/Xi/chpkpair.h new file mode 100644 index 000000000..1acf54921 --- /dev/null +++ b/Xi/chpkpair.h @@ -0,0 +1,40 @@ +/************************************************************ + +Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef CHPKPAIR_H +#define CHPKPAIR_H 1 + +int SProcXChangePointerKeyboardPairing(ClientPtr /* client */ + ); + +int ProcXChangePointerKeyboardPairing(ClientPtr /* client */ + ); + +#endif /* WARPDEVP_H */ + diff --git a/Xi/closedev.c b/Xi/closedev.c index 8d38ec8fd..8aebe1043 100644 --- a/Xi/closedev.c +++ b/Xi/closedev.c @@ -156,8 +156,8 @@ ProcXCloseDevice(ClientPtr client) return Success; } - if (d->grab && SameClient(d->grab, client)) - (*d->DeactivateGrab) (d); /* release active grab */ + if (d->deviceGrab.grab && SameClient(d->deviceGrab.grab, client)) + (*d->deviceGrab.DeactivateGrab) (d); /* release active grab */ /* Remove event selections from all windows for events from this device * and selected by this client. diff --git a/Xi/exevents.c b/Xi/exevents.c index 9e71a9e4e..26f3640b7 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -82,7 +82,7 @@ SOFTWARE. #define Motion_Filter(class) (DevicePointerMotionMask | \ (class)->state | (class)->motionMask) -static Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , +Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , Bool /* ignoreSelectedEvents */ ); static Bool MakeInputMasks(WindowPtr /* pWin */ @@ -99,33 +99,60 @@ RegisterOtherDevice(DeviceIntPtr device) { device->public.processInputProc = ProcessOtherEvent; device->public.realInputProc = ProcessOtherEvent; - (device)->ActivateGrab = ActivateKeyboardGrab; - (device)->DeactivateGrab = DeactivateKeyboardGrab; + (device)->deviceGrab.ActivateGrab = ActivateKeyboardGrab; + (device)->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; + if (DeviceIsPointerType(device)) + { + (device)->coreGrab.ActivateGrab = ActivatePointerGrab; + (device)->coreGrab.DeactivateGrab = DeactivatePointerGrab; + } else + { + (device)->coreGrab.ActivateGrab = ActivateKeyboardGrab; + (device)->coreGrab.DeactivateGrab = DeactivateKeyboardGrab; + } } /*ARGSUSED*/ void -ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) +ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) { BYTE *kptr; int i; CARD16 modifiers; CARD16 mask; - GrabPtr grab = other->grab; + GrabPtr grab = device->deviceGrab.grab; Bool deactivateDeviceGrab = FALSE; int key = 0, bit = 0, rootX, rootY; - ButtonClassPtr b = other->button; - KeyClassPtr k = other->key; - ValuatorClassPtr v = other->valuator; + ButtonClassPtr b = device->button; + KeyClassPtr k = device->key; + ValuatorClassPtr v = device->valuator; deviceValuator *xV = (deviceValuator *) xE; if (xE->u.u.type != DeviceValuator) { - GetSpritePosition(&rootX, &rootY); + DeviceIntPtr mouse = NULL, kbd = NULL; + GetSpritePosition(device, &rootX, &rootY); xE->u.keyButtonPointer.rootX = rootX; xE->u.keyButtonPointer.rootY = rootY; key = xE->u.u.detail; NoticeEventTime(xE); - xE->u.keyButtonPointer.state = inputInfo.keyboard->key->state | - inputInfo.pointer->button->state; + + /* If 'device' is a pointer device, we need to get the paired keyboard + * for the state. If there is none, the kbd bits of state are 0. + * If 'device' is a keyboard device, get the paired pointer and use the + * pointer's state for the button bits. + */ + if (IsPointerDevice(device)) + { + kbd = GetPairedKeyboard(device); + mouse = device; + } + else + { + mouse = GetPairedPointer(device); + kbd = device; + } + xE->u.keyButtonPointer.state = (kbd) ? (kbd->key->state) : 0; + xE->u.keyButtonPointer.state |= (mouse) ? (mouse->button->state) : 0; + bit = 1 << (key & 7); } if (DeviceEventCallback) { @@ -145,7 +172,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) || (xV->num_valuators && (first + xV->num_valuators > v->numAxes)))) FatalError("Bad valuators reported for device %s\n", - other->name); + device->name); xV->device_state = 0; if (k) xV->device_state |= k->state; @@ -182,15 +209,15 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) if (*kptr & bit) { /* allow ddx to generate multiple downs */ if (!modifiers) { xE->u.u.type = DeviceKeyRelease; - ProcessOtherEvent(xE, other, count); + ProcessOtherEvent(xE, device, count); xE->u.u.type = DeviceKeyPress; /* release can have side effects, don't fall through */ - ProcessOtherEvent(xE, other, count); + ProcessOtherEvent(xE, device, count); } return; } - if (other->valuator) - other->valuator->motionHintWindow = NullWindow; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; *kptr |= bit; k->prev_state = k->state; for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { @@ -201,8 +228,8 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) modifiers &= ~mask; } } - if (!grab && CheckDeviceGrabs(other, xE, 0, count)) { - other->activatingKey = key; + if (!grab && CheckDeviceGrabs(device, xE, 0, count)) { + device->deviceGrab.activatingKey = key; return; } } else if (xE->u.u.type == DeviceKeyRelease) { @@ -213,8 +240,8 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) if (!(*kptr & bit)) /* guard against duplicates */ return; modifiers = k->modifierMap[key]; - if (other->valuator) - other->valuator->motionHintWindow = NullWindow; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; *kptr &= ~bit; k->prev_state = k->state; for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { @@ -228,7 +255,9 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) } } - if (other->fromPassiveGrab && (key == other->activatingKey)) + if (device->deviceGrab.fromPassiveGrab && + !device->deviceGrab.grab->coreGrab && + (key == device->deviceGrab.activatingKey)) deactivateDeviceGrab = TRUE; } else if (xE->u.u.type == DeviceButtonPress) { if (!b) @@ -236,8 +265,8 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) kptr = &b->down[key >> 3]; *kptr |= bit; - if (other->valuator) - other->valuator->motionHintWindow = NullWindow; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; b->buttonsDown++; b->motionMask = DeviceButtonMotionMask; xE->u.u.detail = b->map[key]; @@ -246,9 +275,9 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) if (xE->u.u.detail <= 5) b->state |= (Button1Mask >> 1) << xE->u.u.detail; SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify); - if (!grab) - if (CheckDeviceGrabs(other, xE, 0, count)) - return; + if (!grab) + if (CheckDeviceGrabs(device, xE, 0, count)) + return; } else if (xE->u.u.type == DeviceButtonRelease) { if (!b) @@ -256,8 +285,8 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) kptr = &b->down[key >> 3]; *kptr &= ~bit; - if (other->valuator) - other->valuator->motionHintWindow = NullWindow; + if (device->valuator) + device->valuator->motionHintWindow = NullWindow; if (!--b->buttonsDown) b->motionMask = 0; xE->u.u.detail = b->map[key]; @@ -266,23 +295,25 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count) if (xE->u.u.detail <= 5) b->state &= ~((Button1Mask >> 1) << xE->u.u.detail); SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify); - if (!b->state && other->fromPassiveGrab) - deactivateDeviceGrab = TRUE; + if (!b->state + && device->deviceGrab.fromPassiveGrab + && !device->deviceGrab.grab->coreGrab) + deactivateDeviceGrab = TRUE; } else if (xE->u.u.type == ProximityIn) - other->valuator->mode &= ~OutOfProximity; + device->valuator->mode &= ~OutOfProximity; else if (xE->u.u.type == ProximityOut) - other->valuator->mode |= OutOfProximity; + device->valuator->mode |= OutOfProximity; if (grab) - DeliverGrabbedEvent(xE, other, deactivateDeviceGrab, count); - else if (other->focus) - DeliverFocusedEvent(other, xE, GetSpriteWindow(), count); + DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count); + else if (device->focus) + DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count); else - DeliverDeviceEvents(GetSpriteWindow(), xE, NullGrab, NullWindow, - other, count); + DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow, + device, count); if (deactivateDeviceGrab == TRUE) - (*other->DeactivateGrab) (other); + (*device->deviceGrab.DeactivateGrab) (device); } _X_EXPORT int @@ -394,7 +425,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, event.window = pWin->drawable.id; event.time = currentTime.milliseconds; - (void)DeliverEventsToWindow(pWin, (xEvent *) & event, 1, + (void)DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, DeviceFocusChangeMask, NullGrab, dev->id); if ((type == DeviceFocusIn) && @@ -490,7 +521,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, } } - (void)DeliverEventsToWindow(pWin, (xEvent *) sev, evcount, + (void)DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, DeviceStateNotifyMask, NullGrab, dev->id); xfree(sev); } @@ -658,7 +689,7 @@ SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, if (dev->valuator) if ((dev->valuator->motionHintWindow == pWin) && (mask & DevicePointerMotionHintMask) && - !(check & DevicePointerMotionHintMask) && !dev->grab) + !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) dev->valuator->motionHintWindow = NullWindow; RecalculateDeviceDeliverableEvents(pWin); return Success; @@ -783,7 +814,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, { WindowPtr pWin; WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - WindowPtr spriteWin = GetSpriteWindow(); + WindowPtr spriteWin = GetSpriteWindow(d); if (dest == PointerWindow) pWin = spriteWin; @@ -822,7 +853,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, ev->u.u.type |= 0x80; if (propagate) { for (; pWin; pWin = pWin->parent) { - if (DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, d->id)) + if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id)) return Success; if (pWin == effectiveFocus) return Success; @@ -832,7 +863,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, break; } } else - (void)(DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, d->id)); + (void)(DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id)); return Success; } @@ -1003,8 +1034,8 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) * any input focus changes. * Deactivating a device grab should cause focus events. */ - if (dev->grab && (dev->grab->window == pWin)) - (*dev->DeactivateGrab) (dev); + if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) + (*dev->deviceGrab.DeactivateGrab) (dev); /* If the focus window is a root window (ie. has no parent) * then don't delete the focus from it. */ @@ -1014,7 +1045,7 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) /* If a grab is in progress, then alter the mode of focus events. */ - if (dev->grab) + if (dev->deviceGrab.grab) focusEventMode = NotifyWhileGrabbed; switch (dev->focus->revert) { @@ -1134,7 +1165,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, tempGrab.pointerMode = GrabModeAsync; tempGrab.confineTo = NullWindow; tempGrab.cursor = NullCursor; - (*dev->ActivateGrab) (dev, &tempGrab, currentTime, TRUE); + (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); } } @@ -1157,7 +1188,7 @@ void MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) { WindowPtr pWin; - GrabPtr grab = dev->grab; + GrabPtr grab = dev->deviceGrab.grab; pWin = dev->valuator->motionHintWindow; @@ -1198,7 +1229,7 @@ DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, return Success; } -static Bool +Bool ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) { int i; @@ -1231,7 +1262,7 @@ FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, while (p1) { p2 = p1->firstChild; - (void)DeliverEventsToWindow(p1, ev, count, mask, NullGrab, dev->id); + (void)DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab, dev->id); FindInterestedChildren(dev, p2, mask, ev, count); p1 = p1->nextSib; } @@ -1251,7 +1282,7 @@ SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) for (i = 0; i < screenInfo.numScreens; i++) { pWin = WindowTable[i]; - (void)DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, dev->id); + (void)DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab, dev->id); p1 = pWin->firstChild; FindInterestedChildren(dev, p1, mask, ev, count); } diff --git a/Xi/exglobals.h b/Xi/exglobals.h index 50bb33fdc..8fcd907a3 100644 --- a/Xi/exglobals.h +++ b/Xi/exglobals.h @@ -50,6 +50,9 @@ extern Mask DeviceOwnerGrabButtonMask; extern Mask DeviceButtonGrabMask; extern Mask DeviceButtonMotionMask; extern Mask DevicePresenceNotifyMask; +extern Mask DeviceEnterWindowMask; +extern Mask DeviceLeaveWindowMask; +extern Mask PointerKeyboardPairingChangedNotifyMask; extern Mask PropagateMask[]; extern int DeviceValuator; @@ -68,6 +71,9 @@ extern int DeviceButtonStateNotify; extern int DeviceMappingNotify; extern int ChangeDeviceNotify; extern int DevicePresenceNotify; +extern int DeviceEnterNotify; +extern int DeviceLeaveNotify; +extern int PointerKeyboardPairingChangedNotify; extern int RT_INPUTCLIENT; diff --git a/Xi/extinit.c b/Xi/extinit.c index b1ec321c9..9d921fa07 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -74,35 +74,45 @@ SOFTWARE. /* modules local to Xi */ #include "allowev.h" +#include "chaccess.h" +#include "chdevcur.h" #include "chgdctl.h" #include "chgfctl.h" #include "chgkbd.h" #include "chgprop.h" #include "chgptr.h" +#include "chpkpair.h" #include "closedev.h" #include "devbell.h" #include "getbmap.h" #include "getbmap.h" +#include "getcptr.h" #include "getdctl.h" #include "getfctl.h" #include "getfocus.h" #include "getkmap.h" #include "getmmap.h" +#include "getpairp.h" #include "getprop.h" #include "getselev.h" #include "getvers.h" #include "getvers.h" +#include "grabacc.h" #include "grabdev.h" #include "grabdevb.h" #include "grabdevk.h" #include "gtmotion.h" #include "listdev.h" #include "opendev.h" +#include "qryacces.c" +#include "querydp.h" #include "queryst.h" +#include "regpair.h" #include "selectev.h" #include "sendexev.h" #include "chgkmap.h" #include "setbmap.h" +#include "setcptr.h" #include "setdval.h" #include "setfocus.h" #include "setmmap.h" @@ -110,6 +120,7 @@ SOFTWARE. #include "ungrdev.h" #include "ungrdevb.h" #include "ungrdevk.h" +#include "warpdevp.h" static Mask lastExtEventMask = 1; int ExtEventIndex; @@ -167,6 +178,9 @@ Mask DeviceOwnerGrabButtonMask; Mask DeviceButtonGrabMask; Mask DeviceButtonMotionMask; Mask DevicePresenceNotifyMask; +Mask DeviceEnterWindowMask; +Mask DeviceLeaveWindowMask; +Mask PointerKeyboardPairingChangedMask; int DeviceValuator; int DeviceKeyPress; @@ -184,6 +198,9 @@ int DeviceButtonStateNotify; int DeviceMappingNotify; int ChangeDeviceNotify; int DevicePresenceNotify; +int DeviceEnterNotify; +int DeviceLeaveNotify; +int PointerKeyboardPairingChangedNotify; int RT_INPUTCLIENT; @@ -289,6 +306,28 @@ ProcIDispatch(ClientPtr client) return (ProcXGetDeviceControl(client)); else if (stuff->data == X_ChangeDeviceControl) return (ProcXChangeDeviceControl(client)); + else if (stuff->data == X_QueryDevicePointer) + return (ProcXQueryDevicePointer(client)); + else if (stuff->data == X_WarpDevicePointer) + return (ProcXWarpDevicePointer(client)); + else if (stuff->data == X_ChangeDeviceCursor) + return (ProcXChangeDeviceCursor(client)); + else if (stuff->data == X_ChangePointerKeyboardPairing) + return (ProcXChangePointerKeyboardPairing(client)); + else if (stuff->data == X_RegisterPairingClient) + return (ProcXRegisterPairingClient(client)); + else if (stuff->data == X_GrabAccessControl) + return (ProcXGrabAccessControl(client)); + else if (stuff->data == X_ChangeWindowAccess) + return (ProcXChangeWindowAccess(client)); + else if (stuff->data == X_QueryWindowAccess) + return ProcXQueryWindowAccess(client); + else if (stuff->data == X_SetClientPointer) + return ProcXSetClientPointer(client); + else if (stuff->data == X_GetClientPointer) + return ProcXGetClientPointer(client); + else if (stuff->data == X_GetPairedPointer) + return ProcXGetPairedPointer(client); else { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); } @@ -378,6 +417,28 @@ SProcIDispatch(ClientPtr client) return (SProcXGetDeviceControl(client)); else if (stuff->data == X_ChangeDeviceControl) return (SProcXChangeDeviceControl(client)); + else if (stuff->data == X_QueryDevicePointer) + return (SProcXQueryDevicePointer(client)); + else if (stuff->data == X_WarpDevicePointer) + return (SProcXWarpDevicePointer(client)); + else if (stuff->data == X_ChangeDeviceCursor) + return (SProcXChangeDeviceCursor(client)); + else if (stuff->data == X_ChangePointerKeyboardPairing) + return (SProcXChangePointerKeyboardPairing(client)); + else if (stuff->data == X_RegisterPairingClient) + return (SProcXRegisterPairingClient(client)); + else if (stuff->data == X_GrabAccessControl) + return (SProcXGrabAccessControl(client)); + else if (stuff->data == X_ChangeWindowAccess) + return (SProcXChangeWindowAccess(client)); + else if (stuff->data == X_QueryWindowAccess) + return SProcXQueryWindowAccess(client); + else if (stuff->data == X_SetClientPointer) + return SProcXSetClientPointer(client); + else if (stuff->data == X_GetClientPointer) + return SProcXGetClientPointer(client); + else if (stuff->data == X_GetPairedPointer) + return SProcXGetPairedPointer(client); else { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); } @@ -450,6 +511,22 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep) else if (rep->RepType == X_ChangeDeviceControl) SRepXChangeDeviceControl(client, len, (xChangeDeviceControlReply *) rep); + else if (rep->RepType == X_QueryDevicePointer) + SRepXQueryDevicePointer(client, len, + (xQueryDevicePointerReply *) rep); + else if (rep->RepType == X_RegisterPairingClient) + SRepXRegisterPairingClient(client, len, + (xRegisterPairingClientReply *) rep); + else if (rep->RepType == X_GrabAccessControl) + SRepXGrabAccessControl(client, len, + (xGrabAccessControlReply*) rep); + else if (rep->RepType == X_QueryWindowAccess) + SRepXQueryWindowAccess(client, len, + (xQueryWindowAccessReply*) rep); + else if (rep->RepType == X_GetClientPointer) + SRepXGetClientPointer(client, len, (xGetClientPointerReply*) rep); + else if (rep->RepType == X_GetPairedPointer) + SRepXGetPairedPointer(client, len, (xGetPairedPointerReply*) rep); else { FatalError("XINPUT confused sending swapped reply"); } @@ -555,6 +632,44 @@ SDevicePresenceNotifyEvent (devicePresenceNotify *from, devicePresenceNotify *to swaps(&to->control, n); } +static void +SDeviceEnterNotifyEvent (deviceEnterNotify *from, deviceEnterNotify *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber,n); + swapl(&to->time, n); +} + +static void +SDeviceLeaveNotifyEvent (deviceLeaveNotify *from, deviceLeaveNotify *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber,n); + swapl(&to->time, n); + swapl(&to->root, n); + swapl(&to->event, n); + swapl(&to->child, n); + swaps(&to->rootX, n); + swaps(&to->rootY, n); + swaps(&to->eventX, n); + swaps(&to->eventY, n); +} + +static void +SPointerKeyboardPairingChangedNotifyEvent (pairingChangedNotify *from, + pairingChangedNotify *to) +{ + char n; + + *to = *from; + swaps(&to->sequenceNumber, n); + swapl(&to->time, n); +} + /************************************************************************** * * Allow the specified event to have its propagation suppressed. @@ -675,6 +790,9 @@ FixExtensionEvents(ExtensionEntry * extEntry) DeviceKeyStateNotify = ChangeDeviceNotify + 1; DeviceButtonStateNotify = DeviceKeyStateNotify + 1; DevicePresenceNotify = DeviceButtonStateNotify + 1; + DeviceEnterNotify = DevicePresenceNotify + 1; + DeviceLeaveNotify = DeviceEnterNotify + 1; + PointerKeyboardPairingChangedNotify = DeviceLeaveNotify + 1; event_base[KeyClass] = DeviceKeyPress; event_base[ButtonClass] = DeviceButtonPress; @@ -750,6 +868,20 @@ FixExtensionEvents(ExtensionEntry * extEntry) DevicePresenceNotifyMask = GetNextExtEventMask(); SetEventInfo(DevicePresenceNotifyMask, _devicePresence); + + DeviceEnterWindowMask = GetNextExtEventMask(); + SetMaskForExtEvent(DeviceEnterWindowMask, DeviceEnterNotify); + AllowPropagateSuppress(DeviceEnterWindowMask); + + DeviceLeaveWindowMask = GetNextExtEventMask(); + SetMaskForExtEvent(DeviceLeaveWindowMask, DeviceLeaveNotify); + AllowPropagateSuppress(DeviceLeaveWindowMask); + + PointerKeyboardPairingChangedMask = GetNextExtEventMask(); + SetMaskForExtEvent(PointerKeyboardPairingChangedMask, + PointerKeyboardPairingChangedNotify); + AllowPropagateSuppress(PointerKeyboardPairingChangedMask); + SetEventInfo(0, _noExtensionEvent); } @@ -791,6 +923,9 @@ RestoreExtensionEvents(void) DeviceKeyStateNotify = 13; DeviceButtonStateNotify = 13; DevicePresenceNotify = 14; + DeviceEnterNotify = 15; + DeviceLeaveNotify = 16; + PointerKeyboardPairingChangedNotify = 17; BadDevice = 0; BadEvent = 1; @@ -829,9 +964,28 @@ IResetProc(ExtensionEntry * unused) EventSwapVector[DeviceMappingNotify] = NotImplemented; EventSwapVector[ChangeDeviceNotify] = NotImplemented; EventSwapVector[DevicePresenceNotify] = NotImplemented; + EventSwapVector[DeviceEnterNotify] = NotImplemented; + EventSwapVector[DeviceLeaveNotify] = NotImplemented; + EventSwapVector[PointerKeyboardPairingChangedNotify] = NotImplemented; RestoreExtensionEvents(); } +/***************************************************************** + * + * Returns TRUE if the device has some sort of pointer type. + * + */ + +_X_EXPORT Bool +DeviceIsPointerType(DeviceIntPtr dev) +{ + if (dev_type[1].type == dev->type) + return TRUE; + + return FALSE; +} + + /*********************************************************************** * * Assign an id and type to an input device. @@ -935,6 +1089,14 @@ SEventIDispatch(xEvent * from, xEvent * to) DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify); else if (type == ChangeDeviceNotify) DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify); + else if (type == DevicePresenceNotify) + DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify); + else if (type == DeviceEnterNotify) + DO_SWAP(SDeviceEnterNotifyEvent, deviceEnterNotify); + else if (type == DeviceLeaveNotify) + DO_SWAP(SDeviceLeaveNotifyEvent, deviceLeaveNotify); + else if (type == PointerKeyboardPairingChangedNotify) + DO_SWAP(SPointerKeyboardPairingChangedNotifyEvent, pairingChangedNotify); else { FatalError("XInputExtension: Impossible event!\n"); } @@ -980,6 +1142,9 @@ XInputExtensionInit(void) EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch; EventSwapVector[DeviceMappingNotify] = SEventIDispatch; EventSwapVector[ChangeDeviceNotify] = SEventIDispatch; + EventSwapVector[DeviceEnterNotify] = SEventIDispatch; + EventSwapVector[DeviceLeaveNotify] = SEventIDispatch; + EventSwapVector[PointerKeyboardPairingChangedNotify] = SEventIDispatch; } else { FatalError("IExtensionInit: AddExtensions failed\n"); } diff --git a/Xi/getcptr.c b/Xi/getcptr.c new file mode 100644 index 000000000..d9ca4d360 --- /dev/null +++ b/Xi/getcptr.c @@ -0,0 +1,111 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "getcptr.h" + +/*********************************************************************** + * This procedure allows a client to query another client's client pointer + * setting. + */ + +int +SProcXGetClientPointer(ClientPtr client) +{ + char n; + REQUEST(xGetClientPointerReq); + + swaps(&stuff->length, n); + swapl(&stuff->win, n); + return ProcXGetClientPointer(client); +} + +int ProcXGetClientPointer(ClientPtr client) +{ + int err; + WindowPtr win; + ClientPtr winclient; + xGetClientPointerReply rep; + REQUEST(xGetClientPointerReq); + REQUEST_SIZE_MATCH(xGetClientPointerReq); + + err = dixLookupWindow(&win, stuff->win, client, DixReadAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_GetClientPointer, + stuff->win, err); + return Success; + } + + winclient = wClient(win); + + rep.repType = X_Reply; + rep.RepType = X_GetClientPointer; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.set = (winclient->clientPtr != NULL); + rep.deviceid = (winclient->clientPtr) ? winclient->clientPtr->id : 0; + + WriteReplyToClient(client, sizeof(xGetClientPointerReply), &rep); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGetClientPointer function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGetClientPointer(ClientPtr client, int size, + xGetClientPointerReply* rep) +{ + char n; + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} + diff --git a/Xi/getcptr.h b/Xi/getcptr.h new file mode 100644 index 000000000..456d1bac2 --- /dev/null +++ b/Xi/getcptr.h @@ -0,0 +1,43 @@ +/************************************************************ + +Copyright 2007 by Peter Hutterer <peter@cs.unisa.edu.au> + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef GETCPTR_H +#define GETCPTR_H 1 +int SProcXGetClientPointer(ClientPtr /* client */ + ); + +int ProcXGetClientPointer(ClientPtr /* client */ + ); + +void SRepXGetClientPointer(ClientPtr /* client */, + int /* size */, + xGetClientPointerReply* /* rep */ + ); + +#endif /* GETCPTR_H */ diff --git a/Xi/getpairp.c b/Xi/getpairp.c new file mode 100644 index 000000000..4f1ff0316 --- /dev/null +++ b/Xi/getpairp.c @@ -0,0 +1,110 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#include "getpairp.h" + +/*********************************************************************** + * + * This procedure allows a client to query the paired pointer for a keyboard + * device. + * + */ + +int +SProcXGetPairedPointer(ClientPtr client) +{ + char n; + REQUEST(xGetPairedPointerReq); + swaps(&stuff->length, n); + return (ProcXGetPairedPointer(client)); +} + +int +ProcXGetPairedPointer(ClientPtr client) +{ + xGetPairedPointerReply rep; + DeviceIntPtr kbd, ptr; + + REQUEST(xGetPairedPointerReq); + REQUEST_SIZE_MATCH(xGetPairedPointerReq); + + kbd = LookupDeviceIntRec(stuff->deviceid); + if (!kbd || !kbd->key) { + SendErrorToClient(client, IReqCode, X_GetPairedPointer, + stuff->deviceid, BadDevice); + return Success; + } + + ptr = GetPairedPointer(kbd); + + rep.repType = X_Reply; + rep.RepType = X_GetPairedPointer; + rep.length = 0; + rep.sequenceNumber = client->sequence; + if (ptr == inputInfo.pointer) + { + rep.paired = FALSE; + rep.deviceid = 0; + } else + { + rep.paired = TRUE; + rep.deviceid = ptr->id; + } + WriteReplyToClient(client, sizeof(xGetPairedPointerReply), &rep); + return Success; +} + +void +SRepXGetPairedPointer(ClientPtr client, int size, + xGetPairedPointerReply* rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} diff --git a/Xi/getpairp.h b/Xi/getpairp.h new file mode 100644 index 000000000..9b4759e71 --- /dev/null +++ b/Xi/getpairp.h @@ -0,0 +1,45 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef GETPAIRP_H +#define GETPAIRP_H 1 + +int SProcXGetPairedPointer(ClientPtr /* client */ + ); +int ProcXGetPairedPointer(ClientPtr /* client */ + ); +void SRepXGetPairedPointer(ClientPtr /* client */, + int /* size */, + xGetPairedPointerReply* /* rep */ + ); + +#endif /* GETPAIRP_H */ diff --git a/Xi/grabacc.c b/Xi/grabacc.c new file mode 100644 index 000000000..59888ee15 --- /dev/null +++ b/Xi/grabacc.c @@ -0,0 +1,102 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "grabacc.h" + +/*********************************************************************** + * + * This procedure allows a client to register as the global client to control + * any window access. + * + */ +int +SProcXGrabAccessControl(ClientPtr client) +{ + char n; + REQUEST(xGrabAccessControlReq); + + swaps(&stuff->length, n); + return ProcXGrabAccessControl(client); +} + +int +ProcXGrabAccessControl(ClientPtr client) +{ + xGrabAccessControlReply rep; + REQUEST(xGrabAccessControlReq); + REQUEST_SIZE_MATCH(xGrabAccessControlReq); + + if (stuff->ungrab) + ACUnregisterClient(client); + + rep.repType = X_Reply; + rep.RepType = X_GrabAccessControl; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.success = stuff->ungrab || ACRegisterClient(client); + + WriteReplyToClient(client, sizeof(xGrabAccessControlReply), &rep); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XGrabAccessControl function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXGrabAccessControl(ClientPtr client, int size, + xGrabAccessControlReply* rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} + diff --git a/Xi/grabacc.h b/Xi/grabacc.h new file mode 100644 index 000000000..6dcbcad33 --- /dev/null +++ b/Xi/grabacc.h @@ -0,0 +1,41 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef GRABACC_H +#define GRABACC_H 1 + +int SProcXGrabAccessControl(ClientPtr /* client */); + +int ProcXGrabAccessControl(ClientPtr /* client */); +void SRepXGrabAccessControl(ClientPtr client, int size, + xGrabAccessControlReply* rep); +#endif /* GRABACC_H */ diff --git a/Xi/grabdevb.c b/Xi/grabdevb.c index df62d0c69..0b8a978e7 100644 --- a/Xi/grabdevb.c +++ b/Xi/grabdevb.c @@ -140,7 +140,7 @@ ProcXGrabDeviceButton(ClientPtr client) return Success; } } else - mdev = (DeviceIntPtr) LookupKeyboardDevice(); + mdev = PickKeyboard(client); class = (XEventClass *) (&stuff[1]); /* first word of values */ diff --git a/Xi/grabdevk.c b/Xi/grabdevk.c index b74592f19..297072b6f 100644 --- a/Xi/grabdevk.c +++ b/Xi/grabdevk.c @@ -137,7 +137,7 @@ ProcXGrabDeviceKey(ClientPtr client) return Success; } } else - mdev = (DeviceIntPtr) LookupKeyboardDevice(); + mdev = PickKeyboard(client); class = (XEventClass *) (&stuff[1]); /* first word of values */ diff --git a/Xi/listdev.c b/Xi/listdev.c index 160ad02fb..a9fd40156 100644 --- a/Xi/listdev.c +++ b/Xi/listdev.c @@ -328,6 +328,10 @@ ProcXListInputDevices(ClientPtr client) AddOtherInputDevices(); + SizeDeviceInfo(inputInfo.keyboard, &namesize, &size); + SizeDeviceInfo(inputInfo.pointer, &namesize, &size); + numdevs = 2; + for (d = inputInfo.devices; d; d = d->next) { SizeDeviceInfo(d, &namesize, &size); numdevs++; @@ -344,6 +348,11 @@ ProcXListInputDevices(ClientPtr client) savbuf = devbuf; dev = (xDeviceInfoPtr) devbuf; + ListDeviceInfo(client, inputInfo.keyboard, dev++, + &devbuf, &classbuf, &namebuf); + ListDeviceInfo(client, inputInfo.pointer, dev++, + &devbuf, &classbuf, &namebuf); + for (d = inputInfo.devices; d; d = d->next, dev++) ListDeviceInfo(client, d, dev, &devbuf, &classbuf, &namebuf); for (d = inputInfo.off_devices; d; d = d->next, dev++) diff --git a/Xi/qryacces.c b/Xi/qryacces.c new file mode 100644 index 000000000..817bec8a3 --- /dev/null +++ b/Xi/qryacces.c @@ -0,0 +1,128 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "qryacces.h" + +/*********************************************************************** + * This procedure allows a client to query window access control. + */ + +int +SProcXQueryWindowAccess(ClientPtr client) +{ + char n; + REQUEST(xQueryWindowAccessReq); + + swaps(&stuff->length, n); + swapl(&stuff->win, n); + return ProcXQueryWindowAccess(client); +} + +int +ProcXQueryWindowAccess(ClientPtr client) +{ + int err; + WindowPtr win; + DeviceIntPtr *perm, *deny; + int nperm, ndeny, i; + int defaultRule; + CARD8* deviceids; + xQueryWindowAccessReply rep; + + REQUEST(xQueryWindowAccessReq); + REQUEST_SIZE_MATCH(xQueryWindowAccessReq); + + err = dixLookupWindow(&win, stuff->win, client, DixReadAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_QueryWindowAccess, + stuff->win, err); + return Success; + } + + ACQueryWindowAccess(win, &defaultRule, &perm, &nperm, &deny, &ndeny); + + rep.repType = X_Reply; + rep.RepType = X_QueryWindowAccess; + rep.sequenceNumber = client->sequence; + rep.length = (nperm + ndeny + 3) >> 2; + rep.defaultRule = defaultRule; + rep.npermit = nperm; + rep.ndeny = ndeny; + WriteReplyToClient(client, sizeof(xQueryWindowAccessReply), &rep); + + if (nperm + ndeny) + { + deviceids = (CARD8*)xalloc((nperm + ndeny) * sizeof(CARD8)); + if (!deviceids) + { + ErrorF("ProcXQueryWindowAccess: xalloc failure.\n"); + SendErrorToClient(client, IReqCode, X_QueryWindowAccess, + 0, BadImplementation); + return Success; + } + + for (i = 0; i < nperm; i++) + deviceids[i] = perm[i]->id; + for (i = 0; i < ndeny; i++) + deviceids[i + nperm] = deny[i]->id; + + WriteToClient(client, nperm + ndeny, (char*)deviceids); + xfree(deviceids); + } + return Success; +} + +void +SRepXQueryWindowAccess(ClientPtr client, + int size, + xQueryWindowAccessReply* rep) +{ + char n; + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char*)rep); +} diff --git a/Xi/qryacces.h b/Xi/qryacces.h new file mode 100644 index 000000000..5fce9aec2 --- /dev/null +++ b/Xi/qryacces.h @@ -0,0 +1,41 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef QRYACCES_H +#define QRYACCES_H 1 + +int SProcXQueryWindowAccess(ClientPtr /* client */); +int ProcXQueryWindowAccess(ClientPtr /* client */); +void SRepXQueryWindowAccess(ClientPtr /* client */, + int /* size */, + xQueryWindowAccessReply* /* rep */); +#endif diff --git a/Xi/querydp.c b/Xi/querydp.c new file mode 100644 index 000000000..d2ed0b80a --- /dev/null +++ b/Xi/querydp.c @@ -0,0 +1,167 @@ +/* + +Copyright 2006 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/*********************************************************************** + * + * Request to query the pointer location of an extension input device. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#include "querydp.h" + +/*********************************************************************** + * + * This procedure allows a client to query the pointer of a device. + * + */ + +int +SProcXQueryDevicePointer(ClientPtr client) +{ + char n; + + REQUEST(xQueryDevicePointerReq); + swaps(&stuff->length, n); + return (ProcXQueryDevicePointer(client)); +} + +int +ProcXQueryDevicePointer(ClientPtr client) +{ + int rc; + xQueryDevicePointerReply rep; + DeviceIntPtr pDev; + WindowPtr pWin, t; + SpritePtr pSprite; + + REQUEST(xQueryDevicePointerReq); + REQUEST_SIZE_MATCH(xQueryDevicePointerReq); + + pDev = LookupDeviceIntRec(stuff->deviceid); + if (pDev == NULL || pDev->valuator == NULL) { + SendErrorToClient(client, IReqCode, X_QueryDevicePointer, + stuff->deviceid, BadDevice); + return Success; + } + + rc = dixLookupWindow(&pWin, stuff->win, client, DixReadAccess); + if (rc != Success) + { + SendErrorToClient(client, IReqCode, X_QueryDevicePointer, + stuff->win, rc); + return Success; + } + + if (pDev->valuator->motionHintWindow) + MaybeStopHint(pDev, client); + + pSprite = pDev->spriteInfo->sprite; + rep.repType = X_Reply; + rep.RepType = X_QueryDevicePointer; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.mask = pDev->button->state | inputInfo.keyboard->key->state; + rep.root = (GetCurrentRootWindow())->drawable.id; + rep.rootX = pSprite->hot.x; + rep.rootY = pSprite->hot.y; + rep.child = None; + rep.shared = (pDev->spriteInfo->spriteOwner) ? xFalse : xTrue; + + if (pSprite->hot.pScreen == pWin->drawable.pScreen) + { + rep.sameScreen = xTrue; + rep.winX = pSprite->hot.x - pWin->drawable.x; + rep.winY = pSprite->hot.y - pWin->drawable.y; + for (t = pSprite->win; t; t = t->parent) + if (t->parent == pWin) + { + rep.child = t->drawable.id; + break; + } + } else + { + rep.sameScreen = xFalse; + rep.winX = 0; + rep.winY = 0; + } + +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + rep.rootX += panoramiXdataPtr[0].x; + rep.rootY += panoramiXdataPtr[0].y; + if (stuff->win == rep.root) + { + rep.winX += panoramiXdataPtr[0].x; + rep.winY += panoramiXdataPtr[0].y; + } + } +#endif + + WriteReplyToClient(client, sizeof(xQueryDevicePointerReply), &rep); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XQueryDevicePointer function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXQueryDevicePointer(ClientPtr client, int size, + xQueryDevicePointerReply * rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} + diff --git a/Xi/querydp.h b/Xi/querydp.h new file mode 100644 index 000000000..acad548ab --- /dev/null +++ b/Xi/querydp.h @@ -0,0 +1,44 @@ +/************************************************************ + +Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef QUERYDP_H +#define QUERYDP_H 1 + +int SProcXQueryDevicePointer(ClientPtr /* client */ + ); + +int ProcXQueryDevicePointer(ClientPtr /* client */ + ); + +void SRepXQueryDevicePointer(ClientPtr /* client */ , + int /* size */ , + xQueryDevicePointerReply * /* rep */ + ); + +#endif /* QUERYDP_H */ diff --git a/Xi/regpair.c b/Xi/regpair.c new file mode 100644 index 000000000..cfaddb841 --- /dev/null +++ b/Xi/regpair.c @@ -0,0 +1,108 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/*********************************************************************** + * + * Request to authenticate as pairing client + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "exevents.h" +#include "exglobals.h" + +#include "regpair.h" + +/*********************************************************************** + * + * This procedure allows a client to register the pairing of a pointer + * with a keyboard. + * + */ + +int +SProcXRegisterPairingClient(ClientPtr client) +{ + char n; + REQUEST(xRegisterPairingClientReq); + swaps(&stuff->length, n); + return ProcXRegisterPairingClient(client); +} + +int +ProcXRegisterPairingClient(ClientPtr client) +{ + xRegisterPairingClientReply rep; + + REQUEST(xRegisterPairingClientReq); + REQUEST_SIZE_MATCH(xRegisterPairingClientReq); + + if (stuff->disable) + UnregisterPairingClient(client); + + rep.repType = X_Reply; + rep.RepType = X_RegisterPairingClient; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.success = stuff->disable || RegisterPairingClient(client); + + WriteReplyToClient(client, sizeof(xRegisterPairingClientReply), &rep); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XRegisterPairingClient function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXRegisterPairingClient(ClientPtr client, int size, + xRegisterPairingClientReply* rep) +{ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} + diff --git a/Xi/regpair.h b/Xi/regpair.h new file mode 100644 index 000000000..b2bfaff3e --- /dev/null +++ b/Xi/regpair.h @@ -0,0 +1,43 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef REGPAIR_H +#define REGPAIR_H 1 + +int SProcXRegisterPairingClient(ClientPtr /* client */); +int ProcXRegisterPairingClient(ClientPtr /* client */); + +void SRepXRegisterPairingClient(ClientPtr /* client */, + int /* size */, + xRegisterPairingClientReply* /* rep */); + +#endif /* REGPAIR_H */ diff --git a/Xi/setcptr.c b/Xi/setcptr.c new file mode 100644 index 000000000..25874f0a5 --- /dev/null +++ b/Xi/setcptr.c @@ -0,0 +1,105 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/*********************************************************************** + * + * Request to set the client pointer for the owner of the given window. + * All subsequent calls that are ambiguous will choose the client pointer as + * default value. + */ + + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "setcptr.h" + +int +SProcXSetClientPointer(ClientPtr client) +{ + char n; + + REQUEST(xSetClientPointerReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xSetClientPointerReq); + return (ProcXSetClientPointer(client)); +} + +int +ProcXSetClientPointer(ClientPtr client) +{ + DeviceIntPtr pDev; + WindowPtr pWin; + int err; + + REQUEST(xSetClientPointerReq); + REQUEST_SIZE_MATCH(xSetClientPointerReq); + + + pDev = LookupDeviceIntRec(stuff->deviceid); + if (pDev == NULL || !IsPointerDevice(pDev)) + { + SendErrorToClient(client, IReqCode, X_SetClientPointer, 0, + BadDevice); + return Success; + } + + if (stuff->win != None) + { + err = dixLookupWindow(&pWin, stuff->win, client, DixReadWriteAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_SetClientPointer, + stuff->win, err); + return Success; + } + } + + if (!SetClientPointer(wClient(pWin), client, pDev)) + { + SendErrorToClient(client, IReqCode, X_SetClientPointer, + stuff->win, BadAccess); + return Success; + } + return Success; +} diff --git a/Xi/setcptr.h b/Xi/setcptr.h new file mode 100644 index 000000000..0c24fd4dd --- /dev/null +++ b/Xi/setcptr.h @@ -0,0 +1,39 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef SETCPTR_H +#define SETCPTR_H 1 + +int SProcXSetClientPointer(ClientPtr /* client */); +int ProcXSetClientPointer(ClientPtr /* client */); + +#endif /* SETCPTR_H */ diff --git a/Xi/setdval.c b/Xi/setdval.c index e947a749a..61b98c790 100644 --- a/Xi/setdval.c +++ b/Xi/setdval.c @@ -125,7 +125,7 @@ ProcXSetDeviceValuators(ClientPtr client) return Success; } - if ((dev->grab) && !SameClient(dev->grab, client)) + if ((dev->deviceGrab.grab) && !SameClient(dev->deviceGrab.grab, client)) rep.status = AlreadyGrabbed; else rep.status = SetDeviceValuators(client, dev, (int *)&stuff[1], diff --git a/Xi/setmode.c b/Xi/setmode.c index 688f2a226..00d340055 100644 --- a/Xi/setmode.c +++ b/Xi/setmode.c @@ -113,7 +113,7 @@ ProcXSetDeviceMode(ClientPtr client) SendErrorToClient(client, IReqCode, X_SetDeviceMode, 0, BadMatch); return Success; } - if ((dev->grab) && !SameClient(dev->grab, client)) + if ((dev->deviceGrab.grab) && !SameClient(dev->deviceGrab.grab, client)) rep.status = AlreadyGrabbed; else rep.status = SetDeviceMode(client, dev, stuff->mode); diff --git a/Xi/ungrdev.c b/Xi/ungrdev.c index 0abbd2e80..b2b71694d 100644 --- a/Xi/ungrdev.c +++ b/Xi/ungrdev.c @@ -106,12 +106,12 @@ ProcXUngrabDevice(ClientPtr client) SendErrorToClient(client, IReqCode, X_UngrabDevice, 0, BadDevice); return Success; } - grab = dev->grab; + grab = dev->deviceGrab.grab; time = ClientTimeToServerTime(stuff->time); if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, dev->grabTime) != EARLIER) && + (CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) && (grab) && SameClient(grab, client)) - (*dev->DeactivateGrab) (dev); + (*dev->deviceGrab.DeactivateGrab) (dev); return Success; } diff --git a/Xi/ungrdevb.c b/Xi/ungrdevb.c index b9f236b76..5e0a66328 100644 --- a/Xi/ungrdevb.c +++ b/Xi/ungrdevb.c @@ -133,7 +133,7 @@ ProcXUngrabDeviceButton(ClientPtr client) return Success; } } else - mdev = (DeviceIntPtr) LookupKeyboardDevice(); + mdev = PickKeyboard(client); rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixUnknownAccess); if (rc != Success) { diff --git a/Xi/ungrdevk.c b/Xi/ungrdevk.c index d316990b2..7b06d6e09 100644 --- a/Xi/ungrdevk.c +++ b/Xi/ungrdevk.c @@ -132,7 +132,7 @@ ProcXUngrabDeviceKey(ClientPtr client) return Success; } } else - mdev = (DeviceIntPtr) LookupKeyboardDevice(); + mdev = PickKeyboard(client); rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixUnknownAccess); if (rc != Success) { diff --git a/Xi/warpdevp.c b/Xi/warpdevp.c new file mode 100644 index 000000000..82d71d524 --- /dev/null +++ b/Xi/warpdevp.c @@ -0,0 +1,187 @@ +/* + +Copyright 2006 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/*********************************************************************** + * + * Request to Warp the pointer location of an extension input device. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> /* for inputstr.h */ +#include <X11/Xproto.h> /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include <X11/extensions/XI.h> +#include <X11/extensions/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + + +#include "warpdevp.h" +/*********************************************************************** + * + * This procedure allows a client to warp the pointer of a device. + * + */ + +int +SProcXWarpDevicePointer(ClientPtr client) +{ + char n; + + REQUEST(xWarpDevicePointerReq); + swaps(&stuff->length, n); + return (ProcXWarpDevicePointer(client)); +} + +int +ProcXWarpDevicePointer(ClientPtr client) +{ + int err; + int x, y; + WindowPtr dest = NULL; + DeviceIntPtr pDev; + SpritePtr pSprite; + ScreenPtr newScreen; + + REQUEST(xWarpDevicePointerReq); + REQUEST_SIZE_MATCH(xWarpDevicePointerReq); + + /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */ + + pDev = LookupDeviceIntRec(stuff->deviceid); + if (pDev == NULL) { + SendErrorToClient(client, IReqCode, X_WarpDevicePointer, + stuff->deviceid, + BadDevice); + return Success; + } + + if (stuff->dst_win != None) + { + err = dixLookupWindow(&dest, stuff->dst_win, client, DixReadAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_WarpDevicePointer, + stuff->dst_win, err); + return Success; + } + } + + pSprite = pDev->spriteInfo->sprite; + x = pSprite->hotPhys.x; + y = pSprite->hotPhys.y; + + if (stuff->src_win != None) + { + int winX, winY; + WindowPtr src; + + err = dixLookupWindow(&src, stuff->src_win, client, DixReadAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_WarpDevicePointer, + stuff->src_win, err); + return Success; + } + + winX = src->drawable.x; + winY = src->drawable.y; + if (src->drawable.pScreen != pSprite->hotPhys.pScreen || + x < winX + stuff->src_x || + y < winY + stuff->src_y || + (stuff->src_width != 0 && + winX + stuff->src_x + (int)stuff->src_width < 0) || + (stuff->src_height != 0 && + winY + stuff->src_y + (int)stuff->src_height < y) || + !PointInWindowIsVisible(src, x, y)) + return Success; + } + + if (dest) + { + x = dest->drawable.x; + y = dest->drawable.y; + newScreen = dest->drawable.pScreen; + } else + newScreen = pSprite->hotPhys.pScreen; + + x += stuff->dst_x; + y += stuff->dst_y; + + if (x < 0) + x = 0; + else if (x > newScreen->width) + x = newScreen->width - 1; + + if (y < 0) + y = 0; + else if (y > newScreen->height) + y = newScreen->height - 1; + + if (newScreen == pSprite->hotPhys.pScreen) + { + if (x < pSprite->physLimits.x1) + x = pSprite->physLimits.x1; + else if (x >= pSprite->physLimits.x2) + x = pSprite->physLimits.x2 - 1; + + if (y < pSprite->physLimits.y1) + y = pSprite->physLimits.y1; + else if (y >= pSprite->physLimits.y2) + y = pSprite->physLimits.y2 - 1; + +#if defined(SHAPE) + if (pSprite->hotShape) + ConfineToShape(pDev, pSprite->hotShape, &x, &y); +#endif + (*newScreen->SetCursorPosition)(pDev, newScreen, x, y, TRUE); + } else if (!PointerConfinedToScreen(pDev)) + { + NewCurrentScreen(pDev, newScreen, x, y); + } + + /* if we don't update the device, we get a jump next time it moves */ + pDev->valuator->lastx = x; + pDev->valuator->lasty = x; + miPointerUpdateSprite(pDev); + + /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it + here though. */ + return Success; +} + diff --git a/Xi/warpdevp.h b/Xi/warpdevp.h new file mode 100644 index 000000000..8ce5b7098 --- /dev/null +++ b/Xi/warpdevp.h @@ -0,0 +1,39 @@ +/************************************************************ + +Copyright 2006 by Peter Hutterer <peter@cs.unisa.edu.au> + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef WARPDEVP_H +#define WARPDEVP_H 1 + +int SProcXWarpDevicePointer(ClientPtr /* client */ + ); + +int ProcXWarpDevicePointer(ClientPtr /* client */ + ); + +#endif /* WARPDEVP_H */ diff --git a/autogen.sh b/autogen.sh index 904cd6746..66acd288d 100755 --- a/autogen.sh +++ b/autogen.sh @@ -9,4 +9,4 @@ cd $srcdir autoreconf -v --install || exit 1 cd $ORIGDIR || exit $? -$srcdir/configure --enable-maintainer-mode "$@" +$srcdir/configure --enable-maintainer-mode --disable-dmx --enable-kdrive "$@" diff --git a/configure.ac b/configure.ac index fde6a8955..bd6bbebcc 100644 --- a/configure.ac +++ b/configure.ac @@ -493,7 +493,6 @@ AC_ARG_ENABLE(builtin-fonts, AS_HELP_STRING([--enable-builtin-fonts], [Use only AC_ARG_ENABLE(null-root-cursor, AS_HELP_STRING([--enable-null-root-cursor], [Use an empty root cursor (default: use core cursor)]), [NULL_ROOT_CURSOR=$enableval], [NULL_ROOT_CURSOR=no]) - dnl Extensions. AC_ARG_ENABLE(composite, AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes]) AC_ARG_ENABLE(mitshm, AS_HELP_STRING([--disable-shm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes]) diff --git a/dix/Makefile.am b/dix/Makefile.am index a1f02c1b6..d9083ea52 100644 --- a/dix/Makefile.am +++ b/dix/Makefile.am @@ -5,6 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS) \ -DVENDOR_RELEASE="@VENDOR_RELEASE@" libdix_la_SOURCES = \ + access.c \ atom.c \ colormap.c \ cursor.c \ diff --git a/dix/access.c b/dix/access.c new file mode 100644 index 000000000..970d7c49a --- /dev/null +++ b/dix/access.c @@ -0,0 +1,287 @@ +/* + +Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the author shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the author. + +*/ + +/* This file controls the access control lists for each window. + * Each device can be explicitely allowed or denied access to a given window. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/Xlib.h> +#include <X11/extensions/XI.h> + +#include "input.h" +#include "inputstr.h" +#include "windowstr.h" + + +/* Only one single client can be responsible for window access control. */ +static ClientPtr ACClient = NULL; + + +/* Forward declarations */ +static void acReplaceList(DeviceIntPtr** list, + int* count, + DeviceIntPtr* devices, + int ndevices); + +/* Register global window access control client + * Return True on success or False otherwise. + */ + +Bool +ACRegisterClient(ClientPtr client) +{ + if (ACClient && ACClient != client) + return False; + + ACClient = client; + return True; +} + + +/* Unregister global client. If client is not the registered client, nothing + * happens and False is returned. If no client is registered, return True. + * Returns True if client was registred and is now unregistered. + */ + +Bool +ACUnregisterClient(ClientPtr client) +{ + if (ACClient && ACClient != client) + return False; + + ACClient = NULL; + return True; +} + +/* Clears all access control for the window and remove the default rule, + * depending on what is set. */ +int ACClearWindowAccess(ClientPtr client, + WindowPtr win, + int what) +{ + if (client != ACClient && client != wClient(win)) + return BadAccess; + + if (!win->optional) + { + /* we shouldn't get here if programmers know what they're doing. + * A client should not request to clear a window's access controls + * if they've never been set before anyway. If they do, do nothing and + * let the client figure out what to do next. + */ + return Success; + } + + if (what & WindowAccessClearPerm) + { + xfree(win->optional->access.perm); + win->optional->access.perm = NULL; + win->optional->access.nperm = 0; + } + + if (what & WindowAccessClearDeny) + { + xfree(win->optional->access.deny); + win->optional->access.deny = NULL; + win->optional->access.ndeny = 0; + } + + if (what & WindowAccessClearRule) + win->optional->access.defaultRule = WindowAccessNoRule; + + return Success; +} + +/* + * Changes window access control. + * + * Returns Success or BadAccess if the client is not allowed to change + * anything. + */ + +int +ACChangeWindowAccess(ClientPtr client, + WindowPtr win, + int defaultRule, + DeviceIntPtr* perm_devices, + int nperm, + DeviceIntPtr* deny_devices, + int ndeny) +{ + if (client != ACClient && client != wClient(win)) + return BadAccess; + + if (!win->optional && !MakeWindowOptional(win)) + { + ErrorF("ACChangeWindowAcccess: Failed to make window optional.\n"); + return BadImplementation; + } + + if (defaultRule != WindowAccessKeepRule) + win->optional->access.defaultRule = defaultRule; + + if (nperm) + { + acReplaceList(&win->optional->access.perm, + &win->optional->access.nperm, + perm_devices, nperm); + } + + if (ndeny) + { + acReplaceList(&win->optional->access.deny, + &win->optional->access.ndeny, + deny_devices, ndeny); + } + + return Success; +} + +static void +acReplaceList(DeviceIntPtr** list, + int* count, + DeviceIntPtr* devices, + int ndevices) +{ + xfree(*list); + *list = NULL; + *count = 0; + + if (ndevices) + { + *list = + xalloc(ndevices * sizeof(DeviceIntPtr*)); + if (!*list) + { + ErrorF("ACChangeWindowAccess: out of memory\n"); + return; + } + memcpy(*list, + devices, + ndevices * sizeof(DeviceIntPtr)); + *count = ndevices; + } + return; +} + +/* + * Query the given window for the devices allowed to access a window. + * The caller is responsible for freeing perm and deny. + */ +void +ACQueryWindowAccess(WindowPtr win, + int* defaultRule, + DeviceIntPtr** perm, + int* nperm, + DeviceIntPtr** deny, + int* ndeny) +{ + *defaultRule = WindowAccessNoRule; + *perm = NULL; + *nperm = 0; + *deny = NULL; + *ndeny = 0; + + if (!win->optional) + return; + + *defaultRule = win->optional->access.defaultRule; + + if (win->optional->access.nperm) + { + *nperm = win->optional->access.nperm; + *perm = (DeviceIntPtr*)xalloc(*nperm * sizeof(DeviceIntPtr)); + if (!*perm) + { + ErrorF("ACQuerywinAccess: xalloc failure\n"); + return; + } + memcpy(*perm, + win->optional->access.perm, + *nperm * sizeof(DeviceIntPtr)); + } + + if (win->optional->access.ndeny) + { + *ndeny = win->optional->access.ndeny; + *deny = (DeviceIntPtr*)xalloc(*ndeny * sizeof(DeviceIntPtr)); + if (!*deny) + { + ErrorF("ACQuerywinAccess: xalloc failure\n"); + return; + } + memcpy(*deny, + win->optional->access.deny, + *ndeny * sizeof(DeviceIntPtr)); + } +} + +/* + * Check if the given device is allowed to send events to the window. Returns + * true if device is allowed or false otherwise. + * + * Checks are done in the following order until a result is found: + * If the device is explicitely permitted, allow. + * If the window has a default of DenyAll, do not allow. + * If the device is explicitely denied, do not allow. + * Check parent window. Rinse, wash, repeat. + * If no rule could be found, allow. + */ +Bool +ACDeviceAllowed(WindowPtr win, DeviceIntPtr dev) +{ + int i; + + if (!win) /* happens for parent of RootWindow */ + return True; + + if (!win->optional) /* no list, check parent */ + return ACDeviceAllowed(win->parent, dev); + + for (i = 0; i < win->optional->access.nperm; i++) + { + if (win->optional->access.perm[i]->id == dev->id) + return True; + } + + if (win->optional->access.defaultRule == WindowAccessDenyAll) + return False; + + for (i = 0; i < win->optional->access.ndeny; i++) + { + if (win->optional->access.deny[i]->id == dev->id) + return False; + } + + return ACDeviceAllowed(win->parent, dev); +} + diff --git a/dix/cursor.c b/dix/cursor.c index 5ab562ead..5886422d5 100644 --- a/dix/cursor.c +++ b/dix/cursor.c @@ -59,6 +59,7 @@ SOFTWARE. #include "cursorstr.h" #include "dixfontstr.h" #include "opaque.h" +#include "inputstr.h" typedef struct _GlyphShare { FontPtr font; @@ -114,14 +115,19 @@ FreeCursor(pointer value, XID cid) CursorPtr pCurs = (CursorPtr)value; ScreenPtr pscr; + DeviceIntPtr pDev; - if ( --pCurs->refcnt > 0) + if ( --pCurs->refcnt != 0) return(Success); for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { pscr = screenInfo.screens[nscr]; - (void)( *pscr->UnrealizeCursor)( pscr, pCurs); + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + (void)( *pscr->UnrealizeCursor)(pDev, pscr, pCurs); + } } FreeCursorBits(pCurs->bits); xfree( pCurs); @@ -171,8 +177,9 @@ AllocCursorARGB(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb, CursorPtr pCurs; int nscr; ScreenPtr pscr; + DeviceIntPtr pDev; - pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits)); + pCurs = (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1); if (!pCurs) { xfree(psrcbits); @@ -189,11 +196,10 @@ AllocCursorARGB(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb, bits->height = cm->height; bits->xhot = cm->xhot; bits->yhot = cm->yhot; - bits->refcnt = -1; + pCurs->refcnt = 1; CheckForEmptyMask(bits); pCurs->bits = bits; - pCurs->refcnt = 1; #ifdef XFIXES pCurs->serialNumber = ++cursorSerial; pCurs->name = None; @@ -209,21 +215,50 @@ AllocCursorARGB(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb, /* * realize the cursor for every screen + * Do not change the refcnt, this will be changed when ChangeToCursor + * actually changes the sprite. */ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { - pscr = screenInfo.screens[nscr]; - if (!( *pscr->RealizeCursor)( pscr, pCurs)) - { - while (--nscr >= 0) - { - pscr = screenInfo.screens[nscr]; - ( *pscr->UnrealizeCursor)( pscr, pCurs); - } - FreeCursorBits(bits); - xfree(pCurs); - return (CursorPtr)NULL; - } + pscr = screenInfo.screens[nscr]; + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + if (!( *pscr->RealizeCursor)(pDev, pscr, pCurs)) + { + /* Realize failed for device pDev on screen pscr. + * We have to assume that for all devices before, realize + * worked. We need to rollback all devices so far on the + * current screen and then all devices on previous + * screens. + */ + DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator*/ + while(pDevIt && pDevIt != pDev) + { + if (DevHasCursor(pDevIt)) + ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); + pDevIt = pDevIt->next; + } + while (--nscr >= 0) + { + pscr = screenInfo.screens[nscr]; + /* now unrealize all devices on previous screens */ + pDevIt = inputInfo.devices; + while (pDevIt) + { + if (DevHasCursor(pDevIt)) + ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); + pDevIt = pDevIt->next; + } + ( *pscr->UnrealizeCursor)(pDev, pscr, pCurs); + } + FreeCursorBits(bits); + xfree(pCurs); + return (CursorPtr)NULL; + } + } + } } return pCurs; } @@ -260,6 +295,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, int nscr; ScreenPtr pscr; GlyphSharePtr pShare; + DeviceIntPtr pDev; sourcefont = (FontPtr) SecurityLookupIDByType(client, source, RT_FONT, DixReadAccess); @@ -290,7 +326,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, } if (pShare) { - pCurs = (CursorPtr)xalloc(sizeof(CursorRec)); + pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1); if (!pCurs) return BadAlloc; bits = pShare->bits; @@ -332,7 +368,8 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, } if (sourcefont != maskfont) { - pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits)); + pCurs = + (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1); if (pCurs) bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec)); else @@ -340,9 +377,9 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, } else { - pCurs = (CursorPtr)xalloc(sizeof(CursorRec)); + pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1); if (pCurs) - bits = (CursorBitsPtr)xalloc(sizeof(CursorBits)); + bits = (CursorBitsPtr)xcalloc(sizeof(CursorBits), 1); else bits = (CursorBitsPtr)NULL; } @@ -382,6 +419,7 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, sharedGlyphs = pShare; } } + CheckForEmptyMask(bits); pCurs->bits = bits; pCurs->refcnt = 1; @@ -403,18 +441,51 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, */ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { - pscr = screenInfo.screens[nscr]; - if (!( *pscr->RealizeCursor)( pscr, pCurs)) - { - while (--nscr >= 0) - { - pscr = screenInfo.screens[nscr]; - ( *pscr->UnrealizeCursor)( pscr, pCurs); - } - FreeCursorBits(pCurs->bits); - xfree(pCurs); - return BadAlloc; - } + pscr = screenInfo.screens[nscr]; + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + if (!( *pscr->RealizeCursor)(pDev, pscr, pCurs)) + { + /* Realize failed for device pDev on screen pscr. + * We have to assume that for all devices before, realize + * worked. We need to rollback all devices so far on the + * current screen and then all devices on previous + * screens. + */ + DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator*/ + while(pDevIt && pDevIt != pDev) + { + if (DevHasCursor(pDevIt)) + ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); + pDevIt = pDevIt->next; + } + + (*pscr->UnrealizeCursor)(inputInfo.pointer, pscr, pCurs); + + while (--nscr >= 0) + { + pscr = screenInfo.screens[nscr]; + /* now unrealize all devices on previous screens */ + ( *pscr->UnrealizeCursor)(inputInfo.pointer, pscr, pCurs); + + pDevIt = inputInfo.devices; + while (pDevIt) + { + if (DevHasCursor(pDevIt)) + ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); + pDevIt = pDevIt->next; + } + ( *pscr->UnrealizeCursor)(pDev, pscr, pCurs); + } + FreeCursorBits(bits); + xfree(pCurs); + return BadAlloc; + } + } + } } *ppCurs = pCurs; return Success; diff --git a/dix/devices.c b/dix/devices.c index f622be756..411188d8f 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -82,6 +82,9 @@ SOFTWARE. int CoreDevicePrivatesIndex = 0; static int CoreDevicePrivatesGeneration = -1; +/* The client that is allowed to change pointer-keyboard pairings. */ +static ClientPtr pairingClient = NULL; + DeviceIntPtr AddInputDevice(DeviceProc deviceProc, Bool autoStart) { @@ -102,14 +105,27 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart) dev->public.enqueueInputProc = EnqueueEvent; dev->deviceProc = deviceProc; dev->startup = autoStart; - dev->sync.frozen = FALSE; - dev->sync.other = NullGrab; - dev->sync.state = NOT_GRABBED; - dev->sync.event = (xEvent *) NULL; - dev->sync.evcount = 0; - dev->grab = NullGrab; - dev->grabTime = currentTime; - dev->fromPassiveGrab = FALSE; + + /* core grab defaults */ + dev->coreGrab.sync.frozen = FALSE; + dev->coreGrab.sync.other = NullGrab; + dev->coreGrab.sync.state = NOT_GRABBED; + dev->coreGrab.sync.event = (xEvent *) NULL; + dev->coreGrab.sync.evcount = 0; + dev->coreGrab.grab = NullGrab; + dev->coreGrab.grabTime = currentTime; + dev->coreGrab.fromPassiveGrab = FALSE; + + /* device grab defaults */ + dev->deviceGrab.sync.frozen = FALSE; + dev->deviceGrab.sync.other = NullGrab; + dev->deviceGrab.sync.state = NOT_GRABBED; + dev->deviceGrab.sync.event = (xEvent *) NULL; + dev->deviceGrab.sync.evcount = 0; + dev->deviceGrab.grab = NullGrab; + dev->deviceGrab.grabTime = currentTime; + dev->deviceGrab.fromPassiveGrab = FALSE; + dev->key = (KeyClassPtr)NULL; dev->valuator = (ValuatorClassPtr)NULL; dev->button = (ButtonClassPtr)NULL; @@ -132,6 +148,13 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart) dev->inited = FALSE; dev->enabled = FALSE; + /* sprite defaults */ + dev->spriteInfo = (SpriteInfoPtr)xcalloc(sizeof(SpriteInfoRec), 1); + if (!dev->spriteInfo) + return (DeviceIntPtr)NULL; + dev->spriteInfo->sprite = NULL; + dev->spriteInfo->spriteOwner = FALSE; + for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next) ; *prev = dev; @@ -158,6 +181,11 @@ EnableDevice(DeviceIntPtr dev) dev->enabled = TRUE; *prev = dev->next; + if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner) + InitializeSprite(dev, GetCurrentRootWindow()); + else + PairDevices(NULL, inputInfo.pointer, dev); + for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next) ; *prev = dev; @@ -337,14 +365,23 @@ InitCoreDevices() dev->public.processInputProc = ProcessKeyboardEvent; dev->public.realInputProc = ProcessKeyboardEvent; #endif - dev->ActivateGrab = ActivateKeyboardGrab; - dev->DeactivateGrab = DeactivateKeyboardGrab; + dev->coreGrab.ActivateGrab = ActivateKeyboardGrab; + dev->coreGrab.DeactivateGrab = DeactivateKeyboardGrab; dev->coreEvents = FALSE; + dev->spriteInfo->spriteOwner = FALSE; if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex)) FatalError("Couldn't allocate keyboard devPrivates\n"); dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; (void)ActivateDevice(dev); + + /* Enable device, and then remove it from the device list. Virtual + * devices are kept separate, not in the standard device list. + */ + if (dev->inited && dev->startup) + EnableDevice(dev); + inputInfo.off_devices = inputInfo.devices = NULL; inputInfo.keyboard = dev; + inputInfo.keyboard->next = NULL; } if (!inputInfo.pointer) { @@ -361,14 +398,27 @@ InitCoreDevices() dev->public.processInputProc = ProcessPointerEvent; dev->public.realInputProc = ProcessPointerEvent; #endif - dev->ActivateGrab = ActivatePointerGrab; - dev->DeactivateGrab = DeactivatePointerGrab; + dev->coreGrab.ActivateGrab = ActivatePointerGrab; + dev->coreGrab.DeactivateGrab = DeactivatePointerGrab; dev->coreEvents = FALSE; if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex)) FatalError("Couldn't allocate pointer devPrivates\n"); dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; + InitializeSprite(dev, NullWindow); (void)ActivateDevice(dev); + + /* Enable device, and then remove it from the device list. Virtual + * devices are kept separate, not in the standard device list. + */ + if (dev->inited && dev->startup) + EnableDevice(dev); + inputInfo.off_devices = inputInfo.devices = NULL; inputInfo.pointer = dev; + inputInfo.pointer->next = NULL; + + /* the core keyboard is initialised by now. set the keyboard's sprite + * to the core pointer's sprite. */ + PairDevices(pairingClient, inputInfo.pointer, inputInfo.keyboard); } } @@ -388,21 +438,24 @@ InitAndStartDevices() if (dev->inited && dev->startup) (void)EnableDevice(dev); } - for (dev = inputInfo.devices; - dev && (dev != inputInfo.keyboard); - dev = dev->next) - if (!dev || (dev != inputInfo.keyboard)) { + + if (!inputInfo.keyboard) { ErrorF("No core keyboard\n"); return BadImplementation; } - for (dev = inputInfo.devices; - dev && (dev != inputInfo.pointer); - dev = dev->next) - ; - if (!dev || (dev != inputInfo.pointer)) { + if (!inputInfo.pointer) { ErrorF("No core pointer\n"); return BadImplementation; } + + /* All of the devices are started up now. Try to pair each keyboard with a + * real pointer, if possible. */ + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (!DevHasCursor(dev)) + PairDevices(NULL, GuessFreePointerDevice(), dev); + } + return Success; } @@ -415,6 +468,7 @@ CloseDevice(DeviceIntPtr dev) StringFeedbackPtr s, snext; BellFeedbackPtr b, bnext; LedFeedbackPtr l, lnext; + int j; if (dev->inited) (void)(*dev->deviceProc)(dev, DEVICE_CLOSE); @@ -494,11 +548,23 @@ CloseDevice(DeviceIntPtr dev) while (dev->xkb_interest) XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource); #endif + + if (DevHasCursor(dev)) + xfree((pointer)dev->spriteInfo->sprite); + + /* a client may have the device set as client pointer */ + for (j = 0; j < currentMaxClients; j++) + { + if (clients[j]->clientPtr == dev) + PickPointer(clients[j]); + } if (dev->devPrivates) xfree(dev->devPrivates); - xfree(dev->sync.event); + xfree(dev->coreGrab.sync.event); + xfree(dev->deviceGrab.sync.event); + xfree(dev->spriteInfo); xfree(dev); } @@ -582,6 +648,8 @@ RemoveDevice(DeviceIntPtr dev) int NumMotionEvents() { + /* only called to fill data in initial connection reply. + * VCP is ok here, it is the only fixed device we have. */ return inputInfo.pointer->valuator->numMotionEvents; } @@ -1069,8 +1137,8 @@ InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms, } _X_EXPORT void -SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count, - ClientPtr client) +SendMappingNotify(DeviceIntPtr pDev, unsigned request, unsigned firstKeyCode, + unsigned count, ClientPtr client) { int i; xEvent event; @@ -1085,8 +1153,7 @@ SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count, #ifdef XKB if (!noXkbExtension && ((request == MappingKeyboard) || (request == MappingModifier))) { - XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count, - client); + XkbApplyMappingChange(pDev,request,firstKeyCode,count, client); } #endif @@ -1250,7 +1317,7 @@ ProcSetModifierMapping(ClientPtr client) stuff->numKeyPerModifier); /* FIXME: Send mapping notifies for all the extended devices as well. */ - SendMappingNotify(MappingModifier, 0, 0, client); + SendMappingNotify(inputInfo.keyboard, MappingModifier, 0, 0, client); WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); return client->noClientException; } @@ -1321,8 +1388,8 @@ ProcChangeKeyboardMapping(ClientPtr client) } /* FIXME: Send mapping notifies for all the extended devices as well. */ - SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes, - client); + SendMappingNotify(inputInfo.keyboard, MappingKeyboard, + stuff->firstKeyCode, stuff->keyCodes, client); return client->noClientException; } @@ -1362,6 +1429,7 @@ ProcSetPointerMapping(ClientPtr client) REQUEST(xSetPointerMappingReq); BYTE *map; int ret; + DeviceIntPtr ptr = PickPointer(client); xSetPointerMappingReply rep; REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); @@ -1375,14 +1443,18 @@ ProcSetPointerMapping(ClientPtr client) /* So we're bounded here by the number of core buttons. This check * probably wants disabling through XFixes. */ - if (stuff->nElts != inputInfo.pointer->button->numButtons) { + /* MPX: With ClientPointer, we can return the right number of buttons. + * Let's just hope nobody changed ClientPointer between GetPointerMapping + * and SetPointerMapping + */ + if (stuff->nElts != ptr->button->numButtons) { client->errorValue = stuff->nElts; return BadValue; } if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue)) return BadValue; - ret = DoSetPointerMapping(inputInfo.pointer, map, stuff->nElts); + ret = DoSetPointerMapping(ptr, map, stuff->nElts); if (ret != Success) { rep.success = ret; WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); @@ -1390,7 +1462,7 @@ ProcSetPointerMapping(ClientPtr client) } /* FIXME: Send mapping notifies for all the extended devices as well. */ - SendMappingNotify(MappingPointer, 0, 0, client); + SendMappingNotify(ptr, MappingPointer, 0, 0, client); WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); return Success; } @@ -1400,7 +1472,8 @@ ProcGetKeyboardMapping(ClientPtr client) { xGetKeyboardMappingReply rep; REQUEST(xGetKeyboardMappingReq); - KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms; + DeviceIntPtr kbd = PickKeyboard(client); + KeySymsPtr curKeySyms = &kbd->key->curKeySyms; REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); @@ -1435,7 +1508,9 @@ int ProcGetPointerMapping(ClientPtr client) { xGetPointerMappingReply rep; - ButtonClassPtr butc = inputInfo.pointer->button; + /* Apps may get different values each time they call GetPointerMapping as + * the ClientPointer could change. */ + ButtonClassPtr butc = PickPointer(client)->button; REQUEST_SIZE_MATCH(xReq); rep.type = X_Reply; @@ -1739,7 +1814,7 @@ ProcBell(ClientPtr client) int ProcChangePointerControl(ClientPtr client) { - DeviceIntPtr mouse = inputInfo.pointer; + DeviceIntPtr mouse = PickPointer(client); PtrCtrl ctrl; /* might get BadValue part way through */ REQUEST(xChangePointerControlReq); @@ -1795,7 +1870,7 @@ ProcChangePointerControl(ClientPtr client) for (mouse = inputInfo.devices; mouse; mouse = mouse->next) { - if ((mouse->coreEvents || mouse == inputInfo.pointer) && + if ((mouse->coreEvents || mouse == PickPointer(client)) && mouse->ptrfeed && mouse->ptrfeed->CtrlProc) { mouse->ptrfeed->ctrl = ctrl; (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl); @@ -1808,7 +1883,8 @@ ProcChangePointerControl(ClientPtr client) int ProcGetPointerControl(ClientPtr client) { - PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl; + DeviceIntPtr ptr = PickPointer(client); + PtrCtrl *ctrl = &ptr->ptrfeed->ctrl; xGetPointerControlReply rep; REQUEST_SIZE_MATCH(xReq); @@ -1825,7 +1901,7 @@ ProcGetPointerControl(ClientPtr client) void MaybeStopHint(DeviceIntPtr dev, ClientPtr client) { - GrabPtr grab = dev->grab; + GrabPtr grab = dev->coreGrab.grab; if ((grab && SameClient(grab, client) && ((grab->eventMask & PointerMotionHintMask) || @@ -1846,7 +1922,7 @@ ProcGetMotionEvents(ClientPtr client) xGetMotionEventsReply rep; int i, count, xmin, xmax, ymin, ymax, rc; unsigned long nEvents; - DeviceIntPtr mouse = inputInfo.pointer; + DeviceIntPtr mouse = PickPointer(client); TimeStamp start, stop; REQUEST(xGetMotionEventsReq); @@ -1924,5 +2000,146 @@ ProcQueryKeymap(ClientPtr client) bzero((char *)&rep.map[0], 32); WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); + + return Success; +} + +/* Pair the keyboard to the pointer device. Keyboard events will follow the + * pointer sprite. + */ +int +PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) +{ + if (!ptr) + return BadDevice; + + if (!pairingClient) + RegisterPairingClient(client); + else if (pairingClient != client) + return BadAccess; + + if (kbd->spriteInfo->spriteOwner) + { + xfree(kbd->spriteInfo->sprite); + kbd->spriteInfo->sprite = NULL; + kbd->spriteInfo->spriteOwner = FALSE; + } + + kbd->spriteInfo->sprite = ptr->spriteInfo->sprite; 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->spriteInfo->sprite == kbd->spriteInfo->sprite && + ptr->spriteInfo->spriteOwner) + { + return ptr; + } + ptr = ptr->next; + } + + return inputInfo.pointer; +} + +/* Find the keyboard device that is paired with the given pointer. If none is + * found, return NULL. + * We also check if the paired device is a keyboard. If not (e.g. evdev brain) + * we don't return it. This probably needs to be fixed. + */ +_X_EXPORT DeviceIntPtr +GetPairedKeyboard(DeviceIntPtr ptr) +{ + DeviceIntPtr dev = inputInfo.devices; + + while(dev) + { + if (ptr != dev && + IsKeyboardDevice(dev) && + ptr->spriteInfo->sprite == dev->spriteInfo->sprite) + return dev; + dev = dev->next; + } + return dev; +} + +/* + * Register a client to be able to pair devices. + */ +Bool +RegisterPairingClient(ClientPtr client) +{ + if (!pairingClient) + { + pairingClient = client; + } else if (pairingClient != client) + { + return False; + } + return True; +} + +/* + * Unregister pairing client; + */ +Bool +UnregisterPairingClient(ClientPtr client) +{ + if (pairingClient) + { + if ( pairingClient == client) + { + pairingClient = NULL; + } else + return False; + } + return True; +} + +/* Guess a pointer that could be a good one for pairing. Any pointer that is + * not yet paired with keyboard is considered a good one. + * If no pointer is found, the last real pointer is chosen. If that doesn't + * work either, we take the core pointer. + */ +DeviceIntPtr +GuessFreePointerDevice() +{ + DeviceIntPtr it, it2; + DeviceIntPtr lastRealPtr = NULL; + + it = inputInfo.devices; + + while(it) + { + /* found device with a sprite? */ + if (it->spriteInfo->spriteOwner) + { + lastRealPtr = it; + + it2 = inputInfo.devices; + while(it2) + { + /* something paired with it? */ + if (it != it2 && + it2->spriteInfo->sprite == it->spriteInfo->sprite) + break; + + it2 = it2->next; + } + + /* woohoo! no pairing set up for 'it' yet */ + if (!it2) + return it; + } + it = it->next; + } + + return (lastRealPtr) ? lastRealPtr : inputInfo.pointer; +} diff --git a/dix/dispatch.c b/dix/dispatch.c index 490b29c34..25987b6d1 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -3581,6 +3581,8 @@ CloseDownClient(ClientPtr client) DeleteClientFromAnySelections(client); ReleaseActiveGrabs(client); DeleteClientFontStuff(client); + ACUnregisterClient(client); + UnregisterPairingClient(client); /* other clients can pair devices */ if (!really_close_down) { /* This frees resources that should never be retained @@ -3719,6 +3721,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 e008e3613..de8ff9b6b 100644 --- a/dix/events.c +++ b/dix/events.c @@ -107,6 +107,12 @@ of the copyright holder. ******************************************************************/ +/* + * MPX additions + * Copyright 2006 by Peter Hutterer + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + */ + #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> @@ -234,25 +240,36 @@ static WindowPtr *spriteTrace = (WindowPtr *)NULL; static int spriteTraceSize = 0; static int spriteTraceGood; -static struct { - CursorPtr current; - BoxRec hotLimits; /* logical constraints of hot spot */ - Bool confined; /* confined to screen */ -#if defined(SHAPE) || defined(PANORAMIX) - RegionPtr hotShape; /* additional logical shape constraint */ -#endif - BoxRec physLimits; /* physical constraints of hot spot */ - WindowPtr win; /* window of logical position */ - HotSpot hot; /* logical pointer position */ - HotSpot hotPhys; /* physical pointer position */ -#ifdef PANORAMIX - ScreenPtr screen; /* all others are in Screen 0 coordinates */ - RegionRec Reg1; /* Region 1 for confining motion */ - RegionRec Reg2; /* Region 2 for confining virtual motion */ - WindowPtr windows[MAXSCREENS]; - WindowPtr confineWin; /* confine window */ -#endif -} sprite; /* info about the cursor sprite */ +/** + * True if device owns a cursor, false if device shares a cursor sprite with + * another device. + */ +_X_EXPORT Bool +DevHasCursor(DeviceIntPtr pDev) +{ + return (pDev != inputInfo.pointer && pDev->spriteInfo->spriteOwner); +} + +/* + * Return true if a device is a pointer, check is the same as used by XI to + * fill the 'use' field. + */ +_X_EXPORT Bool +IsPointerDevice(DeviceIntPtr dev) +{ + return ((dev->valuator && dev->button) || dev == inputInfo.pointer); +} + +/* + * Return true if a device is a keyboard, check is the same as used by XI to + * fill the 'use' field. + */ +_X_EXPORT Bool +IsKeyboardDevice(DeviceIntPtr dev) +{ + return ((dev->key && dev->kbdfeed) || dev == inputInfo.keyboard); +} + #ifdef XEVIE _X_EXPORT WindowPtr xeviewin; @@ -260,6 +277,7 @@ _X_EXPORT HotSpot xeviehot; #endif static void DoEnterLeaveEvents( + DeviceIntPtr pDev, WindowPtr fromWin, WindowPtr toWin, int mode @@ -324,18 +342,18 @@ static CARD8 criticalEvents[32] = }; #ifdef PANORAMIX -static void ConfineToShape(RegionPtr shape, int *px, int *py); -static void PostNewCursor(void); +static void PostNewCursor(DeviceIntPtr pDev); -#define SyntheticMotion(x, y) \ - PostSyntheticMotion(x, y, noPanoramiXExtension ? 0 : \ - sprite.screen->myNum, \ +#define SyntheticMotion(dev, x, y) \ + PostSyntheticMotion(dev, x, y, noPanoramiXExtension ? 0 : \ + dev->spriteInfo->sprite->screen->myNum, \ syncEvents.playingEvents ? \ syncEvents.time.milliseconds : \ currentTime.milliseconds); static Bool XineramaSetCursorPosition( + DeviceIntPtr pDev, int x, int y, Bool generateEvent @@ -343,12 +361,13 @@ XineramaSetCursorPosition( ScreenPtr pScreen; BoxRec box; int i; + SpritePtr pSprite = pDev->spriteInfo->sprite; /* x,y are in Screen 0 coordinates. We need to decide what Screen to send the message too and what the coordinates relative to that screen are. */ - pScreen = sprite.screen; + pScreen = pSprite->screen; x += panoramiXdataPtr[0].x; y += panoramiXdataPtr[0].y; @@ -367,21 +386,25 @@ XineramaSetCursorPosition( } } - sprite.screen = pScreen; - sprite.hotPhys.x = x - panoramiXdataPtr[0].x; - sprite.hotPhys.y = y - panoramiXdataPtr[0].y; + pSprite->screen = pScreen; + pSprite->hotPhys.x = x - panoramiXdataPtr[0].x; + pSprite->hotPhys.y = y - panoramiXdataPtr[0].y; x -= panoramiXdataPtr[pScreen->myNum].x; y -= panoramiXdataPtr[pScreen->myNum].y; - return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent); + return (*pScreen->SetCursorPosition)(pDev, pScreen, x, y, generateEvent); } static void -XineramaConstrainCursor(void) +XineramaConstrainCursor(DeviceIntPtr pDev) { - ScreenPtr pScreen = sprite.screen; - BoxRec newBox = sprite.physLimits; + SpritePtr pSprite = pDev->spriteInfo->sprite; + ScreenPtr pScreen; + BoxRec newBox; + + pScreen = pSprite->screen; + newBox = pSprite->physLimits; /* Translate the constraining box to the screen the sprite is actually on */ @@ -390,56 +413,60 @@ XineramaConstrainCursor(void) newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; - (* pScreen->ConstrainCursor)(pScreen, &newBox); + (* pScreen->ConstrainCursor)(pDev, pScreen, &newBox); } static void XineramaCheckPhysLimits( + DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents ){ HotSpot new; + SpritePtr pSprite = pDev->spriteInfo->sprite; if (!cursor) return; - new = sprite.hotPhys; + new = pSprite->hotPhys; /* I don't care what the DDX has to say about it */ - sprite.physLimits = sprite.hotLimits; + pSprite->physLimits = pSprite->hotLimits; /* constrain the pointer to those limits */ - if (new.x < sprite.physLimits.x1) - new.x = sprite.physLimits.x1; + if (new.x < pSprite->physLimits.x1) + new.x = pSprite->physLimits.x1; else - if (new.x >= sprite.physLimits.x2) - new.x = sprite.physLimits.x2 - 1; - if (new.y < sprite.physLimits.y1) - new.y = sprite.physLimits.y1; + if (new.x >= pSprite->physLimits.x2) + new.x = pSprite->physLimits.x2 - 1; + if (new.y < pSprite->physLimits.y1) + new.y = pSprite->physLimits.y1; else - if (new.y >= sprite.physLimits.y2) - new.y = sprite.physLimits.y2 - 1; + if (new.y >= pSprite->physLimits.y2) + new.y = pSprite->physLimits.y2 - 1; - if (sprite.hotShape) /* more work if the shape is a mess */ - ConfineToShape(sprite.hotShape, &new.x, &new.y); + if (pSprite->hotShape) /* more work if the shape is a mess */ + ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y); - if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y)) + if((new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) { - XineramaSetCursorPosition (new.x, new.y, generateEvents); + XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents); if (!generateEvents) - SyntheticMotion(new.x, new.y); + SyntheticMotion(pDev, new.x, new.y); } /* Tell DDX what the limits are */ - XineramaConstrainCursor(); + XineramaConstrainCursor(pDev); } static Bool -XineramaSetWindowPntrs(WindowPtr pWin) +XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) { + SpritePtr pSprite = pDev->spriteInfo->sprite; + if(pWin == WindowTable[0]) { - memcpy(sprite.windows, WindowTable, + memcpy(pSprite->windows, WindowTable, PanoramiXNumScreens*sizeof(WindowPtr)); } else { PanoramiXRes *win; @@ -451,8 +478,8 @@ XineramaSetWindowPntrs(WindowPtr pWin) return FALSE; for(i = 0; i < PanoramiXNumScreens; i++) { - sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW); - if(!sprite.windows[i]) /* window is being unmapped */ + pSprite->windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW); + if(!pSprite->windows[i]) /* window is being unmapped */ return FALSE; } } @@ -461,16 +488,18 @@ XineramaSetWindowPntrs(WindowPtr pWin) static void XineramaCheckVirtualMotion( + DeviceIntPtr pDev, QdEventPtr qe, - WindowPtr pWin -){ + WindowPtr pWin) +{ + SpritePtr pSprite = pDev->spriteInfo->sprite; if (qe) { - sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */ - sprite.hot.x = qe->event->u.keyButtonPointer.rootX; - sprite.hot.y = qe->event->u.keyButtonPointer.rootY; - pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo : + pSprite->hot.pScreen = qe->pScreen; /* should always be Screen 0 */ + pSprite->hot.x = qe->event->u.keyButtonPointer.rootX; + pSprite->hot.y = qe->event->u.keyButtonPointer.rootY; + pWin = pDev->coreGrab.grab ? pDev->coreGrab.grab->confineTo : NullWindow; } if (pWin) @@ -478,13 +507,13 @@ XineramaCheckVirtualMotion( int x, y, off_x, off_y, i; BoxRec lims; - if(!XineramaSetWindowPntrs(pWin)) + if(!XineramaSetWindowPntrs(pDev, pWin)) return; i = PanoramiXNumScreens - 1; - REGION_COPY(sprite.screen, &sprite.Reg2, - &sprite.windows[i]->borderSize); + REGION_COPY(pSprite->screen, &pSprite->Reg2, + &pSprite->windows[i]->borderSize); off_x = panoramiXdataPtr[i].x; off_y = panoramiXdataPtr[i].y; @@ -493,97 +522,102 @@ XineramaCheckVirtualMotion( y = off_y - panoramiXdataPtr[i].y; if(x || y) - REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y); + REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, x, y); - REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, - &sprite.windows[i]->borderSize); + REGION_UNION(pSprite->screen, &pSprite->Reg2, &pSprite->Reg2, + &pSprite->windows[i]->borderSize); off_x = panoramiXdataPtr[i].x; off_y = panoramiXdataPtr[i].y; } - lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2); + lims = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg2); - if (sprite.hot.x < lims.x1) - sprite.hot.x = lims.x1; - else if (sprite.hot.x >= lims.x2) - sprite.hot.x = lims.x2 - 1; - if (sprite.hot.y < lims.y1) - sprite.hot.y = lims.y1; - else if (sprite.hot.y >= lims.y2) - sprite.hot.y = lims.y2 - 1; + if (pSprite->hot.x < lims.x1) + pSprite->hot.x = lims.x1; + else if (pSprite->hot.x >= lims.x2) + pSprite->hot.x = lims.x2 - 1; + if (pSprite->hot.y < lims.y1) + pSprite->hot.y = lims.y1; + else if (pSprite->hot.y >= lims.y2) + pSprite->hot.y = lims.y2 - 1; - if (REGION_NUM_RECTS(&sprite.Reg2) > 1) - ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y); + if (REGION_NUM_RECTS(&pSprite->Reg2) > 1) + ConfineToShape(pDev, &pSprite->Reg2, + &pSprite->hot.x, &pSprite->hot.y); if (qe) { - qe->pScreen = sprite.hot.pScreen; - qe->event->u.keyButtonPointer.rootX = sprite.hot.x; - qe->event->u.keyButtonPointer.rootY = sprite.hot.y; + qe->pScreen = pSprite->hot.pScreen; + qe->event->u.keyButtonPointer.rootX = pSprite->hot.x; + qe->event->u.keyButtonPointer.rootY = pSprite->hot.y; } } #ifdef XEVIE - xeviehot.x = sprite.hot.x; - xeviehot.y = sprite.hot.y; + xeviehot.x = pSprite->hot.x; + xeviehot.y = pSprite->hot.y; #endif } static Bool -XineramaCheckMotion(xEvent *xE) +XineramaCheckMotion(xEvent *xE, DeviceIntPtr pDev) { - WindowPtr prevSpriteWin = sprite.win; + WindowPtr prevSpriteWin; + SpritePtr pSprite = pDev->spriteInfo->sprite; + + prevSpriteWin = pSprite->win; if (xE && !syncEvents.playingEvents) { /* Motion events entering DIX get translated to Screen 0 coordinates. Replayed events have already been translated since they've entered DIX before */ - XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x - + XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x - panoramiXdataPtr[0].x; - XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y - + XE_KBPTR.rootY += panoramiXdataPtr[pSprite->screen->myNum].y - panoramiXdataPtr[0].y; - sprite.hot.x = XE_KBPTR.rootX; - sprite.hot.y = XE_KBPTR.rootY; - if (sprite.hot.x < sprite.physLimits.x1) - sprite.hot.x = sprite.physLimits.x1; - else if (sprite.hot.x >= sprite.physLimits.x2) - sprite.hot.x = sprite.physLimits.x2 - 1; - if (sprite.hot.y < sprite.physLimits.y1) - sprite.hot.y = sprite.physLimits.y1; - else if (sprite.hot.y >= sprite.physLimits.y2) - sprite.hot.y = sprite.physLimits.y2 - 1; - - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y); - - sprite.hotPhys = sprite.hot; - if ((sprite.hotPhys.x != XE_KBPTR.rootX) || - (sprite.hotPhys.y != XE_KBPTR.rootY)) + pSprite->hot.x = XE_KBPTR.rootX; + pSprite->hot.y = XE_KBPTR.rootY; + if (pSprite->hot.x < pSprite->physLimits.x1) + pSprite->hot.x = pSprite->physLimits.x1; + else if (pSprite->hot.x >= pSprite->physLimits.x2) + pSprite->hot.x = pSprite->physLimits.x2 - 1; + if (pSprite->hot.y < pSprite->physLimits.y1) + pSprite->hot.y = pSprite->physLimits.y1; + else if (pSprite->hot.y >= pSprite->physLimits.y2) + pSprite->hot.y = pSprite->physLimits.y2 - 1; + + if (pSprite->hotShape) + ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); + + pSprite->hotPhys = pSprite->hot; + if ((pSprite->hotPhys.x != XE_KBPTR.rootX) || + (pSprite->hotPhys.y != XE_KBPTR.rootY)) { XineramaSetCursorPosition( - sprite.hotPhys.x, sprite.hotPhys.y, FALSE); + pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); } - XE_KBPTR.rootX = sprite.hot.x; - XE_KBPTR.rootY = sprite.hot.y; + XE_KBPTR.rootX = pSprite->hot.x; + XE_KBPTR.rootY = pSprite->hot.y; } #ifdef XEVIE - xeviehot.x = sprite.hot.x; - xeviehot.y = sprite.hot.y; + xeviehot.x = pSprite->hot.x; + xeviehot.y = pSprite->hot.y; xeviewin = #endif - sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y); + pSprite->win = XYToWindow(pSprite->hot.x, pSprite->hot.y); - if (sprite.win != prevSpriteWin) + if (pSprite->win != prevSpriteWin) { if (prevSpriteWin != NullWindow) { if (!xE) UpdateCurrentTimeIf(); - DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal); - } - PostNewCursor(); + DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win, + NotifyNormal); + } + PostNewCursor(pDev); return FALSE; } return TRUE; @@ -591,25 +625,28 @@ XineramaCheckMotion(xEvent *xE) static void -XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents) +XineramaConfineCursorToWindow(DeviceIntPtr pDev, + WindowPtr pWin, + Bool generateEvents) { + SpritePtr pSprite = pDev->spriteInfo->sprite; if (syncEvents.playingEvents) { - XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin); - SyntheticMotion(sprite.hot.x, sprite.hot.y); + XineramaCheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin); + SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y); } else { int x, y, off_x, off_y, i; - if(!XineramaSetWindowPntrs(pWin)) + if(!XineramaSetWindowPntrs(pDev, pWin)) return; i = PanoramiXNumScreens - 1; - REGION_COPY(sprite.screen, &sprite.Reg1, - &sprite.windows[i]->borderSize); + REGION_COPY(pSprite->screen, &pSprite->Reg1, + &pSprite->windows[i]->borderSize); off_x = panoramiXdataPtr[i].x; off_y = panoramiXdataPtr[i].y; @@ -618,42 +655,45 @@ XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents) y = off_y - panoramiXdataPtr[i].y; if(x || y) - REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y); + REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y); - REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, - &sprite.windows[i]->borderSize); + REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1, + &pSprite->windows[i]->borderSize); off_x = panoramiXdataPtr[i].x; off_y = panoramiXdataPtr[i].y; } - sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1); + pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1); - if(REGION_NUM_RECTS(&sprite.Reg1) > 1) - sprite.hotShape = &sprite.Reg1; + if(REGION_NUM_RECTS(&pSprite->Reg1) > 1) + pSprite->hotShape = &pSprite->Reg1; else - sprite.hotShape = NullRegion; + pSprite->hotShape = NullRegion; - sprite.confined = FALSE; - sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; + pSprite->confined = FALSE; + pSprite->confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; - XineramaCheckPhysLimits(sprite.current, generateEvents); + XineramaCheckPhysLimits(pDev, pSprite->current, + generateEvents); } } static void -XineramaChangeToCursor(CursorPtr cursor) +XineramaChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) { - if (cursor != sprite.current) + SpritePtr pSprite = pDev->spriteInfo->sprite; + + if (cursor != pSprite->current) { - if ((sprite.current->bits->xhot != cursor->bits->xhot) || - (sprite.current->bits->yhot != cursor->bits->yhot)) - XineramaCheckPhysLimits(cursor, FALSE); - (*sprite.screen->DisplayCursor)(sprite.screen, cursor); - FreeCursor(sprite.current, (Cursor)0); - sprite.current = cursor; - sprite.current->refcnt++; + if ((pSprite->current->bits->xhot != cursor->bits->xhot) || + (pSprite->current->bits->yhot != cursor->bits->yhot)) + XineramaCheckPhysLimits(pDev, cursor, FALSE); + (*pSprite->screen->DisplayCursor)(pDev, pSprite->screen, cursor); + FreeCursor(pSprite->current, (Cursor)0); + pSprite->current = cursor; + pSprite->current->refcnt++; } } @@ -677,16 +717,17 @@ SetCriticalEvent(int event) } #ifdef SHAPE -static void -ConfineToShape(RegionPtr shape, int *px, int *py) +void +ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) { BoxRec box; int x = *px, y = *py; int incx = 1, incy = 1; + SpritePtr pSprite = pDev->spriteInfo->sprite; - if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box)) + if (POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box)) return; - box = *REGION_EXTENTS(sprite.hot.pScreen, shape); + box = *REGION_EXTENTS(pSprite->hot.pScreen, shape); /* this is rather crude */ do { x += incx; @@ -708,7 +749,7 @@ ConfineToShape(RegionPtr shape, int *px, int *py) else if (y < box.y1) return; /* should never get here! */ } - } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box)); + } while (!POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box)); *px = x; *py = y; } @@ -716,160 +757,170 @@ ConfineToShape(RegionPtr shape, int *px, int *py) static void CheckPhysLimits( + DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents, Bool confineToScreen, ScreenPtr pScreen) { HotSpot new; + SpritePtr pSprite = pDev->spriteInfo->sprite; if (!cursor) return; - new = sprite.hotPhys; + new = pSprite->hotPhys; if (pScreen) new.pScreen = pScreen; else pScreen = new.pScreen; - (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits, - &sprite.physLimits); - sprite.confined = confineToScreen; - (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits); - if (new.x < sprite.physLimits.x1) - new.x = sprite.physLimits.x1; + (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits, + &pSprite->physLimits); + pSprite->confined = confineToScreen; + (* pScreen->ConstrainCursor)(pDev, pScreen, &pSprite->physLimits); + if (new.x < pSprite->physLimits.x1) + new.x = pSprite->physLimits.x1; else - if (new.x >= sprite.physLimits.x2) - new.x = sprite.physLimits.x2 - 1; - if (new.y < sprite.physLimits.y1) - new.y = sprite.physLimits.y1; + if (new.x >= pSprite->physLimits.x2) + new.x = pSprite->physLimits.x2 - 1; + if (new.y < pSprite->physLimits.y1) + new.y = pSprite->physLimits.y1; else - if (new.y >= sprite.physLimits.y2) - new.y = sprite.physLimits.y2 - 1; + if (new.y >= pSprite->physLimits.y2) + new.y = pSprite->physLimits.y2 - 1; #ifdef SHAPE - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &new.x, &new.y); + if (pSprite->hotShape) + ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y); #endif - if ((pScreen != sprite.hotPhys.pScreen) || - (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y)) + if ((pScreen != pSprite->hotPhys.pScreen) || + (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) { - if (pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys = new; - (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents); - if (!generateEvents) - SyntheticMotion(new.x, new.y); + if (pScreen != pSprite->hotPhys.pScreen) + pSprite->hotPhys = new; + (*pScreen->SetCursorPosition) + (pDev, pScreen, new.x, new.y, generateEvents); + if (!generateEvents) + SyntheticMotion(pDev, new.x, new.y); } } static void CheckVirtualMotion( + DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin) { + SpritePtr pSprite = pDev->spriteInfo->sprite; + #ifdef PANORAMIX if(!noPanoramiXExtension) { - XineramaCheckVirtualMotion(qe, pWin); + XineramaCheckVirtualMotion(pDev, qe, pWin); return; } #endif if (qe) { - sprite.hot.pScreen = qe->pScreen; - sprite.hot.x = qe->event->u.keyButtonPointer.rootX; - sprite.hot.y = qe->event->u.keyButtonPointer.rootY; - pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo : - NullWindow; + pSprite->hot.pScreen = qe->pScreen; + pSprite->hot.x = qe->event->u.keyButtonPointer.rootX; + pSprite->hot.y = qe->event->u.keyButtonPointer.rootY; + pWin = pDev->coreGrab.grab ? pDev->coreGrab.grab->confineTo : NullWindow; } if (pWin) { BoxRec lims; - if (sprite.hot.pScreen != pWin->drawable.pScreen) + if (pSprite->hot.pScreen != pWin->drawable.pScreen) { - sprite.hot.pScreen = pWin->drawable.pScreen; - sprite.hot.x = sprite.hot.y = 0; + pSprite->hot.pScreen = pWin->drawable.pScreen; + pSprite->hot.x = pSprite->hot.y = 0; } lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize); - if (sprite.hot.x < lims.x1) - sprite.hot.x = lims.x1; - else if (sprite.hot.x >= lims.x2) - sprite.hot.x = lims.x2 - 1; - if (sprite.hot.y < lims.y1) - sprite.hot.y = lims.y1; - else if (sprite.hot.y >= lims.y2) - sprite.hot.y = lims.y2 - 1; + if (pSprite->hot.x < lims.x1) + pSprite->hot.x = lims.x1; + else if (pSprite->hot.x >= lims.x2) + pSprite->hot.x = lims.x2 - 1; + if (pSprite->hot.y < lims.y1) + pSprite->hot.y = lims.y1; + else if (pSprite->hot.y >= lims.y2) + pSprite->hot.y = lims.y2 - 1; #ifdef SHAPE if (wBoundingShape(pWin)) - ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y); + ConfineToShape(pDev, &pWin->borderSize, + &pSprite->hot.x, &pSprite->hot.y); #endif if (qe) { - qe->pScreen = sprite.hot.pScreen; - qe->event->u.keyButtonPointer.rootX = sprite.hot.x; - qe->event->u.keyButtonPointer.rootY = sprite.hot.y; + qe->pScreen = pSprite->hot.pScreen; + qe->event->u.keyButtonPointer.rootX = pSprite->hot.x; + qe->event->u.keyButtonPointer.rootY = pSprite->hot.y; } } #ifdef XEVIE - xeviehot.x = sprite.hot.x; - xeviehot.y = sprite.hot.y; + xeviehot.x = pSprite->hot.x; + xeviehot.y = pSprite->hot.y; #endif - ROOT = WindowTable[sprite.hot.pScreen->myNum]; + ROOT = WindowTable[pSprite->hot.pScreen->myNum]; } static void -ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen) +ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bool confineToScreen) { ScreenPtr pScreen = pWin->drawable.pScreen; + SpritePtr pSprite = pDev->spriteInfo->sprite; #ifdef PANORAMIX if(!noPanoramiXExtension) { - XineramaConfineCursorToWindow(pWin, generateEvents); + XineramaConfineCursorToWindow(pDev, pWin, generateEvents); return; } #endif if (syncEvents.playingEvents) { - CheckVirtualMotion((QdEventPtr)NULL, pWin); - SyntheticMotion(sprite.hot.x, sprite.hot.y); + CheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin); + SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y); } else { - sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize); + pSprite->hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize); #ifdef SHAPE - sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize + pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize : NullRegion; #endif - CheckPhysLimits(sprite.current, generateEvents, confineToScreen, - pScreen); + CheckPhysLimits(pDev, pSprite->current, generateEvents, + confineToScreen, pScreen); } } _X_EXPORT Bool -PointerConfinedToScreen() +PointerConfinedToScreen(DeviceIntPtr pDev) { - return sprite.confined; + return pDev->spriteInfo->sprite->confined; } static void -ChangeToCursor(CursorPtr cursor) +ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) { + SpritePtr pSprite = pDev->spriteInfo->sprite; + #ifdef PANORAMIX if(!noPanoramiXExtension) { - XineramaChangeToCursor(cursor); + XineramaChangeToCursor(pDev, cursor); return; } #endif - if (cursor != sprite.current) + if (cursor != pSprite->current) { - if ((sprite.current->bits->xhot != cursor->bits->xhot) || - (sprite.current->bits->yhot != cursor->bits->yhot)) - CheckPhysLimits(cursor, FALSE, sprite.confined, + if ((pSprite->current->bits->xhot != cursor->bits->xhot) || + (pSprite->current->bits->yhot != cursor->bits->yhot)) + CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined, (ScreenPtr)NULL); - (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen, - cursor); - FreeCursor(sprite.current, (Cursor)0); - sprite.current = cursor; - sprite.current->refcnt++; + (*pSprite->hotPhys.pScreen->DisplayCursor) (pDev, + pSprite->hotPhys.pScreen, + cursor); + FreeCursor(pSprite->current, (Cursor)0); + pSprite->current = cursor; + pSprite->current->refcnt++; } } @@ -883,10 +934,12 @@ IsParent(WindowPtr a, WindowPtr b) } static void -PostNewCursor(void) +PostNewCursor(DeviceIntPtr pDev) { WindowPtr win; - GrabPtr grab = inputInfo.pointer->grab; + GrabPtr grab = pDev->coreGrab.grab; + SpritePtr pSprite = pDev->spriteInfo->sprite; + CursorPtr pCursor; if (syncEvents.playingEvents) return; @@ -894,22 +947,30 @@ PostNewCursor(void) { if (grab->cursor) { - ChangeToCursor(grab->cursor); + ChangeToCursor(pDev, grab->cursor); return; } - if (IsParent(grab->window, sprite.win)) - win = sprite.win; + if (IsParent(grab->window, pSprite->win)) + win = pSprite->win; else win = grab->window; } else - win = sprite.win; + win = pSprite->win; for (; win; win = win->parent) - if (win->optional && win->optional->cursor != NullCursor) - { - ChangeToCursor(win->optional->cursor); - return; + { + if (win->optional) + { + pCursor = WindowGetDeviceCursor(win, pDev); + if (!pCursor && win->optional->cursor != NullCursor) + pCursor = win->optional->cursor; + if (pCursor) + { + ChangeToCursor(pDev, pCursor); + return; + } } + } } _X_EXPORT WindowPtr @@ -919,30 +980,31 @@ GetCurrentRootWindow() } _X_EXPORT WindowPtr -GetSpriteWindow() +GetSpriteWindow(DeviceIntPtr pDev) { - return sprite.win; + return pDev->spriteInfo->sprite->win; } _X_EXPORT CursorPtr -GetSpriteCursor() +GetSpriteCursor(DeviceIntPtr pDev) { - return sprite.current; + return pDev->spriteInfo->sprite->current; } _X_EXPORT void -GetSpritePosition(int *px, int *py) +GetSpritePosition(DeviceIntPtr pDev, int *px, int *py) { - *px = sprite.hotPhys.x; - *py = sprite.hotPhys.y; + SpritePtr pSprite = pDev->spriteInfo->sprite; + *px = pSprite->hotPhys.x; + *py = pSprite->hotPhys.y; } #ifdef PANORAMIX _X_EXPORT int -XineramaGetCursorScreen() +XineramaGetCursorScreen(DeviceIntPtr pDev) { if(!noPanoramiXExtension) { - return sprite.screen->myNum; + return pDev->spriteInfo->sprite->screen->myNum; } else { return 0; } @@ -987,6 +1049,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) QdEventPtr tail = *syncEvents.pendtail; QdEventPtr qe; xEvent *qxE; + SpritePtr pSprite = device->spriteInfo->sprite; NoticeTime(xE); @@ -1011,7 +1074,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) */ if (xE->u.u.type == MotionNotify) XE_KBPTR.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; + WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; eventinfo.events = xE; eventinfo.count = count; CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); @@ -1020,21 +1083,21 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) { #ifdef PANORAMIX if(!noPanoramiXExtension) { - XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x - + XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x - panoramiXdataPtr[0].x; - XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y - + XE_KBPTR.rootY += panoramiXdataPtr[pSprite->screen->myNum].y - panoramiXdataPtr[0].y; } #endif - sprite.hotPhys.x = XE_KBPTR.rootX; - sprite.hotPhys.y = XE_KBPTR.rootY; + pSprite->hotPhys.x = XE_KBPTR.rootX; + pSprite->hotPhys.y = XE_KBPTR.rootY; /* do motion compression */ if (tail && (tail->event->u.u.type == MotionNotify) && - (tail->pScreen == sprite.hotPhys.pScreen)) + (tail->pScreen == pSprite->hotPhys.pScreen)) { - tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x; - tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y; + tail->event->u.keyButtonPointer.rootX = pSprite->hotPhys.x; + tail->event->u.keyButtonPointer.rootY = pSprite->hotPhys.y; tail->event->u.keyButtonPointer.time = XE_KBPTR.time; tail->months = currentTime.months; return; @@ -1045,7 +1108,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count) return; qe->next = (QdEventPtr)NULL; qe->device = device; - qe->pScreen = sprite.hotPhys.pScreen; + qe->pScreen = pSprite->hotPhys.pScreen; qe->months = currentTime.months; qe->event = (xEvent *)(qe + 1); qe->evcount = count; @@ -1061,17 +1124,19 @@ PlayReleasedEvents(void) { QdEventPtr *prev, qe; DeviceIntPtr dev; + DeviceIntPtr pDev; prev = &syncEvents.pending; while ( (qe = *prev) ) { - if (!qe->device->sync.frozen) + if (!qe->device->coreGrab.sync.frozen) { *prev = qe->next; + pDev = qe->device; if (*syncEvents.pendtail == *prev) syncEvents.pendtail = prev; if (qe->event->u.u.type == MotionNotify) - CheckVirtualMotion(qe, NullWindow); + CheckVirtualMotion(pDev, qe, NullWindow); syncEvents.time.months = qe->months; syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time; #ifdef PANORAMIX @@ -1081,16 +1146,16 @@ PlayReleasedEvents(void) if(!noPanoramiXExtension) { qe->event->u.keyButtonPointer.rootX += panoramiXdataPtr[0].x - - panoramiXdataPtr[sprite.screen->myNum].x; + panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x; qe->event->u.keyButtonPointer.rootY += panoramiXdataPtr[0].y - - panoramiXdataPtr[sprite.screen->myNum].y; + panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y; } #endif (*qe->device->public.processInputProc)(qe->event, qe->device, qe->evcount); xfree(qe); - for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next) + for (dev = inputInfo.devices; dev && dev->coreGrab.sync.frozen; dev = dev->next) ; if (!dev) break; @@ -1106,7 +1171,7 @@ PlayReleasedEvents(void) static void FreezeThaw(DeviceIntPtr dev, Bool frozen) { - dev->sync.frozen = frozen; + dev->coreGrab.sync.frozen = frozen; if (frozen) dev->public.processInputProc = dev->public.enqueueInputProc; else @@ -1125,14 +1190,15 @@ ComputeFreezes() DeviceIntPtr dev; for (dev = inputInfo.devices; dev; dev = dev->next) - FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN)); + FreezeThaw(dev, dev->coreGrab.sync.other || + (dev->coreGrab.sync.state >= FROZEN)); if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending)) return; syncEvents.playingEvents = TRUE; if (replayDev) { - xE = replayDev->sync.event; - count = replayDev->sync.evcount; + xE = replayDev->coreGrab.sync.event; + count = replayDev->coreGrab.sync.evcount; syncEvents.replayDev = (DeviceIntPtr)NULL; w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY); @@ -1159,24 +1225,34 @@ ComputeFreezes() playmore: for (dev = inputInfo.devices; dev; dev = dev->next) { - if (!dev->sync.frozen) + if (!dev->coreGrab.sync.frozen) { PlayReleasedEvents(); break; } } syncEvents.playingEvents = FALSE; - /* the following may have been skipped during replay, so do it now */ - if ((grab = inputInfo.pointer->grab) && grab->confineTo) + for (dev = inputInfo.devices; dev; dev = dev->next) { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); + if (DevHasCursor(dev)) + { + /* the following may have been skipped during replay, + so do it now */ + if ((grab = dev->coreGrab.grab) && grab->confineTo) + { + if (grab->confineTo->drawable.pScreen != + dev->spriteInfo->sprite->hotPhys.pScreen) + dev->spriteInfo->sprite->hotPhys.x = + dev->spriteInfo->sprite->hotPhys.y = 0; + ConfineCursorToWindow(dev, grab->confineTo, TRUE, TRUE); + } + else + ConfineCursorToWindow(dev, + WindowTable[dev->spriteInfo->sprite->hotPhys.pScreen->myNum], + TRUE, FALSE); + PostNewCursor(dev); + } } - else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], - TRUE, FALSE); - PostNewCursor(); } #ifdef RANDR @@ -1184,47 +1260,56 @@ void ScreenRestructured (ScreenPtr pScreen) { GrabPtr grab; + DeviceIntPtr pDev; - if ((grab = inputInfo.pointer->grab) && grab->confineTo) + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); + + /* GrabDevice doesn't have a confineTo field, so we don't need to + * worry about it. */ + if ((grab = pDev->coreGrab.grab) && grab->confineTo) + { + if (grab->confineTo->drawable.pScreen + != pDev->spriteInfo->sprite->hotPhys.pScreen) + pDev->spriteInfo->sprite->hotPhys.x = pDev->spriteInfo->sprite->hotPhys.y = 0; + ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE); + } + else + ConfineCursorToWindow(pDev, + WindowTable[pDev->spriteInfo->sprite->hotPhys.pScreen->myNum], + TRUE, FALSE); } - else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], - TRUE, FALSE); } #endif void CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) { - GrabPtr grab = thisDev->grab; + GrabPtr grab = thisDev->coreGrab.grab; DeviceIntPtr dev; if (thisMode == GrabModeSync) - thisDev->sync.state = FROZEN_NO_EVENT; + thisDev->coreGrab.sync.state = FROZEN_NO_EVENT; else { /* free both if same client owns both */ - thisDev->sync.state = THAWED; - if (thisDev->sync.other && - (CLIENT_BITS(thisDev->sync.other->resource) == + thisDev->coreGrab.sync.state = THAWED; + if (thisDev->coreGrab.sync.other && + (CLIENT_BITS(thisDev->coreGrab.sync.other->resource) == CLIENT_BITS(grab->resource))) - thisDev->sync.other = NullGrab; + thisDev->coreGrab.sync.other = NullGrab; } for (dev = inputInfo.devices; dev; dev = dev->next) { if (dev != thisDev) { if (otherMode == GrabModeSync) - dev->sync.other = grab; + dev->coreGrab.sync.other = grab; else { /* free both if same client owns both */ - if (dev->sync.other && - (CLIENT_BITS(dev->sync.other->resource) == + if (dev->coreGrab.sync.other && + (CLIENT_BITS(dev->coreGrab.sync.other->resource) == CLIENT_BITS(grab->resource))) - dev->sync.other = NullGrab; + dev->coreGrab.sync.other = NullGrab; } } } @@ -1235,49 +1320,53 @@ void ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, TimeStamp time, Bool autoGrab) { - WindowPtr oldWin = (mouse->grab) ? mouse->grab->window - : sprite.win; + WindowPtr oldWin = (mouse->coreGrab.grab) ? + mouse->coreGrab.grab->window + : mouse->spriteInfo->sprite->win; if (grab->confineTo) { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, FALSE, TRUE); + if (grab->confineTo->drawable.pScreen + != mouse->spriteInfo->sprite->hotPhys.pScreen) + mouse->spriteInfo->sprite->hotPhys.x = + mouse->spriteInfo->sprite->hotPhys.y = 0; + ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE); } - DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab); + DoEnterLeaveEvents(mouse, oldWin, grab->window, NotifyGrab); mouse->valuator->motionHintWindow = NullWindow; if (syncEvents.playingEvents) - mouse->grabTime = syncEvents.time; + mouse->coreGrab.grabTime = syncEvents.time; else - mouse->grabTime = time; + mouse->coreGrab.grabTime = time; if (grab->cursor) grab->cursor->refcnt++; - mouse->activeGrab = *grab; - mouse->grab = &mouse->activeGrab; - mouse->fromPassiveGrab = autoGrab; - PostNewCursor(); + mouse->coreGrab.activeGrab = *grab; + mouse->coreGrab.grab = &mouse->coreGrab.activeGrab; + mouse->coreGrab.fromPassiveGrab = autoGrab; + PostNewCursor(mouse); CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); } void DeactivatePointerGrab(DeviceIntPtr mouse) { - GrabPtr grab = mouse->grab; + GrabPtr grab = mouse->coreGrab.grab; DeviceIntPtr dev; mouse->valuator->motionHintWindow = NullWindow; - mouse->grab = NullGrab; - mouse->sync.state = NOT_GRABBED; - mouse->fromPassiveGrab = FALSE; + mouse->coreGrab.grab = NullGrab; + mouse->coreGrab.sync.state = NOT_GRABBED; + mouse->coreGrab.fromPassiveGrab = FALSE; for (dev = inputInfo.devices; dev; dev = dev->next) { - if (dev->sync.other == grab) - dev->sync.other = NullGrab; + if (dev->coreGrab.sync.other == grab) + dev->coreGrab.sync.other = NullGrab; } - DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab); + DoEnterLeaveEvents(mouse, grab->window, + mouse->spriteInfo->sprite->win, NotifyUngrab); if (grab->confineTo) - ConfineCursorToWindow(ROOT, FALSE, FALSE); - PostNewCursor(); + ConfineCursorToWindow(mouse, ROOT, FALSE, FALSE); + PostNewCursor(mouse); if (grab->cursor) FreeCursor(grab->cursor, (Cursor)0); ComputeFreezes(); @@ -1288,82 +1377,94 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass { WindowPtr oldWin; - if (keybd->grab) - oldWin = keybd->grab->window; + if (keybd->coreGrab.grab) + oldWin = keybd->coreGrab.grab->window; else if (keybd->focus) oldWin = keybd->focus->win; else - oldWin = sprite.win; + oldWin = keybd->spriteInfo->sprite->win; if (oldWin == FollowKeyboardWin) oldWin = inputInfo.keyboard->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); if (syncEvents.playingEvents) - keybd->grabTime = syncEvents.time; + keybd->coreGrab.grabTime = syncEvents.time; else - keybd->grabTime = time; - keybd->activeGrab = *grab; - keybd->grab = &keybd->activeGrab; - keybd->fromPassiveGrab = passive; + keybd->coreGrab.grabTime = time; + keybd->coreGrab.activeGrab = *grab; + keybd->coreGrab.grab = &keybd->coreGrab.activeGrab; + keybd->coreGrab.fromPassiveGrab = passive; CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode); } void DeactivateKeyboardGrab(DeviceIntPtr keybd) { - GrabPtr grab = keybd->grab; + GrabPtr grab = keybd->coreGrab.grab; DeviceIntPtr dev; WindowPtr focusWin = keybd->focus ? keybd->focus->win - : sprite.win; + : keybd->spriteInfo->sprite->win; if (focusWin == FollowKeyboardWin) focusWin = inputInfo.keyboard->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; - keybd->grab = NullGrab; - keybd->sync.state = NOT_GRABBED; - keybd->fromPassiveGrab = FALSE; + keybd->coreGrab.grab = NullGrab; + keybd->coreGrab.sync.state = NOT_GRABBED; + keybd->coreGrab.fromPassiveGrab = FALSE; for (dev = inputInfo.devices; dev; dev = dev->next) { - if (dev->sync.other == grab) - dev->sync.other = NullGrab; + if (dev->coreGrab.sync.other == grab) + dev->coreGrab.sync.other = NullGrab; } DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab); ComputeFreezes(); } +/* + * Core flag decides whether to work on the coreGrab or deviceGrab sync + * fields. + */ void -AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) +AllowSome(ClientPtr client, + TimeStamp time, + DeviceIntPtr thisDev, + int newState, + Bool core) { Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced; TimeStamp grabTime; DeviceIntPtr dev; + GrabInfoPtr devgrabinfo, + grabinfo = (core) ? &thisDev->coreGrab : &thisDev->deviceGrab; - thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client); + thisGrabbed = grabinfo->grab && SameClient(grabinfo->grab, client); thisSynced = FALSE; otherGrabbed = FALSE; othersFrozen = TRUE; - grabTime = thisDev->grabTime; + grabTime = grabinfo->grabTime; for (dev = inputInfo.devices; dev; dev = dev->next) { + devgrabinfo = (core) ? &dev->coreGrab : &dev->deviceGrab; + if (dev == thisDev) continue; - if (dev->grab && SameClient(dev->grab, client)) + if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) { if (!(thisGrabbed || otherGrabbed) || - (CompareTimeStamps(dev->grabTime, grabTime) == LATER)) - grabTime = dev->grabTime; + (CompareTimeStamps(devgrabinfo->grabTime, grabTime) == LATER)) + grabTime = devgrabinfo->grabTime; otherGrabbed = TRUE; - if (thisDev->sync.other == dev->grab) + if (grabinfo->sync.other == devgrabinfo->grab) thisSynced = TRUE; - if (dev->sync.state < FROZEN) + if (devgrabinfo->sync.state < FROZEN) othersFrozen = FALSE; } - else if (!dev->sync.other || !SameClient(dev->sync.other, client)) + else if (!devgrabinfo->sync.other || !SameClient(devgrabinfo->sync.other, client)) othersFrozen = FALSE; } - if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced)) + if (!((thisGrabbed && grabinfo->sync.state >= FROZEN) || thisSynced)) return; if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, grabTime) == EARLIER)) @@ -1372,17 +1473,17 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) { case THAWED: /* Async */ if (thisGrabbed) - thisDev->sync.state = THAWED; + grabinfo->sync.state = THAWED; if (thisSynced) - thisDev->sync.other = NullGrab; + grabinfo->sync.other = NullGrab; ComputeFreezes(); break; case FREEZE_NEXT_EVENT: /* Sync */ if (thisGrabbed) { - thisDev->sync.state = FREEZE_NEXT_EVENT; + grabinfo->sync.state = FREEZE_NEXT_EVENT; if (thisSynced) - thisDev->sync.other = NullGrab; + grabinfo->sync.other = NullGrab; ComputeFreezes(); } break; @@ -1391,10 +1492,13 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) { for (dev = inputInfo.devices; dev; dev = dev->next) { - if (dev->grab && SameClient(dev->grab, client)) - dev->sync.state = THAWED; - if (dev->sync.other && SameClient(dev->sync.other, client)) - dev->sync.other = NullGrab; + devgrabinfo = (core) ? &dev->coreGrab : &dev->deviceGrab; + if (devgrabinfo->grab + && SameClient(devgrabinfo->grab, client)) + devgrabinfo->sync.state = THAWED; + if (devgrabinfo->sync.other && + SameClient(devgrabinfo->sync.other, client)) + devgrabinfo->sync.other = NullGrab; } ComputeFreezes(); } @@ -1404,22 +1508,25 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) { for (dev = inputInfo.devices; dev; dev = dev->next) { - if (dev->grab && SameClient(dev->grab, client)) - dev->sync.state = FREEZE_BOTH_NEXT_EVENT; - if (dev->sync.other && SameClient(dev->sync.other, client)) - dev->sync.other = NullGrab; + devgrabinfo = (core) ? &dev->coreGrab : &dev->deviceGrab; + if (devgrabinfo->grab + && SameClient(devgrabinfo->grab, client)) + devgrabinfo->sync.state = FREEZE_BOTH_NEXT_EVENT; + if (devgrabinfo->sync.other + && SameClient(devgrabinfo->sync.other, client)) + devgrabinfo->sync.other = NullGrab; } ComputeFreezes(); } break; case NOT_GRABBED: /* Replay */ - if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT) + if (thisGrabbed && grabinfo->sync.state == FROZEN_WITH_EVENT) { if (thisSynced) - thisDev->sync.other = NullGrab; + grabinfo->sync.other = NullGrab; syncEvents.replayDev = thisDev; - syncEvents.replayWin = thisDev->grab->window; - (*thisDev->DeactivateGrab)(thisDev); + syncEvents.replayWin = grabinfo->grab->window; + (*grabinfo->DeactivateGrab)(thisDev); syncEvents.replayDev = (DeviceIntPtr)NULL; } break; @@ -1430,10 +1537,13 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState) { if (dev == thisDev) continue; - if (dev->grab && SameClient(dev->grab, client)) - dev->sync.state = THAWED; - if (dev->sync.other && SameClient(dev->sync.other, client)) - dev->sync.other = NullGrab; + devgrabinfo = (core) ? &dev->coreGrab : &dev->deviceGrab; + if (devgrabinfo->grab + && SameClient(devgrabinfo->grab, client)) + devgrabinfo->sync.state = THAWED; + if (devgrabinfo->sync.other + && SameClient(devgrabinfo->sync.other, client)) + devgrabinfo->sync.other = NullGrab; } ComputeFreezes(); } @@ -1445,8 +1555,8 @@ int ProcAllowEvents(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); @@ -1454,28 +1564,28 @@ ProcAllowEvents(ClientPtr client) switch (stuff->mode) { case ReplayPointer: - AllowSome(client, time, mouse, NOT_GRABBED); + AllowSome(client, time, mouse, NOT_GRABBED, True); break; case SyncPointer: - AllowSome(client, time, mouse, FREEZE_NEXT_EVENT); + AllowSome(client, time, mouse, FREEZE_NEXT_EVENT, True); break; case AsyncPointer: - AllowSome(client, time, mouse, THAWED); + AllowSome(client, time, mouse, THAWED, True); break; case ReplayKeyboard: - AllowSome(client, time, keybd, NOT_GRABBED); + AllowSome(client, time, keybd, NOT_GRABBED, True); break; case SyncKeyboard: - AllowSome(client, time, keybd, FREEZE_NEXT_EVENT); + AllowSome(client, time, keybd, FREEZE_NEXT_EVENT, True); break; case AsyncKeyboard: - AllowSome(client, time, keybd, THAWED); + AllowSome(client, time, keybd, THAWED, True); break; case SyncBoth: - AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT); + AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT, True); break; case AsyncBoth: - AllowSome(client, time, keybd, THAWED_BOTH); + AllowSome(client, time, keybd, THAWED_BOTH, True); break; default: client->errorValue = stuff->mode; @@ -1497,9 +1607,15 @@ ReleaseActiveGrabs(ClientPtr client) done = TRUE; for (dev = inputInfo.devices; dev; dev = dev->next) { - if (dev->grab && SameClient(dev->grab, client)) + if (dev->coreGrab.grab && SameClient(dev->coreGrab.grab, client)) { - (*dev->DeactivateGrab)(dev); + (*dev->coreGrab.DeactivateGrab)(dev); + done = FALSE; + } + + if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) + { + (*dev->deviceGrab.DeactivateGrab)(dev); done = FALSE; } } @@ -1589,8 +1705,8 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask, } int -DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, - Mask filter, GrabPtr grab, int mskidx) +DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent + *pEvents, int count, Mask filter, GrabPtr grab, int mskidx) { int deliveries = 0, nondeliveries = 0; int attempt; @@ -1599,6 +1715,11 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, Mask deliveryMask = 0; /* If a grab occurs due to a button press, then this mask is the mask of the grab. */ int type = pEvents->u.u.type; + + /* if a is denied, we return 0. This could cause the caller to + * traverse the parent. May be bad! (whot) */ + if (!ACDeviceAllowed(pWin, pDev)) + return 0; /* CantBeFiltered means only window owner gets the event */ if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE)) @@ -1607,6 +1728,11 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, if (filter != CantBeFiltered && !((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) return 0; + + if (!(type & EXTENSION_EVENT_BASE) && + IsInterferingGrab(wClient(pWin), pDev, pEvents)) + return 0; + if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count, pWin->eventMask, filter, grab)) ) { @@ -1635,6 +1761,11 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, other = (InputClients *)wOtherClients(pWin); for (; other; other = other->next) { + /* core event? check for grab interference */ + if (!(type & EXTENSION_EVENT_BASE) && + IsInterferingGrab(rClient(other), pDev, pEvents)) + continue; + if ( (attempt = TryClientEvents(rClient(other), pEvents, count, other->mask[mskidx], filter, grab)) ) { @@ -1652,7 +1783,7 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, { GrabRec tempGrab; - tempGrab.device = inputInfo.pointer; + tempGrab.device = pDev; tempGrab.resource = client->clientAsMask; tempGrab.window = pWin; tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; @@ -1661,11 +1792,12 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count, tempGrab.pointerMode = GrabModeAsync; tempGrab.confineTo = NullWindow; tempGrab.cursor = NullCursor; - (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab, + tempGrab.coreGrab = True; + (*inputInfo.pointer->coreGrab.ActivateGrab)(pDev, &tempGrab, currentTime, TRUE); } else if ((type == MotionNotify) && deliveries) - inputInfo.pointer->valuator->motionHintWindow = pWin; + pDev->valuator->motionHintWindow = pWin; #ifdef XINPUT else { @@ -1746,11 +1878,14 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, static void FixUpEventFromWindow( + DeviceIntPtr pDev, xEvent *xE, WindowPtr pWin, Window child, Bool calcChild) { + SpritePtr pSprite = pDev->spriteInfo->sprite; + if (calcChild) { WindowPtr w=spriteTrace[spriteTraceGood-1]; @@ -1780,7 +1915,7 @@ FixUpEventFromWindow( } XE_KBPTR.root = ROOT->drawable.id; XE_KBPTR.event = pWin->drawable.id; - if (sprite.hot.pScreen == pWin->drawable.pScreen) + if (pSprite->hot.pScreen == pWin->drawable.pScreen) { XE_KBPTR.sameScreen = xTrue; XE_KBPTR.child = child; @@ -1819,8 +1954,8 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab, { if (inputMasks && (inputMasks->inputEvents[mskidx] & filter)) { - FixUpEventFromWindow(xE, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(pWin, xE, count, filter, + FixUpEventFromWindow(dev, xE, pWin, child, FALSE); + deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter, grab, mskidx); if (deliveries > 0) return deliveries; @@ -1844,8 +1979,8 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab, { if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter) { - FixUpEventFromWindow(xE, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(pWin, xE, count, filter, + FixUpEventFromWindow(dev, xE, pWin, child, FALSE); + deliveries = DeliverEventsToWindow(dev, pWin, xE, count, filter, grab, 0); if (deliveries > 0) return deliveries; @@ -1880,20 +2015,20 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count, if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify)) xE->u.destroyNotify.event = pWin->drawable.id; if (filter != StructureAndSubMask) - return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0); - deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask, + return DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, filter, NullGrab, 0); + deliveries = DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, StructureNotifyMask, NullGrab, 0); if (pWin->parent) { xE->u.destroyNotify.event = pWin->parent->drawable.id; - deliveries += DeliverEventsToWindow(pWin->parent, xE, count, + deliveries += DeliverEventsToWindow(inputInfo.pointer, pWin->parent, xE, count, SubstructureNotifyMask, NullGrab, 0); if (xE->u.u.type == ReparentNotify) { xE->u.destroyNotify.event = otherParent->drawable.id; - deliveries += DeliverEventsToWindow(otherParent, xE, count, - SubstructureNotifyMask, + deliveries += DeliverEventsToWindow(inputInfo.pointer, + otherParent, xE, count, SubstructureNotifyMask, NullGrab, 0); } } @@ -1905,17 +2040,19 @@ static Bool PointInBorderSize(WindowPtr pWin, int x, int y) { BoxRec box; + SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite; if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box)) return TRUE; #ifdef PANORAMIX - if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) { + if(!noPanoramiXExtension && + XineramaSetWindowPntrs(inputInfo.pointer, pWin)) { int i; for(i = 1; i < PanoramiXNumScreens; i++) { - if(POINT_IN_REGION(sprite.screen, - &sprite.windows[i]->borderSize, + if(POINT_IN_REGION(pSprite->screen, + &pSprite->windows[i]->borderSize, x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, &box)) @@ -1974,73 +2111,79 @@ XYToWindow(int x, int y) return spriteTrace[spriteTraceGood-1]; } -static Bool -CheckMotion(xEvent *xE) +Bool +CheckMotion(xEvent *xE, DeviceIntPtr pDev) { - WindowPtr prevSpriteWin = sprite.win; + WindowPtr prevSpriteWin; + SpritePtr pSprite = pDev->spriteInfo->sprite; + + prevSpriteWin = pSprite->win; #ifdef PANORAMIX if(!noPanoramiXExtension) - return XineramaCheckMotion(xE); + return XineramaCheckMotion(xE, pDev); #endif if (xE && !syncEvents.playingEvents) { - if (sprite.hot.pScreen != sprite.hotPhys.pScreen) + if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) { - sprite.hot.pScreen = sprite.hotPhys.pScreen; - ROOT = WindowTable[sprite.hot.pScreen->myNum]; + pSprite->hot.pScreen = pSprite->hotPhys.pScreen; + ROOT = WindowTable[pSprite->hot.pScreen->myNum]; } - sprite.hot.x = XE_KBPTR.rootX; - sprite.hot.y = XE_KBPTR.rootY; - if (sprite.hot.x < sprite.physLimits.x1) - sprite.hot.x = sprite.physLimits.x1; - else if (sprite.hot.x >= sprite.physLimits.x2) - sprite.hot.x = sprite.physLimits.x2 - 1; - if (sprite.hot.y < sprite.physLimits.y1) - sprite.hot.y = sprite.physLimits.y1; - else if (sprite.hot.y >= sprite.physLimits.y2) - sprite.hot.y = sprite.physLimits.y2 - 1; + pSprite->hot.x = XE_KBPTR.rootX; + pSprite->hot.y = XE_KBPTR.rootY; + if (pSprite->hot.x < pSprite->physLimits.x1) + pSprite->hot.x = pSprite->physLimits.x1; + else if (pSprite->hot.x >= pSprite->physLimits.x2) + pSprite->hot.x = pSprite->physLimits.x2 - 1; + if (pSprite->hot.y < pSprite->physLimits.y1) + pSprite->hot.y = pSprite->physLimits.y1; + else if (pSprite->hot.y >= pSprite->physLimits.y2) + pSprite->hot.y = pSprite->physLimits.y2 - 1; #ifdef SHAPE - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y); + if (pSprite->hotShape) + ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); #endif #ifdef XEVIE - xeviehot.x = sprite.hot.x; - xeviehot.y = sprite.hot.y; + xeviehot.x = pSprite->hot.x; + xeviehot.y = pSprite->hot.y; #endif - sprite.hotPhys = sprite.hot; - if ((sprite.hotPhys.x != XE_KBPTR.rootX) || - (sprite.hotPhys.y != XE_KBPTR.rootY)) + pSprite->hotPhys = pSprite->hot; + + if ((pSprite->hotPhys.x != XE_KBPTR.rootX) || + (pSprite->hotPhys.y != XE_KBPTR.rootY)) { - (*sprite.hotPhys.pScreen->SetCursorPosition)( - sprite.hotPhys.pScreen, - sprite.hotPhys.x, sprite.hotPhys.y, FALSE); + (*pSprite->hotPhys.pScreen->SetCursorPosition)( + pDev, pSprite->hotPhys.pScreen, + pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); } - XE_KBPTR.rootX = sprite.hot.x; - XE_KBPTR.rootY = sprite.hot.y; + + XE_KBPTR.rootX = pSprite->hot.x; + XE_KBPTR.rootY = pSprite->hot.y; } #ifdef XEVIE xeviewin = #endif - sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y); + pSprite->win = XYToWindow(pSprite->hot.x, pSprite->hot.y); #ifdef notyet - if (!(sprite.win->deliverableEvents & - Motion_Filter(inputInfo.pointer->button)) + if (!(pSprite->win->deliverableEvents & + Motion_Filter(pDev->button)) !syncEvents.playingEvents) { /* XXX Do PointerNonInterestBox here */ } #endif - if (sprite.win != prevSpriteWin) + if (pSprite->win != prevSpriteWin) { if (prevSpriteWin != NullWindow) { if (!xE) UpdateCurrentTimeIf(); - DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal); - } - PostNewCursor(); + DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win, + NotifyNormal); + } + PostNewCursor(pDev); return FALSE; } return TRUE; @@ -2049,7 +2192,13 @@ CheckMotion(xEvent *xE) _X_EXPORT void WindowsRestructured() { - (void) CheckMotion((xEvent *)NULL); + DeviceIntPtr pDev = inputInfo.devices; + while(pDev) + { + if (DevHasCursor(pDev)) + CheckMotion((xEvent *)NULL, pDev); + pDev = pDev->next; + } } #ifdef PANORAMIX @@ -2061,77 +2210,136 @@ WindowsRestructured() void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) { GrabPtr grab; + DeviceIntPtr pDev; + SpritePtr pSprite; if (noPanoramiXExtension) return; - - sprite.hot.x -= xoff; - sprite.hot.y -= yoff; - - sprite.hotPhys.x -= xoff; - sprite.hotPhys.y -= yoff; - - sprite.hotLimits.x1 -= xoff; - sprite.hotLimits.y1 -= yoff; - sprite.hotLimits.x2 -= xoff; - sprite.hotLimits.y2 -= yoff; - - if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1)) - REGION_TRANSLATE(sprite.screen, &sprite.Reg1, xoff, yoff); - if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2)) - REGION_TRANSLATE(sprite.screen, &sprite.Reg2, xoff, yoff); - - /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */ - if ((grab = inputInfo.pointer->grab) && grab->confineTo) { - if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen) - sprite.hotPhys.x = sprite.hotPhys.y = 0; - ConfineCursorToWindow(grab->confineTo, TRUE, TRUE); - } else - ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum], - TRUE, FALSE); + + pDev = inputInfo.devices; + while(pDev) + { + if (DevHasCursor(pDev)) + { + pSprite = pDev->spriteInfo->sprite; + pSprite->hot.x -= xoff; + pSprite->hot.y -= yoff; + + pSprite->hotPhys.x -= xoff; + pSprite->hotPhys.y -= yoff; + + pSprite->hotLimits.x1 -= xoff; + pSprite->hotLimits.y1 -= yoff; + pSprite->hotLimits.x2 -= xoff; + pSprite->hotLimits.y2 -= yoff; + + if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg1)) + REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, xoff, yoff); + if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg2)) + REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, xoff, yoff); + + /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */ + if ((grab = pDev->coreGrab.grab) && grab->confineTo) { + if (grab->confineTo->drawable.pScreen + != pSprite->hotPhys.pScreen) + pSprite->hotPhys.x = pSprite->hotPhys.y = 0; + ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE); + } else + ConfineCursorToWindow( + pDev, + WindowTable[pSprite->hotPhys.pScreen->myNum], + TRUE, FALSE); + + } + pDev = pDev->next; + } } #endif void DefineInitialRootWindow(WindowPtr win) { - ScreenPtr pScreen = win->drawable.pScreen; - - sprite.hotPhys.pScreen = pScreen; - sprite.hotPhys.x = pScreen->width / 2; - sprite.hotPhys.y = pScreen->height / 2; - sprite.hot = sprite.hotPhys; - sprite.hotLimits.x2 = pScreen->width; - sprite.hotLimits.y2 = pScreen->height; + DeviceIntPtr pDev = inputInfo.devices; + #ifdef XEVIE - xeviewin = + xeviewin = win; #endif - sprite.win = win; - sprite.current = wCursor (win); - sprite.current->refcnt++; - spriteTraceGood = 1; ROOT = win; - (*pScreen->CursorLimits) ( - pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits); - sprite.confined = FALSE; - (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits); - (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE); - (*pScreen->DisplayCursor) (pScreen, sprite.current); + InitializeSprite(inputInfo.pointer, win); + + while (pDev) + { + if (DevHasCursor(pDev)) + InitializeSprite(pDev, win); + pDev = pDev->next; + } +} + +void +InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) +{ + SpritePtr pSprite; + ScreenPtr pScreen; + + if (!pDev->spriteInfo->sprite) + { + pDev->spriteInfo->sprite = (SpritePtr)xcalloc(1, sizeof(SpriteRec)); + if (!pDev->spriteInfo->sprite) + FatalError("InitializeSprite: failed to allocate sprite struct"); + } + + pSprite = pDev->spriteInfo->sprite; + pDev->spriteInfo->spriteOwner = TRUE; + + pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr)NULL; + pSprite->hot.pScreen = pScreen; + pSprite->hotPhys.pScreen = pScreen; + 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->win = pWin; + + if (pWin) + { + pSprite->current = wCursor(pWin); + pSprite->current->refcnt++; + } else + pSprite->current = NullCursor; + + 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); + } #ifdef PANORAMIX if(!noPanoramiXExtension) { - sprite.hotLimits.x1 = -panoramiXdataPtr[0].x; - sprite.hotLimits.y1 = -panoramiXdataPtr[0].y; - sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x; - sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y; - sprite.physLimits = sprite.hotLimits; - sprite.confineWin = NullWindow; + pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x; + pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y; + pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x; + pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y; + pSprite->physLimits = pSprite->hotLimits; + pSprite->confineWin = NullWindow; #ifdef SHAPE - sprite.hotShape = NullRegion; + pSprite->hotShape = NullRegion; #endif - sprite.screen = pScreen; - /* gotta UNINIT these someplace */ - REGION_NULL(pScreen, &sprite.Reg1); - REGION_NULL(pScreen, &sprite.Reg2); + pSprite->screen = pScreen; + /* gotta UNINIT these someplace */ + REGION_NULL(pScreen, &pSprite->Reg1); + REGION_NULL(pScreen, &pSprite->Reg2); } #endif } @@ -2146,40 +2354,50 @@ DefineInitialRootWindow(WindowPtr win) void WindowHasNewCursor(WindowPtr pWin) { - PostNewCursor(); + DeviceIntPtr pDev; + + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + if (DevHasCursor(pDev)) + PostNewCursor(pDev); } _X_EXPORT void -NewCurrentScreen(ScreenPtr newScreen, int x, int y) +NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y) { - sprite.hotPhys.x = x; - sprite.hotPhys.y = y; + SpritePtr pSprite = pDev->spriteInfo->sprite; + + pSprite->hotPhys.x = x; + pSprite->hotPhys.y = y; #ifdef PANORAMIX if(!noPanoramiXExtension) { - sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - + pSprite->hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - panoramiXdataPtr[0].x; - sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - + pSprite->hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - panoramiXdataPtr[0].y; - if (newScreen != sprite.screen) { - sprite.screen = newScreen; + if (newScreen != pSprite->screen) { + pSprite->screen = newScreen; /* Make sure we tell the DDX to update its copy of the screen */ - if(sprite.confineWin) - XineramaConfineCursorToWindow(sprite.confineWin, TRUE); + if(pSprite->confineWin) + XineramaConfineCursorToWindow(pDev, + pSprite->confineWin, TRUE); else - XineramaConfineCursorToWindow(WindowTable[0], TRUE); + XineramaConfineCursorToWindow(pDev, WindowTable[0], TRUE); /* if the pointer wasn't confined, the DDX won't get told of the pointer warp so we reposition it here */ if(!syncEvents.playingEvents) - (*sprite.screen->SetCursorPosition)(sprite.screen, - sprite.hotPhys.x + panoramiXdataPtr[0].x - - panoramiXdataPtr[sprite.screen->myNum].x, - sprite.hotPhys.y + panoramiXdataPtr[0].y - - panoramiXdataPtr[sprite.screen->myNum].y, FALSE); + (*pSprite->screen->SetCursorPosition)( + pDev, + pSprite->screen, + pSprite->hotPhys.x + panoramiXdataPtr[0].x - + panoramiXdataPtr[pSprite->screen->myNum].x, + pSprite->hotPhys.y + panoramiXdataPtr[0].y - + panoramiXdataPtr[pSprite->screen->myNum].y, FALSE); } } else #endif - if (newScreen != sprite.hotPhys.pScreen) - ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE); + if (newScreen != pSprite->hotPhys.pScreen) + ConfineCursorToWindow(pDev, WindowTable[newScreen->myNum], + TRUE, FALSE); } #ifdef PANORAMIX @@ -2200,13 +2418,13 @@ XineramaPointInWindowIsVisible( if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)) return TRUE; - if(!XineramaSetWindowPntrs(pWin)) return FALSE; + if(!XineramaSetWindowPntrs(inputInfo.pointer, pWin)) return FALSE; xoff = x + panoramiXdataPtr[0].x; yoff = y + panoramiXdataPtr[0].y; for(i = 1; i < PanoramiXNumScreens; i++) { - pWin = sprite.windows[i]; + pWin = inputInfo.pointer->spriteInfo->sprite->windows[i]; pScreen = pWin->drawable.pScreen; x = xoff - panoramiXdataPtr[i].x; y = yoff - panoramiXdataPtr[i].y; @@ -2229,6 +2447,7 @@ XineramaWarpPointer(ClientPtr client) { WindowPtr dest = NULL; int x, y, rc; + SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; REQUEST(xWarpPointerReq); @@ -2238,8 +2457,8 @@ XineramaWarpPointer(ClientPtr client) if (rc != Success) return rc; } - x = sprite.hotPhys.x; - y = sprite.hotPhys.y; + x = pSprite->hotPhys.x; + y = pSprite->hotPhys.y; if (stuff->srcWid != None) { @@ -2278,18 +2497,18 @@ XineramaWarpPointer(ClientPtr client) x += stuff->dstX; y += stuff->dstY; - if (x < sprite.physLimits.x1) - x = sprite.physLimits.x1; - else if (x >= sprite.physLimits.x2) - x = sprite.physLimits.x2 - 1; - if (y < sprite.physLimits.y1) - y = sprite.physLimits.y1; - else if (y >= sprite.physLimits.y2) - y = sprite.physLimits.y2 - 1; - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &x, &y); + if (x < pSprite->physLimits.x1) + x = pSprite->physLimits.x1; + else if (x >= pSprite->physLimits.x2) + x = pSprite->physLimits.x2 - 1; + if (y < pSprite->physLimits.y1) + y = pSprite->physLimits.y1; + else if (y >= pSprite->physLimits.y2) + y = pSprite->physLimits.y2 - 1; + if (pSprite->hotShape) + ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); - XineramaSetCursorPosition(x, y, TRUE); + XineramaSetCursorPosition(PickPointer(client), x, y, TRUE); return Success; } @@ -2303,6 +2522,7 @@ ProcWarpPointer(ClientPtr client) WindowPtr dest = NULL; int x, y, rc; ScreenPtr newScreen; + SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; REQUEST(xWarpPointerReq); @@ -2318,8 +2538,8 @@ ProcWarpPointer(ClientPtr client) if (rc != Success) return rc; } - x = sprite.hotPhys.x; - y = sprite.hotPhys.y; + x = pSprite->hotPhys.x; + y = pSprite->hotPhys.y; if (stuff->srcWid != None) { @@ -2333,7 +2553,7 @@ ProcWarpPointer(ClientPtr client) winX = source->drawable.x; winY = source->drawable.y; - if (source->drawable.pScreen != sprite.hotPhys.pScreen || + if (source->drawable.pScreen != pSprite->hotPhys.pScreen || x < winX + stuff->srcX || y < winY + stuff->srcY || (stuff->srcWidth != 0 && @@ -2349,7 +2569,7 @@ ProcWarpPointer(ClientPtr client) y = dest->drawable.y; newScreen = dest->drawable.pScreen; } else - newScreen = sprite.hotPhys.pScreen; + newScreen = pSprite->hotPhys.pScreen; x += stuff->dstX; y += stuff->dstY; @@ -2363,41 +2583,43 @@ ProcWarpPointer(ClientPtr client) else if (y >= newScreen->height) y = newScreen->height - 1; - if (newScreen == sprite.hotPhys.pScreen) + if (newScreen == pSprite->hotPhys.pScreen) { - if (x < sprite.physLimits.x1) - x = sprite.physLimits.x1; - else if (x >= sprite.physLimits.x2) - x = sprite.physLimits.x2 - 1; - if (y < sprite.physLimits.y1) - y = sprite.physLimits.y1; - else if (y >= sprite.physLimits.y2) - y = sprite.physLimits.y2 - 1; + if (x < pSprite->physLimits.x1) + x = pSprite->physLimits.x1; + else if (x >= pSprite->physLimits.x2) + x = pSprite->physLimits.x2 - 1; + if (y < pSprite->physLimits.y1) + y = pSprite->physLimits.y1; + else if (y >= pSprite->physLimits.y2) + y = pSprite->physLimits.y2 - 1; #if defined(SHAPE) - if (sprite.hotShape) - ConfineToShape(sprite.hotShape, &x, &y); + if (pSprite->hotShape) + ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); #endif - (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE); + (*newScreen->SetCursorPosition)(PickPointer(client), newScreen, x, y, + TRUE); } - else if (!PointerConfinedToScreen()) + else if (!PointerConfinedToScreen(PickPointer(client))) { - NewCurrentScreen(newScreen, x, y); + NewCurrentScreen(PickPointer(client), newScreen, x, y); } return Success; } static Bool -BorderSizeNotEmpty(WindowPtr pWin) +BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin) { - if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize)) + if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->hotPhys.pScreen, &pWin->borderSize)) return TRUE; #ifdef PANORAMIX - if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) { + if(!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) { int i; for(i = 1; i < PanoramiXNumScreens; i++) { - if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize)) + if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->screen, + &pDev->spriteInfo->sprite->windows[i]->borderSize)) return TRUE; } } @@ -2417,6 +2639,7 @@ CheckPassiveGrabsOnWindow( { GrabPtr grab = wPassiveGrabs(pWin); GrabRec tempGrab; + GrabInfoPtr grabinfo; xEvent *dxE; if (!grab) @@ -2459,7 +2682,7 @@ CheckPassiveGrabsOnWindow( if (GrabMatchesSecond(&tempGrab, grab) && (!grab->confineTo || (grab->confineTo->realized && - BorderSizeNotEmpty(grab->confineTo)))) + BorderSizeNotEmpty(device, grab->confineTo)))) { if (!XaceHook(XACE_DEVICE_ACCESS, wClient(pWin), device, FALSE)) return FALSE; @@ -2470,28 +2693,30 @@ CheckPassiveGrabsOnWindow( tempGrab.modifiersDetail.exact&(~0x1f00); } #endif - (*device->ActivateGrab)(device, grab, currentTime, TRUE); + grabinfo = (xE->u.u.type & EXTENSION_EVENT_BASE) ? + &device->deviceGrab : &device->coreGrab; + (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); - FixUpEventFromWindow(xE, grab->window, None, TRUE); + FixUpEventFromWindow(device, xE, grab->window, None, TRUE); (void) TryClientEvents(rClient(grab), xE, count, filters[xE->u.u.type], filters[xE->u.u.type], grab); - if (device->sync.state == FROZEN_NO_EVENT) + if (grabinfo->sync.state == FROZEN_NO_EVENT) { - if (device->sync.evcount < count) + if (grabinfo->sync.evcount < count) { Must_have_memory = TRUE; /* XXX */ - device->sync.event = (xEvent *)xrealloc(device->sync.event, + grabinfo->sync.event = (xEvent *)xrealloc(grabinfo->sync.event, count* sizeof(xEvent)); Must_have_memory = FALSE; /* XXX */ } - device->sync.evcount = count; - for (dxE = device->sync.event; --count >= 0; dxE++, xE++) + grabinfo->sync.evcount = count; + for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++) *dxE = *xE; - device->sync.state = FROZEN_WITH_EVENT; + grabinfo->sync.state = FROZEN_WITH_EVENT; } return TRUE; } @@ -2577,10 +2802,10 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count) return; } /* just deliver it to the focus window */ - FixUpEventFromWindow(xE, focus, None, FALSE); + FixUpEventFromWindow(inputInfo.pointer, xE, focus, None, FALSE); if (xE->u.u.type & EXTENSION_EVENT_BASE) mskidx = keybd->id; - (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type], + (void)DeliverEventsToWindow(keybd, focus, xE, count, filters[xE->u.u.type], NullGrab, mskidx); } @@ -2588,10 +2813,19 @@ void DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, Bool deactivateGrab, int count) { - GrabPtr grab = thisDev->grab; + GrabPtr grab; + GrabInfoPtr grabinfo; int deliveries = 0; DeviceIntPtr dev; xEvent *dxE; + SpritePtr pSprite = thisDev->spriteInfo->sprite; + + if (xE->u.u.type & EXTENSION_EVENT_BASE) + grabinfo = &thisDev->deviceGrab; + else + grabinfo = &thisDev->coreGrab; + + grab = grabinfo->grab; if (grab->ownerEvents) { @@ -2606,10 +2840,11 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, else focus = PointerRootWin; if (focus == PointerRootWin) - deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow, - thisDev, count); - else if (focus && (focus == sprite.win || IsParent(focus, sprite.win))) - deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus, + deliveries = DeliverDeviceEvents(pSprite->win, xE, grab, + NullWindow, thisDev, count); + else if (focus && (focus == pSprite->win || + IsParent(focus, pSprite->win))) + deliveries = DeliverDeviceEvents(pSprite->win, xE, grab, focus, thisDev, count); else if (focus) deliveries = DeliverDeviceEvents(focus, xE, grab, focus, @@ -2617,23 +2852,27 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, } if (!deliveries) { - FixUpEventFromWindow(xE, grab->window, None, TRUE); - deliveries = TryClientEvents(rClient(grab), xE, count, - (Mask)grab->eventMask, - filters[xE->u.u.type], grab); - if (deliveries && (xE->u.u.type == MotionNotify + if (ACDeviceAllowed(grab->window, thisDev)) + { + + FixUpEventFromWindow(thisDev, xE, grab->window, None, TRUE); + deliveries = TryClientEvents(rClient(grab), xE, count, + (Mask)grab->eventMask, + filters[xE->u.u.type], grab); + if (deliveries && (xE->u.u.type == MotionNotify #ifdef XINPUT - || xE->u.u.type == DeviceMotionNotify + || xE->u.u.type == DeviceMotionNotify #endif - )) - thisDev->valuator->motionHintWindow = grab->window; + )) + thisDev->valuator->motionHintWindow = grab->window; + } } if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify #ifdef XINPUT && xE->u.u.type != DeviceMotionNotify #endif )) - switch (thisDev->sync.state) + switch (grabinfo->sync.state) { case FREEZE_BOTH_NEXT_EVENT: for (dev = inputInfo.devices; dev; dev = dev->next) @@ -2641,26 +2880,26 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev, if (dev == thisDev) continue; FreezeThaw(dev, TRUE); - if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) && - (CLIENT_BITS(dev->grab->resource) == - CLIENT_BITS(thisDev->grab->resource))) - dev->sync.state = FROZEN_NO_EVENT; + if ((grabinfo->sync.state == FREEZE_BOTH_NEXT_EVENT) && + (CLIENT_BITS(grab->resource) == + CLIENT_BITS(grab->resource))) + grabinfo->sync.state = FROZEN_NO_EVENT; else - dev->sync.other = thisDev->grab; + grabinfo->sync.other = grab; } /* fall through */ case FREEZE_NEXT_EVENT: - thisDev->sync.state = FROZEN_WITH_EVENT; + grabinfo->sync.state = FROZEN_WITH_EVENT; FreezeThaw(thisDev, TRUE); - if (thisDev->sync.evcount < count) + if (grabinfo->sync.evcount < count) { Must_have_memory = TRUE; /* XXX */ - thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event, + grabinfo->sync.event = (xEvent *)xrealloc(grabinfo->sync.event, count*sizeof(xEvent)); Must_have_memory = FALSE; /* XXX */ } - thisDev->sync.evcount = count; - for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++) + grabinfo->sync.evcount = count; + for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++) *dxE = *xE; break; } @@ -2678,7 +2917,8 @@ ProcessKeyboardEvent (xEvent *xE, DeviceIntPtr keybd, int count) int i; CARD8 modifiers; CARD16 mask; - GrabPtr grab = keybd->grab; + GrabPtr grab; + GrabInfoPtr grabinfo; Bool deactivateGrab = FALSE; KeyClassPtr keyc = keybd->key; #ifdef XEVIE @@ -2721,6 +2961,13 @@ drawable.id:0; } #endif + if (xE->u.u.type & EXTENSION_EVENT_BASE) + grabinfo = &keybd->deviceGrab; + else + grabinfo = &keybd->coreGrab; + + grab = grabinfo->grab; + if (!syncEvents.playingEvents) { NoticeTime(xE); @@ -2741,9 +2988,9 @@ drawable.id:0; #endif ))) #endif - XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state); - XE_KBPTR.rootX = sprite.hot.x; - XE_KBPTR.rootY = sprite.hot.y; + XE_KBPTR.state = (keyc->state | GetPairedPointer(keybd)->button->state); + XE_KBPTR.rootX = keybd->spriteInfo->sprite->hot.x; + XE_KBPTR.rootY = keybd->spriteInfo->sprite->hot.y; key = xE->u.u.detail; kptr = &keyc->down[key >> 3]; bit = 1 << (key & 7); @@ -2774,7 +3021,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) @@ -2789,14 +3036,14 @@ drawable.id:0; } if (!grab && CheckDeviceGrabs(keybd, xE, 0, count)) { - keybd->activatingKey = key; + grabinfo->activatingKey = key; return; } break; 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) @@ -2810,7 +3057,7 @@ drawable.id:0; modifiers &= ~mask; } } - if (keybd->fromPassiveGrab && (key == keybd->activatingKey)) + if (grabinfo->fromPassiveGrab && (key == grabinfo->activatingKey)) deactivateGrab = TRUE; break; default: @@ -2819,9 +3066,9 @@ drawable.id:0; if (grab) DeliverGrabbedEvent(xE, keybd, deactivateGrab, count); else - DeliverFocusedEvent(keybd, xE, sprite.win, count); + DeliverFocusedEvent(keybd, xE, keybd->spriteInfo->sprite->win, count); if (deactivateGrab) - (*keybd->DeactivateGrab)(keybd); + (*grabinfo->DeactivateGrab)(keybd); XaceHook(XACE_KEY_AVAIL, xE, keybd, count); } @@ -2868,9 +3115,11 @@ CoreProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) #endif { - GrabPtr grab = mouse->grab; + GrabPtr grab = mouse->coreGrab.grab; Bool deactivateGrab = FALSE; - ButtonClassPtr butc = mouse->button; + ButtonClassPtr butc = mouse->button; + SpritePtr pSprite = mouse->spriteInfo->sprite; + #ifdef XKB XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo; #endif @@ -2906,7 +3155,7 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) /* see comment in EnqueueEvents regarding the next three lines */ if (xE->u.u.type == MotionNotify) XE_KBPTR.root = - WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id; + WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; eventinfo.events = xE; eventinfo.count = count; CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo); @@ -2918,8 +3167,8 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) BYTE *kptr; int bit; - XE_KBPTR.rootX = sprite.hot.x; - XE_KBPTR.rootY = sprite.hot.y; + XE_KBPTR.rootX = pSprite->hot.x; + XE_KBPTR.rootY = pSprite->hot.y; key = xE->u.u.detail; kptr = &butc->down[key >> 3]; @@ -2953,22 +3202,22 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count) if (xE->u.u.detail <= 5) butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail); filters[MotionNotify] = Motion_Filter(butc); - if (!butc->state && mouse->fromPassiveGrab) + if (!butc->state && mouse->coreGrab.fromPassiveGrab) deactivateGrab = TRUE; break; default: FatalError("bogus pointer event from ddx"); } } - else if (!CheckMotion(xE)) + else if (!CheckMotion(xE, mouse)) return; if (grab) DeliverGrabbedEvent(xE, mouse, deactivateGrab, count); else - DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow, + DeliverDeviceEvents(pSprite->win, xE, NullGrab, NullWindow, mouse, count); if (deactivateGrab) - (*mouse->DeactivateGrab)(mouse); + (*mouse->coreGrab.DeactivateGrab)(mouse); } #define AtMostOneClient \ @@ -3110,7 +3359,7 @@ maskSet: if ((inputInfo.pointer->valuator->motionHintWindow == pWin) && (mask & PointerMotionHintMask) && !(check & PointerMotionHintMask) && - !inputInfo.pointer->grab) + !inputInfo.pointer->coreGrab.grab) /* VCP shouldn't have deviceGrab */ inputInfo.pointer->valuator->motionHintWindow = NullWindow; RecalculateDeliverableEvents(pWin); return Success; @@ -3184,19 +3433,25 @@ CommonAncestor( static void EnterLeaveEvent( + DeviceIntPtr pDev, int type, int mode, int detail, WindowPtr pWin, Window child) { - xEvent event; - DeviceIntPtr keybd = inputInfo.keyboard; + xEvent event; + DeviceIntPtr keybd = inputInfo.keyboard; WindowPtr focus; - DeviceIntPtr mouse = inputInfo.pointer; - GrabPtr grab = mouse->grab; + DeviceIntPtr mouse = pDev; + GrabPtr grab = mouse->coreGrab.grab; + GrabPtr devgrab = mouse->deviceGrab.grab; Mask mask; + deviceEnterNotify *devEnterLeave; + int mskidx; + OtherInputMasks *inputMasks; + if ((pWin == mouse->valuator->motionHintWindow) && (detail != NotifyInferior)) mouse->valuator->motionHintWindow = NullWindow; @@ -3210,40 +3465,63 @@ EnterLeaveEvent( { mask = pWin->eventMask | wOtherEventMasks(pWin); } - if (mask & filters[type]) - { - event.u.u.type = type; - event.u.u.detail = detail; - event.u.enterLeave.time = currentTime.milliseconds; - event.u.enterLeave.rootX = sprite.hot.x; - event.u.enterLeave.rootY = sprite.hot.y; - /* Counts on the same initial structure of crossing & button events! */ - FixUpEventFromWindow(&event, pWin, None, FALSE); - /* Enter/Leave events always set child */ - event.u.enterLeave.child = child; - event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? - ELFlagSameScreen : 0; + + event.u.u.type = type; + event.u.u.detail = detail; + event.u.enterLeave.time = currentTime.milliseconds; + event.u.enterLeave.rootX = pDev->spriteInfo->sprite->hot.x; + event.u.enterLeave.rootY = pDev->spriteInfo->sprite->hot.y; + /* Counts on the same initial structure of crossing & button events! */ + FixUpEventFromWindow(mouse, &event, pWin, None, FALSE); + /* Enter/Leave events always set child */ + event.u.enterLeave.child = child; + event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? + ELFlagSameScreen : 0; #ifdef XKB - if (!noXkbExtension) { - event.u.enterLeave.state = mouse->button->state & 0x1f00; - event.u.enterLeave.state |= - XkbGrabStateFromRec(&keybd->key->xkbInfo->state); - } else + if (!noXkbExtension) { + event.u.enterLeave.state = mouse->button->state & 0x1f00; + event.u.enterLeave.state |= + XkbGrabStateFromRec(&keybd->key->xkbInfo->state); + } else #endif - event.u.enterLeave.state = keybd->key->state | mouse->button->state; - event.u.enterLeave.mode = mode; - focus = keybd->focus->win; - if ((focus != NoneWin) && - ((pWin == focus) || (focus == PointerRootWin) || - IsParent(focus, pWin))) - event.u.enterLeave.flags |= ELFlagFocus; + event.u.enterLeave.state = keybd->key->state | mouse->button->state; + event.u.enterLeave.mode = mode; + focus = keybd->focus->win; + if ((focus != NoneWin) && + ((pWin == focus) || (focus == PointerRootWin) || + IsParent(focus, pWin))) + event.u.enterLeave.flags |= ELFlagFocus; + + if (mask & filters[type]) + { if (grab) (void)TryClientEvents(rClient(grab), &event, 1, mask, filters[type], grab); else - (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], + (void)DeliverEventsToWindow(pDev, pWin, &event, 1, filters[type], NullGrab, 0); } + + devEnterLeave = (deviceEnterNotify*)&event; + devEnterLeave->type = (type == EnterNotify) ? DeviceEnterNotify : + DeviceLeaveNotify; + devEnterLeave->type = (type == EnterNotify) ? DeviceEnterNotify : + DeviceLeaveNotify; + devEnterLeave->deviceid = pDev->id; + mskidx = pDev->id; + inputMasks = wOtherInputMasks(pWin); + if (inputMasks && + (filters[devEnterLeave->type] & inputMasks->deliverableEvents[mskidx])) + { + if (devgrab) + (void)TryClientEvents(rClient(devgrab), (xEvent*)devEnterLeave, 1, + mask, filters[devEnterLeave->type], devgrab); + else + (void)DeliverEventsToWindow(pDev, pWin, (xEvent*)devEnterLeave, + 1, filters[devEnterLeave->type], + NullGrab, pDev->id); + } + if ((type == EnterNotify) && (mask & KeymapStateMask)) { xKeymapEvent ke; @@ -3259,24 +3537,32 @@ EnterLeaveEvent( (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask, KeymapStateMask, grab); else - (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1, + (void)DeliverEventsToWindow(pDev, pWin, (xEvent *)&ke, 1, KeymapStateMask, NullGrab, 0); } } static void -EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail) +EnterNotifies(DeviceIntPtr pDev, + WindowPtr ancestor, + WindowPtr child, + int mode, + int detail) { WindowPtr parent = child->parent; if (ancestor == parent) return; - EnterNotifies(ancestor, parent, mode, detail); - EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id); -} + EnterNotifies(pDev, ancestor, parent, mode, detail); + EnterLeaveEvent(pDev, EnterNotify, mode, detail, parent, + child->drawable.id); } static void -LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail) +LeaveNotifies(DeviceIntPtr pDev, + WindowPtr child, + WindowPtr ancestor, + int mode, + int detail) { WindowPtr pWin; @@ -3284,36 +3570,45 @@ LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail) return; for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent) { - EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id); - child = pWin; + EnterLeaveEvent(pDev, LeaveNotify, mode, detail, pWin, + child->drawable.id); + child = pWin; } } static void -DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode) +DoEnterLeaveEvents(DeviceIntPtr pDev, + WindowPtr fromWin, + WindowPtr toWin, + int mode) { if (fromWin == toWin) return; if (IsParent(fromWin, toWin)) { - EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None); - EnterNotifies(fromWin, toWin, mode, NotifyVirtual); - EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None); + EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyInferior, fromWin, + None); + EnterNotifies(pDev, fromWin, toWin, mode, + NotifyVirtual); + EnterLeaveEvent(pDev, EnterNotify, mode, NotifyAncestor, toWin, None); } else if (IsParent(toWin, fromWin)) { - EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None); - LeaveNotifies(fromWin, toWin, mode, NotifyVirtual); - EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None); + EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyAncestor, fromWin, + None); + LeaveNotifies(pDev, fromWin, toWin, mode, NotifyVirtual); + 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 */ - EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None); - LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual); - EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual); - EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None); + EnterLeaveEvent(pDev, LeaveNotify, mode, NotifyNonlinear, fromWin, + None); + LeaveNotifies(pDev, fromWin, common, mode, NotifyNonlinearVirtual); + EnterNotifies(pDev, common, toWin, mode, NotifyNonlinearVirtual); + EnterLeaveEvent(pDev, EnterNotify, mode, NotifyNonlinear, toWin, + None); } } @@ -3333,8 +3628,8 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) event.u.u.type = type; event.u.u.detail = detail; event.u.focus.window = pWin->drawable.id; - (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab, - 0); + (void)DeliverEventsToWindow(dev, pWin, &event, 1, filters[type], NullGrab, + 0); if ((type == FocusIn) && ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) { @@ -3346,7 +3641,7 @@ FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) bzero((char *)&ke.map[0], 31); ke.type = KeymapNotify; - (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1, + (void)DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1, KeymapStateMask, NullGrab, 0); } } @@ -3402,6 +3697,7 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) int out, in; /* for holding details for to/from PointerRoot/None */ int i; + SpritePtr pSprite = dev->spriteInfo->sprite; if (fromWin == toWin) return; @@ -3414,8 +3710,8 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) { if (fromWin == PointerRootWin) - FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer, - TRUE); + FocusOutEvents(dev, pSprite->win, ROOT, mode, + NotifyPointer, TRUE); /* Notify all the roots */ #ifdef PANORAMIX if ( !noPanoramiXExtension ) @@ -3427,8 +3723,8 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) } else { - if (IsParent(fromWin, sprite.win)) - FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer, + if (IsParent(fromWin, pSprite->win)) + FocusOutEvents(dev, pSprite->win, fromWin, mode, NotifyPointer, FALSE); FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin); /* next call catches the root too, if the screen changed */ @@ -3444,7 +3740,7 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) for (i=0; i<screenInfo.numScreens; i++) FocusEvent(dev, FocusIn, mode, in, WindowTable[i]); if (toWin == PointerRootWin) - (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode, + (void)FocusInEvents(dev, ROOT, pSprite->win, NullWindow, mode, NotifyPointer, TRUE); } else @@ -3452,7 +3748,7 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) { if (fromWin == PointerRootWin) - FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer, + FocusOutEvents(dev, pSprite->win, ROOT, mode, NotifyPointer, TRUE); #ifdef PANORAMIX if ( !noPanoramiXExtension ) @@ -3465,8 +3761,8 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) (void)FocusInEvents(dev, ROOT, toWin, toWin, mode, NotifyNonlinearVirtual, TRUE); FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin); - if (IsParent(toWin, sprite.win)) - (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode, + if (IsParent(toWin, pSprite->win)) + (void)FocusInEvents(dev, toWin, pSprite->win, NullWindow, mode, NotifyPointer, FALSE); } else @@ -3477,21 +3773,21 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) FocusOutEvents(dev, fromWin->parent, toWin, mode, NotifyVirtual, FALSE); FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin); - if ((IsParent(toWin, sprite.win)) && - (sprite.win != fromWin) && - (!IsParent(fromWin, sprite.win)) && - (!IsParent(sprite.win, fromWin))) - (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, + if ((IsParent(toWin, pSprite->win)) && + (pSprite->win != fromWin) && + (!IsParent(fromWin, pSprite->win)) && + (!IsParent(pSprite->win, fromWin))) + (void)FocusInEvents(dev, toWin, pSprite->win, NullWindow, mode, NotifyPointer, FALSE); } else if (IsParent(fromWin, toWin)) { - if ((IsParent(fromWin, sprite.win)) && - (sprite.win != fromWin) && - (!IsParent(toWin, sprite.win)) && - (!IsParent(sprite.win, toWin))) - FocusOutEvents(dev, sprite.win, fromWin, mode, + if ((IsParent(fromWin, pSprite->win)) && + (pSprite->win != fromWin) && + (!IsParent(toWin, pSprite->win)) && + (!IsParent(pSprite->win, toWin))) + FocusOutEvents(dev, pSprite->win, fromWin, mode, NotifyPointer, FALSE); FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin); (void)FocusInEvents(dev, fromWin, toWin, toWin, mode, @@ -3503,8 +3799,8 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) /* neither fromWin or toWin is child of other */ WindowPtr common = CommonAncestor(toWin, fromWin); /* common == NullWindow ==> different screens */ - if (IsParent(fromWin, sprite.win)) - FocusOutEvents(dev, sprite.win, fromWin, mode, + if (IsParent(fromWin, pSprite->win)) + FocusOutEvents(dev, pSprite->win, fromWin, mode, NotifyPointer, FALSE); FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin); if (fromWin->parent != NullWindow) @@ -3514,8 +3810,8 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode) (void)FocusInEvents(dev, common, toWin, toWin, mode, NotifyNonlinearVirtual, FALSE); FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin); - if (IsParent(toWin, sprite.win)) - (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, + if (IsParent(toWin, pSprite->win)) + (void)FocusInEvents(dev, toWin, pSprite->win, NullWindow, mode, NotifyPointer, FALSE); } } @@ -3563,7 +3859,7 @@ SetInputFocus( if ((CompareTimeStamps(time, currentTime) == LATER) || (CompareTimeStamps(time, focus->time) == EARLIER)) return Success; - mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal; + mode = (dev->coreGrab.grab) ? NotifyWhileGrabbed : NotifyNormal; if (focus->win == FollowKeyboardWin) DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode); else @@ -3602,6 +3898,7 @@ int ProcSetInputFocus(client) ClientPtr client; { + DeviceIntPtr kbd = PickKeyboard(client); REQUEST(xSetInputFocusReq); REQUEST_SIZE_MATCH(xSetInputFocusReq); @@ -3609,16 +3906,17 @@ ProcSetInputFocus(client) if (!XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) return Success; - return SetInputFocus(client, inputInfo.keyboard, stuff->focus, + return SetInputFocus(client, kbd, stuff->focus, stuff->revertTo, stuff->time, FALSE); } int ProcGetInputFocus(ClientPtr client) { + DeviceIntPtr kbd = PickKeyboard(client); xGetInputFocusReply rep; /* REQUEST(xReq); */ - FocusClassPtr focus = inputInfo.keyboard->focus; + FocusClassPtr focus = kbd->focus; REQUEST_SIZE_MATCH(xReq); rep.type = X_Reply; @@ -3638,7 +3936,7 @@ int ProcGrabPointer(ClientPtr client) { xGrabPointerReply rep; - DeviceIntPtr device = inputInfo.pointer; + DeviceIntPtr device = PickPointer(client); GrabPtr grab; WindowPtr pWin, confineTo; CursorPtr cursor, oldCursor; @@ -3699,18 +3997,20 @@ ProcGrabPointer(ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; - grab = device->grab; + grab = device->coreGrab.grab; if ((grab) && !SameClient(grab, client)) rep.status = AlreadyGrabbed; else if ((!pWin->realized) || (confineTo && - !(confineTo->realized && BorderSizeNotEmpty(confineTo)))) + !(confineTo->realized + && BorderSizeNotEmpty(device, confineTo)))) rep.status = GrabNotViewable; - else if (device->sync.frozen && - device->sync.other && !SameClient(device->sync.other, client)) + else if (device->coreGrab.sync.frozen && + device->coreGrab.sync.other && + !SameClient(device->coreGrab.sync.other, client)) rep.status = GrabFrozen; else if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, device->grabTime) == EARLIER)) + (CompareTimeStamps(time, device->coreGrab.grabTime) == EARLIER)) rep.status = GrabInvalidTime; else { @@ -3720,7 +4020,7 @@ ProcGrabPointer(ClientPtr client) if (grab) { if (grab->confineTo && !confineTo) - ConfineCursorToWindow(ROOT, FALSE, FALSE); + ConfineCursorToWindow(device, ROOT, FALSE, FALSE); oldCursor = grab->cursor; } tempGrab.cursor = cursor; @@ -3732,7 +4032,8 @@ ProcGrabPointer(ClientPtr client) tempGrab.keyboardMode = stuff->keyboardMode; tempGrab.pointerMode = stuff->pointerMode; tempGrab.device = device; - (*device->ActivateGrab)(device, &tempGrab, time, FALSE); + tempGrab.coreGrab = True; + (*device->coreGrab.ActivateGrab)(device, &tempGrab, time, FALSE); if (oldCursor) FreeCursor (oldCursor, (Cursor)0); rep.status = GrabSuccess; @@ -3744,8 +4045,8 @@ ProcGrabPointer(ClientPtr client) int ProcChangeActivePointerGrab(ClientPtr client) { - DeviceIntPtr device = inputInfo.pointer; - GrabPtr grab = device->grab; + DeviceIntPtr device = PickPointer(client); + GrabPtr grab = device->coreGrab.grab; CursorPtr newCursor, oldCursor; REQUEST(xChangeActivePointerGrabReq); TimeStamp time; @@ -3774,13 +4075,13 @@ ProcChangeActivePointerGrab(ClientPtr client) return Success; time = ClientTimeToServerTime(stuff->time); if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, device->grabTime) == EARLIER)) + (CompareTimeStamps(time, device->coreGrab.grabTime) == EARLIER)) return Success; oldCursor = grab->cursor; grab->cursor = newCursor; if (newCursor) newCursor->refcnt++; - PostNewCursor(); + PostNewCursor(device); if (oldCursor) FreeCursor(oldCursor, (Cursor)0); grab->eventMask = stuff->eventMask; @@ -3790,19 +4091,19 @@ ProcChangeActivePointerGrab(ClientPtr client) int ProcUngrabPointer(ClientPtr client) { - DeviceIntPtr device = inputInfo.pointer; + DeviceIntPtr device = PickPointer(client); GrabPtr grab; TimeStamp time; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); UpdateCurrentTime(); - grab = device->grab; + grab = device->coreGrab.grab; time = ClientTimeToServerTime(stuff->id); if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, device->grabTime) != EARLIER) && + (CompareTimeStamps(time, device->coreGrab.grabTime) != EARLIER) && (grab) && SameClient(grab, client)) - (*device->DeactivateGrab)(device); + (*device->coreGrab.DeactivateGrab)(device); return Success; } @@ -3836,21 +4137,24 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, if (rc != Success) return rc; time = ClientTimeToServerTime(ctime); - grab = dev->grab; + grab = dev->coreGrab.grab; if (grab && !SameClient(grab, client)) *status = AlreadyGrabbed; else if (!pWin->realized) *status = GrabNotViewable; else if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, dev->grabTime) == EARLIER)) + (CompareTimeStamps(time, dev->coreGrab.grabTime) == EARLIER)) *status = GrabInvalidTime; - else if (dev->sync.frozen && - dev->sync.other && !SameClient(dev->sync.other, client)) + else if (dev->coreGrab.sync.frozen && + dev->coreGrab.sync.other && !SameClient(dev->coreGrab.sync.other, client)) *status = GrabFrozen; else { GrabRec tempGrab; + /* Otherwise segfaults happen on grabbed MPX devices */ + memset(&tempGrab, 0, sizeof(GrabRec)); + tempGrab.window = pWin; tempGrab.resource = client->clientAsMask; tempGrab.ownerEvents = ownerEvents; @@ -3858,7 +4162,9 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, tempGrab.pointerMode = other_mode; tempGrab.eventMask = mask; tempGrab.device = dev; - (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE); + tempGrab.cursor = NULL; + + (*dev->coreGrab.ActivateGrab)(dev, &tempGrab, time, FALSE); *status = GrabSuccess; } return Success; @@ -3870,11 +4176,12 @@ ProcGrabKeyboard(ClientPtr client) xGrabKeyboardReply rep; REQUEST(xGrabKeyboardReq); int result; + DeviceIntPtr keyboard = PickKeyboard(client); REQUEST_SIZE_MATCH(xGrabKeyboardReq); - if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE)) - result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode, + if (XaceHook(XACE_DEVICE_ACCESS, client, keyboard, TRUE)) + result = GrabDevice(client, keyboard, stuff->keyboardMode, stuff->pointerMode, stuff->grabWindow, stuff->ownerEvents, stuff->time, KeyPressMask | KeyReleaseMask, &rep.status); @@ -3895,19 +4202,19 @@ ProcGrabKeyboard(ClientPtr client) int ProcUngrabKeyboard(ClientPtr client) { - DeviceIntPtr device = inputInfo.keyboard; + DeviceIntPtr device = PickKeyboard(client); GrabPtr grab; TimeStamp time; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); UpdateCurrentTime(); - grab = device->grab; + grab = device->coreGrab.grab; time = ClientTimeToServerTime(stuff->id); if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, device->grabTime) != EARLIER) && + (CompareTimeStamps(time, device->coreGrab.grabTime) != EARLIER) && (grab) && SameClient(grab, client)) - (*device->DeactivateGrab)(device); + (*device->coreGrab.DeactivateGrab)(device); return Success; } @@ -3916,10 +4223,12 @@ ProcQueryPointer(ClientPtr client) { xQueryPointerReply rep; WindowPtr pWin, t; - REQUEST(xResourceReq); - DeviceIntPtr mouse = inputInfo.pointer; + DeviceIntPtr mouse = PickPointer(client); + SpritePtr pSprite = mouse->spriteInfo->sprite; int rc; + REQUEST(xResourceReq); + REQUEST_SIZE_MATCH(xResourceReq); rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); if (rc != Success) @@ -3931,15 +4240,15 @@ ProcQueryPointer(ClientPtr client) rep.mask = mouse->button->state | inputInfo.keyboard->key->state; rep.length = 0; rep.root = (ROOT)->drawable.id; - rep.rootX = sprite.hot.x; - rep.rootY = sprite.hot.y; + rep.rootX = pSprite->hot.x; + rep.rootY = pSprite->hot.y; rep.child = None; - if (sprite.hot.pScreen == pWin->drawable.pScreen) + if (pSprite->hot.pScreen == pWin->drawable.pScreen) { rep.sameScreen = xTrue; - rep.winX = sprite.hot.x - pWin->drawable.x; - rep.winY = sprite.hot.y - pWin->drawable.y; - for (t = sprite.win; t; t = t->parent) + rep.winX = pSprite->hot.x - pWin->drawable.x; + rep.winY = pSprite->hot.y - pWin->drawable.y; + for (t = pSprite->win; t; t = t->parent) if (t->parent == pWin) { rep.child = t->drawable.id; @@ -3974,7 +4283,6 @@ InitEvents() { int i; - sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL; inputInfo.numDevices = 0; inputInfo.devices = (DeviceIntPtr)NULL; inputInfo.off_devices = (DeviceIntPtr)NULL; @@ -3984,6 +4292,11 @@ InitEvents() { spriteTraceSize = 32; spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr)); + /* FIXME: spriteTrace[0] needs to be NULL, otherwise + * GetCurrentRootWindow() in EnableDevice() may return a invalid + * value. (whot) + */ + memset(spriteTrace, 0, 32 * sizeof(WindowPtr)); if (!spriteTrace) FatalError("failed to allocate spriteTrace"); } @@ -3991,15 +4304,9 @@ InitEvents() lastEventMask = OwnerGrabButtonMask; filters[MotionNotify] = PointerMotionMask; #ifdef XEVIE - xeviewin = + xeviewin = NULL; #endif - sprite.win = NullWindow; - sprite.current = NullCursor; - sprite.hotLimits.x1 = 0; - sprite.hotLimits.y1 = 0; - sprite.hotLimits.x2 = 0; - sprite.hotLimits.y2 = 0; - sprite.confined = FALSE; + syncEvents.replayDev = (DeviceIntPtr)NULL; syncEvents.replayWin = NullWindow; while (syncEvents.pending) @@ -4022,6 +4329,7 @@ InitEvents() } } + void CloseDownEvents(void) { @@ -4035,6 +4343,7 @@ ProcSendEvent(ClientPtr client) { WindowPtr pWin; WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ + SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; REQUEST(xSendEventReq); REQUEST_SIZE_MATCH(xSendEventReq); @@ -4065,7 +4374,7 @@ ProcSendEvent(ClientPtr client) } if (stuff->destination == PointerWindow) - pWin = sprite.win; + pWin = pSprite->win; else if (stuff->destination == InputFocus) { WindowPtr inputFocus = inputInfo.keyboard->focus->win; @@ -4078,10 +4387,10 @@ ProcSendEvent(ClientPtr client) if (inputFocus == PointerRootWin) inputFocus = ROOT; - if (IsParent(inputFocus, sprite.win)) + if (IsParent(inputFocus, pSprite->win)) { effectiveFocus = inputFocus; - pWin = sprite.win; + pWin = pSprite->win; } else effectiveFocus = pWin = inputFocus; @@ -4101,8 +4410,8 @@ ProcSendEvent(ClientPtr client) { for (;pWin; pWin = pWin->parent) { - if (DeliverEventsToWindow(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; @@ -4112,8 +4421,8 @@ ProcSendEvent(ClientPtr client) } } else - (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask, - NullGrab, 0); + (void)DeliverEventsToWindow(PickPointer(client), pWin, &stuff->event, + 1, stuff->eventMask, NullGrab, 0); return Success; } @@ -4123,7 +4432,7 @@ ProcUngrabKey(ClientPtr client) REQUEST(xUngrabKeyReq); WindowPtr pWin; GrabRec tempGrab; - DeviceIntPtr keybd = inputInfo.keyboard; + DeviceIntPtr keybd = PickKeyboard(client); int rc; REQUEST_SIZE_MATCH(xUngrabKeyReq); @@ -4165,7 +4474,7 @@ ProcGrabKey(ClientPtr client) WindowPtr pWin; REQUEST(xGrabKeyReq); GrabPtr grab; - DeviceIntPtr keybd = inputInfo.keyboard; + DeviceIntPtr keybd = PickKeyboard(client); int rc; REQUEST_SIZE_MATCH(xGrabKeyReq); @@ -4277,7 +4586,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, @@ -4306,7 +4615,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; @@ -4329,19 +4638,21 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) FocusClassPtr focus = keybd->focus; OtherClientsPtr oc; GrabPtr passive; + GrabPtr grab; /* Deactivate any grabs performed on this window, before making any input focus changes. */ - - if (mouse->grab && - ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin))) - (*mouse->DeactivateGrab)(mouse); + grab = mouse->coreGrab.grab; + if (grab && + ((grab->window == pWin) || (grab->confineTo == pWin))) + (*mouse->coreGrab.DeactivateGrab)(mouse); /* Deactivating a keyboard grab should cause focus events. */ - if (keybd->grab && (keybd->grab->window == pWin)) - (*keybd->DeactivateGrab)(keybd); + grab = keybd->coreGrab.grab; + if (grab && (grab->window == pWin)) + (*keybd->coreGrab.DeactivateGrab)(keybd); /* If the focus window is a root window (ie. has no parent) then don't delete the focus from it. */ @@ -4352,7 +4663,7 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) /* If a grab is in progress, then alter the mode of focus events. */ - if (keybd->grab) + if (keybd->coreGrab.grab) focusEventMode = NotifyWhileGrabbed; switch (focus->revert) @@ -4414,19 +4725,27 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) _X_EXPORT void CheckCursorConfinement(WindowPtr pWin) { - GrabPtr grab = inputInfo.pointer->grab; + GrabPtr grab; WindowPtr confineTo; + DeviceIntPtr pDev; #ifdef PANORAMIX if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return; #endif - if (grab && (confineTo = grab->confineTo)) + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if (!BorderSizeNotEmpty(confineTo)) - (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer); - else if ((pWin == confineTo) || IsParent(pWin, confineTo)) - ConfineCursorToWindow(confineTo, TRUE, TRUE); + if (DevHasCursor(pDev)) + { + grab = pDev->coreGrab.grab; + if (grab && (confineTo = grab->confineTo)) + { + if (!BorderSizeNotEmpty(pDev, confineTo)) + (*inputInfo.pointer->coreGrab.DeactivateGrab)(pDev); + else if ((pWin == confineTo) || IsParent(pWin, confineTo)) + ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE); + } + } } } @@ -4452,6 +4771,7 @@ ProcRecolorCursor(ClientPtr client) int nscr; ScreenPtr pscr; Bool displayed; + SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; REQUEST(xRecolorCursorReq); REQUEST_SIZE_MATCH(xRecolorCursorReq); @@ -4476,12 +4796,12 @@ ProcRecolorCursor(ClientPtr client) pscr = screenInfo.screens[nscr]; #ifdef PANORAMIX if(!noPanoramiXExtension) - displayed = (pscr == sprite.screen); + displayed = (pscr == pSprite->screen); else #endif - displayed = (pscr == sprite.hotPhys.pScreen); - ( *pscr->RecolorCursor)(pscr, pCursor, - (pCursor == sprite.current) && displayed); + displayed = (pscr == pSprite->hotPhys.pScreen); + ( *pscr->RecolorCursor)(PickPointer(client), pscr, pCursor, + (pCursor == pSprite->current) && displayed); } return (Success); } @@ -4567,3 +4887,117 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events); } } + +/* + * Set the client pointer for the given client. Second parameter setter could + * be used in the future to determine access rights. Unused for now. + */ +_X_EXPORT Bool +SetClientPointer(ClientPtr client, ClientPtr setter, DeviceIntPtr device) +{ + client->clientPtr = device; + return TRUE; +} + +/* 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, but will not store it on the client. + */ +_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->spriteInfo->spriteOwner) + { + client->clientPtr = it; + break; + } + it = it->next; + } + + if (!it) + { + ErrorF("Picking VCP\n"); + return 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 ptr = PickPointer(client); + DeviceIntPtr kbd = inputInfo.devices; + + while(kbd) + { + if (ptr != kbd && + IsKeyboardDevice(kbd) && + ptr->spriteInfo->sprite == kbd->spriteInfo->sprite) + return kbd; + kbd = kbd->next; + } + + return (kbd) ? kbd : inputInfo.keyboard; +} + +/* A client that has one or more core grabs does not get core events from + * devices it does not have a grab on. Legacy applications behave bad + * otherwise because they are not used to it and the events interfere. + * Only applies for core events. + * + * Return true if a core event from the device would interfere and should not + * be delivered. + */ +Bool +IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event) +{ + DeviceIntPtr it = inputInfo.devices; + + if (dev->coreGrab.grab && SameClient(dev->coreGrab.grab, client)) + return FALSE; + + switch(event->u.u.type) + { + case KeyPress: + case KeyRelease: + case ButtonPress: + case ButtonRelease: + case MotionNotify: + case EnterNotify: + case LeaveNotify: + break; + default: + return FALSE; + } + + while(it) + { + if (it != dev) + { + if (it->coreGrab.grab && SameClient(it->coreGrab.grab, client)) + { + return TRUE; + + } + } + it = it->next; + } + + return FALSE; +} + diff --git a/dix/getevents.c b/dix/getevents.c index 219d1a1c8..d446a2d3c 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -21,6 +21,12 @@ * * Author: Daniel Stone <daniel@fooishbar.org> */ + /* + * MPX additions: + * Copyright © 2006 Peter Hutterer + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + * + */ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> @@ -60,7 +66,6 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies); #include "exglobals.h" #include "extnsionst.h" - /* Maximum number of valuators, divided by six, rounded up, to get number * of events. */ #define MAX_VALUATOR_EVENTS 6 @@ -476,6 +481,7 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, * events is not NULL-terminated; the return value is the number of events. * The DDX is responsible for allocating the event structure in the first * place via GetMaximumEventsNum(), and for freeing it. + * */ _X_EXPORT int GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, @@ -487,8 +493,9 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, /* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies * with DeviceValuators. */ Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE); - DeviceIntPtr cp = inputInfo.pointer; + DeviceIntPtr pointer = NULL; int x = 0, y = 0; + /* The core pointer must not send Xi events. */ Bool coreOnly = (pDev == inputInfo.pointer); /* Sanity checks. */ @@ -498,7 +505,7 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, if ((type == ButtonPress || type == ButtonRelease) && !pDev->button) return 0; - if (!coreOnly && pDev->coreEvents) + if (!coreOnly && (pDev->coreEvents)) num_events = 2; else num_events = 1; @@ -522,6 +529,8 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, ms = GetTimeInMillis(); + pointer = pDev; + /* Set x and y based on whether this is absolute or relative, and * accelerate if we need to. */ if (flags & POINTER_ABSOLUTE) { @@ -529,20 +538,14 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, x = valuators[0]; } else { - if (pDev->coreEvents) - x = cp->valuator->lastx; - else - x = pDev->valuator->lastx; + x = pointer->valuator->lastx; } if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { y = valuators[1 - first_valuator]; } else { - if (pDev->coreEvents) - y = cp->valuator->lasty; - else - y = pDev->valuator->lasty; + y = pointer->valuator->lasty; } } else { @@ -550,28 +553,15 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, acceleratePointer(pDev, first_valuator, num_valuators, valuators); - if (pDev->coreEvents) { - if (first_valuator == 0 && num_valuators >= 1) - x = cp->valuator->lastx + valuators[0]; - else - x = cp->valuator->lastx; + if (first_valuator == 0 && num_valuators >= 1) + x = pointer->valuator->lastx + valuators[0]; + else + x = pointer->valuator->lastx; - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - y = cp->valuator->lasty + valuators[1 - first_valuator]; - else - y = cp->valuator->lasty; - } - else { - if (first_valuator == 0 && num_valuators >= 1) - x = pDev->valuator->lastx + valuators[0]; - else - x = pDev->valuator->lastx; - - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - y = pDev->valuator->lasty + valuators[1 - first_valuator]; - else - y = pDev->valuator->lasty; - } + if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) + y = pointer->valuator->lasty + valuators[1 - first_valuator]; + else + y = pointer->valuator->lasty; } /* Clip both x and y to the defined limits (usually co-ord space limit). */ @@ -592,13 +582,10 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators); - if (pDev->coreEvents) { - cp->valuator->lastx = x; - cp->valuator->lasty = y; - } pDev->valuator->lastx = x; pDev->valuator->lasty = y; + /* create Xi event */ if (!coreOnly) { kbp = (deviceKeyButtonPointer *) events; @@ -628,7 +615,6 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons, } } - /* for some reason inputInfo.pointer does not have coreEvents set */ if (coreOnly || pDev->coreEvents) { events->u.u.type = type; events->u.keyButtonPointer.time = ms; @@ -736,7 +722,7 @@ SwitchCoreKeyboard(DeviceIntPtr pDev) } #endif - SendMappingNotify(MappingKeyboard, ckeyc->curKeySyms.minKeyCode, + SendMappingNotify(pDev, MappingKeyboard, ckeyc->curKeySyms.minKeyCode, (ckeyc->curKeySyms.maxKeyCode - ckeyc->curKeySyms.minKeyCode), serverClient); @@ -766,7 +752,11 @@ SwitchCorePointer(DeviceIntPtr pDev) * to shift the pointer to get it inside the new bounds. */ void -PostSyntheticMotion(int x, int y, int screen, unsigned long time) +PostSyntheticMotion(DeviceIntPtr pDev, + int x, + int y, + int screen, + unsigned long time) { xEvent xE; @@ -786,5 +776,5 @@ PostSyntheticMotion(int x, int y, int screen, unsigned long time) xE.u.keyButtonPointer.rootY = y; xE.u.keyButtonPointer.time = time; - (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1); + (*pDev->public.processInputProc)(&xE, pDev, 1); } diff --git a/dix/window.c b/dix/window.c index 96002eb1f..4e553193e 100644 --- a/dix/window.c +++ b/dix/window.c @@ -110,6 +110,7 @@ Equipment Corporation. #include "validate.h" #include "windowstr.h" #include "input.h" +#include "inputstr.h" #include "resource.h" #include "colormapst.h" #include "cursorstr.h" @@ -135,12 +136,21 @@ Equipment Corporation. * GetWindowAttributes, DeleteWindow, DestroySubWindows, * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows, * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow, - * + * ChangeWindowDeviceCursor ******/ static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11}; static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88}; +static Bool WindowParentHasDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + CursorPtr pCurs); +static Bool +WindowSeekDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + DevCursNodePtr* pNode, + DevCursNodePtr* pPrev); + _X_EXPORT int screenIsSaved = SCREEN_SAVER_OFF; _X_EXPORT ScreenSaverStuffRec savedScreenInfo[MAXSCREENS]; @@ -436,7 +446,15 @@ CreateRootWindow(ScreenPtr pScreen) #endif #ifdef XINPUT pWin->optional->inputMasks = NULL; + pWin->optional->deviceCursors = NULL; #endif + + pWin->optional->access.perm = NULL; + pWin->optional->access.deny = NULL; + pWin->optional->access.nperm = 0; + pWin->optional->access.ndeny = 0; + pWin->optional->access.defaultRule = 0; + pWin->optional->colormap = pScreen->defColormap; pWin->optional->visual = pScreen->rootVisual; @@ -490,7 +508,6 @@ CreateRootWindow(ScreenPtr pScreen) if (disableSaveUnders) pScreen->saveUnderSupport = NotUseful; - return TRUE; } @@ -508,6 +525,7 @@ InitRootWindow(WindowPtr pWin) pWin->optional->cursor = rootCursor; rootCursor->refcnt++; + if (!blackRoot && !whiteRoot) { MakeRootTile(pWin); backFlag |= CWBackPixmap; @@ -847,6 +865,26 @@ DisposeWindowOptional (WindowPtr pWin) } else pWin->cursorIsNone = TRUE; + + if (pWin->optional->deviceCursors) + { + DevCursorList pList; + DevCursorList pPrev; + pList = pWin->optional->deviceCursors; + while(pList) + { + if (pList->cursor) + FreeCursor(pList->cursor, (XID)0); + pPrev = pList; + pList = pList->next; + xfree(pPrev); + } + pWin->optional->deviceCursors = NULL; + } + + xfree(pWin->optional->access.perm); + xfree(pWin->optional->access.deny); + xfree (pWin->optional); pWin->optional = NULL; } @@ -3640,6 +3678,20 @@ CheckWindowOptionalNeed (WindowPtr w) if (optional->inputMasks != NULL) return; #endif + if (optional->deviceCursors != NULL) + { + DevCursNodePtr pNode = optional->deviceCursors; + while(pNode) + { + if (pNode->cursor != None) + return; + pNode = pNode->next; + } + } + if (optional->access.nperm != 0 || + optional->access.ndeny != 0) + return; + parentOptional = FindWindowWithOptional(w)->optional; if (optional->visual != parentOptional->visual) return; @@ -3685,6 +3737,12 @@ MakeWindowOptional (WindowPtr pWin) #ifdef XINPUT optional->inputMasks = NULL; #endif + optional->deviceCursors = NULL; + optional->access.nperm = 0; + optional->access.ndeny = 0; + optional->access.perm = NULL; + optional->access.deny = NULL; + optional->access.defaultRule = 0; parentOptional = FindWindowWithOptional(pWin)->optional; optional->visual = parentOptional->visual; if (!pWin->cursorIsNone) @@ -3701,6 +3759,216 @@ MakeWindowOptional (WindowPtr pWin) return TRUE; } +/* + * Changes the cursor struct for the given device and the given window. + * A cursor that does not have a device cursor set will use whatever the + * standard cursor is for the window. If all devices have a cursor set, + * changing the window cursor (e.g. using XDefineCursor()) will not have any + * visible effect. Only when one of the device cursors is set to None again, + * this device's cursor will display the changed standard cursor. + * + * CursorIsNone of the window struct is NOT modified if you set a device + * cursor. + * + * Assumption: If there is a node for a device in the list, the device has a + * cursor. If the cursor is set to None, it is inherited by the parent. + */ +_X_EXPORT int +ChangeWindowDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + CursorPtr pCursor) +{ + DevCursNodePtr pNode, pPrev; + CursorPtr pOldCursor = NULL; + ScreenPtr pScreen; + WindowPtr pChild; + + if (!pWin->optional && !MakeWindowOptional(pWin)) + return BadAlloc; + + /* 1) Check if window has device cursor set + * Yes: 1.1) swap cursor with given cursor if parent does not have same + * cursor, free old cursor + * 1.2) free old cursor, use parent cursor + * No: 1.1) add node to beginning of list. + * 1.2) add cursor to node if parent does not have same cursor + * 1.3) use parent cursor if parent does not have same cursor + * 2) Patch up children if child has a devcursor + * 2.1) if child has cursor None, it inherited from parent, set to old + * cursor + * 2.2) if child has same cursor as new cursor, remove and set to None + */ + + pScreen = pWin->drawable.pScreen; + + if (WindowSeekDeviceCursor(pWin, pDev, &pNode, &pPrev)) + { + /* has device cursor */ + + if (pNode->cursor == pCursor) + return Success; + + pOldCursor = pNode->cursor; + + if (!pCursor) /* remove from list */ + { + pPrev->next = pNode->next; + xfree(pNode); + } + + } else + { + /* no device cursor yet */ + DevCursNodePtr pNewNode; + + if (!pCursor) + return Success; + + pNewNode = (DevCursNodePtr)xalloc(sizeof(DevCursNodeRec)); + pNewNode->dev = pDev; + pNewNode->next = pWin->optional->deviceCursors; + pWin->optional->deviceCursors = pNewNode; + pNode = pNewNode; + + } + + if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) + pNode->cursor = None; + else + { + pNode->cursor = pCursor; + pCursor->refcnt++; + } + + pNode = pPrev = NULL; + /* fix up children */ + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) + { + if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) + { + if (pNode->cursor == None) /* inherited from parent */ + { + pNode->cursor = pOldCursor; + pOldCursor->refcnt++; + } else if (pNode->cursor == pCursor) + { + pNode->cursor = None; + FreeCursor(pCursor, (Cursor)0); /* fix up refcnt */ + } + } + } + + if (pWin->realized) + WindowHasNewCursor(pWin); + + if (pOldCursor) + FreeCursor(pOldCursor, (Cursor)0); + + /* FIXME: We SHOULD check for an error value here XXX + (comment taken from ChangeWindowAttributes) */ + (*pScreen->ChangeWindowAttributes)(pWin, CWCursor); + + return Success; +} + +/* Get device cursor for given device or None if none is set */ +_X_EXPORT CursorPtr +WindowGetDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev) +{ + DevCursorList pList; + + if (!pWin->optional || !pWin->optional->deviceCursors) + return NULL; + + pList = pWin->optional->deviceCursors; + + while(pList) + { + if (pList->dev == pDev) + { + if (pList->cursor == None) /* inherited from parent */ + return WindowGetDeviceCursor(pWin->parent, pDev); + else + return pList->cursor; + } + pList = pList->next; + } + return NULL; +} + +/* Searches for a DevCursorNode for the given window and device. If one is + * found, return True and set pNode and pPrev to the node and to the node + * before the node respectively. Otherwise return False. + * If the device is the first in list, pPrev is set to NULL. + */ +static Bool +WindowSeekDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + DevCursNodePtr* pNode, + DevCursNodePtr* pPrev) +{ + DevCursorList pList; + + if (!pWin->optional) + return FALSE; + + pList = pWin->optional->deviceCursors; + + if (pList && pList->dev == pDev) + { + *pNode = pList; + *pPrev = NULL; + return TRUE; + } + + while(pList) + { + if (pList->next) + { + if (pList->next->dev == pDev) + { + *pNode = pList->next; + *pPrev = pList; + return TRUE; + } + } + pList = pList->next; + } + return FALSE; +} + +/* Return True if a parent has the same device cursor set or False if + * otherwise + */ +static Bool +WindowParentHasDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, + CursorPtr pCursor) +{ + WindowPtr pParent; + DevCursNodePtr pParentNode, pParentPrev; + + pParent = pWin->parent; + while(pParent) + { + if (WindowSeekDeviceCursor(pParent, pDev, + &pParentNode, &pParentPrev)) + { + /* if there is a node in the list, the win has a dev cursor */ + if (!pParentNode->cursor) /* inherited. loop needs to cont. */ + { + } else if (pParentNode->cursor == pCursor) /* inherit */ + return TRUE; + else /* different cursor */ + return FALSE; + } + else + /* parent does not have a device cursor for our device */ + return FALSE; + } + return FALSE; +} + #ifndef NOLOGOHACK static void DrawLogo(WindowPtr pWin) diff --git a/hw/kdrive/ati/ati_cursor.c b/hw/kdrive/ati/ati_cursor.c index e8c711707..082062d3d 100644 --- a/hw/kdrive/ati/ati_cursor.c +++ b/hw/kdrive/ati/ati_cursor.c @@ -28,9 +28,10 @@ #include "ati_reg.h" #include "cursorstr.h" #include "ati_draw.h" +#include "inputstr.h" static void -ATIMoveCursor(ScreenPtr pScreen, int x, int y) +ATIMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); @@ -360,7 +361,7 @@ ATIUnloadCursor(ScreenPtr pScreen) } static Bool -ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +ATIRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); @@ -375,26 +376,26 @@ ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) { int x, y; - miPointerPosition(&x, &y); + miPointerGetPosition(pDev, &x, &y); if (atic->is_radeon) RadeonLoadCursor (pScreen); else ClassicLoadCursor(pScreen); /* Move to new position */ - ATIMoveCursor(pScreen, x, y); + ATIMoveCursor(pDev, pScreen, x, y); } return TRUE; } static Bool -ATIUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +ATIUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { return TRUE; } static void -ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +ATISetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) { KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); @@ -413,7 +414,7 @@ ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) else ClassicLoadCursor(pScreen); /* Move to new position */ - ATIMoveCursor(pScreen, x, y); + ATIMoveCursor(pDev, pScreen, x, y); } else ATIUnloadCursor(pScreen); @@ -465,6 +466,7 @@ ATICursorSave(ScreenPtr pScreen, KdOffscreenArea *area) void ATICursorEnable(ScreenPtr pScreen) { + DeviceIntPtr pDev = inputInfo.pointer; KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); ATIScreenInfo(pScreenPriv); @@ -489,13 +491,13 @@ ATICursorEnable(ScreenPtr pScreen) if (pCurPriv->pCursor) { int x, y; - miPointerPosition(&x, &y); + miPointerGetPosition(pDev, &x, &y); if (atic->is_radeon) RadeonLoadCursor(pScreen); else ClassicLoadCursor(pScreen); /* Move to new position */ - ATIMoveCursor(pScreen, x, y); + ATIMoveCursor(pDev, pScreen, x, y); } else ATIUnloadCursor(pScreen); diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index 45e2d3067..4a212e304 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -151,25 +151,25 @@ OsVendorInit (void) /* 'Fake' cursor stuff, could be improved */ static Bool -ephyrRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +ephyrRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { return TRUE; } static Bool -ephyrUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +ephyrUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { return TRUE; } static void -ephyrSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +ephyrSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) { ; } static void -ephyrMoveCursor(ScreenPtr pScreen, int x, int y) +ephyrMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { ; } diff --git a/hw/kdrive/i810/i810_cursor.c b/hw/kdrive/i810/i810_cursor.c index cf4f717f2..d361bf077 100644 --- a/hw/kdrive/i810/i810_cursor.c +++ b/hw/kdrive/i810/i810_cursor.c @@ -78,6 +78,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "kxv.h" #include "i810.h" #include "cursorstr.h" +#include "inputstr.h" #define SetupCursor(s) KdScreenPriv(pScreen); \ i810CardInfo(pScreenPriv); \ @@ -129,7 +130,7 @@ _i810MoveCursor(ScreenPtr pScreen, int x, int y) static void i810LoadCursor(ScreenPtr pScreen, int x, int y); static void -i810MoveCursor (ScreenPtr pScreen, int x, int y) +i810MoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { KdScreenPriv(pScreen); i810ScreenInfo(pScreenPriv); @@ -281,7 +282,7 @@ i810UnloadCursor(ScreenPtr pScreen) static Bool -i810RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +i810RealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { KdScreenPriv(pScreen); i810ScreenInfo(pScreenPriv); @@ -297,7 +298,7 @@ i810RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) { int x, y; - miPointerPosition (&x, &y); + miPointerGetPosition (pDev, &x, &y); i810LoadCursor (pScreen, x, y); } } @@ -305,13 +306,13 @@ i810RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) } static Bool -i810UnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +i810UnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { return TRUE; } static void -i810SetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +i810SetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) { KdScreenPriv(pScreen); i810ScreenInfo(pScreenPriv); diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 857f04f6d..20440dc2c 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -2219,11 +2219,11 @@ KdCrossScreen(ScreenPtr pScreen, Bool entering) int KdCurScreen; /* current event screen */ static void -KdWarpCursor (ScreenPtr pScreen, int x, int y) +KdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { KdBlockSigio (); KdCurScreen = pScreen->myNum; - miPointerWarpCursor (pScreen, x, y); + miPointerWarpCursor(pDev, pScreen, x, y); KdUnblockSigio (); } @@ -2238,7 +2238,7 @@ void ProcessInputEvents () { mieqProcessInputEvents(); - miPointerUpdate(); + miPointerUpdateSprite(inputInfo.pointer); if (kdSwitchPending) KdProcessSwitch (); KdCheckLock (); diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 4db844e19..66e6b055b 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -2459,8 +2459,6 @@ xf86HandleConfigFile(Bool autoconfig) return CONFIG_PARSE_ERROR; } - checkInput(&xf86ConfigLayout); - /* * Handle some command line options that can override some of the * ServerFlags settings. diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c index 46d812804..bbd6124af 100644 --- a/hw/xfree86/common/xf86Cursor.c +++ b/hw/xfree86/common/xf86Cursor.c @@ -69,7 +69,7 @@ typedef struct { static Bool xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y); static void xf86CrossScreen(ScreenPtr pScreen, Bool entering); -static void xf86WarpCursor(ScreenPtr pScreen, int x, int y); +static void xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y); static void xf86PointerMoved(int scrnIndex, int x, int y); @@ -269,7 +269,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode) (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0); if (pScreen == pCursorScreen) - xf86WarpCursor(pScreen, px, py); + xf86WarpCursor(inputInfo.pointer, pScreen, px, py); return Switched; } @@ -430,13 +430,13 @@ xf86CrossScreen (ScreenPtr pScreen, Bool entering) /* ARGSUSED */ static void -xf86WarpCursor (ScreenPtr pScreen, int x, int y) +xf86WarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { int sigstate; sigstate = xf86BlockSIGIO (); - miPointerWarpCursor(pScreen,x,y); + miPointerWarpCursor(pDev, pScreen, x, y); - xf86Info.currentScreen = pScreen; + xf86Info.currentScreen = pScreen; xf86UnblockSIGIO (sigstate); } diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c index 43db1ee1a..e588e9a8f 100644 --- a/hw/xfree86/common/xf86DGA.c +++ b/hw/xfree86/common/xf86DGA.c @@ -1117,9 +1117,11 @@ DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd) else { /* If the keyboard is actively grabbed, deliver a grabbed core event */ - if (keybd->grab && !keybd->fromPassiveGrab) + if (keybd->coreGrab.grab && !keybd->coreGrab.fromPassiveGrab) { - core.u.u.type = coreEquiv; + /* I've got no clue if that is correct but only working on core + * grabs seems the right thing here. (whot) */ + core.u.u.type = coreEquiv; core.u.u.detail = de->u.u.detail; core.u.keyButtonPointer.time = de->u.event.time; core.u.keyButtonPointer.eventX = de->u.event.dx; @@ -1196,8 +1198,10 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse) else { /* If the pointer is actively grabbed, deliver a grabbed core event */ - if (mouse->grab && !mouse->fromPassiveGrab) + if (mouse->coreGrab.grab && !mouse->coreGrab.fromPassiveGrab) { + /* I've got no clue if that is correct but only working on core + * grabs seems the right thing here. (whot) */ core.u.u.type = coreEquiv; core.u.u.detail = de->u.u.detail; core.u.keyButtonPointer.time = de->u.event.time; diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 3610c17c0..84588996d 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -246,8 +246,8 @@ ProcessInputEvents () xf86Info.inputPending = FALSE; mieqProcessInputEvents(); - miPointerUpdateSprite(inputInfo.pointer); + /* FIXME: This is a problem if we have multiple pointers */ miPointerGetPosition(inputInfo.pointer, &x, &y); xf86SetViewport(xf86Info.currentScreen, x, y); } @@ -290,12 +290,13 @@ xf86ProcessActionEvent(ActionEvent action, void *arg) break; case ACTION_DISABLEGRAB: if (!xf86Info.grabInfo.disabled && xf86Info.grabInfo.allowDeactivate) { - if (inputInfo.pointer && inputInfo.pointer->grab != NULL && - inputInfo.pointer->DeactivateGrab) - inputInfo.pointer->DeactivateGrab(inputInfo.pointer); - if (inputInfo.keyboard && inputInfo.keyboard->grab != NULL && - inputInfo.keyboard->DeactivateGrab) - inputInfo.keyboard->DeactivateGrab(inputInfo.keyboard); + if (inputInfo.pointer && inputInfo.pointer->coreGrab.grab != NULL && + inputInfo.pointer->coreGrab.DeactivateGrab) + inputInfo.pointer->coreGrab.DeactivateGrab(inputInfo.pointer); + if (inputInfo.keyboard && + inputInfo.keyboard->coreGrab.grab != NULL && + inputInfo.keyboard->coreGrab.DeactivateGrab) + inputInfo.keyboard->coreGrab.DeactivateGrab(inputInfo.keyboard); } break; case ACTION_CLOSECLIENT: @@ -303,10 +304,11 @@ xf86ProcessActionEvent(ActionEvent action, void *arg) ClientPtr pointer, keyboard, server; pointer = keyboard = server = NULL; - if (inputInfo.pointer && inputInfo.pointer->grab != NULL) - pointer = clients[CLIENT_ID(inputInfo.pointer->grab->resource)]; - if (inputInfo.keyboard && inputInfo.keyboard->grab != NULL) { - keyboard = clients[CLIENT_ID(inputInfo.keyboard->grab->resource)]; + if (inputInfo.pointer && inputInfo.pointer->coreGrab.grab != NULL) + pointer = clients[CLIENT_ID(inputInfo.pointer->coreGrab.grab->resource)]; + if (inputInfo.keyboard && inputInfo.keyboard->coreGrab.grab != NULL) + { + keyboard = clients[CLIENT_ID(inputInfo.keyboard->coreGrab.grab->resource)]; if (keyboard == pointer) keyboard = NULL; } diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c index 288d72193..87d5a364b 100644 --- a/hw/xfree86/common/xf86RandR.c +++ b/hw/xfree86/common/xf86RandR.c @@ -34,6 +34,7 @@ #include "xf86DDC.h" #include "mipointer.h" #include <randrstr.h> +#include "inputstr.h" typedef struct _xf86RandRInfo { CreateScreenResourcesProcPtr CreateScreenResources; @@ -291,7 +292,7 @@ xf86RandRSetConfig (ScreenPtr pScreen, xf86SetViewport(pScreen, px, py); - (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE); + (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE); } return TRUE; diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 17ffed899..cc98a0cb2 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -47,6 +47,15 @@ */ /* $XConsortium: xf86Xinput.c /main/14 1996/10/27 11:05:25 kaleb $ */ + /* + * MPX additions: + * Copyright © 2006 Peter Hutterer + * License see above. + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + * + */ + + #ifdef HAVE_XORG_CONFIG_H #include <xorg-config.h> #endif @@ -119,7 +128,7 @@ _X_EXPORT void xf86ProcessCommonOptions(LocalDevicePtr local, pointer list) { - if (!xf86SetBoolOption(list, "AlwaysCore", 0) || + if (xf86SetBoolOption(list, "AlwaysCore", 0) || xf86SetBoolOption(list, "SendCoreEvents", 0) || xf86SetBoolOption(list, "CorePointer", 0) || xf86SetBoolOption(list, "CoreKeyboard", 0)) { @@ -127,6 +136,11 @@ xf86ProcessCommonOptions(LocalDevicePtr local, xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name); } + if (xf86SetBoolOption(list, "SharedPointer", 0)) { + local->flags |= XI86_SHARED_POINTER; + xf86Msg(X_CONFIG, "%s: is shared device\n", local->name); + } + if (xf86SetBoolOption(list, "SendDragEvents", 1)) { local->flags |= XI86_SEND_DRAG_EVENTS; } else { @@ -163,7 +177,22 @@ xf86ActivateDevice(LocalDevicePtr local) dev->public.devicePrivate = (pointer) local; local->dev = dev; - dev->coreEvents = local->flags & XI86_ALWAYS_CORE; + dev->coreEvents = local->flags & XI86_ALWAYS_CORE; + dev->spriteInfo->spriteOwner = !(local->flags & XI86_SHARED_POINTER); + +#ifdef XKB + if (!DeviceIsPointerType(dev)) + { + /* FIXME: that's not the nice way to do it. XKB wraps the previously + * set procs, so if we don't have them here, our event will disappear + * in a black hole.*/ + dev->public.processInputProc = CoreProcessKeyboardEvent; + dev->public.realInputProc = CoreProcessKeyboardEvent; + if (!noXkbExtension) + XkbSetExtension(dev, ProcessKeyboardEvent); + } +#endif + RegisterOtherDevice(dev); if (serverGeneration == 1) @@ -353,6 +382,16 @@ NewInputDeviceRequest (InputOption *options) } } + if (!drv) { + xf86Msg(X_ERROR, "No input driver specified (ignoring)\n"); + return BadMatch; + } + + if (!idev->identifier) { + xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n"); + return BadMatch; + } + if (!drv->PreInit) { xf86Msg(X_ERROR, "Input driver `%s' has no PreInit function (ignoring)\n", @@ -382,10 +421,16 @@ NewInputDeviceRequest (InputOption *options) xf86ActivateDevice(pInfo); dev = pInfo->dev; - dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); + ActivateDevice(dev); if (dev->inited && dev->startup) EnableDevice(dev); + if (!IsPointerDevice(dev)) + PairDevices(NULL, GuessFreePointerDevice(), dev); + + /* send enter/leave event, update sprite window */ + CheckMotion(NULL, dev); + return Success; } @@ -413,7 +458,7 @@ xf86PostMotionEvent(DeviceIntPtr device, flags = POINTER_ABSOLUTE; else flags = POINTER_RELATIVE | POINTER_ACCELERATE; - + valuators = xcalloc(sizeof(int), num_valuators); va_start(var, num_valuators); @@ -513,7 +558,6 @@ xf86PostButtonEvent(DeviceIntPtr device, return; } #endif - valuators = xcalloc(sizeof(int), num_valuators); va_start(var, num_valuators); @@ -528,8 +572,7 @@ xf86PostButtonEvent(DeviceIntPtr device, nevents = GetPointerEvents(xf86Events, device, is_down ? ButtonPress : ButtonRelease, button, - is_absolute ? POINTER_ABSOLUTE : - POINTER_RELATIVE, + (is_absolute) ? POINTER_ABSOLUTE : POINTER_RELATIVE, first_valuator, num_valuators, valuators); for (i = 0; i < nevents; i++) diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h index b2bc8dec1..60f9ec337 100644 --- a/hw/xfree86/common/xf86Xinput.h +++ b/hw/xfree86/common/xf86Xinput.h @@ -82,6 +82,7 @@ #define XI86_CORE_KEYBOARD 0x20 /* device is the core keyboard */ #define XI86_POINTER_CAPABLE 0x40 /* capable of being a core pointer */ #define XI86_KEYBOARD_CAPABLE 0x80 /* capable of being a core keyboard */ +#define XI86_SHARED_POINTER 0x100 /* device shares core cursor */ #define XI_PRIVATE(dev) \ (((LocalDevicePtr)((dev)->public.devicePrivate))->private) diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index 7bd07c003..05df54aec 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -70,6 +70,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mi.h" #include "mipointer.h" #include "xf86_OSproc.h" +#include "inputstr.h" #define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu) @@ -2100,7 +2101,7 @@ DRIAdjustFrame(int scrnIndex, int x, int y, int flags) if (px > pScrn->frameX1) px = pScrn->frameX1; if (py < pScrn->frameY0) py = pScrn->frameY0; if (py > pScrn->frameY1) py = pScrn->frameY1; - pScreen->SetCursorPosition(pScreen, px, py, TRUE); + pScreen->SetCursorPosition(inputInfo.pointer, pScreen, px, py, TRUE); return; } diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 009cccf89..15641822d 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -45,6 +45,7 @@ #include "picturestr.h" #endif #include "cursorstr.h" +#include "inputstr.h" /* * Given a screen coordinate, rotate back to a cursor source coordinate @@ -566,7 +567,7 @@ xf86_reload_cursors (ScreenPtr screen) return; cursor = xf86_config->cursor; - GetSpritePosition (&x, &y); + GetSpritePosition (inputInfo.pointer, &x, &y); if (!(cursor_info->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) (*cursor_info->HideCursor)(scrn); diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 6f52ee2d9..13437a5a5 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -40,6 +40,7 @@ #include "xf86DDC.h" #include "mipointer.h" #include "windowstr.h" +#include "inputstr.h" #include <randrstr.h> #include <X11/extensions/render.h> @@ -266,7 +267,7 @@ xf86RandR12SetConfig (ScreenPtr pScreen, randrp->virtualY = scrp->virtualY; } - miPointerPosition (&px, &py); + miPointerGetPosition (inputInfo.pointer, &px, &py); for (mode = scrp->modes; ; mode = mode->next) { if (randrp->maxX == 0 || randrp->maxY == 0) @@ -313,14 +314,14 @@ xf86RandR12SetConfig (ScreenPtr pScreen, /* * Move the cursor back where it belongs; SwitchMode repositions it */ - if (pScreen == miPointerCurrentScreen ()) + if (pScreen == miPointerGetScreen(inputInfo.pointer)) { px = (px >= pScreen->width ? (pScreen->width - 1) : px); py = (py >= pScreen->height ? (pScreen->height - 1) : py); xf86SetViewport(pScreen, px, py); - (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE); + (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE); } return TRUE; diff --git a/hw/xfree86/os-support/linux/lnx_agp.c b/hw/xfree86/os-support/linux/lnx_agp.c index ded9e0fae..300b08df6 100644 --- a/hw/xfree86/os-support/linux/lnx_agp.c +++ b/hw/xfree86/os-support/linux/lnx_agp.c @@ -10,6 +10,7 @@ #ifdef HAVE_XORG_CONFIG_H #include <xorg-config.h> +#include <linux/types.h> #endif #include <X11/X.h> diff --git a/hw/xfree86/rac/xf86RAC.c b/hw/xfree86/rac/xf86RAC.c index aba86226e..022f4748e 100644 --- a/hw/xfree86/rac/xf86RAC.c +++ b/hw/xfree86/rac/xf86RAC.c @@ -154,13 +154,16 @@ static PixmapPtr RACCreatePixmap(ScreenPtr pScreen, int w, int h, int depth); static Bool RACCreateGC(GCPtr pGC); static Bool RACSaveScreen(ScreenPtr pScreen, Bool unblank); static void RACStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs); -static void RACRecolorCursor (ScreenPtr pScreen, CursorPtr pCurs, - Bool displayed); -static Bool RACRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor); -static Bool RACUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor); -static Bool RACDisplayCursor (ScreenPtr pScreen, CursorPtr pCursor); -static Bool RACSetCursorPosition (ScreenPtr pScreen, int x, int y, - Bool generateEvent); +static void RACRecolorCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCurs, Bool displayed); +static Bool RACRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool RACUnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool RACDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool RACSetCursorPosition (DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, Bool generateEvent); static void RACAdjustFrame(int index, int x, int y, int flags); static Bool RACSwitchMode(int index, DisplayModePtr mode, int flags); static Bool RACEnterVT(int index, int flags); @@ -224,11 +227,14 @@ static void RACPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit, static void RACPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg ); /* miSpriteFuncs */ -static Bool RACSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCur); -static Bool RACSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCur); -static void RACSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCur, - int x, int y); -static void RACSpriteMoveCursor(ScreenPtr pScreen, int x, int y); +static Bool RACSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCur); +static Bool RACSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCur); +static void RACSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCur, int x, int y); +static void RACSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y); #ifdef RENDER static void RACComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, @@ -583,6 +589,7 @@ RACStoreColors ( static void RACRecolorCursor ( + DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, Bool displayed @@ -591,15 +598,16 @@ RACRecolorCursor ( DPRINT_S("RACRecolorCursor",pScreen->myNum); SCREEN_PROLOG (RecolorCursor); ENABLE; - (*pScreen->RecolorCursor) (pScreen,pCurs,displayed); + (*pScreen->RecolorCursor) (pDev, pScreen,pCurs,displayed); SCREEN_EPILOG ( RecolorCursor, RACRecolorCursor); } static Bool RACRealizeCursor ( - ScreenPtr pScreen, - CursorPtr pCursor + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor ) { Bool val; @@ -607,7 +615,7 @@ RACRealizeCursor ( DPRINT_S("RACRealizeCursor",pScreen->myNum); SCREEN_PROLOG (RealizeCursor); ENABLE; - val = (*pScreen->RealizeCursor) (pScreen,pCursor); + val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor); SCREEN_EPILOG ( RealizeCursor, RACRealizeCursor); return val; @@ -615,8 +623,9 @@ RACRealizeCursor ( static Bool RACUnrealizeCursor ( - ScreenPtr pScreen, - CursorPtr pCursor + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor ) { Bool val; @@ -624,7 +633,7 @@ RACUnrealizeCursor ( DPRINT_S("RACUnrealizeCursor",pScreen->myNum); SCREEN_PROLOG (UnrealizeCursor); ENABLE; - val = (*pScreen->UnrealizeCursor) (pScreen,pCursor); + val = (*pScreen->UnrealizeCursor) (pDev, pScreen,pCursor); SCREEN_EPILOG ( UnrealizeCursor, RACUnrealizeCursor); return val; @@ -632,8 +641,9 @@ RACUnrealizeCursor ( static Bool RACDisplayCursor ( - ScreenPtr pScreen, - CursorPtr pCursor + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor ) { Bool val; @@ -641,7 +651,7 @@ RACDisplayCursor ( DPRINT_S("RACDisplayCursor",pScreen->myNum); SCREEN_PROLOG (DisplayCursor); ENABLE; - val = (*pScreen->DisplayCursor) (pScreen,pCursor); + val = (*pScreen->DisplayCursor) (pDev, pScreen,pCursor); SCREEN_EPILOG ( DisplayCursor, RACDisplayCursor); return val; @@ -649,6 +659,7 @@ RACDisplayCursor ( static Bool RACSetCursorPosition ( + DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, Bool generateEvent) @@ -658,7 +669,7 @@ RACSetCursorPosition ( DPRINT_S("RACSetCursorPosition",pScreen->myNum); SCREEN_PROLOG (SetCursorPosition); ENABLE; - val = (*pScreen->SetCursorPosition) (pScreen,x,y,generateEvent); + val = (*pScreen->SetCursorPosition) (pDev, pScreen,x,y,generateEvent); SCREEN_EPILOG ( SetCursorPosition, RACSetCursorPosition); return val; @@ -1158,46 +1169,47 @@ RACPushPixels( /* miSpriteFuncs */ static Bool -RACSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCur) +RACSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur) { Bool val; SPRITE_PROLOG; DPRINT_S("RACSpriteRealizeCursor",pScreen->myNum); ENABLE; - val = PointPriv->spriteFuncs->RealizeCursor(pScreen, pCur); + val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur); SPRITE_EPILOG; return val; } static Bool -RACSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCur) +RACSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur) { Bool val; SPRITE_PROLOG; DPRINT_S("RACSpriteUnrealizeCursor",pScreen->myNum); ENABLE; - val = PointPriv->spriteFuncs->UnrealizeCursor(pScreen, pCur); + val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur); SPRITE_EPILOG; return val; } static void -RACSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCur, int x, int y) +RACSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCur, int x, int y) { SPRITE_PROLOG; DPRINT_S("RACSpriteSetCursor",pScreen->myNum); ENABLE; - PointPriv->spriteFuncs->SetCursor(pScreen, pCur, x, y); + PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y); SPRITE_EPILOG; } static void -RACSpriteMoveCursor(ScreenPtr pScreen, int x, int y) +RACSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { SPRITE_PROLOG; DPRINT_S("RACSpriteMoveCursor",pScreen->myNum); ENABLE; - PointPriv->spriteFuncs->MoveCursor(pScreen, x, y); + PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y); SPRITE_EPILOG; } diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c index 457807698..c968f185f 100644 --- a/hw/xfree86/ramdac/xf86Cursor.c +++ b/hw/xfree86/ramdac/xf86Cursor.c @@ -8,15 +8,25 @@ #include "colormapst.h" #include "cursorstr.h" +/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for + * MPX. + * inputInfo is needed to pass the core pointer as the default argument into + * the cursor functions. + * + * Externing inputInfo is not the nice way to do it but it works. + */ +#include "inputstr.h" +extern InputInfo inputInfo; + int xf86CursorScreenIndex = -1; static unsigned long xf86CursorGeneration = 0; /* sprite functions */ -static Bool xf86CursorRealizeCursor(ScreenPtr, CursorPtr); -static Bool xf86CursorUnrealizeCursor(ScreenPtr, CursorPtr); -static void xf86CursorSetCursor(ScreenPtr, CursorPtr, int, int); -static void xf86CursorMoveCursor(ScreenPtr, int, int); +static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr); +static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr); +static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int); +static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int); static miPointerSpriteFuncRec xf86CursorSpriteFuncs = { xf86CursorRealizeCursor, @@ -28,7 +38,7 @@ static miPointerSpriteFuncRec xf86CursorSpriteFuncs = { /* Screen functions */ static void xf86CursorInstallColormap(ColormapPtr); -static void xf86CursorRecolorCursor(ScreenPtr, CursorPtr, Bool); +static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr, Bool); static Bool xf86CursorCloseScreen(int, ScreenPtr); static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*, ScreenPtr); @@ -171,6 +181,7 @@ xf86CursorInstallColormap(ColormapPtr pMap) static void xf86CursorRecolorCursor( + DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) @@ -182,7 +193,7 @@ xf86CursorRecolorCursor( return; if (ScreenPriv->SWCursor) - (*ScreenPriv->RecolorCursor)(pScreen, pCurs, displayed); + (*ScreenPriv->RecolorCursor)(pDev, pScreen, pCurs, displayed); else xf86RecolorCursor(pScreen, pCurs, displayed); } @@ -194,14 +205,17 @@ xf86CursorEnableDisableFBAccess( int index, Bool enable) { + DeviceIntPtr pDev = inputInfo.pointer; + ScreenPtr pScreen = screenInfo.screens[index]; xf86CursorScreenPtr ScreenPriv = pScreen->devPrivates[xf86CursorScreenIndex].ptr; if (!enable && ScreenPriv->CurrentCursor != NullCursor) { - CursorPtr currentCursor = ScreenPriv->CurrentCursor; - xf86CursorSetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y); - ScreenPriv->isUp = FALSE; + CursorPtr currentCursor = ScreenPriv->CurrentCursor; + xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x, + ScreenPriv->y); + ScreenPriv->isUp = FALSE; ScreenPriv->SWCursor = TRUE; ScreenPriv->SavedCursor = currentCursor; } @@ -215,7 +229,7 @@ xf86CursorEnableDisableFBAccess( * Re-set current cursor so drivers can react to FB access having been * temporarily disabled. */ - xf86CursorSetCursor(pScreen, ScreenPriv->SavedCursor, + xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor, ScreenPriv->x, ScreenPriv->y); ScreenPriv->SavedCursor = NULL; } @@ -252,7 +266,7 @@ xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags) /****** miPointerSpriteFunctions *******/ static Bool -xf86CursorRealizeCursor(ScreenPtr pScreen, CursorPtr pCurs) +xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs) { xf86CursorScreenPtr ScreenPriv = pScreen->devPrivates[xf86CursorScreenIndex].ptr; @@ -260,11 +274,12 @@ xf86CursorRealizeCursor(ScreenPtr pScreen, CursorPtr pCurs) if (pCurs->refcnt <= 1) pCurs->devPriv[pScreen->myNum] = NULL; - return (*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCurs); + return (*ScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs); } static Bool -xf86CursorUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCurs) +xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCurs) { xf86CursorScreenPtr ScreenPriv = pScreen->devPrivates[xf86CursorScreenIndex].ptr; @@ -274,11 +289,12 @@ xf86CursorUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCurs) pCurs->devPriv[pScreen->myNum] = NULL; } - return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCurs); + return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs); } static void -xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) +xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, + int x, int y) { xf86CursorScreenPtr ScreenPriv = pScreen->devPrivates[xf86CursorScreenIndex].ptr; @@ -295,8 +311,10 @@ xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */ if (ScreenPriv->SWCursor) - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, NullCursor, x, y); - else if (ScreenPriv->isUp) { + (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, + x, y); + else if + (ScreenPriv->isUp) { xf86SetCursor(pScreen, NullCursor, x, y); ScreenPriv->isUp = FALSE; } @@ -320,7 +338,7 @@ xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) { if (ScreenPriv->SWCursor) /* remove the SW cursor */ - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, NullCursor, x, y); + (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y); xf86SetCursor(pScreen, pCurs, x, y); ScreenPriv->SWCursor = FALSE; @@ -345,11 +363,11 @@ xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent) pCurs = NullCursor; - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCurs, x, y); + (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y); } static void -xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y) +xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { xf86CursorScreenPtr ScreenPriv = pScreen->devPrivates[xf86CursorScreenIndex].ptr; @@ -358,10 +376,10 @@ xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y) ScreenPriv->y = y; if (ScreenPriv->CursorToRestore) - xf86CursorSetCursor(pScreen, ScreenPriv->CursorToRestore, + xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, ScreenPriv->x, ScreenPriv->y); else if (ScreenPriv->SWCursor) - (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y); + (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y); else if (ScreenPriv->isUp) xf86MoveCursor(pScreen, x, y); } @@ -369,6 +387,8 @@ xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y) void xf86ForceHWCursor (ScreenPtr pScreen, Bool on) { + DeviceIntPtr pDev = inputInfo.pointer; + xf86CursorScreenPtr ScreenPriv = pScreen->devPrivates[xf86CursorScreenIndex].ptr; @@ -379,7 +399,7 @@ xf86ForceHWCursor (ScreenPtr pScreen, Bool on) if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor) { ScreenPriv->HWCursorForced = TRUE; - xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor, + xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor, ScreenPriv->x, ScreenPriv->y); } else @@ -391,7 +411,7 @@ xf86ForceHWCursor (ScreenPtr pScreen, Bool on) if (--ScreenPriv->ForceHWCursorCount == 0) { if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor) - xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor, + xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor, ScreenPriv->x, ScreenPriv->y); } } diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c index 91caea047..2dfc4b27b 100644 --- a/hw/xfree86/ramdac/xf86HWCurs.c +++ b/hw/xfree86/ramdac/xf86HWCurs.c @@ -73,6 +73,10 @@ static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr); Bool xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) { + /* Graphics cards cannot render multiple cursors in hardware. We have to + software render them. */ + return FALSE; + if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0)) return FALSE; diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index a20924128..8f794edcc 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -25,6 +25,7 @@ is" without express or implied warranty. #include "scrnintstr.h" #include "windowstr.h" #include "servermd.h" +#include "inputstr.h" #include "mi.h" @@ -183,7 +184,7 @@ xnestCollectEvents() if (X.xcrossing.detail != NotifyInferior) { pScreen = xnestScreen(X.xcrossing.window); if (pScreen) { - NewCurrentScreen(pScreen, X.xcrossing.x, X.xcrossing.y); + NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y); valuators[0] = X.xcrossing.x; valuators[1] = X.xcrossing.y; lastEventTime = GetTimeInMillis(); diff --git a/include/cursor.h b/include/cursor.h index bdf4fd301..e51394cb5 100644 --- a/include/cursor.h +++ b/include/cursor.h @@ -59,6 +59,8 @@ SOFTWARE. #define ARGB_CURSOR #endif +struct _DeviceIntRec; + typedef struct _Cursor *CursorPtr; typedef struct _CursorMetric *CursorMetricPtr; @@ -129,18 +131,20 @@ extern void CheckCursorConfinement( WindowPtr /*pWin*/); extern void NewCurrentScreen( + struct _DeviceIntRec* /*pDev*/, ScreenPtr /*newScreen*/, int /*x*/, int /*y*/); -extern Bool PointerConfinedToScreen(void); +extern Bool PointerConfinedToScreen(struct _DeviceIntRec* /* pDev */); extern void GetSpritePosition( + struct _DeviceIntRec* /* pDev */, int * /*px*/, int * /*py*/); #ifdef PANORAMIX -extern int XineramaGetCursorScreen(void); +extern int XineramaGetCursorScreen(struct _DeviceIntRec* pDev); #endif /* PANORAMIX */ #endif /* CURSOR_H */ diff --git a/include/dix.h b/include/dix.h index 2d452d1c7..2ad6c77fa 100644 --- a/include/dix.h +++ b/include/dix.h @@ -345,6 +345,13 @@ extern void SetMaskForEvent( Mask /* mask */, int /* event */); +#ifdef SHAPE +extern void ConfineToShape( + DeviceIntPtr /* pDev */, + RegionPtr /* shape */, + int* /* px */, + int* /* py */); +#endif extern Bool IsParent( WindowPtr /* maybeparent */, @@ -352,7 +359,7 @@ extern Bool IsParent( extern WindowPtr GetCurrentRootWindow(void); -extern WindowPtr GetSpriteWindow(void); +extern WindowPtr GetSpriteWindow(DeviceIntPtr pDev); extern void NoticeEventTime(xEventPtr /* xE */); @@ -391,12 +398,14 @@ extern void AllowSome( ClientPtr /* client */, TimeStamp /* time */, DeviceIntPtr /* thisDev */, - int /* newState */); + int /* newState */, + Bool /* core */); extern void ReleaseActiveGrabs( ClientPtr client); extern int DeliverEventsToWindow( + DeviceIntPtr /* pWin */, WindowPtr /* pWin */, xEventPtr /* pEvents */, int /* count */, @@ -415,6 +424,10 @@ extern int DeliverDeviceEvents( extern void DefineInitialRootWindow( WindowPtr /* win */); +extern void InitializeSprite( + DeviceIntPtr /* pDev */, + WindowPtr /* pWin */); + extern void WindowHasNewCursor( WindowPtr /* pWin */); @@ -475,6 +488,10 @@ extern int GrabDevice( CARD8 * /* status */); extern void InitEvents(void); +extern void InitSprite( + DeviceIntPtr /* pDev */, + Bool /* hasCursor */ + ); extern void CloseDownEvents(void); @@ -495,6 +512,10 @@ extern int DeliverEvents( int /*count*/, WindowPtr /*otherParent*/); +extern Bool +CheckMotion( + xEvent* /* xE */, + DeviceIntPtr /* pDev */); extern void WriteEventsToClient( ClientPtr /*pClient*/, @@ -511,6 +532,22 @@ extern int TryClientEvents( extern void WindowsRestructured(void); +extern Bool SetClientPointer( + ClientPtr /* client */, + ClientPtr /* setter */, + DeviceIntPtr /* device */); + +extern DeviceIntPtr PickPointer( + ClientPtr /* client */); + +extern DeviceIntPtr PickKeyboard( + ClientPtr /* client */); + +extern Bool IsInterferingGrab( + ClientPtr /* client */, + DeviceIntPtr /* dev */, + xEvent* /* events */); + #ifdef PANORAMIX extern void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff); #endif @@ -643,4 +680,9 @@ extern int xstrcasecmp(char *s1, char *s2); /* ffs.c */ extern int ffs(int i); +extern Bool DevHasCursor(DeviceIntPtr pDev); + +extern Bool IsPointerDevice( DeviceIntPtr dev); +extern Bool IsKeyboardDevice(DeviceIntPtr dev); + #endif /* DIX_H */ diff --git a/include/dixevents.h b/include/dixevents.h index 62c867277..21d16a2de 100644 --- a/include/dixevents.h +++ b/include/dixevents.h @@ -28,7 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern void SetCriticalEvent(int /* event */); -extern CursorPtr GetSpriteCursor(void); +extern CursorPtr GetSpriteCursor(DeviceIntPtr /*pDev*/); extern int ProcAllowEvents(ClientPtr /* client */); @@ -103,7 +103,11 @@ extern int ProcUngrabButton(ClientPtr /* client */); extern int ProcRecolorCursor(ClientPtr /* client */); #ifdef PANORAMIX -extern void PostSyntheticMotion(int x, int y, int screen, unsigned long time); +extern void PostSyntheticMotion(DeviceIntPtr pDev, + int x, + int y, + int screen, + unsigned long time); #endif #endif /* DIXEVENTS_H */ 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/extinit.h b/include/extinit.h index e616b6d93..d008651ce 100644 --- a/include/extinit.h +++ b/include/extinit.h @@ -37,6 +37,11 @@ XInputExtensionInit( void ); +Bool +DeviceIsPointerType( + DeviceIntPtr dev + ); + void AssignTypeAndName ( DeviceIntPtr /* dev */, diff --git a/include/input.h b/include/input.h index fc607d35b..765d71dc3 100644 --- a/include/input.h +++ b/include/input.h @@ -323,6 +323,7 @@ extern Bool InitKeyboardDeviceStruct( KbdCtrlProcPtr /*controlProc*/); extern void SendMappingNotify( + DeviceIntPtr /* pDev */, unsigned int /*request*/, unsigned int /*firstKeyCode*/, unsigned int /*count*/, @@ -419,6 +420,7 @@ extern int GetProximityEvents( int *valuators); extern void PostSyntheticMotion( + DeviceIntPtr pDev, int x, int y, int screen, @@ -443,6 +445,42 @@ extern void SwitchCorePointer(DeviceIntPtr pDev); extern DeviceIntPtr LookupDeviceIntRec( CARD8 deviceid); +/* Pairing input devices */ +extern int PairDevices(ClientPtr client, + DeviceIntPtr pointer, + DeviceIntPtr keyboard); + +extern DeviceIntPtr GetPairedPointer(DeviceIntPtr kbd); +extern DeviceIntPtr GetPairedKeyboard(DeviceIntPtr ptr); + +extern Bool RegisterPairingClient(ClientPtr client); +extern Bool UnregisterPairingClient(ClientPtr client); + +extern DeviceIntPtr GuessFreePointerDevice(void); + +/* Window/device based access control */ +extern Bool ACRegisterClient(ClientPtr client); +extern Bool ACUnregisterClient(ClientPtr client); +extern int ACClearWindowAccess(ClientPtr client, + WindowPtr win, + int what); +extern int ACChangeWindowAccess(ClientPtr client, + WindowPtr win, + int defaultRule, + DeviceIntPtr* perm_devices, + int npermit, + DeviceIntPtr* deny_devices, + int ndeny); +extern void ACQueryWindowAccess(WindowPtr win, + int* defaultRule, + DeviceIntPtr** perm, + int* nperm, + DeviceIntPtr** deny, + int* ndeny); + +extern Bool ACDeviceAllowed(WindowPtr win, + DeviceIntPtr dev); + /* Implemented by the DDX. */ extern int NewInputDeviceRequest( InputOption *options); diff --git a/include/inputstr.h b/include/inputstr.h index 8f4e9b9d1..d8d12d732 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -52,6 +52,7 @@ SOFTWARE. #include "input.h" #include "window.h" #include "dixstruct.h" +#include "cursorstr.h" #define BitIsOn(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))) @@ -177,7 +178,7 @@ typedef struct _ButtonClassRec { } ButtonClassRec, *ButtonClassPtr; typedef struct _FocusClassRec { - WindowPtr win; + WindowPtr win; /* May be set to a int constant (e.g. PointerRootWin)! */ int revert; TimeStamp time; WindowPtr *trace; @@ -264,6 +265,30 @@ typedef struct _LedFeedbackClassRec { #endif } LedFeedbackClassRec; + +/** + * Sprite information for a device. + */ +typedef struct { + CursorPtr current; + BoxRec hotLimits; /* logical constraints of hot spot */ + Bool confined; /* confined to screen */ +#if defined(SHAPE) || defined(PANORAMIX) + RegionPtr hotShape; /* additional logical shape constraint */ +#endif + BoxRec physLimits; /* physical constraints of hot spot */ + WindowPtr win; /* window of logical position */ + HotSpot hot; /* logical pointer position */ + HotSpot hotPhys; /* physical pointer position */ +#ifdef PANORAMIX + ScreenPtr screen; /* all others are in Screen 0 coordinates */ + RegionRec Reg1; /* Region 1 for confining motion */ + RegionRec Reg2; /* Region 2 for confining virtual motion */ + WindowPtr windows[MAXSCREENS]; + WindowPtr confineWin; /* confine window */ +#endif +} SpriteRec, *SpritePtr; + /* states for devices */ #define NOT_GRABBED 0 @@ -275,11 +300,40 @@ typedef struct _LedFeedbackClassRec { #define FROZEN_NO_EVENT 5 #define FROZEN_WITH_EVENT 6 #define THAW_OTHERS 7 +typedef struct _GrabInfoRec { + TimeStamp grabTime; + Bool fromPassiveGrab; + GrabRec activeGrab; + GrabPtr grab; + CARD8 activatingKey; + void (*ActivateGrab) ( + DeviceIntPtr /*device*/, + GrabPtr /*grab*/, + TimeStamp /*time*/, + Bool /*autoGrab*/); + void (*DeactivateGrab)( + DeviceIntPtr /*device*/); + struct { + Bool frozen; + int state; + GrabPtr other; /* if other grab has this frozen */ + xEvent *event; /* saved to be replayed */ + int evcount; + } sync; +} GrabInfoRec, *GrabInfoPtr; + +typedef struct _SpriteInfoRec { + /* sprite must always point to a valid sprite. For devices sharing the + * sprite, let sprite point to a paired spriteOwner's sprite. */ + SpritePtr sprite; /* sprite information */ + Bool spriteOwner; /* True if device owns the sprite */ + DeviceIntPtr paired; /* the real owner of the sprite or + NULL if spriteOwner is TRUE*/ +} SpriteInfoRec, *SpriteInfoPtr; typedef struct _DeviceIntRec { DeviceRec public; DeviceIntPtr next; - TimeStamp grabTime; Bool startup; /* true if needs to be turned on at server intialization time */ DeviceProc deviceProc; /* proc(DevicePtr, DEVICE_xx). It is @@ -288,27 +342,11 @@ typedef struct _DeviceIntRec { Bool inited; /* TRUE if INIT returns Success */ Bool enabled; /* TRUE if ON returns Success */ Bool coreEvents; /* TRUE if device also sends core */ - GrabPtr grab; /* the grabber - used by DIX */ - struct { - Bool frozen; - int state; - GrabPtr other; /* if other grab has this frozen */ - xEvent *event; /* saved to be replayed */ - int evcount; - } sync; + GrabInfoRec coreGrab; /* grab on core events */ + GrabInfoRec deviceGrab; /* grab on device events */ Atom type; char *name; CARD8 id; - CARD8 activatingKey; - Bool fromPassiveGrab; - GrabRec activeGrab; - void (*ActivateGrab) ( - DeviceIntPtr /*device*/, - GrabPtr /*grab*/, - TimeStamp /*time*/, - Bool /*autoGrab*/); - void (*DeactivateGrab)( - DeviceIntPtr /*device*/); KeyClassPtr key; ValuatorClassPtr valuator; ButtonClassPtr button; @@ -329,6 +367,7 @@ typedef struct _DeviceIntRec { DevUnion *devPrivates; int nPrivates; DeviceUnwrapProc unwrapProc; + SpriteInfoPtr spriteInfo; } DeviceIntRec; typedef struct { @@ -352,4 +391,5 @@ typedef struct _QdEvent { int evcount; } QdEventRec; +#define MPXDBG(...) ErrorF("MPX: " __VA_ARGS__ ) #endif /* INPUTSTRUCT_H */ diff --git a/include/scrnintstr.h b/include/scrnintstr.h index 110f4dce9..0d468c338 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -121,6 +121,7 @@ typedef void (* GetSpansProcPtr)( char * /*pdstStart*/); typedef void (* PointerNonInterestBoxProcPtr)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, BoxPtr /*pBox*/); @@ -257,33 +258,40 @@ typedef Bool (* UnrealizeFontProcPtr)( FontPtr /*pFont*/); typedef void (* ConstrainCursorProcPtr)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, BoxPtr /*pBox*/); typedef void (* CursorLimitsProcPtr)( + DeviceIntPtr /* pDev */, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/, BoxPtr /*pHotBox*/, BoxPtr /*pTopLeftBox*/); typedef Bool (* DisplayCursorProcPtr)( + DeviceIntPtr /* pDev */, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/); typedef Bool (* RealizeCursorProcPtr)( + DeviceIntPtr /* pDev */, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/); typedef Bool (* UnrealizeCursorProcPtr)( + DeviceIntPtr /* pDev */, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/); typedef void (* RecolorCursorProcPtr)( + DeviceIntPtr /* pDev */, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/, Bool /*displayed*/); typedef Bool (* SetCursorPositionProcPtr)( + DeviceIntPtr /* pDev */, ScreenPtr /*pScreen*/, int /*x*/, int /*y*/, diff --git a/include/window.h b/include/window.h index cd8c5b283..87118e3b0 100644 --- a/include/window.h +++ b/include/window.h @@ -67,6 +67,10 @@ SOFTWARE. #define WT_NOMATCH 3 #define NullWindow ((WindowPtr) 0) +/* Forward declaration, we can't include input.h here */ +struct _DeviceIntRec; +struct _Cursor; + typedef struct _BackingStore *BackingStorePtr; typedef struct _Window *WindowPtr; @@ -135,6 +139,15 @@ extern int ChangeWindowAttributes( XID* /*vlist*/, ClientPtr /*client*/); +extern int ChangeWindowDeviceCursor( + WindowPtr /*pWin*/, + struct _DeviceIntRec* /*pDev*/, + struct _Cursor* /*pCursor*/); + +extern struct _Cursor* WindowGetDeviceCursor( + WindowPtr /*pWin*/, + struct _DeviceIntRec* /*pDev*/); + /* Quartz support on Mac OS X uses the HIToolbox framework whose GetWindowAttributes function conflicts here. */ #ifdef __DARWIN__ diff --git a/include/windowstr.h b/include/windowstr.h index 9fd6d768c..95954a7c3 100644 --- a/include/windowstr.h +++ b/include/windowstr.h @@ -70,6 +70,21 @@ SOFTWARE. #define SameBorder(as, a, bs, b) \ EqualPixUnion(as, a, bs, b) +/* used as NULL-terminated list */ +typedef struct _DevCursorNode { + CursorPtr cursor; + DeviceIntPtr dev; + struct _DevCursorNode* next; +} DevCursNodeRec, *DevCursNodePtr, *DevCursorList; + +typedef struct _WindowAccessRec { + int defaultRule; /* WindowAccessDenyAll */ + DeviceIntPtr* perm; + int nperm; + DeviceIntPtr* deny; + int ndeny; +} WindowAccessRec, *WindowAccessPtr; + typedef struct _WindowOpt { VisualID visual; /* default: same as parent */ CursorPtr cursor; /* default: window.cursorNone */ @@ -89,6 +104,8 @@ typedef struct _WindowOpt { #ifdef XINPUT struct _OtherInputMasks *inputMasks; /* default: NULL */ #endif + DevCursorList deviceCursors; /* default: NULL */ + WindowAccessRec access; } WindowOptRec, *WindowOptPtr; #define BackgroundPixel 2L @@ -125,6 +125,7 @@ extern void miPutImage( /* micursor.c */ extern void miRecolorCursor( + DeviceIntPtr /* pDev */, ScreenPtr /*pScr*/, CursorPtr /*pCurs*/, Bool /*displayed*/ diff --git a/mi/micursor.c b/mi/micursor.c index 6e06fbc07..af2cd0870 100644 --- a/mi/micursor.c +++ b/mi/micursor.c @@ -52,24 +52,26 @@ SOFTWARE. #include "cursor.h" #include "misc.h" #include "mi.h" +#include "inputstr.h" extern Bool Must_have_memory; _X_EXPORT void -miRecolorCursor( pScr, pCurs, displayed) - ScreenPtr pScr; - CursorPtr pCurs; - Bool displayed; +miRecolorCursor( pDev, pScr, pCurs, displayed) + DeviceIntPtr pDev; + ScreenPtr pScr; + CursorPtr pCurs; + Bool displayed; { /* * This is guaranteed to correct any color-dependent state which may have * been bound up in private state created by RealizeCursor */ - (* pScr->UnrealizeCursor)( pScr, pCurs); + (* pScr->UnrealizeCursor)( pDev, pScr, pCurs); Must_have_memory = TRUE; /* XXX */ - (* pScr->RealizeCursor)( pScr, pCurs); + (* pScr->RealizeCursor)( pDev, pScr, pCurs); Must_have_memory = FALSE; /* XXX */ if ( displayed) - (* pScr->DisplayCursor)( pScr, pCurs); + (* pScr->DisplayCursor)( pDev, pScr, pCurs); } diff --git a/mi/midispcur.c b/mi/midispcur.c index de009cbaf..35f0fbaa7 100644 --- a/mi/midispcur.c +++ b/mi/midispcur.c @@ -29,6 +29,12 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ +/* + * MPX additions: + * Copyright © 2006 Peter Hutterer + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + * + */ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> @@ -52,6 +58,8 @@ in this Software without prior written authorization from The Open Group. # include "picturestr.h" #endif +# include "inputstr.h" /* for MAX_DEVICES */ + /* per-screen private data */ static int miDCScreenIndex; @@ -64,12 +72,21 @@ typedef struct { GCPtr pSaveGC, pRestoreGC; GCPtr pMoveGC; GCPtr pPixSourceGC, pPixMaskGC; - CloseScreenProcPtr CloseScreen; PixmapPtr pSave, pTemp; #ifdef ARGB_CURSOR PicturePtr pRootPicture; PicturePtr pTempPicture; #endif +} miDCBufferRec, *miDCBufferPtr; + +/* + * The core pointer buffer will point to the index of the virtual core pointer + * in the pCursorBuffers array. + */ +typedef struct { + miDCBufferPtr pCoreBuffer; /* for core pointer */ + miDCBufferPtr pCursorBuffers; /* one for each device */ + CloseScreenProcPtr CloseScreen; } miDCScreenRec, *miDCScreenPtr; /* per-cursor per-screen private data */ @@ -87,18 +104,22 @@ typedef struct { static Bool miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); static Bool miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -static Bool miDCPutUpCursor(ScreenPtr pScreen, CursorPtr pCursor, - int x, int y, unsigned long source, - unsigned long mask); -static Bool miDCSaveUnderCursor(ScreenPtr pScreen, int x, int y, +static Bool miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y, + unsigned long source, unsigned long mask); +static Bool miDCSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h); -static Bool miDCRestoreUnderCursor(ScreenPtr pScreen, int x, int y, +static Bool miDCRestoreUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h); -static Bool miDCMoveCursor(ScreenPtr pScreen, CursorPtr pCursor, - int x, int y, int w, int h, int dx, int dy, +static Bool miDCMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y, + int w, int h, int dx, int dy, unsigned long source, unsigned long mask); -static Bool miDCChangeSave(ScreenPtr pScreen, int x, int y, int w, int h, - int dx, int dy); +static Bool miDCChangeSave(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, int w, int h, + int dx, int dy); static miSpriteCursorFuncRec miDCFuncs = { miDCRealizeCursor, @@ -116,6 +137,8 @@ miDCInitialize (pScreen, screenFuncs) miPointerScreenFuncPtr screenFuncs; { miDCScreenPtr pScreenPriv; + miDCBufferPtr pBuffer; + int mpBufferIdx; if (miDCGeneration != serverGeneration) { @@ -132,19 +155,37 @@ miDCInitialize (pScreen, screenFuncs) * initialize the entire private structure to zeros */ - pScreenPriv->pSourceGC = - pScreenPriv->pMaskGC = - pScreenPriv->pSaveGC = - pScreenPriv->pRestoreGC = - pScreenPriv->pMoveGC = - pScreenPriv->pPixSourceGC = - pScreenPriv->pPixMaskGC = NULL; + pScreenPriv->pCursorBuffers = (miDCBufferPtr)xalloc(MAX_DEVICES * + sizeof(miDCBufferRec)); + if (!pScreenPriv->pCursorBuffers) + { + xfree((pointer)pScreenPriv); + return FALSE; + } + + /* virtual core pointer ID is 1 */ + pScreenPriv->pCoreBuffer = &pScreenPriv->pCursorBuffers[1]; + + mpBufferIdx = 0; + while(mpBufferIdx < MAX_DEVICES) + { + pBuffer = &pScreenPriv->pCursorBuffers[mpBufferIdx]; + pBuffer->pSourceGC = + pBuffer->pMaskGC = + pBuffer->pSaveGC = + pBuffer->pRestoreGC = + pBuffer->pMoveGC = + pBuffer->pPixSourceGC = + pBuffer->pPixMaskGC = NULL; #ifdef ARGB_CURSOR - pScreenPriv->pRootPicture = NULL; - pScreenPriv->pTempPicture = NULL; + pBuffer->pRootPicture = NULL; + pBuffer->pTempPicture = NULL; #endif - - pScreenPriv->pSave = pScreenPriv->pTemp = NULL; + pBuffer->pSave = pBuffer->pTemp = NULL; + + mpBufferIdx++; + } + pScreenPriv->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = miDCCloseScreen; @@ -153,6 +194,7 @@ miDCInitialize (pScreen, screenFuncs) if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs)) { + xfree ((pointer) pScreenPriv->pCursorBuffers); xfree ((pointer) pScreenPriv); return FALSE; } @@ -169,24 +211,38 @@ miDCCloseScreen (index, pScreen) ScreenPtr pScreen; { miDCScreenPtr pScreenPriv; + miDCBufferPtr pBuffer; + int mpBufferIdx; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreen->CloseScreen = pScreenPriv->CloseScreen; - tossGC (pScreenPriv->pSourceGC); - tossGC (pScreenPriv->pMaskGC); - tossGC (pScreenPriv->pSaveGC); - tossGC (pScreenPriv->pRestoreGC); - tossGC (pScreenPriv->pMoveGC); - tossGC (pScreenPriv->pPixSourceGC); - tossGC (pScreenPriv->pPixMaskGC); - tossPix (pScreenPriv->pSave); - tossPix (pScreenPriv->pTemp); + + mpBufferIdx = 0; + while (mpBufferIdx < MAX_DEVICES) + { + pBuffer = &pScreenPriv->pCursorBuffers[mpBufferIdx]; + + tossGC (pBuffer->pSourceGC); + tossGC (pBuffer->pMaskGC); + tossGC (pBuffer->pSaveGC); + tossGC (pBuffer->pRestoreGC); + tossGC (pBuffer->pMoveGC); + tossGC (pBuffer->pPixSourceGC); + tossGC (pBuffer->pPixMaskGC); + tossPix (pBuffer->pSave); + tossPix (pBuffer->pTemp); #ifdef ARGB_CURSOR #if 0 /* This has been free()d before */ - tossPict (pScreenPriv->pRootPicture); + tossPict (pScreenPriv->pRootPicture); #endif - tossPict (pScreenPriv->pTempPicture); + tossPict (pBuffer->pTempPicture); #endif + + mpBufferIdx++; + } + + xfree((pointer) pScreenPriv->pCursorBuffers); + xfree ((pointer) pScreenPriv); return (*pScreen->CloseScreen) (index, pScreen); } @@ -459,7 +515,8 @@ miDCMakeGC( static Bool -miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) +miDCPutUpCursor (pDev, pScreen, pCursor, x, y, source, mask) + DeviceIntPtr pDev; ScreenPtr pScreen; CursorPtr pCursor; int x, y; @@ -467,6 +524,7 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) { miDCScreenPtr pScreenPriv; miDCCursorPtr pPriv; + miDCBufferPtr pBuffer; WindowPtr pWin; pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum]; @@ -478,15 +536,20 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) } pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pWin = WindowTable[pScreen->myNum]; + pBuffer = pScreenPriv->pCoreBuffer; + + if (DevHasCursor(pDev)) + pBuffer = &pScreenPriv->pCursorBuffers[pDev->id]; + #ifdef ARGB_CURSOR if (pPriv->pPicture) { - if (!EnsurePicture(pScreenPriv->pRootPicture, &pWin->drawable, pWin)) + if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin)) return FALSE; CompositePicture (PictOpOver, pPriv->pPicture, NULL, - pScreenPriv->pRootPicture, + pBuffer->pRootPicture, 0, 0, 0, 0, x, y, pCursor->bits->width, @@ -495,16 +558,16 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) else #endif { - if (!EnsureGC(pScreenPriv->pSourceGC, pWin)) + if (!EnsureGC(pBuffer->pSourceGC, pWin)) return FALSE; - if (!EnsureGC(pScreenPriv->pMaskGC, pWin)) + if (!EnsureGC(pBuffer->pMaskGC, pWin)) { - FreeGC (pScreenPriv->pSourceGC, (GContext) 0); - pScreenPriv->pSourceGC = 0; + FreeGC (pBuffer->pSourceGC, (GContext) 0); + pBuffer->pSourceGC = 0; return FALSE; } miDCPutBits ((DrawablePtr)pWin, pPriv, - pScreenPriv->pSourceGC, pScreenPriv->pMaskGC, + pBuffer->pSourceGC, pBuffer->pMaskGC, x, y, pCursor->bits->width, pCursor->bits->height, source, mask); } @@ -512,30 +575,37 @@ miDCPutUpCursor (pScreen, pCursor, x, y, source, mask) } static Bool -miDCSaveUnderCursor (pScreen, x, y, w, h) +miDCSaveUnderCursor (pDev, pScreen, x, y, w, h) + DeviceIntPtr pDev; ScreenPtr pScreen; int x, y, w, h; { miDCScreenPtr pScreenPriv; + miDCBufferPtr pBuffer; PixmapPtr pSave; WindowPtr pWin; GCPtr pGC; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; - pSave = pScreenPriv->pSave; + pBuffer = pScreenPriv->pCoreBuffer; + + if (DevHasCursor(pDev)) + pBuffer = &pScreenPriv->pCursorBuffers[pDev->id]; + + pSave = pBuffer->pSave; pWin = WindowTable[pScreen->myNum]; if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) { if (pSave) (*pScreen->DestroyPixmap) (pSave); - pScreenPriv->pSave = pSave = + pBuffer->pSave = pSave = (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth); if (!pSave) return FALSE; } - if (!EnsureGC(pScreenPriv->pSaveGC, pWin)) + if (!EnsureGC(pBuffer->pSaveGC, pWin)) return FALSE; - pGC = pScreenPriv->pSaveGC; + pGC = pBuffer->pSaveGC; if (pSave->drawable.serialNumber != pGC->serialNumber) ValidateGC ((DrawablePtr) pSave, pGC); (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC, @@ -544,23 +614,30 @@ miDCSaveUnderCursor (pScreen, x, y, w, h) } static Bool -miDCRestoreUnderCursor (pScreen, x, y, w, h) +miDCRestoreUnderCursor (pDev, pScreen, x, y, w, h) + DeviceIntPtr pDev; ScreenPtr pScreen; int x, y, w, h; { miDCScreenPtr pScreenPriv; + miDCBufferPtr pBuffer; PixmapPtr pSave; WindowPtr pWin; GCPtr pGC; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; - pSave = pScreenPriv->pSave; + pBuffer = pScreenPriv->pCoreBuffer; + + if (DevHasCursor(pDev)) + pBuffer = &pScreenPriv->pCursorBuffers[pDev->id]; + + pSave = pBuffer->pSave; pWin = WindowTable[pScreen->myNum]; if (!pSave) return FALSE; - if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) + if (!EnsureGC(pBuffer->pRestoreGC, pWin)) return FALSE; - pGC = pScreenPriv->pRestoreGC; + pGC = pBuffer->pRestoreGC; if (pWin->drawable.serialNumber != pGC->serialNumber) ValidateGC ((DrawablePtr) pWin, pGC); (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, @@ -569,27 +646,34 @@ miDCRestoreUnderCursor (pScreen, x, y, w, h) } static Bool -miDCChangeSave (pScreen, x, y, w, h, dx, dy) +miDCChangeSave (pDev, pScreen, x, y, w, h, dx, dy) + DeviceIntPtr pDev; ScreenPtr pScreen; int x, y, w, h, dx, dy; { miDCScreenPtr pScreenPriv; + miDCBufferPtr pBuffer; PixmapPtr pSave; WindowPtr pWin; GCPtr pGC; int sourcex, sourcey, destx, desty, copyw, copyh; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; - pSave = pScreenPriv->pSave; + pBuffer = pScreenPriv->pCoreBuffer; + + if (DevHasCursor(pDev)) + pBuffer = &pScreenPriv->pCursorBuffers[pDev->id]; + + pSave = pBuffer->pSave; pWin = WindowTable[pScreen->myNum]; /* * restore the bits which are about to get trashed */ if (!pSave) return FALSE; - if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) + if (!EnsureGC(pBuffer->pRestoreGC, pWin)) return FALSE; - pGC = pScreenPriv->pRestoreGC; + pGC = pBuffer->pRestoreGC; if (pWin->drawable.serialNumber != pGC->serialNumber) ValidateGC ((DrawablePtr) pWin, pGC); /* @@ -627,9 +711,9 @@ miDCChangeSave (pScreen, x, y, w, h, dx, dy) (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC, 0, sourcey, -dx, copyh, x + dx, desty); } - if (!EnsureGC(pScreenPriv->pSaveGC, pWin)) + if (!EnsureGC(pBuffer->pSaveGC, pWin)) return FALSE; - pGC = pScreenPriv->pSaveGC; + pGC = pBuffer->pSaveGC; if (pSave->drawable.serialNumber != pGC->serialNumber) ValidateGC ((DrawablePtr) pSave, pGC); /* @@ -701,7 +785,8 @@ miDCChangeSave (pScreen, x, y, w, h, dx, dy) } static Bool -miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) +miDCMoveCursor (pDev, pScreen, pCursor, x, y, w, h, dx, dy, source, mask) + DeviceIntPtr pDev; ScreenPtr pScreen; CursorPtr pCursor; int x, y, w, h, dx, dy; @@ -709,6 +794,7 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) { miDCCursorPtr pPriv; miDCScreenPtr pScreenPriv; + miDCBufferPtr pBuffer; int status; WindowPtr pWin; GCPtr pGC; @@ -724,39 +810,44 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) } pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pWin = WindowTable[pScreen->myNum]; - pTemp = pScreenPriv->pTemp; + pBuffer = pScreenPriv->pCoreBuffer; + + if (DevHasCursor(pDev)) + pBuffer = &pScreenPriv->pCursorBuffers[pDev->id]; + + pTemp = pBuffer->pTemp; if (!pTemp || - pTemp->drawable.width != pScreenPriv->pSave->drawable.width || - pTemp->drawable.height != pScreenPriv->pSave->drawable.height) + pTemp->drawable.width != pBuffer->pSave->drawable.width || + pTemp->drawable.height != pBuffer->pSave->drawable.height) { if (pTemp) (*pScreen->DestroyPixmap) (pTemp); #ifdef ARGB_CURSOR - if (pScreenPriv->pTempPicture) + if (pBuffer->pTempPicture) { - FreePicture (pScreenPriv->pTempPicture, 0); - pScreenPriv->pTempPicture = 0; + FreePicture (pBuffer->pTempPicture, 0); + pBuffer->pTempPicture = 0; } #endif - pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap) - (pScreen, w, h, pScreenPriv->pSave->drawable.depth); + pBuffer->pTemp = pTemp = (*pScreen->CreatePixmap) + (pScreen, w, h, pBuffer->pSave->drawable.depth); if (!pTemp) return FALSE; } - if (!pScreenPriv->pMoveGC) + if (!pBuffer->pMoveGC) { - pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp, + pBuffer->pMoveGC = CreateGC ((DrawablePtr)pTemp, GCGraphicsExposures, &gcval, &status); - if (!pScreenPriv->pMoveGC) + if (!pBuffer->pMoveGC) return FALSE; } /* * copy the saved area to a temporary pixmap */ - pGC = pScreenPriv->pMoveGC; + pGC = pBuffer->pMoveGC; if (pGC->serialNumber != pTemp->drawable.serialNumber) ValidateGC ((DrawablePtr) pTemp, pGC); - (*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave, + (*pGC->ops->CopyArea)((DrawablePtr)pBuffer->pSave, (DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0); /* @@ -765,12 +856,12 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) #ifdef ARGB_CURSOR if (pPriv->pPicture) { - if (!EnsurePicture(pScreenPriv->pTempPicture, &pTemp->drawable, pWin)) + if (!EnsurePicture(pBuffer->pTempPicture, &pTemp->drawable, pWin)) return FALSE; CompositePicture (PictOpOver, pPriv->pPicture, NULL, - pScreenPriv->pTempPicture, + pBuffer->pTempPicture, 0, 0, 0, 0, dx, dy, pCursor->bits->width, @@ -779,22 +870,22 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) else #endif { - if (!pScreenPriv->pPixSourceGC) + if (!pBuffer->pPixSourceGC) { - pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp, + pBuffer->pPixSourceGC = CreateGC ((DrawablePtr)pTemp, GCGraphicsExposures, &gcval, &status); - if (!pScreenPriv->pPixSourceGC) + if (!pBuffer->pPixSourceGC) return FALSE; } - if (!pScreenPriv->pPixMaskGC) + if (!pBuffer->pPixMaskGC) { - pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp, + pBuffer->pPixMaskGC = CreateGC ((DrawablePtr)pTemp, GCGraphicsExposures, &gcval, &status); - if (!pScreenPriv->pPixMaskGC) + if (!pBuffer->pPixMaskGC) return FALSE; } miDCPutBits ((DrawablePtr)pTemp, pPriv, - pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC, + pBuffer->pPixSourceGC, pBuffer->pPixMaskGC, dx, dy, pCursor->bits->width, pCursor->bits->height, source, mask); } @@ -803,9 +894,9 @@ miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) * copy the temporary pixmap onto the screen */ - if (!EnsureGC(pScreenPriv->pRestoreGC, pWin)) + if (!EnsureGC(pBuffer->pRestoreGC, pWin)) return FALSE; - pGC = pScreenPriv->pRestoreGC; + pGC = pBuffer->pRestoreGC; if (pWin->drawable.serialNumber != pGC->serialNumber) ValidateGC ((DrawablePtr) pWin, pGC); @@ -24,6 +24,13 @@ in this Software without prior written authorization from The Open Group. * * Author: Keith Packard, MIT X Consortium */ + /* + * MPX additions: + * Copyright © 2006 Peter Hutterer + * License see above. + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + * + */ /* * mieq.c @@ -112,10 +119,13 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e) deviceKeyButtonPointer *lastkbp = (deviceKeyButtonPointer *) &laste->event[0]; + /* avoid merging events from different devices */ if (e->u.u.type == MotionNotify) + isMotion = pDev->id; + else if (e->u.u.type == MotionNotify) isMotion = inputInfo.pointer->id; else if (e->u.u.type == DeviceMotionNotify) - isMotion = pDev->id; + isMotion = pDev->id | (1 << 8); /* flag to indicate DeviceMotion */ /* We silently steal valuator events: just tack them on to the last * motion event they need to be attached to. Sigh. */ @@ -222,7 +232,7 @@ mieqProcessInputEvents() miEventQueue.head = 0; else ++miEventQueue.head; - NewCurrentScreen (miEventQueue.pDequeueScreen, x, y); + NewCurrentScreen (e->pDev, miEventQueue.pDequeueScreen, x, y); } else { if (miEventQueue.head == QUEUE_SIZE - 1) @@ -249,14 +259,23 @@ mieqProcessInputEvents() else if (e->event[0].u.u.type == MotionNotify || e->event[0].u.u.type == ButtonPress || e->event[0].u.u.type == ButtonRelease) { - SwitchCorePointer(e->pDev); dev = inputInfo.pointer; } else { dev = e->pDev; } - dev->public.processInputProc(e->event, dev, e->nevents); + /* MPX devices send both core and Xi events. + * Use dev to get the correct processing function but supply + * e->pDev to pass the correct device + */ + dev->public.processInputProc(e->event, e->pDev, e->nevents); + } + + /* Update the sprite now. Next event may be from different device. */ + if (e->event[0].u.u.type == MotionNotify && e->pDev->coreEvents) + { + miPointerUpdateSprite(e->pDev); } } } diff --git a/mi/mipointer.c b/mi/mipointer.c index b86a26a97..863a4052a 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -22,6 +22,13 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ + /* + * MPX additions: + * Copyright © 2006 Peter Hutterer + * License see above. + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + * + */ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> @@ -51,19 +58,35 @@ static unsigned long miPointerGeneration = 0; * until more than one pointer device exists. */ -static miPointerRec miPointer; +static miPointerPtr miCorePointer; -static Bool miPointerRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -static Bool miPointerUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -static Bool miPointerDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor); -static void miPointerConstrainCursor(ScreenPtr pScreen, BoxPtr pBox); -static void miPointerPointerNonInterestBox(ScreenPtr pScreen, BoxPtr pBox); -static void miPointerCursorLimits(ScreenPtr pScreen, CursorPtr pCursor, - BoxPtr pHotBox, BoxPtr pTopLeftBox); -static Bool miPointerSetCursorPosition(ScreenPtr pScreen, int x, int y, +/* Multipointers + * ID of a device == index in this array. + */ +static miPointerRec miPointers[MAX_DEVICES]; +#define MIPOINTER(dev) \ + (DevHasCursor((dev))) ? &miPointers[(dev)->id] : miCorePointer + +static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + BoxPtr pBox); +static void miPointerPointerNonInterestBox(DeviceIntPtr pDev, + ScreenPtr pScreen, BoxPtr pBox); +static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, BoxPtr pHotBox, + BoxPtr pTopLeftBox); +static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, Bool generateEvent); static Bool miPointerCloseScreen(int index, ScreenPtr pScreen); -static void miPointerMove(ScreenPtr pScreen, int x, int y, unsigned long time); +static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y, + unsigned long time); static xEvent* events; /* for WarpPointer MotionNotifies */ @@ -75,6 +98,8 @@ miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate) Bool waitForUpdate; { miPointerScreenPtr pScreenPriv; + miPointerPtr pPointer; + int ptrIdx; if (miPointerGeneration != serverGeneration) { @@ -111,23 +136,30 @@ miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate) pScreen->SetCursorPosition = miPointerSetCursorPosition; pScreen->RecolorCursor = miRecolorCursor; pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox; + /* * set up the pointer object + * virtual core pointer ID is always 1, so we let it point to the matching + * index in the array. */ - miPointer.pScreen = NULL; - miPointer.pSpriteScreen = NULL; - miPointer.pCursor = NULL; - miPointer.pSpriteCursor = NULL; - miPointer.limits.x1 = 0; - miPointer.limits.x2 = 32767; - miPointer.limits.y1 = 0; - miPointer.limits.y2 = 32767; - miPointer.confined = FALSE; - miPointer.x = 0; - miPointer.y = 0; + miCorePointer = &miPointers[1]; + for(ptrIdx = 0; ptrIdx < MAX_DEVICES; ptrIdx++) + { + pPointer = &miPointers[ptrIdx]; + pPointer->pScreen = NULL; + pPointer->pSpriteScreen = NULL; + pPointer->pCursor = NULL; + pPointer->pSpriteCursor = NULL; + pPointer->limits.x1 = 0; + pPointer->limits.x2 = 32767; + pPointer->limits.y1 = 0; + pPointer->limits.y2 = 32767; + pPointer->confined = FALSE; + pPointer->x = 0; + pPointer->y = 0; + } events = NULL; - return TRUE; } @@ -136,12 +168,21 @@ miPointerCloseScreen (index, pScreen) int index; ScreenPtr pScreen; { + miPointerPtr pPointer; + int ptrIdx; + SetupScreen(pScreen); - if (pScreen == miPointer.pScreen) - miPointer.pScreen = 0; - if (pScreen == miPointer.pSpriteScreen) - miPointer.pSpriteScreen = 0; + for(ptrIdx = 0; ptrIdx < MAX_DEVICES; ptrIdx++) + { + pPointer = &miPointers[ptrIdx]; + + if (pScreen == pPointer->pScreen) + pPointer->pScreen = 0; + if (pScreen == pPointer->pSpriteScreen) + pPointer->pSpriteScreen = 0; + } + pScreen->CloseScreen = pScreenPriv->CloseScreen; xfree ((pointer) pScreenPriv); xfree ((pointer) events); @@ -154,61 +195,69 @@ miPointerCloseScreen (index, pScreen) */ static Bool -miPointerRealizeCursor (pScreen, pCursor) - ScreenPtr pScreen; - CursorPtr pCursor; +miPointerRealizeCursor (pDev, pScreen, pCursor) + DeviceIntPtr pDev; + ScreenPtr pScreen; + CursorPtr pCursor; { SetupScreen(pScreen); - - return (*pScreenPriv->spriteFuncs->RealizeCursor) (pScreen, pCursor); + return (*pScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCursor); } static Bool -miPointerUnrealizeCursor (pScreen, pCursor) - ScreenPtr pScreen; - CursorPtr pCursor; +miPointerUnrealizeCursor (pDev, pScreen, pCursor) + DeviceIntPtr pDev; + ScreenPtr pScreen; + CursorPtr pCursor; { SetupScreen(pScreen); - - return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pScreen, pCursor); + return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCursor); } static Bool -miPointerDisplayCursor (pScreen, pCursor) - ScreenPtr pScreen; - CursorPtr pCursor; +miPointerDisplayCursor (pDev, pScreen, pCursor) + DeviceIntPtr pDev; + ScreenPtr pScreen; + CursorPtr pCursor; { - miPointer.pCursor = pCursor; - miPointer.pScreen = pScreen; - miPointerUpdateSprite(inputInfo.pointer); + miPointerPtr pPointer = MIPOINTER(pDev); + + pPointer->pCursor = pCursor; + pPointer->pScreen = pScreen; + miPointerUpdateSprite(pDev); return TRUE; } static void -miPointerConstrainCursor (pScreen, pBox) +miPointerConstrainCursor (pDev, pScreen, pBox) + DeviceIntPtr pDev; ScreenPtr pScreen; BoxPtr pBox; { - miPointer.limits = *pBox; - miPointer.confined = PointerConfinedToScreen(); + miPointerPtr pPointer = MIPOINTER(pDev); + + pPointer->limits = *pBox; + pPointer->confined = PointerConfinedToScreen(pDev); } /*ARGSUSED*/ static void -miPointerPointerNonInterestBox (pScreen, pBox) - ScreenPtr pScreen; - BoxPtr pBox; +miPointerPointerNonInterestBox (pDev, pScreen, pBox) + DeviceIntPtr pDev; + ScreenPtr pScreen; + BoxPtr pBox; { /* until DIX uses this, this will remain a stub */ } /*ARGSUSED*/ static void -miPointerCursorLimits(pScreen, pCursor, pHotBox, pTopLeftBox) - ScreenPtr pScreen; - CursorPtr pCursor; - BoxPtr pHotBox; - BoxPtr pTopLeftBox; +miPointerCursorLimits(pDev, pScreen, pCursor, pHotBox, pTopLeftBox) + DeviceIntPtr pDev; + ScreenPtr pScreen; + CursorPtr pCursor; + BoxPtr pHotBox; + BoxPtr pTopLeftBox; { *pTopLeftBox = *pHotBox; } @@ -216,51 +265,54 @@ miPointerCursorLimits(pScreen, pCursor, pHotBox, pTopLeftBox) static Bool GenerateEvent; static Bool -miPointerSetCursorPosition(pScreen, x, y, generateEvent) - ScreenPtr pScreen; - int x, y; - Bool generateEvent; +miPointerSetCursorPosition(pDev, pScreen, x, y, generateEvent) + DeviceIntPtr pDev; + ScreenPtr pScreen; + int x, y; + Bool generateEvent; { SetupScreen (pScreen); GenerateEvent = generateEvent; /* device dependent - must pend signal and call miPointerWarpCursor */ - (*pScreenPriv->screenFuncs->WarpCursor) (pScreen, x, y); + (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y); if (!generateEvent) - miPointerUpdateSprite(inputInfo.pointer); + miPointerUpdateSprite(pDev); return TRUE; } /* Once signals are ignored, the WarpCursor function can call this */ _X_EXPORT void -miPointerWarpCursor (pScreen, x, y) - ScreenPtr pScreen; - int x, y; +miPointerWarpCursor (pDev, pScreen, x, y) + DeviceIntPtr pDev; + ScreenPtr pScreen; + int x, y; { + miPointerPtr pPointer = MIPOINTER(pDev); SetupScreen (pScreen); - if (miPointer.pScreen != pScreen) + if (pPointer->pScreen != pScreen) (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, TRUE); if (GenerateEvent) { - miPointerMove (pScreen, x, y, GetTimeInMillis()); + miPointerMove (pDev, pScreen, x, y, GetTimeInMillis()); } else { /* everything from miPointerMove except the event and history */ - if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen) + if (!pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) { - miPointer.devx = x; - miPointer.devy = y; - if(!miPointer.pCursor->bits->emptyMask) - (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y); + pPointer->devx = x; + pPointer->devy = y; + if(!pPointer->pCursor->bits->emptyMask) + (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } - miPointer.x = x; - miPointer.y = y; - miPointer.pScreen = pScreen; + pPointer->x = x; + pPointer->y = y; + pPointer->pScreen = pScreen; } } @@ -287,66 +339,69 @@ miPointerUpdateSprite (DeviceIntPtr pDev) miPointerScreenPtr pScreenPriv; CursorPtr pCursor; int x, y, devx, devy; + miPointerPtr pPointer; - if (!pDev || !(pDev->coreEvents || pDev == inputInfo.pointer)) + if (!pDev || pDev == inputInfo.pointer || !pDev->coreEvents) return; - pScreen = miPointer.pScreen; + pPointer = MIPOINTER(pDev); + + pScreen = pPointer->pScreen; if (!pScreen) return; - x = miPointer.x; - y = miPointer.y; - devx = miPointer.devx; - devy = miPointer.devy; + x = pPointer->x; + y = pPointer->y; + devx = pPointer->devx; + devy = pPointer->devy; pScreenPriv = GetScreenPrivate (pScreen); /* * if the cursor has switched screens, disable the sprite * on the old screen */ - if (pScreen != miPointer.pSpriteScreen) + if (pScreen != pPointer->pSpriteScreen) { - if (miPointer.pSpriteScreen) + if (pPointer->pSpriteScreen) { miPointerScreenPtr pOldPriv; - pOldPriv = GetScreenPrivate (miPointer.pSpriteScreen); - if (miPointer.pCursor) + pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen); + if (pPointer->pCursor) { (*pOldPriv->spriteFuncs->SetCursor) - (miPointer.pSpriteScreen, NullCursor, 0, 0); + (pDev, pPointer->pSpriteScreen, NullCursor, 0, 0); } - (*pOldPriv->screenFuncs->CrossScreen) (miPointer.pSpriteScreen, FALSE); + (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE); } (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE); (*pScreenPriv->spriteFuncs->SetCursor) - (pScreen, miPointer.pCursor, x, y); - miPointer.devx = x; - miPointer.devy = y; - miPointer.pSpriteCursor = miPointer.pCursor; - miPointer.pSpriteScreen = pScreen; + (pDev, pScreen, pPointer->pCursor, x, y); + pPointer->devx = x; + pPointer->devy = y; + pPointer->pSpriteCursor = pPointer->pCursor; + pPointer->pSpriteScreen = pScreen; } /* * if the cursor has changed, display the new one */ - else if (miPointer.pCursor != miPointer.pSpriteCursor) + else if (pPointer->pCursor != pPointer->pSpriteCursor) { - pCursor = miPointer.pCursor; + pCursor = pPointer->pCursor; if (pCursor->bits->emptyMask && !pScreenPriv->showTransparent) pCursor = NullCursor; - (*pScreenPriv->spriteFuncs->SetCursor) (pScreen, pCursor, x, y); + (*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y); - miPointer.devx = x; - miPointer.devy = y; - miPointer.pSpriteCursor = miPointer.pCursor; + pPointer->devx = x; + pPointer->devy = y; + pPointer->pSpriteCursor = pPointer->pCursor; } else if (x != devx || y != devy) { - miPointer.devx = x; - miPointer.devy = y; - if(!miPointer.pCursor->bits->emptyMask) - (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y); + pPointer->devx = x; + pPointer->devy = y; + if(!pPointer->pCursor->bits->emptyMask) + (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } } @@ -358,7 +413,7 @@ miPointerUpdateSprite (DeviceIntPtr pDev) void miPointerDeltaCursor (int dx, int dy, unsigned long time) { - int x = miPointer.x + dx, y = miPointer.y + dy; + int x = miCorePointer->x + dx, y = miCorePointer->y + dy; miPointerSetPosition(inputInfo.pointer, &x, &y, time); } @@ -374,13 +429,15 @@ miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y) { miPointerScreenPtr pScreenPriv; ScreenPtr pScreen; + miPointerPtr pPointer = MIPOINTER(pDev); pScreen = screenInfo.screens[screen_no]; pScreenPriv = GetScreenPrivate (pScreen); (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE); - NewCurrentScreen (pScreen, x, y); - miPointer.limits.x2 = pScreen->width; - miPointer.limits.y2 = pScreen->height; + NewCurrentScreen (pDev, pScreen, x, y); + + pPointer->limits.x2 = pScreen->width; + pPointer->limits.y2 = pScreen->height; } _X_EXPORT ScreenPtr @@ -392,7 +449,8 @@ miPointerCurrentScreen () _X_EXPORT ScreenPtr miPointerGetScreen(DeviceIntPtr pDev) { - return miPointer.pScreen; + miPointerPtr pPointer = MIPOINTER(pDev); + return pPointer->pScreen; } /* Move the pointer to x, y on the current screen, update the sprite, and @@ -409,20 +467,23 @@ static void miPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, unsigned long time) { + int valuators[2]; + miPointerPtr pPointer = MIPOINTER(pDev); SetupScreen(pScreen); - if (pDev && (pDev->coreEvents || pDev == inputInfo.pointer) && - !pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen) + + if (pDev && (pDev->coreEvents || pDev == inputInfo.pointer) + && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen) { - miPointer.devx = x; - miPointer.devy = y; - if(!miPointer.pCursor->bits->emptyMask) - (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y); + pPointer->devx = x; + pPointer->devy = y; + if(!pPointer->pCursor->bits->emptyMask) + (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y); } - miPointer.x = x; - miPointer.y = y; - miPointer.pScreen = pScreen; + pPointer->x = x; + pPointer->y = y; + pPointer->pScreen = pScreen; } _X_EXPORT void @@ -432,7 +493,9 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y, unsigned long time) ScreenPtr pScreen; ScreenPtr newScreen; - pScreen = miPointer.pScreen; + miPointerPtr pPointer = MIPOINTER(pDev); + + pScreen = pPointer->pScreen; if (!pScreen) return; /* called before ready */ @@ -442,7 +505,7 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y, unsigned long time) if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height) { pScreenPriv = GetScreenPrivate (pScreen); - if (!miPointer.confined) + if (!pPointer->confined) { newScreen = pScreen; (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y); @@ -452,23 +515,24 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y, unsigned long time) (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE); pScreenPriv = GetScreenPrivate (pScreen); /* Smash the confine to the new screen */ - miPointer.limits.x2 = pScreen->width; - miPointer.limits.y2 = pScreen->height; + pPointer->limits.x2 = pScreen->width; + pPointer->limits.y2 = pScreen->height; } } } /* Constrain the sprite to the current limits. */ - if (*x < miPointer.limits.x1) - *x = miPointer.limits.x1; - if (*x >= miPointer.limits.x2) - *x = miPointer.limits.x2 - 1; - if (*y < miPointer.limits.y1) - *y = miPointer.limits.y1; - if (*y >= miPointer.limits.y2) - *y = miPointer.limits.y2 - 1; - - if (miPointer.x == *x && miPointer.y == *y && miPointer.pScreen == pScreen) - return; + if (*x < pPointer->limits.x1) + *x = pPointer->limits.x1; + if (*x >= pPointer->limits.x2) + *x = pPointer->limits.x2 - 1; + if (*y < pPointer->limits.y1) + *y = pPointer->limits.y1; + if (*y >= pPointer->limits.y2) + *y = pPointer->limits.y2 - 1; + + if (pPointer->x == *x && pPointer->y == *y && + pPointer->pScreen == pScreen) + return; miPointerMoved(pDev, pScreen, *x, *y, time); } @@ -482,17 +546,18 @@ miPointerPosition (int *x, int *y) _X_EXPORT void miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y) { - *x = miPointer.x; - *y = miPointer.y; + miPointerPtr pPointer = MIPOINTER(pDev); + *x = pPointer->x; + *y = pPointer->y; } void -miPointerMove (ScreenPtr pScreen, int x, int y, unsigned long time) +miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, unsigned long time) { int i, nevents; int valuators[2]; - miPointerMoved(inputInfo.pointer, pScreen, x, y, time); + miPointerMoved(pDev, pScreen, x, y, time); /* generate motion notify */ valuators[0] = x; diff --git a/mi/mipointer.h b/mi/mipointer.h index 1bce42c26..c4834139a 100644 --- a/mi/mipointer.h +++ b/mi/mipointer.h @@ -31,20 +31,24 @@ in this Software without prior written authorization from The Open Group. typedef struct _miPointerSpriteFuncRec { Bool (*RealizeCursor)( + DeviceIntPtr /* pDev */, ScreenPtr /* pScr */, CursorPtr /* pCurs */ ); Bool (*UnrealizeCursor)( + DeviceIntPtr /* pDev */, ScreenPtr /* pScr */, CursorPtr /* pCurs */ ); void (*SetCursor)( + DeviceIntPtr /* pDev */, ScreenPtr /* pScr */, CursorPtr /* pCurs */, int /* x */, int /* y */ ); void (*MoveCursor)( + DeviceIntPtr /* pDev */, ScreenPtr /* pScr */, int /* x */, int /* y */ @@ -62,6 +66,7 @@ typedef struct _miPointerScreenFuncRec { int /* entering */ ); void (*WarpCursor)( + DeviceIntPtr /*pDev*/, ScreenPtr /* pScr */, int /* x */, int /* y */ @@ -89,6 +94,7 @@ extern Bool miPointerInitialize( ); extern void miPointerWarpCursor( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, int /*x*/, int /*y*/ diff --git a/mi/misprite.c b/mi/misprite.c index c0560a4bb..bb67f48da 100644 --- a/mi/misprite.c +++ b/mi/misprite.c @@ -29,6 +29,12 @@ Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ +/* + * MPX additions: + * Copyright © 2006 Peter Hutterer + * Author: Peter Hutterer <peter@cs.unisa.edu.au> + * + */ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> @@ -50,12 +56,15 @@ in this Software without prior written authorization from The Open Group. # include "mispritest.h" # include "dixfontstr.h" # include <X11/fonts/fontstruct.h> +# include "inputstr.h" #ifdef RENDER # include "mipict.h" #endif # include "damage.h" + + #define SPRITE_DEBUG_ENABLE 0 #if SPRITE_DEBUG_ENABLE #define SPRITE_DEBUG(x) ErrorF x @@ -92,7 +101,8 @@ static void miSpriteStoreColors(ColormapPtr pMap, int ndef, static void miSpriteSaveDoomedAreas(WindowPtr pWin, RegionPtr pObscured, int dx, int dy); -static void miSpriteComputeSaved(ScreenPtr pScreen); +static void miSpriteComputeSaved(DeviceIntPtr pDev, + ScreenPtr pScreen); #define SCREEN_PROLOGUE(pScreen, field)\ ((pScreen)->field = \ @@ -105,11 +115,14 @@ static void miSpriteComputeSaved(ScreenPtr pScreen); * pointer-sprite method table */ -static Bool miSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -static Bool miSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor); -static void miSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCursor, - int x, int y); -static void miSpriteMoveCursor(ScreenPtr pScreen, int x, int y); +static Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor, int x, int y); +static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y); _X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = { miSpriteRealizeCursor, @@ -122,22 +135,37 @@ _X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = { * other misc functions */ -static void miSpriteRemoveCursor(ScreenPtr pScreen); -static void miSpriteRestoreCursor(ScreenPtr pScreen); +static void miSpriteRemoveCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); +static void miSpriteSaveUnderCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); +static void miSpriteRestoreCursor(DeviceIntPtr pDev, + ScreenPtr pScreen); static void miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) { ScreenPtr pScreen = closure; miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; + DeviceIntPtr pDev; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - - if (pScreenPriv->isUp && - RECT_IN_REGION (pScreen, pRegion, &pScreenPriv->saved) != rgnOUT) + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - SPRITE_DEBUG(("Damage remove\n")); - miSpriteRemoveCursor (pScreen); + if (DevHasCursor(pDev)) + { + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + if (pCursorInfo->isUp && + RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved) + != rgnOUT) + { + SPRITE_DEBUG(("Damage remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } } } @@ -155,6 +183,8 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs) { miSpriteScreenPtr pScreenPriv; VisualPtr pVisual; + miCursorInfoPtr pCursorInfo; + int cursorIdx; if (!DamageSetup (pScreen)) return FALSE; @@ -202,39 +232,61 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs) pScreenPriv->BlockHandler = pScreen->BlockHandler; - pScreenPriv->pCursor = NULL; - pScreenPriv->x = 0; - pScreenPriv->y = 0; - pScreenPriv->isUp = FALSE; - pScreenPriv->shouldBeUp = FALSE; - pScreenPriv->pCacheWin = NullWindow; - pScreenPriv->isInCacheWin = FALSE; - pScreenPriv->checkPixels = TRUE; - pScreenPriv->pInstalledMap = NULL; - pScreenPriv->pColormap = NULL; + /* alloc and zero memory for all cursors */ + pScreenPriv->pDevCursors = + (miCursorInfoPtr)xalloc(MAX_DEVICES * sizeof(miCursorInfoRec)); + + if (!pScreenPriv->pDevCursors) + { + xfree((pointer)pScreenPriv); + return FALSE; + } + /* virtual core pointer's ID is 1 */ + pScreenPriv->cp = &(pScreenPriv->pDevCursors[1]); + + cursorIdx = 0; + while (cursorIdx < MAX_DEVICES) + { + pCursorInfo = &(pScreenPriv->pDevCursors[cursorIdx]); + pCursorInfo->pCursor = NULL; + pCursorInfo->x = 0; + pCursorInfo->y = 0; + pCursorInfo->isUp = FALSE; + pCursorInfo->shouldBeUp = FALSE; + pCursorInfo->pCacheWin = NullWindow; + pCursorInfo->isInCacheWin = FALSE; + pCursorInfo->checkPixels = TRUE; + pCursorInfo->pInstalledMap = NULL; + pCursorInfo->pColormap = NULL; + pCursorInfo->colors[SOURCE_COLOR].red = 0; + pCursorInfo->colors[SOURCE_COLOR].green = 0; + pCursorInfo->colors[SOURCE_COLOR].blue = 0; + pCursorInfo->colors[MASK_COLOR].red = 0; + pCursorInfo->colors[MASK_COLOR].green = 0; + pCursorInfo->colors[MASK_COLOR].blue = 0; + + cursorIdx++; + } + pScreenPriv->funcs = cursorFuncs; - pScreenPriv->colors[SOURCE_COLOR].red = 0; - pScreenPriv->colors[SOURCE_COLOR].green = 0; - pScreenPriv->colors[SOURCE_COLOR].blue = 0; - pScreenPriv->colors[MASK_COLOR].red = 0; - pScreenPriv->colors[MASK_COLOR].green = 0; - pScreenPriv->colors[MASK_COLOR].blue = 0; pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pScreenPriv; - + pScreen->CloseScreen = miSpriteCloseScreen; pScreen->GetImage = miSpriteGetImage; pScreen->GetSpans = miSpriteGetSpans; pScreen->SourceValidate = miSpriteSourceValidate; - + pScreen->CopyWindow = miSpriteCopyWindow; - + pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas; - + pScreen->InstallColormap = miSpriteInstallColormap; pScreen->StoreColors = miSpriteStoreColors; pScreen->BlockHandler = miSpriteBlockHandler; - + + damageRegister = 0; + return TRUE; } @@ -253,6 +305,7 @@ miSpriteCloseScreen (i, pScreen) ScreenPtr pScreen; { miSpriteScreenPtr pScreenPriv; + DeviceIntPtr pDev; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; @@ -265,9 +318,18 @@ miSpriteCloseScreen (i, pScreen) pScreen->StoreColors = pScreenPriv->StoreColors; pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas; - miSpriteIsUpFALSE (pScreen, pScreenPriv); + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + miCursorInfoPtr pCursor; + pCursor = &pScreenPriv->pDevCursors[pDev->id]; + miSpriteIsUpFALSE (pCursor, pScreen, pScreenPriv); + } + } DamageDestroy (pScreenPriv->pDamage); - + + xfree ((pointer)(pScreenPriv->pDevCursors)); xfree ((pointer) pScreenPriv); return (*pScreen->CloseScreen) (i, pScreen); @@ -283,17 +345,27 @@ miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine) { ScreenPtr pScreen = pDrawable->pScreen; miSpriteScreenPtr pScreenPriv; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; SCREEN_PROLOGUE (pScreen, GetImage); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pDrawable->type == DRAWABLE_WINDOW && - pScreenPriv->isUp && - ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h)) + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) { - SPRITE_DEBUG (("GetImage remove\n")); - miSpriteRemoveCursor (pScreen); + if (DevHasCursor(pDev)) + { + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + if (pDrawable->type == DRAWABLE_WINDOW && + pCursorInfo->isUp && + ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, + sx, sy, w, h)) + { + SPRITE_DEBUG (("GetImage remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } } (*pScreen->GetImage) (pDrawable, sx, sy, w, h, @@ -313,34 +385,44 @@ miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart) { ScreenPtr pScreen = pDrawable->pScreen; miSpriteScreenPtr pScreenPriv; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; SCREEN_PROLOGUE (pScreen, GetSpans); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp) + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) { - DDXPointPtr pts; - int *widths; - int nPts; - int xorg, - yorg; - - xorg = pDrawable->x; - yorg = pDrawable->y; - - for (pts = ppt, widths = pwidth, nPts = nspans; - nPts--; - pts++, widths++) - { - if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg, - pts->x+xorg,*widths)) - { - SPRITE_DEBUG (("GetSpans remove\n")); - miSpriteRemoveCursor (pScreen); - break; - } - } + if (DevHasCursor(pDev)) + { + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp) + { + DDXPointPtr pts; + int *widths; + int nPts; + int xorg, + yorg; + + xorg = pDrawable->x; + yorg = pDrawable->y; + + for (pts = ppt, widths = pwidth, nPts = nspans; + nPts--; + pts++, widths++) + { + if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg, + pts->x+xorg,*widths)) + { + SPRITE_DEBUG (("GetSpans remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + break; + } + } + } + } } (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); @@ -355,17 +437,26 @@ miSpriteSourceValidate (pDrawable, x, y, width, height) { ScreenPtr pScreen = pDrawable->pScreen; miSpriteScreenPtr pScreenPriv; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; SCREEN_PROLOGUE (pScreen, SourceValidate); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp && - ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y, - x, y, width, height)) + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) { - SPRITE_DEBUG (("SourceValidate remove\n")); - miSpriteRemoveCursor (pScreen); + if (DevHasCursor(pDev)) + { + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp && + ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, + x, y, width, height)) + { + SPRITE_DEBUG (("SourceValidate remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } } if (pScreen->SourceValidate) @@ -379,18 +470,28 @@ miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWindow->drawable.pScreen; miSpriteScreenPtr pScreenPriv; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; SCREEN_PROLOGUE (pScreen, CopyWindow); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - /* - * Damage will take care of destination check - */ - if (pScreenPriv->isUp && - RECT_IN_REGION (pScreen, prgnSrc, &pScreenPriv->saved) != rgnOUT) + + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) { - SPRITE_DEBUG (("CopyWindow remove\n")); - miSpriteRemoveCursor (pScreen); + if (DevHasCursor(pDev)) + { + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + /* + * Damage will take care of destination check + */ + if (pCursorInfo->isUp && + RECT_IN_REGION (pScreen, prgnSrc, &pCursorInfo->saved) != rgnOUT) + { + SPRITE_DEBUG (("CopyWindow remove\n")); + miSpriteRemoveCursor (pDev, pScreen); + } + } } (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); @@ -406,6 +507,8 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask) { ScreenPtr pScreen = screenInfo.screens[i]; miSpriteScreenPtr pPriv; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; @@ -415,10 +518,29 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask) SCREEN_EPILOGUE(pScreen, BlockHandler); - if (!pPriv->isUp && pPriv->shouldBeUp) + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) { - SPRITE_DEBUG (("BlockHandler restore\n")); - miSpriteRestoreCursor (pScreen); + if (DevHasCursor(pDev)) + { + pCursorInfo = &pPriv->pDevCursors[pDev->id]; + if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp) + { + SPRITE_DEBUG (("BlockHandler restore\n")); + miSpriteSaveUnderCursor (pDev, pScreen); + } + } + } + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = &pPriv->pDevCursors[pDev->id]; + if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp) + { + SPRITE_DEBUG (("BlockHandler restore\n")); + miSpriteRestoreCursor (pDev, pScreen); + } + } } } @@ -428,6 +550,9 @@ miSpriteInstallColormap (pMap) { ScreenPtr pScreen = pMap->pScreen; miSpriteScreenPtr pPriv; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; + int cursorIdx; pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; @@ -437,12 +562,29 @@ miSpriteInstallColormap (pMap) SCREEN_EPILOGUE(pScreen, InstallColormap); - pPriv->pInstalledMap = pMap; - if (pPriv->pColormap != pMap) + /* InstallColormap is called before devices are initialized. We cannot + * just run through the device list, we need to go through all possible + * sprite structs.*/ + for (cursorIdx = 0; cursorIdx < MAX_DEVICES; cursorIdx++) { - pPriv->checkPixels = TRUE; - if (pPriv->isUp) - miSpriteRemoveCursor (pScreen); + pCursorInfo = &pPriv->pDevCursors[cursorIdx]; + pCursorInfo->pInstalledMap = pMap; + if (pCursorInfo->pColormap != pMap) + { + pCursorInfo->checkPixels = TRUE; + if (pCursorInfo->isUp) + { + /* find matching device */ + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (pDev->id == cursorIdx) + { + miSpriteRemoveCursor(pDev, pScreen); + break; + } + } + } + } } } @@ -457,6 +599,8 @@ miSpriteStoreColors (pMap, ndef, pdef) int i; int updated; VisualPtr pVisual; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; @@ -466,74 +610,82 @@ miSpriteStoreColors (pMap, ndef, pdef) SCREEN_EPILOGUE(pScreen, StoreColors); - if (pPriv->pColormap == pMap) - { - updated = 0; - pVisual = pMap->pVisual; - if (pVisual->class == DirectColor) - { - /* Direct color - match on any of the subfields */ - #define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) -#define UpdateDAC(plane,dac,mask) {\ - if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\ - pPriv->colors[plane].dac = pdef[i].dac; \ +#define UpdateDAC(dev, plane,dac,mask) {\ + if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\ + dev->colors[plane].dac = pdef[i].dac; \ updated = 1; \ } \ } -#define CheckDirect(plane) \ - UpdateDAC(plane,red,redMask) \ - UpdateDAC(plane,green,greenMask) \ - UpdateDAC(plane,blue,blueMask) +#define CheckDirect(dev, plane) \ + UpdateDAC(dev, plane,red,redMask) \ + UpdateDAC(dev, plane,green,greenMask) \ + UpdateDAC(dev, plane,blue,blueMask) - for (i = 0; i < ndef; i++) - { - CheckDirect (SOURCE_COLOR) - CheckDirect (MASK_COLOR) - } - } - else - { - /* PseudoColor/GrayScale - match on exact pixel */ - for (i = 0; i < ndef; i++) - { - if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel) - { - pPriv->colors[SOURCE_COLOR] = pdef[i]; - if (++updated == 2) - break; - } - if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) - { - pPriv->colors[MASK_COLOR] = pdef[i]; - if (++updated == 2) - break; - } - } - } - if (updated) - { - pPriv->checkPixels = TRUE; - if (pPriv->isUp) - miSpriteRemoveCursor (pScreen); - } + for(pDev = inputInfo.devices; pDev; pDev = pDev->next) + { + if (DevHasCursor(pDev)) + { + pCursorInfo = &pPriv->pDevCursors[pDev->id]; + if (pCursorInfo->pColormap == pMap) + { + updated = 0; + pVisual = pMap->pVisual; + if (pVisual->class == DirectColor) + { + /* Direct color - match on any of the subfields */ + + for (i = 0; i < ndef; i++) + { + CheckDirect (pCursorInfo, SOURCE_COLOR) + CheckDirect (pCursorInfo, MASK_COLOR) + } + } + else + { + /* PseudoColor/GrayScale - match on exact pixel */ + for (i = 0; i < ndef; i++) + { + if (pdef[i].pixel == + pCursorInfo->colors[SOURCE_COLOR].pixel) + { + pCursorInfo->colors[SOURCE_COLOR] = pdef[i]; + if (++updated == 2) + break; + } + if (pdef[i].pixel == + pCursorInfo->colors[MASK_COLOR].pixel) + { + pCursorInfo->colors[MASK_COLOR] = pdef[i]; + if (++updated == 2) + break; + } + } + } + if (updated) + { + pCursorInfo->checkPixels = TRUE; + if (pCursorInfo->isUp) + miSpriteRemoveCursor (pDev, pScreen); + } + } + } } + } static void -miSpriteFindColors (ScreenPtr pScreen) +miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) { - miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr) - pScreen->devPrivates[miSpriteScreenIndex].ptr; CursorPtr pCursor; xColorItem *sourceColor, *maskColor; - pCursor = pScreenPriv->pCursor; - sourceColor = &pScreenPriv->colors[SOURCE_COLOR]; - maskColor = &pScreenPriv->colors[MASK_COLOR]; - if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap || + pCursor = pDevCursor->pCursor; + sourceColor = &pDevCursor->colors[SOURCE_COLOR]; + maskColor = &pDevCursor->colors[MASK_COLOR]; + if (pDevCursor->pColormap != pDevCursor->pInstalledMap || !(pCursor->foreRed == sourceColor->red && pCursor->foreGreen == sourceColor->green && pCursor->foreBlue == sourceColor->blue && @@ -541,20 +693,22 @@ miSpriteFindColors (ScreenPtr pScreen) pCursor->backGreen == maskColor->green && pCursor->backBlue == maskColor->blue)) { - pScreenPriv->pColormap = pScreenPriv->pInstalledMap; + pDevCursor->pColormap = pDevCursor->pInstalledMap; sourceColor->red = pCursor->foreRed; sourceColor->green = pCursor->foreGreen; sourceColor->blue = pCursor->foreBlue; - FakeAllocColor (pScreenPriv->pColormap, sourceColor); + FakeAllocColor (pDevCursor->pColormap, sourceColor); maskColor->red = pCursor->backRed; maskColor->green = pCursor->backGreen; maskColor->blue = pCursor->backBlue; - FakeAllocColor (pScreenPriv->pColormap, maskColor); + FakeAllocColor (pDevCursor->pColormap, maskColor); /* "free" the pixels right away, don't let this confuse you */ - FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel); - FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel); + FakeFreeColor(pDevCursor->pColormap, sourceColor->pixel); + FakeFreeColor(pDevCursor->pColormap, maskColor->pixel); } - pScreenPriv->checkPixels = FALSE; + + pDevCursor->checkPixels = FALSE; + } /* @@ -570,25 +724,36 @@ miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy) ScreenPtr pScreen; miSpriteScreenPtr pScreenPriv; BoxRec cursorBox; + DeviceIntPtr pDev = inputInfo.pointer; + miCursorInfoPtr pCursorInfo; pScreen = pWin->drawable.pScreen; SCREEN_PROLOGUE (pScreen, SaveDoomedAreas); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pScreenPriv->isUp) + + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - cursorBox = pScreenPriv->saved; - - if (dx || dy) - { - cursorBox.x1 += dx; - cursorBox.y1 += dy; - cursorBox.x2 += dx; - cursorBox.y2 += dy; - } - if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT) - miSpriteRemoveCursor (pScreen); + if(DevHasCursor(pDev)) + { + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + if (pCursorInfo->isUp) + { + cursorBox = pCursorInfo->saved; + + if (dx || dy) + { + cursorBox.x1 += dx; + cursorBox.y1 += dy; + cursorBox.x2 += dx; + cursorBox.y2 += dy; + } + if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT) + miSpriteRemoveCursor (pDev, pScreen); + } + + } } (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy); @@ -603,20 +768,29 @@ miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy) #define SPRITE_PAD 8 static Bool -miSpriteRealizeCursor (pScreen, pCursor) +miSpriteRealizeCursor (pDev, pScreen, pCursor) + DeviceIntPtr pDev; ScreenPtr pScreen; CursorPtr pCursor; { miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pCursor == pScreenPriv->pCursor) - pScreenPriv->checkPixels = TRUE; + pCursorInfo = pScreenPriv->cp; + + if (DevHasCursor(pDev)) + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + if (pCursor == pCursorInfo->pCursor) + pCursorInfo->checkPixels = TRUE; + return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor); } static Bool -miSpriteUnrealizeCursor (pScreen, pCursor) +miSpriteUnrealizeCursor (pDev, pScreen, pCursor) + DeviceIntPtr pDev; ScreenPtr pScreen; CursorPtr pCursor; { @@ -627,7 +801,8 @@ miSpriteUnrealizeCursor (pScreen, pCursor) } static void -miSpriteSetCursor (pScreen, pCursor, x, y) +miSpriteSetCursor (pDev, pScreen, pCursor, x, y) + DeviceIntPtr pDev; ScreenPtr pScreen; CursorPtr pCursor; int x; @@ -636,107 +811,130 @@ miSpriteSetCursor (pScreen, pCursor, x, y) miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; + miCursorInfoPtr pPointer = pScreenPriv->cp; + + if (DevHasCursor(pDev)) + pPointer = &pScreenPriv->pDevCursors[pDev->id]; + if (!pCursor) { - pScreenPriv->shouldBeUp = FALSE; - if (pScreenPriv->isUp) - miSpriteRemoveCursor (pScreen); - pScreenPriv->pCursor = 0; + pPointer->shouldBeUp = FALSE; + if (pPointer->isUp) + miSpriteRemoveCursor (pDev, pScreen); + pPointer->pCursor = 0; return; } - pScreenPriv->shouldBeUp = TRUE; - if (pScreenPriv->x == x && - pScreenPriv->y == y && - pScreenPriv->pCursor == pCursor && - !pScreenPriv->checkPixels) + pPointer->shouldBeUp = TRUE; + if (pPointer->x == x && + pPointer->y == y && + pPointer->pCursor == pCursor && + !pPointer->checkPixels) { return; } - pScreenPriv->x = x; - pScreenPriv->y = y; - pScreenPriv->pCacheWin = NullWindow; - if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor) + pPointer->x = x; + pPointer->y = y; + pPointer->pCacheWin = NullWindow; + if (pPointer->checkPixels || pPointer->pCursor != pCursor) { - pScreenPriv->pCursor = pCursor; - miSpriteFindColors (pScreen); + pPointer->pCursor = pCursor; + miSpriteFindColors (pPointer, pScreen); } - if (pScreenPriv->isUp) { + if (pPointer->isUp) { +#if 0 + /* FIXME: Disabled for MPX, should be rewritten */ int sx, sy; /* * check to see if the old saved region * encloses the new sprite, in which case we use * the flicker-free MoveCursor primitive. */ - sx = pScreenPriv->x - (int)pCursor->bits->xhot; - sy = pScreenPriv->y - (int)pCursor->bits->yhot; - if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 && - sx < pScreenPriv->saved.x2 && - sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 && - sy < pScreenPriv->saved.y2 && + sx = pointer->x - (int)pCursor->bits->xhot; + sy = pointer->y - (int)pCursor->bits->yhot; + if (sx + (int) pCursor->bits->width >= pointer->saved.x1 && + sx < pointer->saved.x2 && + sy + (int) pCursor->bits->height >= pointer->saved.y1 && + sy < pointer->saved.y2 && (int) pCursor->bits->width + (2 * SPRITE_PAD) == - pScreenPriv->saved.x2 - pScreenPriv->saved.x1 && + pointer->saved.x2 - pointer->saved.x1 && (int) pCursor->bits->height + (2 * SPRITE_PAD) == - pScreenPriv->saved.y2 - pScreenPriv->saved.y1 + pointer->saved.y2 - pointer->saved.y1 ) { DamageDrawInternal (pScreen, TRUE); miSpriteIsUpFALSE (pScreen, pScreenPriv); - if (!(sx >= pScreenPriv->saved.x1 && - sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 && - sy >= pScreenPriv->saved.y1 && - sy + (int)pCursor->bits->height < pScreenPriv->saved.y2)) - { + if (!(sx >= pointer->saved.x1 && + sx + (int)pCursor->bits->width < pointer->saved.x2 + && sy >= pointer->saved.y1 && + sy + (int)pCursor->bits->height < + pointer->saved.y2)) + { int oldx1, oldy1, dx, dy; - oldx1 = pScreenPriv->saved.x1; - oldy1 = pScreenPriv->saved.y1; + oldx1 = pointer->saved.x1; + oldy1 = pointer->saved.y1; dx = oldx1 - (sx - SPRITE_PAD); dy = oldy1 - (sy - SPRITE_PAD); - pScreenPriv->saved.x1 -= dx; - pScreenPriv->saved.y1 -= dy; - pScreenPriv->saved.x2 -= dx; - pScreenPriv->saved.y2 -= dy; + pointer->saved.x1 -= dx; + pointer->saved.y1 -= dy; + pointer->saved.x2 -= dx; + pointer->saved.y2 -= dy; (void) (*pScreenPriv->funcs->ChangeSave) (pScreen, - pScreenPriv->saved.x1, - pScreenPriv->saved.y1, - pScreenPriv->saved.x2 - pScreenPriv->saved.x1, - pScreenPriv->saved.y2 - pScreenPriv->saved.y1, + pointer->saved.x1, + pointer->saved.y1, + pointer->saved.x2 - + pointer->saved.x1, + pointer->saved.y2 - + pointer->saved.y1, dx, dy); } (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor, - pScreenPriv->saved.x1, - pScreenPriv->saved.y1, - pScreenPriv->saved.x2 - pScreenPriv->saved.x1, - pScreenPriv->saved.y2 - pScreenPriv->saved.y1, - sx - pScreenPriv->saved.x1, - sy - pScreenPriv->saved.y1, - pScreenPriv->colors[SOURCE_COLOR].pixel, - pScreenPriv->colors[MASK_COLOR].pixel); + pointer->saved.x1, + pointer->saved.y1, + pointer->saved.x2 - + pointer->saved.x1, + pointer->saved.y2 - + pointer->saved.y1, + sx - pointer->saved.x1, + sy - pointer->saved.y1, + pointer->colors[SOURCE_COLOR].pixel, + pointer->colors[MASK_COLOR].pixel); miSpriteIsUpTRUE (pScreen, pScreenPriv); DamageDrawInternal (pScreen, FALSE); } else +#endif { - SPRITE_DEBUG (("SetCursor remove\n")); - miSpriteRemoveCursor (pScreen); + SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id)); + miSpriteRemoveCursor (pDev, pScreen); } } - if (!pScreenPriv->isUp && pScreenPriv->pCursor) + + if (!pPointer->isUp && pPointer->pCursor) { - SPRITE_DEBUG (("SetCursor restore\n")); - miSpriteRestoreCursor (pScreen); + SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id)); + miSpriteSaveUnderCursor(pDev, pScreen); + miSpriteRestoreCursor (pDev, pScreen); } + } static void -miSpriteMoveCursor (pScreen, x, y) +miSpriteMoveCursor (pDev, pScreen, x, y) + DeviceIntPtr pDev; ScreenPtr pScreen; int x, y; { miSpriteScreenPtr pScreenPriv; + CursorPtr pCursor; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y); + pCursor = pScreenPriv->cp->pCursor; + + if (DevHasCursor(pDev)) + pCursor = pScreenPriv->pDevCursors[pDev->id].pCursor; + + miSpriteSetCursor (pDev, pScreen, pCursor, x, y); } /* @@ -744,60 +942,121 @@ miSpriteMoveCursor (pScreen, x, y) */ static void -miSpriteRemoveCursor (pScreen) +miSpriteRemoveCursor (pDev, pScreen) + DeviceIntPtr pDev; ScreenPtr pScreen; { miSpriteScreenPtr pScreenPriv; + miCursorInfoPtr pCursorInfo; + DamageDrawInternal (pScreen, TRUE); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - miSpriteIsUpFALSE (pScreen, pScreenPriv); - pScreenPriv->pCacheWin = NullWindow; - if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen, - pScreenPriv->saved.x1, - pScreenPriv->saved.y1, - pScreenPriv->saved.x2 - pScreenPriv->saved.x1, - pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) + pCursorInfo = pScreenPriv->cp; + + if (DevHasCursor(pDev)) + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv); + pCursorInfo->pCacheWin = NullWindow; + miSpriteDisableDamage(pScreen, pScreenPriv); + if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pDev, + pScreen, + pCursorInfo->saved.x1, + pCursorInfo->saved.y1, + pCursorInfo->saved.x2 - + pCursorInfo->saved.x1, + pCursorInfo->saved.y2 - + pCursorInfo->saved.y1)) { - miSpriteIsUpTRUE (pScreen, pScreenPriv); + miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv); } + miSpriteEnableDamage(pScreen, pScreenPriv); + DamageDrawInternal (pScreen, FALSE); +} + +/* + * Called from the block handler, saves area under cursor + * before waiting for something to do. + */ + +static void +miSpriteSaveUnderCursor(pDev, pScreen) + DeviceIntPtr pDev; + ScreenPtr pScreen; +{ + miSpriteScreenPtr pScreenPriv; + int x, y; + CursorPtr pCursor; + miCursorInfoPtr pCursorInfo; + + DamageDrawInternal (pScreen, TRUE); + pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; + pCursorInfo = pScreenPriv->cp; + + if (DevHasCursor(pDev)) + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + miSpriteComputeSaved (pDev, pScreen); + pCursor = pCursorInfo->pCursor; + + x = pCursorInfo->x - (int)pCursor->bits->xhot; + y = pCursorInfo->y - (int)pCursor->bits->yhot; + miSpriteDisableDamage(pScreen, pScreenPriv); + + (*pScreenPriv->funcs->SaveUnderCursor) (pDev, + pScreen, + pCursorInfo->saved.x1, + pCursorInfo->saved.y1, + pCursorInfo->saved.x2 - + pCursorInfo->saved.x1, + pCursorInfo->saved.y2 - + pCursorInfo->saved.y1); + SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id)); + miSpriteEnableDamage(pScreen, pScreenPriv); DamageDrawInternal (pScreen, FALSE); } + /* * Called from the block handler, restores the cursor * before waiting for something to do. */ static void -miSpriteRestoreCursor (pScreen) +miSpriteRestoreCursor (pDev, pScreen) + DeviceIntPtr pDev; ScreenPtr pScreen; { miSpriteScreenPtr pScreenPriv; int x, y; CursorPtr pCursor; + miCursorInfoPtr pCursorInfo; DamageDrawInternal (pScreen, TRUE); - miSpriteComputeSaved (pScreen); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - pCursor = pScreenPriv->pCursor; - x = pScreenPriv->x - (int)pCursor->bits->xhot; - y = pScreenPriv->y - (int)pCursor->bits->yhot; - if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen, - pScreenPriv->saved.x1, - pScreenPriv->saved.y1, - pScreenPriv->saved.x2 - pScreenPriv->saved.x1, - pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) + pCursorInfo = pScreenPriv->cp; + + if (DevHasCursor(pDev)) + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + miSpriteComputeSaved (pDev, pScreen); + pCursor = pCursorInfo->pCursor; + + x = pCursorInfo->x - (int)pCursor->bits->xhot; + y = pCursorInfo->y - (int)pCursor->bits->yhot; + miSpriteDisableDamage(pScreen, pScreenPriv); + SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id)); + if (pCursorInfo->checkPixels) + miSpriteFindColors (pCursorInfo, pScreen); + if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen, + pCursor, x, y, + pCursorInfo->colors[SOURCE_COLOR].pixel, + pCursorInfo->colors[MASK_COLOR].pixel)) { - if (pScreenPriv->checkPixels) - miSpriteFindColors (pScreen); - if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y, - pScreenPriv->colors[SOURCE_COLOR].pixel, - pScreenPriv->colors[MASK_COLOR].pixel)) - { - miSpriteIsUpTRUE (pScreen, pScreenPriv); - } + miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv); } + miSpriteEnableDamage(pScreen, pScreenPriv); DamageDrawInternal (pScreen, FALSE); } @@ -806,24 +1065,32 @@ miSpriteRestoreCursor (pScreen) */ static void -miSpriteComputeSaved (pScreen) +miSpriteComputeSaved (pDev, pScreen) + DeviceIntPtr pDev; ScreenPtr pScreen; { miSpriteScreenPtr pScreenPriv; int x, y, w, h; int wpad, hpad; CursorPtr pCursor; + miCursorInfoPtr pCursorInfo; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - pCursor = pScreenPriv->pCursor; - x = pScreenPriv->x - (int)pCursor->bits->xhot; - y = pScreenPriv->y - (int)pCursor->bits->yhot; + pCursorInfo = pScreenPriv->cp; + + if (DevHasCursor(pDev)) + pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; + + pCursor = pCursorInfo->pCursor; + x = pCursorInfo->x - (int)pCursor->bits->xhot; + y = pCursorInfo->y - (int)pCursor->bits->yhot; w = pCursor->bits->width; h = pCursor->bits->height; wpad = SPRITE_PAD; hpad = SPRITE_PAD; - pScreenPriv->saved.x1 = x - wpad; - pScreenPriv->saved.y1 = y - hpad; - pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2; - pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2; + pCursorInfo->saved.x1 = x - wpad; + pCursorInfo->saved.y1 = y - hpad; + pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2; + pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2; } + diff --git a/mi/misprite.h b/mi/misprite.h index 5173b7736..96d2d7d54 100644 --- a/mi/misprite.h +++ b/mi/misprite.h @@ -42,6 +42,7 @@ typedef struct { CursorPtr /*pCursor*/ ); Bool (*PutUpCursor)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/, int /*x*/, @@ -50,6 +51,7 @@ typedef struct { unsigned long /*mask*/ ); Bool (*SaveUnderCursor)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, int /*x*/, int /*y*/, @@ -57,6 +59,7 @@ typedef struct { int /*h*/ ); Bool (*RestoreUnderCursor)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, int /*x*/, int /*y*/, @@ -64,6 +67,7 @@ typedef struct { int /*h*/ ); Bool (*MoveCursor)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, CursorPtr /*pCursor*/, int /*x*/, @@ -76,6 +80,7 @@ typedef struct { unsigned long /*mask*/ ); Bool (*ChangeSave)( + DeviceIntPtr /*pDev*/, ScreenPtr /*pScreen*/, int /*x*/, int /*y*/, diff --git a/mi/mispritest.h b/mi/mispritest.h index 5075f0580..8cc206420 100644 --- a/mi/mispritest.h +++ b/mi/mispritest.h @@ -43,6 +43,21 @@ in this Software without prior written authorization from The Open Group. #endif # include "damage.h" +typedef struct { + CursorPtr pCursor; + int x; /* cursor hotspot */ + int y; + BoxRec saved; /* saved area from the screen */ + Bool isUp; /* cursor in frame buffer */ + Bool shouldBeUp; /* cursor should be displayed */ + WindowPtr pCacheWin; /* window the cursor last seen in */ + Bool isInCacheWin; + Bool checkPixels; /* check colormap collision */ + xColorItem colors[2]; + ColormapPtr pInstalledMap; + ColormapPtr pColormap; +} miCursorInfoRec, *miCursorInfoPtr; + /* * per screen information */ @@ -67,36 +82,37 @@ typedef struct { /* os layer procedures */ ScreenBlockHandlerProcPtr BlockHandler; - CursorPtr pCursor; - int x; /* cursor hotspot */ - int y; - BoxRec saved; /* saved area from the screen */ - Bool isUp; /* cursor in frame buffer */ - Bool shouldBeUp; /* cursor should be displayed */ - WindowPtr pCacheWin; /* window the cursor last seen in */ - Bool isInCacheWin; - Bool checkPixels; /* check colormap collision */ - xColorItem colors[2]; - ColormapPtr pInstalledMap; - ColormapPtr pColormap; + miCursorInfoPtr cp; /* core pointer */ + VisualPtr pVisual; miSpriteCursorFuncPtr funcs; DamagePtr pDamage; /* damage tracking structure */ + miCursorInfoPtr pDevCursors; /* all cursors' info */ } miSpriteScreenRec, *miSpriteScreenPtr; #define SOURCE_COLOR 0 #define MASK_COLOR 1 -#define miSpriteIsUpTRUE(pScreen, pScreenPriv) if (!pScreenPriv->isUp) { \ - pScreenPriv->isUp = TRUE; \ - DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ -} +static int damageRegister = 0; -#define miSpriteIsUpFALSE(pScreen, pScreenPriv) if (pScreenPriv->isUp) { \ - DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ - pScreenPriv->isUp = FALSE; \ +#define miSpriteDisableDamage(pScreen, pScreenPriv) \ + if (damageRegister) { \ + DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ + damageRegister = 0; \ } +#define miSpriteEnableDamage(pScreen, pScreenPriv) \ + if (!damageRegister) {\ + damageRegister = 1; \ + DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ + } + +#define miSpriteIsUpTRUE(pDevCursor, pScreen, pScreenPriv) if (!pDevCursor->isUp) \ + pDevCursor->isUp = TRUE; + +#define miSpriteIsUpFALSE(pDevCursor, pScreen, pScreenPriv) if (pDevCursor->isUp) \ + pDevCursor->isUp = FALSE; + /* * Overlap BoxPtr and Box elements */ diff --git a/randr/rrpointer.c b/randr/rrpointer.c index c88a0f83e..fec5d45bf 100644 --- a/randr/rrpointer.c +++ b/randr/rrpointer.c @@ -21,6 +21,7 @@ */ #include "randrstr.h" +#include "inputstr.h" /* * When the pointer moves, check to see if the specified position is outside @@ -95,7 +96,7 @@ RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip) } } if (best_dx || best_dy) - (*pScreen->SetCursorPosition) (pScreen, x + best_dx, y + best_dy, TRUE); + (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, x + best_dx, y + best_dy, TRUE); pScrPriv->pointerCrtc = nearest; } @@ -140,6 +141,6 @@ RRPointerScreenConfigured (ScreenPtr pScreen) if (pScreen != pCurrentScreen) return; - GetSpritePosition (&x, &y); + GetSpritePosition(inputInfo.pointer, &x, &y); RRPointerToNearestCrtc (pScreen, x, y, NULL); } diff --git a/record/record.c b/record/record.c index 0ed8f84c2..4e7f92aef 100644 --- a/record/record.c +++ b/record/record.c @@ -43,6 +43,7 @@ and Jim Haggerty of Metheus. #include <X11/extensions/recordstr.h> #include "set.h" #include "swaprep.h" +#include "inputstr.h" #include <stdio.h> #include <assert.h> @@ -861,7 +862,7 @@ RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata) pev->u.u.type == ButtonRelease || pev->u.u.type == KeyPress || pev->u.u.type == KeyRelease)) { - int scr = XineramaGetCursorScreen(); + int scr = XineramaGetCursorScreen(inputInfo.pointer); memcpy(&shiftedEvent, pev, sizeof(xEvent)); shiftedEvent.u.keyButtonPointer.rootX += panoramiXdataPtr[scr].x - diff --git a/render/animcur.c b/render/animcur.c index 1f25e79d0..7bddc0dad 100644 --- a/render/animcur.c +++ b/render/animcur.c @@ -44,6 +44,7 @@ #include "dixfontstr.h" #include "opaque.h" #include "picturestr.h" +#include "inputstr.h" typedef struct _AnimCurElt { CursorPtr pCursor; /* cursor to show */ @@ -100,11 +101,13 @@ static int AnimCurGeneration; #define Unwrap(as,s,elt) ((s)->elt = (as)->elt) static Bool -AnimCurDisplayCursor (ScreenPtr pScreen, +AnimCurDisplayCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor); static Bool -AnimCurSetCursorPosition (ScreenPtr pScreen, +AnimCurSetCursorPosition (DeviceIntPtr pDev, + ScreenPtr pScreen, int x, int y, Bool generateEvent); @@ -134,7 +137,8 @@ AnimCurCloseScreen (int index, ScreenPtr pScreen) } static void -AnimCurCursorLimits (ScreenPtr pScreen, +AnimCurCursorLimits (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox) @@ -146,11 +150,13 @@ AnimCurCursorLimits (ScreenPtr pScreen, { AnimCurPtr ac = GetAnimCur(pCursor); - (*pScreen->CursorLimits) (pScreen, ac->elts[0].pCursor, pHotBox, pTopLeftBox); + (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor, + pHotBox, pTopLeftBox); } else { - (*pScreen->CursorLimits) (pScreen, pCursor, pHotBox, pTopLeftBox); + (*pScreen->CursorLimits) (inputInfo.pointer, pScreen, pCursor, + pHotBox, pTopLeftBox); } Wrap (as, pScreen, CursorLimits, AnimCurCursorLimits); } @@ -187,7 +193,9 @@ AnimCurScreenBlockHandler (int screenNum, */ DisplayCursor = pScreen->DisplayCursor; pScreen->DisplayCursor = as->DisplayCursor; - (void) (*pScreen->DisplayCursor) (pScreen, ac->elts[elt].pCursor); + (void) (*pScreen->DisplayCursor) (inputInfo.pointer, + pScreen, + ac->elts[elt].pCursor); as->DisplayCursor = pScreen->DisplayCursor; pScreen->DisplayCursor = DisplayCursor; @@ -202,7 +210,8 @@ AnimCurScreenBlockHandler (int screenNum, } static Bool -AnimCurDisplayCursor (ScreenPtr pScreen, +AnimCurDisplayCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor) { AnimCurScreenPtr as = GetAnimCurScreen(pScreen); @@ -215,7 +224,8 @@ AnimCurDisplayCursor (ScreenPtr pScreen, { AnimCurPtr ac = GetAnimCur(pCursor); - ret = (*pScreen->DisplayCursor) (pScreen, ac->elts[0].pCursor); + ret = (*pScreen->DisplayCursor) + (pDev, pScreen, ac->elts[0].pCursor); if (ret) { animCurState.elt = 0; @@ -231,14 +241,15 @@ AnimCurDisplayCursor (ScreenPtr pScreen, { animCurState.pCursor = 0; animCurState.pScreen = 0; - ret = (*pScreen->DisplayCursor) (pScreen, pCursor); + ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); } Wrap (as, pScreen, DisplayCursor, AnimCurDisplayCursor); return ret; } static Bool -AnimCurSetCursorPosition (ScreenPtr pScreen, +AnimCurSetCursorPosition (DeviceIntPtr pDev, + ScreenPtr pScreen, int x, int y, Bool generateEvent) @@ -249,13 +260,14 @@ AnimCurSetCursorPosition (ScreenPtr pScreen, Unwrap (as, pScreen, SetCursorPosition); if (animCurState.pCursor) animCurState.pScreen = pScreen; - ret = (*pScreen->SetCursorPosition) (pScreen, x, y, generateEvent); + ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); Wrap (as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); return ret; } static Bool -AnimCurRealizeCursor (ScreenPtr pScreen, +AnimCurRealizeCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor) { AnimCurScreenPtr as = GetAnimCurScreen(pScreen); @@ -265,13 +277,14 @@ AnimCurRealizeCursor (ScreenPtr pScreen, if (IsAnimCur(pCursor)) ret = TRUE; else - ret = (*pScreen->RealizeCursor) (pScreen, pCursor); + ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor); Wrap (as, pScreen, RealizeCursor, AnimCurRealizeCursor); return ret; } static Bool -AnimCurUnrealizeCursor (ScreenPtr pScreen, +AnimCurUnrealizeCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor) { AnimCurScreenPtr as = GetAnimCurScreen(pScreen); @@ -289,13 +302,14 @@ AnimCurUnrealizeCursor (ScreenPtr pScreen, ret = TRUE; } else - ret = (*pScreen->UnrealizeCursor) (pScreen, pCursor); + ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor); Wrap (as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); return ret; } static void -AnimCurRecolorCursor (ScreenPtr pScreen, +AnimCurRecolorCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor, Bool displayed) { @@ -308,12 +322,12 @@ AnimCurRecolorCursor (ScreenPtr pScreen, int i; for (i = 0; i < ac->nelt; i++) - (*pScreen->RecolorCursor) (pScreen, ac->elts[i].pCursor, + (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor, displayed && animCurState.elt == i); } else - (*pScreen->RecolorCursor) (pScreen, pCursor, displayed); + (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed); Wrap (as, pScreen, RecolorCursor, AnimCurRecolorCursor); } diff --git a/xfixes/cursor.c b/xfixes/cursor.c index 3cdacc0e4..2b357066b 100755 --- a/xfixes/cursor.c +++ b/xfixes/cursor.c @@ -122,7 +122,8 @@ typedef struct _CursorScreen { #define Unwrap(as,s,elt) ((s)->elt = (as)->elt) static Bool -CursorDisplayCursor (ScreenPtr pScreen, +CursorDisplayCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, CursorPtr pCursor) { CursorScreenPtr cs = GetCursorScreen(pScreen); @@ -131,9 +132,9 @@ CursorDisplayCursor (ScreenPtr pScreen, Unwrap (cs, pScreen, DisplayCursor); if (cs->pCursorHideCounts != NULL) { - ret = (*pScreen->DisplayCursor) (pScreen, pInvisibleCursor); + ret = (*pScreen->DisplayCursor) (pDev, pScreen, pInvisibleCursor); } else { - ret = (*pScreen->DisplayCursor) (pScreen, pCursor); + ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); } if (pCursor != CursorCurrent) @@ -356,7 +357,7 @@ ProcXFixesGetCursorImage (ClientPtr client) pCursor = CursorCurrent; if (!pCursor) return BadCursor; - GetSpritePosition (&x, &y); + GetSpritePosition (inputInfo.pointer, &x, &y); width = pCursor->bits->width; height = pCursor->bits->height; npixels = width * height; @@ -504,7 +505,7 @@ ProcXFixesGetCursorImageAndName (ClientPtr client) pCursor = CursorCurrent; if (!pCursor) return BadCursor; - GetSpritePosition (&x, &y); + GetSpritePosition (inputInfo.pointer, &x, &y); width = pCursor->bits->width; height = pCursor->bits->height; npixels = width * height; @@ -867,7 +868,7 @@ ProcXFixesHideCursor (ClientPtr client) ret = createCursorHideCount(client, pWin->drawable.pScreen); if (ret == Success) { - (void) CursorDisplayCursor(pWin->drawable.pScreen, CursorCurrent); + (void) CursorDisplayCursor(inputInfo.pointer, pWin->drawable.pScreen, CursorCurrent); } return ret; @@ -954,7 +955,7 @@ CursorFreeHideCount (pointer data, XID id) ScreenPtr pScreen = pChc->pScreen; deleteCursorHideCount(pChc, pChc->pScreen); - (void) CursorDisplayCursor(pScreen, CursorCurrent); + (void) CursorDisplayCursor(inputInfo.pointer, pScreen, CursorCurrent); return 1; } diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c index 7e27c5189..89c17d28a 100644 --- a/xkb/ddxDevBtn.c +++ b/xkb/ddxDevBtn.c @@ -60,7 +60,7 @@ int nAxes, i, count; if (nAxes > 6) nAxes = 6; - GetSpritePosition(&x,&y); + GetSpritePosition(dev, &x,&y); btn= (deviceKeyButtonPointer *) &events[0]; val= (deviceValuator *) &events[1]; if (press) btn->type= DeviceButtonPress; diff --git a/xkb/ddxFakeBtn.c b/xkb/ddxFakeBtn.c index 77222236f..10ce90b1f 100644 --- a/xkb/ddxFakeBtn.c +++ b/xkb/ddxFakeBtn.c @@ -49,7 +49,7 @@ DevicePtr ptr; if ((ptr = LookupPointerDevice())==NULL) return; - GetSpritePosition(&x,&y); + GetSpritePosition(inputInfo.pointer, &x,&y); ev.u.u.type = event; ev.u.u.detail = button; ev.u.keyButtonPointer.time = GetTimeInMillis(); diff --git a/xkb/ddxFakeMtn.c b/xkb/ddxFakeMtn.c index 1060afe99..446764c86 100644 --- a/xkb/ddxFakeMtn.c +++ b/xkb/ddxFakeMtn.c @@ -53,8 +53,8 @@ XkbDDXFakePointerMotion(unsigned flags,int x,int y) int oldX,oldY; ScreenPtr pScreen, oldScreen; - GetSpritePosition(&oldX, &oldY); - pScreen = oldScreen = GetSpriteWindow()->drawable.pScreen; + GetSpritePosition(inputInfo.pointer, &oldX, &oldY); + pScreen = oldScreen = GetSpriteWindow(inputInfo.pointer)->drawable.pScreen; #ifdef PANORAMIX if (!noPanoramiXExtension) { @@ -113,7 +113,7 @@ ScreenPtr pScreen, oldScreen; } if (pScreen != oldScreen) - NewCurrentScreen(pScreen, oldX, oldY); + NewCurrentScreen(inputInfo.pointer, pScreen, oldX, oldY); if (pScreen->SetCursorPosition) - (*pScreen->SetCursorPosition)(pScreen, oldX, oldY, TRUE); + (*pScreen->SetCursorPosition)(inputInfo.pointer, pScreen, oldX, oldY, TRUE); } diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 2e0c89fc2..4c3efe28d 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -875,7 +875,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); if ((filter->keycode!=0)&&(filter->keycode!=keycode)) return 1; - GetSpritePosition(&x,&y); + GetSpritePosition(inputInfo.pointer, &x,&y); ev.u.keyButtonPointer.time = GetTimeInMillis(); ev.u.keyButtonPointer.rootX = x; ev.u.keyButtonPointer.rootY = y; diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c index 11dc17ad3..1e5a43b1b 100644 --- a/xkb/xkbEvents.c +++ b/xkb/xkbEvents.c @@ -808,6 +808,7 @@ XkbFilterEvents(ClientPtr pClient,int nEvents,xEvent *xE) int i, button_mask; DeviceIntPtr pXDev = (DeviceIntPtr)LookupKeyboardDevice(); XkbSrvInfoPtr xkbi; +GrabInfoPtr grabinfo; xkbi= pXDev->key->xkbInfo; if ( pClient->xkbClientFlags & _XkbClientInitialized ) { @@ -831,7 +832,9 @@ XkbSrvInfoPtr xkbi; (_XkbIsReleaseEvent(xE[0].u.u.type)) ) { return False; } - if ((pXDev->grab != NullGrab) && pXDev->fromPassiveGrab && + /* just coreGrab is fine, pXDev is inputInfo.keyboard (see above) */ + if ((pXDev->coreGrab.grab != NullGrab) + && pXDev->coreGrab.fromPassiveGrab && ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { register unsigned state,flags; |