1
/* $XdotOrg: xserver/xorg/Xext/xtest.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
2
/* $Xorg: xtest.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
5
Copyright 1992, 1998 The Open Group
7
Permission to use, copy, modify, distribute, and sell this software and its
8
documentation for any purpose is hereby granted without fee, provided that
9
the above copyright notice appear in all copies and that both that
10
copyright notice and this permission notice appear in supporting
13
The above copyright notice and this permission notice shall be included
14
in all copies or substantial portions of the Software.
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
OTHER DEALINGS IN THE SOFTWARE.
24
Except as contained in this notice, the name of The Open Group shall
25
not be used in advertising or otherwise to promote the sale, use or
26
other dealings in this Software without prior written authorization
30
/* $XFree86: xc/programs/Xserver/Xext/xtest.c,v 3.10 2003/10/28 23:08:44 tsi Exp $ */
32
#ifdef HAVE_DIX_CONFIG_H
33
#include <dix-config.h>
38
#include <X11/Xproto.h>
41
#include "dixstruct.h"
42
#include "extnsionst.h"
43
#include "windowstr.h"
45
#include "scrnintstr.h"
46
#include "dixevents.h"
47
#include "sleepuntil.h"
48
#define _XTEST_SERVER_
49
#include <X11/extensions/XTest.h>
50
#include <X11/extensions/xteststr.h>
52
#include <X11/extensions/XI.h>
53
#include <X11/extensions/XIproto.h>
54
#define EXTENSION_EVENT_BASE 64
55
#include "extinit.h" /* LookupDeviceIntRec */
58
#include "xf86_ansic.h"
64
static unsigned char XTestReqCode;
68
extern int DeviceValuator;
72
#include "panoramiX.h"
73
#include "panoramiXsrv.h"
76
static void XTestResetProc(
77
ExtensionEntry * /* extEntry */
79
static int XTestSwapFakeInput(
80
ClientPtr /* client */,
84
static DISPATCH_PROC(ProcXTestCompareCursor);
85
static DISPATCH_PROC(ProcXTestDispatch);
86
static DISPATCH_PROC(ProcXTestFakeInput);
87
static DISPATCH_PROC(ProcXTestGetVersion);
88
static DISPATCH_PROC(ProcXTestGrabControl);
89
static DISPATCH_PROC(SProcXTestCompareCursor);
90
static DISPATCH_PROC(SProcXTestDispatch);
91
static DISPATCH_PROC(SProcXTestFakeInput);
92
static DISPATCH_PROC(SProcXTestGetVersion);
93
static DISPATCH_PROC(SProcXTestGrabControl);
96
XTestExtensionInit(INITARGS)
99
ExtensionEntry *extEntry;
101
if ((extEntry = AddExtension(XTestExtensionName, 0, 0,
102
ProcXTestDispatch, SProcXTestDispatch,
103
XTestResetProc, StandardMinorOpcode)) != 0)
104
XTestReqCode = (unsigned char)extEntry->base;
106
(void) AddExtension(XTestExtensionName, 0, 0,
107
ProcXTestDispatch, SProcXTestDispatch,
108
XTestResetProc, StandardMinorOpcode);
114
XTestResetProc (extEntry)
115
ExtensionEntry *extEntry;
120
ProcXTestGetVersion(client)
121
register ClientPtr client;
123
xXTestGetVersionReply rep;
126
REQUEST_SIZE_MATCH(xXTestGetVersionReq);
129
rep.sequenceNumber = client->sequence;
130
rep.majorVersion = XTestMajorVersion;
131
rep.minorVersion = XTestMinorVersion;
132
if (client->swapped) {
133
swaps(&rep.sequenceNumber, n);
134
swaps(&rep.minorVersion, n);
136
WriteToClient(client, sizeof(xXTestGetVersionReply), (char *)&rep);
137
return(client->noClientException);
141
ProcXTestCompareCursor(client)
142
register ClientPtr client;
144
REQUEST(xXTestCompareCursorReq);
145
xXTestCompareCursorReply rep;
150
REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
151
pWin = (WindowPtr)LookupWindow(stuff->window, client);
154
if (stuff->cursor == None)
155
pCursor = NullCursor;
156
else if (stuff->cursor == XTestCurrentCursor)
157
pCursor = GetSpriteCursor();
159
pCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
162
client->errorValue = stuff->cursor;
168
rep.sequenceNumber = client->sequence;
169
rep.same = (wCursor(pWin) == pCursor);
170
if (client->swapped) {
171
swaps(&rep.sequenceNumber, n);
173
WriteToClient(client, sizeof(xXTestCompareCursorReply), (char *)&rep);
174
return(client->noClientException);
178
ProcXTestFakeInput(client)
179
register ClientPtr client;
181
REQUEST(xXTestFakeInputReq);
185
DeviceIntPtr dev = NULL;
189
Bool extension = FALSE;
190
deviceValuator *dv = NULL;
195
nev = (stuff->length << 2) - sizeof(xReq);
196
if ((nev % sizeof(xEvent)) || !nev)
198
nev /= sizeof(xEvent);
200
ev = (xEvent *)&((xReq *)stuff)[1];
201
type = ev->u.u.type & 0177;
203
if (type >= EXTENSION_EVENT_BASE)
205
type -= DeviceValuator;
207
case XI_DeviceKeyPress:
208
case XI_DeviceKeyRelease:
209
case XI_DeviceButtonPress:
210
case XI_DeviceButtonRelease:
211
case XI_DeviceMotionNotify:
213
case XI_ProximityOut:
216
client->errorValue = ev->u.u.type;
219
if (nev == 1 && type == XI_DeviceMotionNotify)
221
if (type == XI_DeviceMotionNotify)
222
base = ((deviceValuator *)(ev+1))->first_valuator;
225
for (n = 1; n < nev; n++)
227
dv = (deviceValuator *)(ev + n);
228
if (dv->type != DeviceValuator)
230
client->errorValue = dv->type;
233
if (dv->first_valuator != base)
235
client->errorValue = dv->first_valuator;
238
if (!dv->num_valuators || dv->num_valuators > 6)
240
client->errorValue = dv->num_valuators;
243
base += dv->num_valuators;
245
type = type - XI_DeviceKeyPress + KeyPress;
262
client->errorValue = ev->u.u.type;
266
if (ev->u.keyButtonPointer.time)
268
TimeStamp activateTime;
271
activateTime = currentTime;
272
ms = activateTime.milliseconds + ev->u.keyButtonPointer.time;
273
if (ms < activateTime.milliseconds)
274
activateTime.months++;
275
activateTime.milliseconds = ms;
276
ev->u.keyButtonPointer.time = 0;
278
/* see mbuf.c:QueueDisplayRequest for code similar to this */
280
if (!ClientSleepUntil(client, &activateTime, NULL, NULL))
284
/* swap the request back so we can simply re-execute it */
287
(void) XTestSwapFakeInput(client, (xReq *)stuff);
288
swaps(&stuff->length, n);
290
ResetCurrentRequest (client);
297
dev = LookupDeviceIntRec(stuff->deviceid & 0177);
300
client->errorValue = stuff->deviceid & 0177;
305
dv = (deviceValuator *)(ev + 1);
306
if (!dev->valuator || dv->first_valuator >= dev->valuator->numAxes)
308
client->errorValue = dv->first_valuator;
311
if (dv->first_valuator + dv->num_valuators >
312
dev->valuator->numAxes)
314
client->errorValue = dv->num_valuators;
327
dev = (DeviceIntPtr)LookupKeyboardDevice();
328
if (ev->u.u.detail < dev->key->curKeySyms.minKeyCode ||
329
ev->u.u.detail > dev->key->curKeySyms.maxKeyCode)
331
client->errorValue = ev->u.u.detail;
339
if (ev->u.u.detail != xFalse && ev->u.u.detail != xTrue)
341
client->errorValue = ev->u.u.detail;
344
if (ev->u.u.detail == xTrue && dev->valuator->mode == Absolute)
346
values = dev->valuator->axisVal + dv->first_valuator;
347
for (n = 1; n < nev; n++)
349
dv = (deviceValuator *)(ev + n);
350
switch (dv->num_valuators)
353
dv->valuator5 += values[5];
355
dv->valuator4 += values[4];
357
dv->valuator3 += values[3];
359
dv->valuator2 += values[2];
361
dv->valuator1 += values[1];
363
dv->valuator0 += values[0];
371
dev = (DeviceIntPtr)LookupPointerDevice();
372
if (ev->u.keyButtonPointer.root == None)
373
root = GetCurrentRootWindow();
376
root = LookupWindow(ev->u.keyButtonPointer.root, client);
381
client->errorValue = ev->u.keyButtonPointer.root;
385
if (ev->u.u.detail == xTrue)
388
GetSpritePosition(&x, &y);
389
ev->u.keyButtonPointer.rootX += x;
390
ev->u.keyButtonPointer.rootY += y;
392
else if (ev->u.u.detail != xFalse)
394
client->errorValue = ev->u.u.detail;
399
if (!noPanoramiXExtension) {
400
ScreenPtr pScreen = root->drawable.pScreen;
403
int x = ev->u.keyButtonPointer.rootX + panoramiXdataPtr[0].x;
404
int y = ev->u.keyButtonPointer.rootY + panoramiXdataPtr[0].y;
405
if (!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
408
if (i == pScreen->myNum) continue;
409
if (POINT_IN_REGION(pScreen,
410
&XineramaScreenRegions[i],
412
root = WindowTable[i];
413
x -= panoramiXdataPtr[i].x;
414
y -= panoramiXdataPtr[i].y;
415
ev->u.keyButtonPointer.rootX = x;
416
ev->u.keyButtonPointer.rootY = y;
424
if (ev->u.keyButtonPointer.rootX < 0)
425
ev->u.keyButtonPointer.rootX = 0;
426
else if (ev->u.keyButtonPointer.rootX >= root->drawable.width)
427
ev->u.keyButtonPointer.rootX = root->drawable.width - 1;
428
if (ev->u.keyButtonPointer.rootY < 0)
429
ev->u.keyButtonPointer.rootY = 0;
430
else if (ev->u.keyButtonPointer.rootY >= root->drawable.height)
431
ev->u.keyButtonPointer.rootY = root->drawable.height - 1;
434
if ((!noPanoramiXExtension
435
&& root->drawable.pScreen->myNum != XineramaGetCursorScreen())
436
|| (noPanoramiXExtension && root != GetCurrentRootWindow()))
439
if (root != GetCurrentRootWindow())
442
NewCurrentScreen(root->drawable.pScreen,
443
ev->u.keyButtonPointer.rootX,
444
ev->u.keyButtonPointer.rootY);
445
return client->noClientException;
447
(*root->drawable.pScreen->SetCursorPosition)
448
(root->drawable.pScreen,
449
ev->u.keyButtonPointer.rootX,
450
ev->u.keyButtonPointer.rootY, FALSE);
457
dev = (DeviceIntPtr)LookupPointerDevice();
458
if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
460
client->errorValue = ev->u.u.detail;
465
if (screenIsSaved == SCREEN_SAVER_ON)
466
SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
467
ev->u.keyButtonPointer.time = currentTime.milliseconds;
468
(*dev->public.processInputProc)(ev, dev, nev);
469
return client->noClientException;
473
ProcXTestGrabControl(client)
474
register ClientPtr client;
476
REQUEST(xXTestGrabControlReq);
478
REQUEST_SIZE_MATCH(xXTestGrabControlReq);
479
if ((stuff->impervious != xTrue) && (stuff->impervious != xFalse))
481
client->errorValue = stuff->impervious;
484
if (stuff->impervious)
485
MakeClientGrabImpervious(client);
487
MakeClientGrabPervious(client);
488
return(client->noClientException);
492
ProcXTestDispatch (client)
493
register ClientPtr client;
498
case X_XTestGetVersion:
499
return ProcXTestGetVersion(client);
500
case X_XTestCompareCursor:
501
return ProcXTestCompareCursor(client);
502
case X_XTestFakeInput:
503
return ProcXTestFakeInput(client);
504
case X_XTestGrabControl:
505
return ProcXTestGrabControl(client);
512
SProcXTestGetVersion(client)
513
register ClientPtr client;
516
REQUEST(xXTestGetVersionReq);
518
swaps(&stuff->length, n);
519
REQUEST_SIZE_MATCH(xXTestGetVersionReq);
520
swaps(&stuff->minorVersion, n);
521
return ProcXTestGetVersion(client);
525
SProcXTestCompareCursor(client)
526
register ClientPtr client;
529
REQUEST(xXTestCompareCursorReq);
531
swaps(&stuff->length, n);
532
REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
533
swapl(&stuff->window, n);
534
swapl(&stuff->cursor, n);
535
return ProcXTestCompareCursor(client);
539
XTestSwapFakeInput(client, req)
540
register ClientPtr client;
548
nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
549
for (ev = (xEvent *)&req[1]; --nev >= 0; ev++)
552
proc = EventSwapVector[ev->u.u.type & 0177];
553
/* no swapping proc; invalid event type? */
554
if (!proc || proc == NotImplemented) {
555
client->errorValue = ev->u.u.type;
565
SProcXTestFakeInput(client)
566
register ClientPtr client;
571
swaps(&stuff->length, n);
572
n = XTestSwapFakeInput(client, stuff);
575
return ProcXTestFakeInput(client);
579
SProcXTestGrabControl(client)
580
register ClientPtr client;
583
REQUEST(xXTestGrabControlReq);
585
swaps(&stuff->length, n);
586
REQUEST_SIZE_MATCH(xXTestGrabControlReq);
587
return ProcXTestGrabControl(client);
591
SProcXTestDispatch (client)
592
register ClientPtr client;
597
case X_XTestGetVersion:
598
return SProcXTestGetVersion(client);
599
case X_XTestCompareCursor:
600
return SProcXTestCompareCursor(client);
601
case X_XTestFakeInput:
602
return SProcXTestFakeInput(client);
603
case X_XTestGrabControl:
604
return SProcXTestGrabControl(client);