aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xext
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xext')
-rw-r--r--xorg-server/Xext/geext.c524
-rw-r--r--xorg-server/Xext/xtest.c1381
2 files changed, 951 insertions, 954 deletions
diff --git a/xorg-server/Xext/geext.c b/xorg-server/Xext/geext.c
index 951daf682..a6fbb0947 100644
--- a/xorg-server/Xext/geext.c
+++ b/xorg-server/Xext/geext.c
@@ -1,262 +1,262 @@
-/*
- * Copyright 2007-2008 Peter Hutterer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-#include "windowstr.h"
-#include <X11/extensions/ge.h>
-
-#include "geint.h"
-#include "geext.h"
-#include "protocol-versions.h"
-
-DevPrivateKeyRec GEClientPrivateKeyRec;
-
-int RT_GECLIENT = 0;
-
-GEExtension GEExtensions[MAXEXTENSIONS];
-
-/* Major available requests */
-static const int version_requests[] = {
- X_GEQueryVersion, /* before client sends QueryVersion */
- X_GEQueryVersion, /* must be set to last request in version 1 */
-};
-
-/* Forward declarations */
-static void SGEGenericEvent(xEvent* from, xEvent* to);
-
-#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
-
-/************************************************************/
-/* request handlers */
-/************************************************************/
-
-static int
-ProcGEQueryVersion(ClientPtr client)
-{
- int n;
- GEClientInfoPtr pGEClient = GEGetClient(client);
- xGEQueryVersionReply rep;
- REQUEST(xGEQueryVersionReq);
-
- REQUEST_SIZE_MATCH(xGEQueryVersionReq);
-
- rep.repType = X_Reply;
- rep.RepType = X_GEQueryVersion;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- /* return the supported version by the server */
- rep.majorVersion = SERVER_GE_MAJOR_VERSION;
- rep.minorVersion = SERVER_GE_MINOR_VERSION;
-
- /* Remember version the client requested */
- pGEClient->major_version = stuff->majorVersion;
- pGEClient->minor_version = stuff->minorVersion;
-
- if (client->swapped)
- {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- }
-
- WriteToClient(client, sizeof(xGEQueryVersionReply), (char*)&rep);
- return Success;
-}
-
-int (*ProcGEVector[GENumberRequests])(ClientPtr) = {
- /* Version 1.0 */
- ProcGEQueryVersion
-};
-
-/************************************************************/
-/* swapped request handlers */
-/************************************************************/
-static int
-SProcGEQueryVersion(ClientPtr client)
-{
- int n;
- REQUEST(xGEQueryVersionReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xGEQueryVersionReq);
- swaps(&stuff->majorVersion, n);
- swaps(&stuff->minorVersion, n);
- return(*ProcGEVector[stuff->ReqType])(client);
-}
-
-int (*SProcGEVector[GENumberRequests])(ClientPtr) = {
- /* Version 1.0 */
- SProcGEQueryVersion
-};
-
-
-/************************************************************/
-/* callbacks */
-/************************************************************/
-
-/* dispatch requests */
-static int
-ProcGEDispatch(ClientPtr client)
-{
- GEClientInfoPtr pGEClient = GEGetClient(client);
- REQUEST(xGEReq);
-
- if (pGEClient->major_version >= NUM_VERSION_REQUESTS)
- return BadRequest;
- if (stuff->ReqType > version_requests[pGEClient->major_version])
- return BadRequest;
-
- return (ProcGEVector[stuff->ReqType])(client);
-}
-
-/* dispatch swapped requests */
-static int
-SProcGEDispatch(ClientPtr client)
-{
- REQUEST(xGEReq);
- if (stuff->ReqType >= GENumberRequests)
- return BadRequest;
- return (*SProcGEVector[stuff->ReqType])(client);
-}
-
-/**
- * Called when a new client inits a connection to the X server.
- *
- * We alloc a simple struct to store the client's major/minor version. Can be
- * used in the furture for versioning support.
- */
-static void
-GEClientCallback(CallbackListPtr *list,
- pointer closure,
- pointer data)
-{
- NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
- ClientPtr pClient = clientinfo->client;
- GEClientInfoPtr pGEClient = GEGetClient(pClient);
-
- pGEClient->major_version = 0;
- pGEClient->minor_version = 0;
-}
-
-/* Reset extension. Called on server shutdown. */
-static void
-GEResetProc(ExtensionEntry *extEntry)
-{
- DeleteCallback(&ClientStateCallback, GEClientCallback, 0);
- EventSwapVector[GenericEvent] = NotImplemented;
-}
-
-/* Calls the registered event swap function for the extension.
- *
- * Each extension can register a swap function to handle GenericEvents being
- * swapped properly. The server calls SGEGenericEvent() before the event is
- * written on the wire, this one calls the registered swap function to do the
- * work.
- */
-static void
-SGEGenericEvent(xEvent* from, xEvent* to)
-{
- xGenericEvent* gefrom = (xGenericEvent*)from;
- xGenericEvent* geto = (xGenericEvent*)to;
-
- if (gefrom->extension > MAXEXTENSIONS)
- {
- ErrorF("GE: Invalid extension offset for event.\n");
- return;
- }
-
- if (GEExtensions[gefrom->extension & 0x7F].evswap)
- GEExtensions[gefrom->extension & 0x7F].evswap(gefrom, geto);
-}
-
-/* Init extension, register at server.
- * Since other extensions may rely on XGE (XInput does already), it is a good
- * idea to init XGE first, before any other extension.
- */
-void
-GEExtensionInit(void)
-{
- ExtensionEntry *extEntry;
-
- if (!dixRegisterPrivateKey(&GEClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(GEClientInfoRec)))
- FatalError("GEExtensionInit: GE private request failed.\n");
-
- if(!AddCallback(&ClientStateCallback, GEClientCallback, 0))
- {
- FatalError("GEExtensionInit: register client callback failed.\n");
- }
-
- if((extEntry = AddExtension(GE_NAME,
- 0, GENumberErrors,
- ProcGEDispatch, SProcGEDispatch,
- GEResetProc, StandardMinorOpcode)) != 0)
- {
- memset(GEExtensions, 0, sizeof(GEExtensions));
-
- EventSwapVector[GenericEvent] = (EventSwapPtr) SGEGenericEvent;
- } else {
- FatalError("GEInit: AddExtensions failed.\n");
- }
-
-}
-
-/************************************************************/
-/* interface for extensions */
-/************************************************************/
-
-/* Register an extension with GE. The given swap function will be called each
- * time an event is sent to a client with different byte order.
- * @param extension The extensions major opcode
- * @param ev_swap The event swap function.
- * @param ev_fill Called for an event before delivery. The extension now has
- * the chance to fill in necessary fields for the event.
- */
-void
-GERegisterExtension(int extension,
- void (*ev_swap)(xGenericEvent* from, xGenericEvent* to))
-{
- if ((extension & 0x7F) >= MAXEXTENSIONS)
- FatalError("GE: extension > MAXEXTENSIONS. This should not happen.\n");
-
- /* extension opcodes are > 128, might as well save some space here */
- GEExtensions[extension & 0x7f].evswap = ev_swap;
-}
-
-
-/* Sets type and extension field for a generic event. This is just an
- * auxiliary function, extensions could do it manually too.
- */
-void
-GEInitEvent(xGenericEvent* ev, int extension)
-{
- ev->type = GenericEvent;
- ev->extension = extension;
- ev->length = 0;
-}
-
+/*
+ * Copyright 2007-2008 Peter Hutterer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Author: Peter Hutterer, University of South Australia, NICTA
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+#include "windowstr.h"
+#include <X11/extensions/ge.h>
+
+#include "geint.h"
+#include "geext.h"
+#include "protocol-versions.h"
+
+DevPrivateKeyRec GEClientPrivateKeyRec;
+
+int RT_GECLIENT = 0;
+
+GEExtension GEExtensions[MAXEXTENSIONS];
+
+/* Major available requests */
+static const int version_requests[] = {
+ X_GEQueryVersion, /* before client sends QueryVersion */
+ X_GEQueryVersion, /* must be set to last request in version 1 */
+};
+
+/* Forward declarations */
+static void SGEGenericEvent(xEvent* from, xEvent* to);
+
+#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
+
+/************************************************************/
+/* request handlers */
+/************************************************************/
+
+static int
+ProcGEQueryVersion(ClientPtr client)
+{
+ int n;
+ GEClientInfoPtr pGEClient = GEGetClient(client);
+ xGEQueryVersionReply rep;
+ REQUEST(xGEQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xGEQueryVersionReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GEQueryVersion;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ /* return the supported version by the server */
+ rep.majorVersion = SERVER_GE_MAJOR_VERSION;
+ rep.minorVersion = SERVER_GE_MINOR_VERSION;
+
+ /* Remember version the client requested */
+ pGEClient->major_version = stuff->majorVersion;
+ pGEClient->minor_version = stuff->minorVersion;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+
+ WriteToClient(client, sizeof(xGEQueryVersionReply), (char*)&rep);
+ return Success;
+}
+
+int (*ProcGEVector[GENumberRequests])(ClientPtr) = {
+ /* Version 1.0 */
+ ProcGEQueryVersion
+};
+
+/************************************************************/
+/* swapped request handlers */
+/************************************************************/
+static int
+SProcGEQueryVersion(ClientPtr client)
+{
+ int n;
+ REQUEST(xGEQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xGEQueryVersionReq);
+ swaps(&stuff->majorVersion, n);
+ swaps(&stuff->minorVersion, n);
+ return(*ProcGEVector[stuff->ReqType])(client);
+}
+
+int (*SProcGEVector[GENumberRequests])(ClientPtr) = {
+ /* Version 1.0 */
+ SProcGEQueryVersion
+};
+
+
+/************************************************************/
+/* callbacks */
+/************************************************************/
+
+/* dispatch requests */
+static int
+ProcGEDispatch(ClientPtr client)
+{
+ GEClientInfoPtr pGEClient = GEGetClient(client);
+ REQUEST(xGEReq);
+
+ if (pGEClient->major_version >= NUM_VERSION_REQUESTS)
+ return BadRequest;
+ if (stuff->ReqType > version_requests[pGEClient->major_version])
+ return BadRequest;
+
+ return (ProcGEVector[stuff->ReqType])(client);
+}
+
+/* dispatch swapped requests */
+static int
+SProcGEDispatch(ClientPtr client)
+{
+ REQUEST(xGEReq);
+ if (stuff->ReqType >= GENumberRequests)
+ return BadRequest;
+ return (*SProcGEVector[stuff->ReqType])(client);
+}
+
+/**
+ * Called when a new client inits a connection to the X server.
+ *
+ * We alloc a simple struct to store the client's major/minor version. Can be
+ * used in the furture for versioning support.
+ */
+static void
+GEClientCallback(CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ GEClientInfoPtr pGEClient = GEGetClient(pClient);
+
+ pGEClient->major_version = 0;
+ pGEClient->minor_version = 0;
+}
+
+/* Reset extension. Called on server shutdown. */
+static void
+GEResetProc(ExtensionEntry *extEntry)
+{
+ DeleteCallback(&ClientStateCallback, GEClientCallback, 0);
+ EventSwapVector[GenericEvent] = NotImplemented;
+}
+
+/* Calls the registered event swap function for the extension.
+ *
+ * Each extension can register a swap function to handle GenericEvents being
+ * swapped properly. The server calls SGEGenericEvent() before the event is
+ * written on the wire, this one calls the registered swap function to do the
+ * work.
+ */
+static void
+SGEGenericEvent(xEvent* from, xEvent* to)
+{
+ xGenericEvent* gefrom = (xGenericEvent*)from;
+ xGenericEvent* geto = (xGenericEvent*)to;
+
+ if ((gefrom->extension & 0x7f) > MAXEXTENSIONS)
+ {
+ ErrorF("GE: Invalid extension offset for event.\n");
+ return;
+ }
+
+ if (GEExtensions[gefrom->extension & 0x7F].evswap)
+ GEExtensions[gefrom->extension & 0x7F].evswap(gefrom, geto);
+}
+
+/* Init extension, register at server.
+ * Since other extensions may rely on XGE (XInput does already), it is a good
+ * idea to init XGE first, before any other extension.
+ */
+void
+GEExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ if (!dixRegisterPrivateKey(&GEClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(GEClientInfoRec)))
+ FatalError("GEExtensionInit: GE private request failed.\n");
+
+ if(!AddCallback(&ClientStateCallback, GEClientCallback, 0))
+ {
+ FatalError("GEExtensionInit: register client callback failed.\n");
+ }
+
+ if((extEntry = AddExtension(GE_NAME,
+ 0, GENumberErrors,
+ ProcGEDispatch, SProcGEDispatch,
+ GEResetProc, StandardMinorOpcode)) != 0)
+ {
+ memset(GEExtensions, 0, sizeof(GEExtensions));
+
+ EventSwapVector[GenericEvent] = (EventSwapPtr) SGEGenericEvent;
+ } else {
+ FatalError("GEInit: AddExtensions failed.\n");
+ }
+
+}
+
+/************************************************************/
+/* interface for extensions */
+/************************************************************/
+
+/* Register an extension with GE. The given swap function will be called each
+ * time an event is sent to a client with different byte order.
+ * @param extension The extensions major opcode
+ * @param ev_swap The event swap function.
+ * @param ev_fill Called for an event before delivery. The extension now has
+ * the chance to fill in necessary fields for the event.
+ */
+void
+GERegisterExtension(int extension,
+ void (*ev_swap)(xGenericEvent* from, xGenericEvent* to))
+{
+ if ((extension & 0x7F) >= MAXEXTENSIONS)
+ FatalError("GE: extension > MAXEXTENSIONS. This should not happen.\n");
+
+ /* extension opcodes are > 128, might as well save some space here */
+ GEExtensions[extension & 0x7f].evswap = ev_swap;
+}
+
+
+/* Sets type and extension field for a generic event. This is just an
+ * auxiliary function, extensions could do it manually too.
+ */
+void
+GEInitEvent(xGenericEvent* ev, int extension)
+{
+ ev->type = GenericEvent;
+ ev->extension = extension;
+ ev->length = 0;
+}
+
diff --git a/xorg-server/Xext/xtest.c b/xorg-server/Xext/xtest.c
index 859057e2b..6780aa62a 100644
--- a/xorg-server/Xext/xtest.c
+++ b/xorg-server/Xext/xtest.c
@@ -1,692 +1,689 @@
-/*
-
- Copyright 1992, 1998 The Open Group
-
- 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 OPEN GROUP 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 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.
-
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xatom.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "windowstr.h"
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "dixevents.h"
-#include "sleepuntil.h"
-#include "mi.h"
-#include "xkbsrv.h"
-#include "xkbstr.h"
-#include <X11/extensions/xtestproto.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "exglobals.h"
-#include "mipointer.h"
-#include "xserver-properties.h"
-#include "exevents.h"
-#include "inpututils.h"
-
-#include "modinit.h"
-
-extern int DeviceValuator;
-
-/* XTest events are sent during request processing and may be interruped by
- * a SIGIO. We need a separate event list to avoid events overwriting each
- * other's memory */
-static EventListPtr xtest_evlist;
-
-/**
- * xtestpointer
- * is the virtual pointer for XTest. It is the first slave
- * device of the VCP.
- * xtestkeyboard
- * is the virtual keyboard for XTest. It is the first slave
- * device of the VCK
- *
- * Neither of these devices can be deleted.
- */
-DeviceIntPtr xtestpointer, xtestkeyboard;
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-static int XTestSwapFakeInput(
- ClientPtr /* client */,
- xReq * /* req */
- );
-
-
-static int
-ProcXTestGetVersion(ClientPtr client)
-{
- xXTestGetVersionReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xXTestGetVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = XTestMajorVersion;
- rep.minorVersion = XTestMinorVersion;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swaps(&rep.minorVersion, n);
- }
- WriteToClient(client, sizeof(xXTestGetVersionReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXTestCompareCursor(ClientPtr client)
-{
- REQUEST(xXTestCompareCursorReq);
- xXTestCompareCursorReply rep;
- WindowPtr pWin;
- CursorPtr pCursor;
- int n, rc;
- DeviceIntPtr ptr = PickPointer(client);
-
- REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- if (stuff->cursor == None)
- pCursor = NullCursor;
- else if (stuff->cursor == XTestCurrentCursor)
- pCursor = GetSpriteCursor(ptr);
- else {
- rc = dixLookupResourceByType((pointer *)&pCursor, stuff->cursor, RT_CURSOR,
- client, DixReadAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->cursor;
- return rc;
- }
- }
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.same = (wCursor(pWin) == pCursor);
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- }
- WriteToClient(client, sizeof(xXTestCompareCursorReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXTestFakeInput(ClientPtr client)
-{
- REQUEST(xXTestFakeInputReq);
- int nev, n, type, rc;
- xEvent *ev;
- DeviceIntPtr dev = NULL;
- WindowPtr root;
- Bool extension = FALSE;
- deviceValuator *dv = NULL;
- ValuatorMask mask;
- int valuators[MAX_VALUATORS] = {0};
- int numValuators = 0;
- int firstValuator = 0;
- int nevents = 0;
- int i;
- int base = 0;
- int flags = 0;
- int need_ptr_update = 1;
-
- nev = (stuff->length << 2) - sizeof(xReq);
- if ((nev % sizeof(xEvent)) || !nev)
- return BadLength;
- nev /= sizeof(xEvent);
- UpdateCurrentTime();
- ev = (xEvent *)&((xReq *)stuff)[1];
- type = ev->u.u.type & 0177;
-
- if (type >= EXTENSION_EVENT_BASE)
- {
- extension = TRUE;
-
- /* check device */
- rc = dixLookupDevice(&dev, stuff->deviceid & 0177, client,
- DixWriteAccess);
- if (rc != Success)
- {
- client->errorValue = stuff->deviceid & 0177;
- return rc;
- }
-
- /* check type */
- type -= DeviceValuator;
- switch (type) {
- case XI_DeviceKeyPress:
- case XI_DeviceKeyRelease:
- if (!dev->key)
- {
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
- break;
- case XI_DeviceButtonPress:
- case XI_DeviceButtonRelease:
- if (!dev->button)
- {
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
- break;
- case XI_DeviceMotionNotify:
- if (!dev->valuator)
- {
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
- break;
- case XI_ProximityIn:
- case XI_ProximityOut:
- if (!dev->proximity)
- {
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
- break;
- default:
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
-
- /* check validity */
- if (nev == 1 && type == XI_DeviceMotionNotify)
- return BadLength; /* DevMotion must be followed by DevValuator */
-
- if (type == XI_DeviceMotionNotify)
- {
- firstValuator = ((deviceValuator *)(ev+1))->first_valuator;
- if (firstValuator > dev->valuator->numAxes)
- {
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
-
- if (ev->u.u.detail == xFalse)
- flags |= POINTER_ABSOLUTE;
- } else
- {
- firstValuator = 0;
- flags |= POINTER_ABSOLUTE;
- }
-
- if (nev > 1 && !dev->valuator)
- {
- client->errorValue = dv->first_valuator;
- return BadValue;
- }
-
-
- /* check validity of valuator events */
- base = firstValuator;
- for (n = 1; n < nev; n++)
- {
- dv = (deviceValuator *)(ev + n);
- if (dv->type != DeviceValuator)
- {
- client->errorValue = dv->type;
- return BadValue;
- }
- if (dv->first_valuator != base)
- {
- client->errorValue = dv->first_valuator;
- return BadValue;
- }
- switch(dv->num_valuators)
- {
- case 6: valuators[base + 5] = dv->valuator5;
- case 5: valuators[base + 4] = dv->valuator4;
- case 4: valuators[base + 3] = dv->valuator3;
- case 3: valuators[base + 2] = dv->valuator2;
- case 2: valuators[base + 1] = dv->valuator1;
- case 1: valuators[base] = dv->valuator0;
- break;
- default:
- client->errorValue = dv->num_valuators;
- return BadValue;
- }
-
- base += dv->num_valuators;
- numValuators += dv->num_valuators;
-
- if (firstValuator + numValuators > dev->valuator->numAxes)
- {
- client->errorValue = dv->num_valuators;
- return BadValue;
- }
- }
- type = type - XI_DeviceKeyPress + KeyPress;
-
- } else
- {
- if (nev != 1)
- return BadLength;
- switch (type)
- {
- case KeyPress:
- case KeyRelease:
- dev = PickKeyboard(client);
- break;
- case ButtonPress:
- case ButtonRelease:
- dev = PickPointer(client);
- break;
- case MotionNotify:
- dev = PickPointer(client);
- valuators[0] = ev->u.keyButtonPointer.rootX;
- valuators[1] = ev->u.keyButtonPointer.rootY;
- numValuators = 2;
- firstValuator = 0;
- if (ev->u.u.detail == xFalse)
- flags = POINTER_ABSOLUTE | POINTER_SCREEN;
- break;
- default:
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
-
- dev = GetXTestDevice(dev);
- }
-
- /* If the event has a time set, wait for it to pass */
- if (ev->u.keyButtonPointer.time)
- {
- TimeStamp activateTime;
- CARD32 ms;
-
- activateTime = currentTime;
- ms = activateTime.milliseconds + ev->u.keyButtonPointer.time;
- if (ms < activateTime.milliseconds)
- activateTime.months++;
- activateTime.milliseconds = ms;
- ev->u.keyButtonPointer.time = 0;
-
- /* see mbuf.c:QueueDisplayRequest (from the deprecated Multibuffer
- * extension) for code similar to this */
-
- if (!ClientSleepUntil(client, &activateTime, NULL, NULL))
- {
- return BadAlloc;
- }
- /* swap the request back so we can simply re-execute it */
- if (client->swapped)
- {
- (void) XTestSwapFakeInput(client, (xReq *)stuff);
- swaps(&stuff->length, n);
- }
- ResetCurrentRequest (client);
- client->sequence--;
- return Success;
- }
-
- switch (type)
- {
- case KeyPress:
- case KeyRelease:
- if (!dev->key)
- return BadDevice;
-
- if (ev->u.u.detail < dev->key->xkbInfo->desc->min_key_code ||
- ev->u.u.detail > dev->key->xkbInfo->desc->max_key_code)
- {
- client->errorValue = ev->u.u.detail;
- return BadValue;
- }
-
- need_ptr_update = 0;
- break;
- case MotionNotify:
- if (!dev->valuator)
- return BadDevice;
-
- /* broken lib, XI events have root uninitialized */
- if (extension || ev->u.keyButtonPointer.root == None)
- root = GetCurrentRootWindow(dev);
- else
- {
- rc = dixLookupWindow(&root, ev->u.keyButtonPointer.root,
- client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
- if (root->parent)
- {
- client->errorValue = ev->u.keyButtonPointer.root;
- return BadValue;
- }
- }
- if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse)
- {
- client->errorValue = ev->u.u.detail;
- return BadValue;
- }
-
- /* FIXME: Xinerama! */
-
- break;
- case ButtonPress:
- case ButtonRelease:
- if (!dev->button)
- return BadDevice;
-
- if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
- {
- client->errorValue = ev->u.u.detail;
- return BadValue;
- }
- break;
- }
- if (screenIsSaved == SCREEN_SAVER_ON)
- dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
-
- switch(type) {
- case MotionNotify:
- valuator_mask_set_range(&mask, firstValuator, numValuators, valuators);
- nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags, &mask);
- break;
- case ButtonPress:
- case ButtonRelease:
- valuator_mask_set_range(&mask, firstValuator, numValuators, valuators);
- nevents = GetPointerEvents(xtest_evlist, dev, type, ev->u.u.detail,
- flags, &mask);
- break;
- case KeyPress:
- case KeyRelease:
- nevents = GetKeyboardEvents(xtest_evlist, dev, type, ev->u.u.detail);
- break;
- }
-
- for (i = 0; i < nevents; i++)
- mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL);
-
- if (need_ptr_update)
- miPointerUpdateSprite(dev);
- return Success;
-}
-
-static int
-ProcXTestGrabControl(ClientPtr client)
-{
- REQUEST(xXTestGrabControlReq);
-
- REQUEST_SIZE_MATCH(xXTestGrabControlReq);
- if ((stuff->impervious != xTrue) && (stuff->impervious != xFalse))
- {
- client->errorValue = stuff->impervious;
- return BadValue;
- }
- if (stuff->impervious)
- MakeClientGrabImpervious(client);
- else
- MakeClientGrabPervious(client);
- return Success;
-}
-
-static int
-ProcXTestDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_XTestGetVersion:
- return ProcXTestGetVersion(client);
- case X_XTestCompareCursor:
- return ProcXTestCompareCursor(client);
- case X_XTestFakeInput:
- return ProcXTestFakeInput(client);
- case X_XTestGrabControl:
- return ProcXTestGrabControl(client);
- default:
- return BadRequest;
- }
-}
-
-static int
-SProcXTestGetVersion(ClientPtr client)
-{
- int n;
- REQUEST(xXTestGetVersionReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXTestGetVersionReq);
- swaps(&stuff->minorVersion, n);
- return ProcXTestGetVersion(client);
-}
-
-static int
-SProcXTestCompareCursor(ClientPtr client)
-{
- int n;
- REQUEST(xXTestCompareCursorReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
- swapl(&stuff->window, n);
- swapl(&stuff->cursor, n);
- return ProcXTestCompareCursor(client);
-}
-
-static int
-XTestSwapFakeInput(ClientPtr client, xReq *req)
-{
- int nev;
- xEvent *ev;
- xEvent sev;
- EventSwapPtr proc;
-
- nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
- for (ev = (xEvent *)&req[1]; --nev >= 0; ev++)
- {
- /* Swap event */
- proc = EventSwapVector[ev->u.u.type & 0177];
- /* no swapping proc; invalid event type? */
- if (!proc || proc == NotImplemented) {
- client->errorValue = ev->u.u.type;
- return BadValue;
- }
- (*proc)(ev, &sev);
- *ev = sev;
- }
- return Success;
-}
-
-static int
-SProcXTestFakeInput(ClientPtr client)
-{
- int n;
- REQUEST(xReq);
-
- swaps(&stuff->length, n);
- n = XTestSwapFakeInput(client, stuff);
- if (n != Success)
- return n;
- return ProcXTestFakeInput(client);
-}
-
-static int
-SProcXTestGrabControl(ClientPtr client)
-{
- int n;
- REQUEST(xXTestGrabControlReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXTestGrabControlReq);
- return ProcXTestGrabControl(client);
-}
-
-static int
-SProcXTestDispatch (ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_XTestGetVersion:
- return SProcXTestGetVersion(client);
- case X_XTestCompareCursor:
- return SProcXTestCompareCursor(client);
- case X_XTestFakeInput:
- return SProcXTestFakeInput(client);
- case X_XTestGrabControl:
- return SProcXTestGrabControl(client);
- default:
- return BadRequest;
- }
-}
-
-/**
- * Allocate an virtual slave device for xtest events, this
- * is a slave device to inputInfo master devices
- */
-void InitXTestDevices(void)
-{
- if(AllocXTestDevice(serverClient, "Virtual core",
- &xtestpointer, &xtestkeyboard,
- inputInfo.pointer, inputInfo.keyboard) != Success)
- FatalError("Failed to allocate XTest devices");
-
- if (ActivateDevice(xtestpointer, TRUE) != Success ||
- ActivateDevice(xtestkeyboard, TRUE) != Success)
- FatalError("Failed to activate XTest core devices.");
- if (!EnableDevice(xtestpointer, TRUE) ||
- !EnableDevice(xtestkeyboard, TRUE))
- FatalError("Failed to enable XTest core devices.");
-
- AttachDevice(NULL, xtestpointer, inputInfo.pointer);
- AttachDevice(NULL, xtestkeyboard, inputInfo.keyboard);
-}
-
-/**
- * Don't allow changing the XTest property.
- */
-static int
-DeviceSetXTestProperty(DeviceIntPtr dev, Atom property,
- XIPropertyValuePtr prop, BOOL checkonly)
-{
- if (property == XIGetKnownProperty(XI_PROP_XTEST_DEVICE))
- return BadAccess;
-
- return Success;
-}
-
-/**
- * Allocate a device pair that is initialised as a slave
- * device with properties that identify the devices as belonging
- * to XTest subsystem.
- * This only creates the pair, Activate/Enable Device
- * still need to be called.
- */
-int AllocXTestDevice (ClientPtr client, char* name,
- DeviceIntPtr* ptr, DeviceIntPtr* keybd,
- DeviceIntPtr master_ptr, DeviceIntPtr master_keybd)
-{
- int retval;
- int len = strlen(name);
- char *xtestname = calloc(len + 7, 1 );
- char dummy = 1;
-
- strncpy( xtestname, name, len);
- strncat( xtestname, " XTEST", 6 );
-
- retval = AllocDevicePair( client, xtestname, ptr, keybd, CorePointerProc, CoreKeyboardProc, FALSE);
- if ( retval == Success ){
- (*ptr)->xtest_master_id = master_ptr->id;
- (*keybd)->xtest_master_id = master_keybd->id;
-
- XIChangeDeviceProperty(*ptr, XIGetKnownProperty(XI_PROP_XTEST_DEVICE),
- XA_INTEGER, 8, PropModeReplace, 1, &dummy,
- FALSE);
- XISetDevicePropertyDeletable(*ptr, XIGetKnownProperty(XI_PROP_XTEST_DEVICE), FALSE);
- XIRegisterPropertyHandler(*ptr, DeviceSetXTestProperty, NULL, NULL);
- XIChangeDeviceProperty(*keybd, XIGetKnownProperty(XI_PROP_XTEST_DEVICE),
- XA_INTEGER, 8, PropModeReplace, 1, &dummy,
- FALSE);
- XISetDevicePropertyDeletable(*keybd, XIGetKnownProperty(XI_PROP_XTEST_DEVICE), FALSE);
- XIRegisterPropertyHandler(*keybd, DeviceSetXTestProperty, NULL, NULL);
- }
-
- free( xtestname );
-
- return retval;
-}
-
-/**
- * If master is NULL, return TRUE if the given device is an xtest device or
- * FALSE otherwise.
- * If master is not NULL, return TRUE if the given device is this master's
- * xtest device.
- */
-BOOL
-IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
-{
- if (IsMaster(dev))
- return FALSE;
-
- /* deviceid 0 is reserved for XIAllDevices, non-zero mid means XTest
- * device */
- if (master)
- return dev->xtest_master_id == master->id;
-
- return dev->xtest_master_id != 0;
-}
-
-/**
- * @return The X Test virtual device for the given master.
- */
-DeviceIntPtr
-GetXTestDevice(DeviceIntPtr master)
-{
- DeviceIntPtr it;
-
- for (it = inputInfo.devices; it; it = it->next)
- {
- if (IsXTestDevice(it, master))
- return it;
- }
-
- /* This only happens if master is a slave device. don't do that */
- return NULL;
-}
-
-void
-XTestExtensionInit(INITARGS)
-{
- AddExtension(XTestExtensionName, 0, 0,
- ProcXTestDispatch, SProcXTestDispatch,
- NULL, StandardMinorOpcode);
-
- xtest_evlist = InitEventList(GetMaximumEventsNum());
-}
+/*
+
+ Copyright 1992, 1998 The Open Group
+
+ 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 OPEN GROUP 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 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.
+
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "dixevents.h"
+#include "sleepuntil.h"
+#include "mi.h"
+#include "xkbsrv.h"
+#include "xkbstr.h"
+#include <X11/extensions/xtestproto.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "exglobals.h"
+#include "mipointer.h"
+#include "xserver-properties.h"
+#include "exevents.h"
+#include "inpututils.h"
+
+#include "modinit.h"
+
+extern int DeviceValuator;
+
+/* XTest events are sent during request processing and may be interruped by
+ * a SIGIO. We need a separate event list to avoid events overwriting each
+ * other's memory */
+static EventListPtr xtest_evlist;
+
+/**
+ * xtestpointer
+ * is the virtual pointer for XTest. It is the first slave
+ * device of the VCP.
+ * xtestkeyboard
+ * is the virtual keyboard for XTest. It is the first slave
+ * device of the VCK
+ *
+ * Neither of these devices can be deleted.
+ */
+DeviceIntPtr xtestpointer, xtestkeyboard;
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+static int XTestSwapFakeInput(
+ ClientPtr /* client */,
+ xReq * /* req */
+ );
+
+
+static int
+ProcXTestGetVersion(ClientPtr client)
+{
+ xXTestGetVersionReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xXTestGetVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XTestMajorVersion;
+ rep.minorVersion = XTestMinorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xXTestGetVersionReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXTestCompareCursor(ClientPtr client)
+{
+ REQUEST(xXTestCompareCursorReq);
+ xXTestCompareCursorReply rep;
+ WindowPtr pWin;
+ CursorPtr pCursor;
+ int n, rc;
+ DeviceIntPtr ptr = PickPointer(client);
+
+ REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (stuff->cursor == None)
+ pCursor = NullCursor;
+ else if (stuff->cursor == XTestCurrentCursor)
+ pCursor = GetSpriteCursor(ptr);
+ else {
+ rc = dixLookupResourceByType((pointer *)&pCursor, stuff->cursor, RT_CURSOR,
+ client, DixReadAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->cursor;
+ return rc;
+ }
+ }
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.same = (wCursor(pWin) == pCursor);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ }
+ WriteToClient(client, sizeof(xXTestCompareCursorReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXTestFakeInput(ClientPtr client)
+{
+ REQUEST(xXTestFakeInputReq);
+ int nev, n, type, rc;
+ xEvent *ev;
+ DeviceIntPtr dev = NULL;
+ WindowPtr root;
+ Bool extension = FALSE;
+ deviceValuator *dv = NULL;
+ ValuatorMask mask;
+ int valuators[MAX_VALUATORS] = {0};
+ int numValuators = 0;
+ int firstValuator = 0;
+ int nevents = 0;
+ int i;
+ int base = 0;
+ int flags = 0;
+ int need_ptr_update = 1;
+
+ nev = (stuff->length << 2) - sizeof(xReq);
+ if ((nev % sizeof(xEvent)) || !nev)
+ return BadLength;
+ nev /= sizeof(xEvent);
+ UpdateCurrentTime();
+ ev = (xEvent *)&((xReq *)stuff)[1];
+ type = ev->u.u.type & 0177;
+
+ if (type >= EXTENSION_EVENT_BASE)
+ {
+ extension = TRUE;
+
+ /* check device */
+ rc = dixLookupDevice(&dev, stuff->deviceid & 0177, client,
+ DixWriteAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->deviceid & 0177;
+ return rc;
+ }
+
+ /* check type */
+ type -= DeviceValuator;
+ switch (type) {
+ case XI_DeviceKeyPress:
+ case XI_DeviceKeyRelease:
+ if (!dev->key)
+ {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ break;
+ case XI_DeviceButtonPress:
+ case XI_DeviceButtonRelease:
+ if (!dev->button)
+ {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ break;
+ case XI_DeviceMotionNotify:
+ if (!dev->valuator)
+ {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ break;
+ case XI_ProximityIn:
+ case XI_ProximityOut:
+ if (!dev->proximity)
+ {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ break;
+ default:
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+
+ /* check validity */
+ if (nev == 1 && type == XI_DeviceMotionNotify)
+ return BadLength; /* DevMotion must be followed by DevValuator */
+
+ if (type == XI_DeviceMotionNotify)
+ {
+ firstValuator = ((deviceValuator *)(ev+1))->first_valuator;
+ if (firstValuator > dev->valuator->numAxes)
+ {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+
+ if (ev->u.u.detail == xFalse)
+ flags |= POINTER_ABSOLUTE;
+ } else
+ {
+ firstValuator = 0;
+ flags |= POINTER_ABSOLUTE;
+ }
+
+ if (nev > 1 && !dev->valuator)
+ {
+ client->errorValue = dv->first_valuator;
+ return BadValue;
+ }
+
+
+ /* check validity of valuator events */
+ base = firstValuator;
+ for (n = 1; n < nev; n++)
+ {
+ dv = (deviceValuator *)(ev + n);
+ if (dv->type != DeviceValuator)
+ {
+ client->errorValue = dv->type;
+ return BadValue;
+ }
+ if (dv->first_valuator != base)
+ {
+ client->errorValue = dv->first_valuator;
+ return BadValue;
+ }
+ switch(dv->num_valuators)
+ {
+ case 6: valuators[base + 5] = dv->valuator5;
+ case 5: valuators[base + 4] = dv->valuator4;
+ case 4: valuators[base + 3] = dv->valuator3;
+ case 3: valuators[base + 2] = dv->valuator2;
+ case 2: valuators[base + 1] = dv->valuator1;
+ case 1: valuators[base] = dv->valuator0;
+ break;
+ default:
+ client->errorValue = dv->num_valuators;
+ return BadValue;
+ }
+
+ base += dv->num_valuators;
+ numValuators += dv->num_valuators;
+
+ if (firstValuator + numValuators > dev->valuator->numAxes)
+ {
+ client->errorValue = dv->num_valuators;
+ return BadValue;
+ }
+ }
+ type = type - XI_DeviceKeyPress + KeyPress;
+
+ } else
+ {
+ if (nev != 1)
+ return BadLength;
+ switch (type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ dev = PickKeyboard(client);
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ dev = PickPointer(client);
+ break;
+ case MotionNotify:
+ dev = PickPointer(client);
+ valuators[0] = ev->u.keyButtonPointer.rootX;
+ valuators[1] = ev->u.keyButtonPointer.rootY;
+ numValuators = 2;
+ firstValuator = 0;
+ if (ev->u.u.detail == xFalse)
+ flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+ break;
+ default:
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+
+ dev = GetXTestDevice(dev);
+ }
+
+ /* If the event has a time set, wait for it to pass */
+ if (ev->u.keyButtonPointer.time)
+ {
+ TimeStamp activateTime;
+ CARD32 ms;
+
+ activateTime = currentTime;
+ ms = activateTime.milliseconds + ev->u.keyButtonPointer.time;
+ if (ms < activateTime.milliseconds)
+ activateTime.months++;
+ activateTime.milliseconds = ms;
+ ev->u.keyButtonPointer.time = 0;
+
+ /* see mbuf.c:QueueDisplayRequest (from the deprecated Multibuffer
+ * extension) for code similar to this */
+
+ if (!ClientSleepUntil(client, &activateTime, NULL, NULL))
+ {
+ return BadAlloc;
+ }
+ /* swap the request back so we can simply re-execute it */
+ if (client->swapped)
+ {
+ (void) XTestSwapFakeInput(client, (xReq *)stuff);
+ swaps(&stuff->length, n);
+ }
+ ResetCurrentRequest (client);
+ client->sequence--;
+ return Success;
+ }
+
+ switch (type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ if (!dev->key)
+ return BadDevice;
+
+ if (ev->u.u.detail < dev->key->xkbInfo->desc->min_key_code ||
+ ev->u.u.detail > dev->key->xkbInfo->desc->max_key_code)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+
+ need_ptr_update = 0;
+ break;
+ case MotionNotify:
+ if (!dev->valuator)
+ return BadDevice;
+
+ if (!(extension || ev->u.keyButtonPointer.root == None))
+ {
+ rc = dixLookupWindow(&root, ev->u.keyButtonPointer.root,
+ client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (root->parent)
+ {
+ client->errorValue = ev->u.keyButtonPointer.root;
+ return BadValue;
+ }
+ }
+ if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+
+ /* FIXME: Xinerama! */
+
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ if (!dev->button)
+ return BadDevice;
+
+ if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+ break;
+ }
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
+
+ switch(type) {
+ case MotionNotify:
+ valuator_mask_set_range(&mask, firstValuator, numValuators, valuators);
+ nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags, &mask);
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ valuator_mask_set_range(&mask, firstValuator, numValuators, valuators);
+ nevents = GetPointerEvents(xtest_evlist, dev, type, ev->u.u.detail,
+ flags, &mask);
+ break;
+ case KeyPress:
+ case KeyRelease:
+ nevents = GetKeyboardEvents(xtest_evlist, dev, type, ev->u.u.detail);
+ break;
+ }
+
+ for (i = 0; i < nevents; i++)
+ mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL);
+
+ if (need_ptr_update)
+ miPointerUpdateSprite(dev);
+ return Success;
+}
+
+static int
+ProcXTestGrabControl(ClientPtr client)
+{
+ REQUEST(xXTestGrabControlReq);
+
+ REQUEST_SIZE_MATCH(xXTestGrabControlReq);
+ if ((stuff->impervious != xTrue) && (stuff->impervious != xFalse))
+ {
+ client->errorValue = stuff->impervious;
+ return BadValue;
+ }
+ if (stuff->impervious)
+ MakeClientGrabImpervious(client);
+ else
+ MakeClientGrabPervious(client);
+ return Success;
+}
+
+static int
+ProcXTestDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XTestGetVersion:
+ return ProcXTestGetVersion(client);
+ case X_XTestCompareCursor:
+ return ProcXTestCompareCursor(client);
+ case X_XTestFakeInput:
+ return ProcXTestFakeInput(client);
+ case X_XTestGrabControl:
+ return ProcXTestGrabControl(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcXTestGetVersion(ClientPtr client)
+{
+ int n;
+ REQUEST(xXTestGetVersionReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXTestGetVersionReq);
+ swaps(&stuff->minorVersion, n);
+ return ProcXTestGetVersion(client);
+}
+
+static int
+SProcXTestCompareCursor(ClientPtr client)
+{
+ int n;
+ REQUEST(xXTestCompareCursorReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->cursor, n);
+ return ProcXTestCompareCursor(client);
+}
+
+static int
+XTestSwapFakeInput(ClientPtr client, xReq *req)
+{
+ int nev;
+ xEvent *ev;
+ xEvent sev;
+ EventSwapPtr proc;
+
+ nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
+ for (ev = (xEvent *)&req[1]; --nev >= 0; ev++)
+ {
+ /* Swap event */
+ proc = EventSwapVector[ev->u.u.type & 0177];
+ /* no swapping proc; invalid event type? */
+ if (!proc || proc == NotImplemented) {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ (*proc)(ev, &sev);
+ *ev = sev;
+ }
+ return Success;
+}
+
+static int
+SProcXTestFakeInput(ClientPtr client)
+{
+ int n;
+ REQUEST(xReq);
+
+ swaps(&stuff->length, n);
+ n = XTestSwapFakeInput(client, stuff);
+ if (n != Success)
+ return n;
+ return ProcXTestFakeInput(client);
+}
+
+static int
+SProcXTestGrabControl(ClientPtr client)
+{
+ int n;
+ REQUEST(xXTestGrabControlReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXTestGrabControlReq);
+ return ProcXTestGrabControl(client);
+}
+
+static int
+SProcXTestDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XTestGetVersion:
+ return SProcXTestGetVersion(client);
+ case X_XTestCompareCursor:
+ return SProcXTestCompareCursor(client);
+ case X_XTestFakeInput:
+ return SProcXTestFakeInput(client);
+ case X_XTestGrabControl:
+ return SProcXTestGrabControl(client);
+ default:
+ return BadRequest;
+ }
+}
+
+/**
+ * Allocate an virtual slave device for xtest events, this
+ * is a slave device to inputInfo master devices
+ */
+void InitXTestDevices(void)
+{
+ if(AllocXTestDevice(serverClient, "Virtual core",
+ &xtestpointer, &xtestkeyboard,
+ inputInfo.pointer, inputInfo.keyboard) != Success)
+ FatalError("Failed to allocate XTest devices");
+
+ if (ActivateDevice(xtestpointer, TRUE) != Success ||
+ ActivateDevice(xtestkeyboard, TRUE) != Success)
+ FatalError("Failed to activate XTest core devices.");
+ if (!EnableDevice(xtestpointer, TRUE) ||
+ !EnableDevice(xtestkeyboard, TRUE))
+ FatalError("Failed to enable XTest core devices.");
+
+ AttachDevice(NULL, xtestpointer, inputInfo.pointer);
+ AttachDevice(NULL, xtestkeyboard, inputInfo.keyboard);
+}
+
+/**
+ * Don't allow changing the XTest property.
+ */
+static int
+DeviceSetXTestProperty(DeviceIntPtr dev, Atom property,
+ XIPropertyValuePtr prop, BOOL checkonly)
+{
+ if (property == XIGetKnownProperty(XI_PROP_XTEST_DEVICE))
+ return BadAccess;
+
+ return Success;
+}
+
+/**
+ * Allocate a device pair that is initialised as a slave
+ * device with properties that identify the devices as belonging
+ * to XTest subsystem.
+ * This only creates the pair, Activate/Enable Device
+ * still need to be called.
+ */
+int AllocXTestDevice (ClientPtr client, char* name,
+ DeviceIntPtr* ptr, DeviceIntPtr* keybd,
+ DeviceIntPtr master_ptr, DeviceIntPtr master_keybd)
+{
+ int retval;
+ int len = strlen(name);
+ char *xtestname = calloc(len + 7, 1 );
+ char dummy = 1;
+
+ strncpy( xtestname, name, len);
+ strncat( xtestname, " XTEST", 6 );
+
+ retval = AllocDevicePair( client, xtestname, ptr, keybd, CorePointerProc, CoreKeyboardProc, FALSE);
+ if ( retval == Success ){
+ (*ptr)->xtest_master_id = master_ptr->id;
+ (*keybd)->xtest_master_id = master_keybd->id;
+
+ XIChangeDeviceProperty(*ptr, XIGetKnownProperty(XI_PROP_XTEST_DEVICE),
+ XA_INTEGER, 8, PropModeReplace, 1, &dummy,
+ FALSE);
+ XISetDevicePropertyDeletable(*ptr, XIGetKnownProperty(XI_PROP_XTEST_DEVICE), FALSE);
+ XIRegisterPropertyHandler(*ptr, DeviceSetXTestProperty, NULL, NULL);
+ XIChangeDeviceProperty(*keybd, XIGetKnownProperty(XI_PROP_XTEST_DEVICE),
+ XA_INTEGER, 8, PropModeReplace, 1, &dummy,
+ FALSE);
+ XISetDevicePropertyDeletable(*keybd, XIGetKnownProperty(XI_PROP_XTEST_DEVICE), FALSE);
+ XIRegisterPropertyHandler(*keybd, DeviceSetXTestProperty, NULL, NULL);
+ }
+
+ free( xtestname );
+
+ return retval;
+}
+
+/**
+ * If master is NULL, return TRUE if the given device is an xtest device or
+ * FALSE otherwise.
+ * If master is not NULL, return TRUE if the given device is this master's
+ * xtest device.
+ */
+BOOL
+IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
+{
+ if (IsMaster(dev))
+ return FALSE;
+
+ /* deviceid 0 is reserved for XIAllDevices, non-zero mid means XTest
+ * device */
+ if (master)
+ return dev->xtest_master_id == master->id;
+
+ return dev->xtest_master_id != 0;
+}
+
+/**
+ * @return The X Test virtual device for the given master.
+ */
+DeviceIntPtr
+GetXTestDevice(DeviceIntPtr master)
+{
+ DeviceIntPtr it;
+
+ for (it = inputInfo.devices; it; it = it->next)
+ {
+ if (IsXTestDevice(it, master))
+ return it;
+ }
+
+ /* This only happens if master is a slave device. don't do that */
+ return NULL;
+}
+
+void
+XTestExtensionInit(INITARGS)
+{
+ AddExtension(XTestExtensionName, 0, 0,
+ ProcXTestDispatch, SProcXTestDispatch,
+ NULL, StandardMinorOpcode);
+
+ xtest_evlist = InitEventList(GetMaximumEventsNum());
+}