From 202b46eb6bf0d5f94973c2bf1e4ebe9d154eadbf Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 20 Dec 2006 13:05:53 +1030 Subject: [PATCH] xfree86: Changing "IsMPDevice" to "SharedPointer" option. Devices will default to MP devices. Xi: Adding QueryDevicePointer request/reply Adding WarpDevicePointer request/reply --- Changelog | 25 ++++- Xi/Makefile.am | 6 +- Xi/extinit.c | 13 +++ Xi/querydp.c | 166 +++++++++++++++++++++++++++++ Xi/querydp.h | 44 ++++++++ Xi/warpdevp.c | 186 +++++++++++++++++++++++++++++++++ Xi/warpdevp.h | 39 +++++++ dix/cursor.c | 3 - dix/events.c | 3 +- hw/xfree86/common/xf86Cursor.c | 4 +- hw/xfree86/common/xf86Xinput.c | 10 +- hw/xfree86/common/xf86Xinput.h | 2 +- include/dix.h | 7 ++ 13 files changed, 493 insertions(+), 15 deletions(-) create mode 100644 Xi/querydp.c create mode 100644 Xi/querydp.h create mode 100644 Xi/warpdevp.c create mode 100644 Xi/warpdevp.h diff --git a/Changelog b/Changelog index 589024860..f69846509 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,27 @@ -== 14.12.06 == +== 20.12.06 == +xfree86: Changing "IsMPDevice" to "SharedPointer" option. Devices will default + to MP devices. + +Xi: Adding QueryDevicePointer request/reply + Adding WarpDevicePointer request/reply + +Files: + hw/xfree86/common/xf86Xinput.c + hw/xfree86/common/xf86Cursor.c + hw/xfree86/common/xf86Xinput.h + Xi/extinit.c + Xi/querydp.c + Xi/querydp.h + Xi/Makefile.am + Xi/warpdevp.c + Xi/warpdevp.h + dix/cursor.c + dix/events.c + dix/dix.h + +Note: This commit requires libXi additions to use the new functions. + +== 18.12.06 == mi: removing MPX ifdefs global sprite renaming in mipointer and misprite fixed: multiple remove cursor call in miSpriteInstallColormap diff --git a/Xi/Makefile.am b/Xi/Makefile.am index fbe438543..0aa58449f 100644 --- a/Xi/Makefile.am +++ b/Xi/Makefile.am @@ -54,6 +54,8 @@ libXi_la_SOURCES = \ listdev.h \ opendev.c \ opendev.h \ + querydp.c \ + querydp.h \ queryst.c \ queryst.h \ selectev.c \ @@ -75,6 +77,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/extinit.c b/Xi/extinit.c index 454883762..161995883 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -98,6 +98,7 @@ SOFTWARE. #include "gtmotion.h" #include "listdev.h" #include "opendev.h" +#include "querydp.h" #include "queryst.h" #include "selectev.h" #include "sendexev.h" @@ -110,6 +111,7 @@ SOFTWARE. #include "ungrdev.h" #include "ungrdevb.h" #include "ungrdevk.h" +#include "warpdevp.h" static Mask lastExtEventMask = 1; int ExtEventIndex; @@ -334,6 +336,10 @@ ProcIDispatch(register 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 { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); } @@ -423,6 +429,10 @@ SProcIDispatch(register 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 { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); } @@ -495,6 +505,9 @@ 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 { FatalError("XINPUT confused sending swapped reply"); } diff --git a/Xi/querydp.c b/Xi/querydp.c new file mode 100644 index 000000000..04323e42a --- /dev/null +++ b/Xi/querydp.c @@ -0,0 +1,166 @@ +/* + +Copyright 2006 Peter Hutterer + +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 +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include +#include +#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(register ClientPtr client) +{ + register char n; + + REQUEST(xQueryDevicePointerReq); + swaps(&stuff->length, n); + return (ProcXQueryDevicePointer(client)); +} + +int +ProcXQueryDevicePointer(register 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) { + 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->pSprite; + 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->isMPDev) ? 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) +{ + register 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 + + 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 +#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/warpdevp.c b/Xi/warpdevp.c new file mode 100644 index 000000000..2b558d103 --- /dev/null +++ b/Xi/warpdevp.c @@ -0,0 +1,186 @@ +/* + +Copyright 2006 Peter Hutterer + +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 +#endif + +#include /* for inputstr.h */ +#include /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "windowstr.h" /* window structure */ +#include "scrnintstr.h" /* screen structure */ +#include +#include +#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(register ClientPtr client) +{ + register char n; + + REQUEST(xWarpDevicePointerReq); + swaps(&stuff->length, n); + return (ProcXWarpDevicePointer(client)); +} + +int +ProcXWarpDevicePointer(register 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, 0, + 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->pSprite; + 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 + + 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 +#endif + +#ifndef WARPDEVP_H +#define WARPDEVP_H 1 + +int SProcXWarpDevicePointer(ClientPtr /* client */ + ); + +int ProcXWarpDevicePointer(ClientPtr /* client */ + ); + +#endif /* WARPDEVP_H */ diff --git a/dix/cursor.c b/dix/cursor.c index f4e332f66..b58a7bf81 100644 --- a/dix/cursor.c +++ b/dix/cursor.c @@ -117,9 +117,6 @@ FreeCursor(pointer value, XID cid) ScreenPtr pscr; DeviceIntPtr pDev; - /* FIXME: MPX: When FreeClientRessources is called, it calls FreeCursor - * too often. Refcnt gots < 0 and FreeCursorBits segfaults because the - * memory is already freed. */ MPXDBG("freecursor refcount %d\n", pCurs->refcnt); if ( --pCurs->refcnt != 0) return(Success); diff --git a/dix/events.c b/dix/events.c index 73977c9f0..81efb708a 100644 --- a/dix/events.c +++ b/dix/events.c @@ -324,7 +324,6 @@ static CARD8 criticalEvents[32] = }; #ifdef PANORAMIX -static void ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py); static void PostNewCursor(DeviceIntPtr pDev); #define SyntheticMotion(dev, x, y) \ @@ -700,7 +699,7 @@ SetCriticalEvent(int event) } #ifdef SHAPE -static void +void ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) { BoxRec box; diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c index 27264a252..bbd6124af 100644 --- a/hw/xfree86/common/xf86Cursor.c +++ b/hw/xfree86/common/xf86Cursor.c @@ -434,9 +434,9 @@ xf86WarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { int sigstate; sigstate = xf86BlockSIGIO (); - miPointerWarpCursor(pDev, pScreen,x,y); + miPointerWarpCursor(pDev, pScreen, x, y); - xf86Info.currentScreen = pScreen; + xf86Info.currentScreen = pScreen; xf86UnblockSIGIO (sigstate); } diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index c262a9561..6f1ebf768 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -132,10 +132,10 @@ xf86ProcessCommonOptions(LocalDevicePtr local, xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name); } - if (xf86SetBoolOption(list, "IsMPDevice", 0)) { - local->flags |= XI86_MP_DEVICE; - xf86Msg(X_CONFIG, "%s: is MP device\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; @@ -171,7 +171,7 @@ xf86ActivateDevice(LocalDevicePtr local) local->dev = dev; dev->coreEvents = local->flags & XI86_ALWAYS_CORE; - dev->isMPDev = (local->flags & XI86_MP_DEVICE); + dev->isMPDev = !(local->flags & XI86_SHARED_POINTER); InitSprite(dev, dev->isMPDev); RegisterOtherDevice(dev); diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h index e8abce7f6..4eaf8fc6d 100644 --- a/hw/xfree86/common/xf86Xinput.h +++ b/hw/xfree86/common/xf86Xinput.h @@ -82,7 +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_MP_DEVICE 0x100 /* device is multipointer device */ +#define XI86_SHARED_POINTER 0x100 /* device shares core cursor */ #define XI_PRIVATE(dev) \ (((LocalDevicePtr)((dev)->public.devicePrivate))->private) diff --git a/include/dix.h b/include/dix.h index 266241906..8e34211c0 100644 --- a/include/dix.h +++ b/include/dix.h @@ -416,6 +416,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 */,