~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to Xext/xtest.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 $ */
 
3
/*
 
4
 
 
5
Copyright 1992, 1998  The Open Group
 
6
 
 
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
 
11
documentation.
 
12
 
 
13
The above copyright notice and this permission notice shall be included
 
14
in all copies or substantial portions of the Software.
 
15
 
 
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.
 
23
 
 
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
 
27
from The Open Group.
 
28
 
 
29
*/
 
30
/* $XFree86: xc/programs/Xserver/Xext/xtest.c,v 3.10 2003/10/28 23:08:44 tsi Exp $ */
 
31
 
 
32
#ifdef HAVE_DIX_CONFIG_H
 
33
#include <dix-config.h>
 
34
#endif
 
35
 
 
36
#include <X11/X.h>
 
37
#define NEED_EVENTS
 
38
#include <X11/Xproto.h>
 
39
#include "misc.h"
 
40
#include "os.h"
 
41
#include "dixstruct.h"
 
42
#include "extnsionst.h"
 
43
#include "windowstr.h"
 
44
#include "inputstr.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>
 
51
#ifdef XINPUT
 
52
#include <X11/extensions/XI.h>
 
53
#include <X11/extensions/XIproto.h>
 
54
#define EXTENSION_EVENT_BASE    64
 
55
#include "extinit.h"            /* LookupDeviceIntRec */
 
56
#endif /* XINPUT */
 
57
#ifdef EXTMODULE
 
58
#include "xf86_ansic.h"
 
59
#endif
 
60
 
 
61
#include "modinit.h"
 
62
 
 
63
#if 0
 
64
static unsigned char XTestReqCode;
 
65
#endif
 
66
 
 
67
#ifdef XINPUT
 
68
extern int DeviceValuator;
 
69
#endif /* XINPUT */
 
70
 
 
71
#ifdef PANORAMIX
 
72
#include "panoramiX.h"
 
73
#include "panoramiXsrv.h"
 
74
#endif
 
75
 
 
76
static void XTestResetProc(
 
77
    ExtensionEntry * /* extEntry */
 
78
);
 
79
static int XTestSwapFakeInput(
 
80
    ClientPtr /* client */,
 
81
    xReq * /* req */
 
82
);
 
83
 
 
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);
 
94
 
 
95
void
 
96
XTestExtensionInit(INITARGS)
 
97
{
 
98
#if 0
 
99
    ExtensionEntry *extEntry;
 
100
 
 
101
    if ((extEntry = AddExtension(XTestExtensionName, 0, 0,
 
102
                                 ProcXTestDispatch, SProcXTestDispatch,
 
103
                                 XTestResetProc, StandardMinorOpcode)) != 0)
 
104
        XTestReqCode = (unsigned char)extEntry->base;
 
105
#else
 
106
    (void) AddExtension(XTestExtensionName, 0, 0,
 
107
                        ProcXTestDispatch, SProcXTestDispatch,
 
108
                        XTestResetProc, StandardMinorOpcode);
 
109
#endif
 
110
}
 
111
 
 
112
/*ARGSUSED*/
 
113
static void
 
114
XTestResetProc (extEntry)
 
115
ExtensionEntry  *extEntry;
 
116
{
 
117
}
 
118
 
 
119
static int
 
120
ProcXTestGetVersion(client)
 
121
    register ClientPtr client;
 
122
{
 
123
    xXTestGetVersionReply rep;
 
124
    register int n;
 
125
 
 
126
    REQUEST_SIZE_MATCH(xXTestGetVersionReq);
 
127
    rep.type = X_Reply;
 
128
    rep.length = 0;
 
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);
 
135
    }
 
136
    WriteToClient(client, sizeof(xXTestGetVersionReply), (char *)&rep);
 
137
    return(client->noClientException);
 
138
}
 
139
 
 
140
static int
 
141
ProcXTestCompareCursor(client)
 
142
    register ClientPtr client;
 
143
{
 
144
    REQUEST(xXTestCompareCursorReq);
 
145
    xXTestCompareCursorReply rep;
 
146
    WindowPtr pWin;
 
147
    CursorPtr pCursor;
 
148
    register int n;
 
149
 
 
150
    REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
 
151
    pWin = (WindowPtr)LookupWindow(stuff->window, client);
 
152
    if (!pWin)
 
153
        return(BadWindow);
 
154
    if (stuff->cursor == None)
 
155
        pCursor = NullCursor;
 
156
    else if (stuff->cursor == XTestCurrentCursor)
 
157
        pCursor = GetSpriteCursor();
 
158
    else {
 
159
        pCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
 
160
        if (!pCursor) 
 
161
        {
 
162
            client->errorValue = stuff->cursor;
 
163
            return (BadCursor);
 
164
        }
 
165
    }
 
166
    rep.type = X_Reply;
 
167
    rep.length = 0;
 
168
    rep.sequenceNumber = client->sequence;
 
169
    rep.same = (wCursor(pWin) == pCursor);
 
170
    if (client->swapped) {
 
171
        swaps(&rep.sequenceNumber, n);
 
172
    }
 
173
    WriteToClient(client, sizeof(xXTestCompareCursorReply), (char *)&rep);
 
174
    return(client->noClientException);
 
175
}
 
176
 
 
177
static int
 
178
ProcXTestFakeInput(client)
 
179
    register ClientPtr client;
 
180
{
 
181
    REQUEST(xXTestFakeInputReq);
 
182
    int nev;
 
183
    int n;
 
184
    xEvent *ev;
 
185
    DeviceIntPtr dev = NULL;
 
186
    WindowPtr root;
 
187
    int type;
 
188
#ifdef XINPUT
 
189
    Bool extension = FALSE;
 
190
    deviceValuator *dv = NULL;
 
191
    int base;
 
192
    int *values;
 
193
#endif /* XINPUT */
 
194
 
 
195
    nev = (stuff->length << 2) - sizeof(xReq);
 
196
    if ((nev % sizeof(xEvent)) || !nev)
 
197
        return BadLength;
 
198
    nev /= sizeof(xEvent);
 
199
    UpdateCurrentTime();
 
200
    ev = (xEvent *)&((xReq *)stuff)[1];
 
201
    type = ev->u.u.type & 0177;
 
202
#ifdef XINPUT
 
203
    if (type >= EXTENSION_EVENT_BASE)
 
204
    {
 
205
        type -= DeviceValuator;
 
206
        switch (type) {
 
207
        case XI_DeviceKeyPress:
 
208
        case XI_DeviceKeyRelease:
 
209
        case XI_DeviceButtonPress:
 
210
        case XI_DeviceButtonRelease:
 
211
        case XI_DeviceMotionNotify:
 
212
        case XI_ProximityIn:
 
213
        case XI_ProximityOut:
 
214
            break;
 
215
        default:
 
216
            client->errorValue = ev->u.u.type;
 
217
            return BadValue;
 
218
        }
 
219
        if (nev == 1 && type == XI_DeviceMotionNotify)
 
220
            return BadLength;
 
221
        if (type == XI_DeviceMotionNotify)
 
222
            base = ((deviceValuator *)(ev+1))->first_valuator;
 
223
        else
 
224
            base = 0;
 
225
        for (n = 1; n < nev; n++)
 
226
        {
 
227
            dv = (deviceValuator *)(ev + n);
 
228
            if (dv->type != DeviceValuator)
 
229
            {
 
230
                client->errorValue = dv->type;
 
231
                return BadValue;
 
232
            }
 
233
            if (dv->first_valuator != base)
 
234
            {
 
235
                client->errorValue = dv->first_valuator;
 
236
                return BadValue;
 
237
            }
 
238
            if (!dv->num_valuators || dv->num_valuators > 6)
 
239
            {
 
240
                client->errorValue = dv->num_valuators;
 
241
                return BadValue;
 
242
            }
 
243
            base += dv->num_valuators;
 
244
        }
 
245
        type = type - XI_DeviceKeyPress + KeyPress;
 
246
        extension = TRUE;
 
247
    }
 
248
    else
 
249
#endif /* XINPUT */
 
250
    {
 
251
        if (nev != 1)
 
252
            return BadLength;
 
253
        switch (type)
 
254
        {
 
255
        case KeyPress:
 
256
        case KeyRelease:
 
257
        case MotionNotify:
 
258
        case ButtonPress:
 
259
        case ButtonRelease:
 
260
            break;
 
261
        default:
 
262
            client->errorValue = ev->u.u.type;
 
263
            return BadValue;
 
264
        }
 
265
    }
 
266
    if (ev->u.keyButtonPointer.time)
 
267
    {
 
268
        TimeStamp activateTime;
 
269
        CARD32 ms;
 
270
 
 
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;
 
277
 
 
278
        /* see mbuf.c:QueueDisplayRequest for code similar to this */
 
279
 
 
280
        if (!ClientSleepUntil(client, &activateTime, NULL, NULL))
 
281
        {
 
282
            return BadAlloc;
 
283
        }
 
284
        /* swap the request back so we can simply re-execute it */
 
285
        if (client->swapped)
 
286
        {
 
287
            (void) XTestSwapFakeInput(client, (xReq *)stuff);
 
288
            swaps(&stuff->length, n);
 
289
        }
 
290
        ResetCurrentRequest (client);
 
291
        client->sequence--;
 
292
        return Success;
 
293
    }
 
294
#ifdef XINPUT
 
295
    if (extension)
 
296
    {
 
297
        dev = LookupDeviceIntRec(stuff->deviceid & 0177);
 
298
        if (!dev)
 
299
        {
 
300
            client->errorValue = stuff->deviceid & 0177;
 
301
            return BadValue;
 
302
        }
 
303
        if (nev > 1)
 
304
        {
 
305
            dv = (deviceValuator *)(ev + 1);
 
306
            if (!dev->valuator || dv->first_valuator >= dev->valuator->numAxes)
 
307
            {
 
308
                client->errorValue = dv->first_valuator;
 
309
                return BadValue;
 
310
            }
 
311
            if (dv->first_valuator + dv->num_valuators >
 
312
                dev->valuator->numAxes)
 
313
            {
 
314
                client->errorValue = dv->num_valuators;
 
315
                return BadValue;
 
316
            }
 
317
        }
 
318
    }
 
319
#endif /* XINPUT */
 
320
    switch (type)
 
321
    {
 
322
    case KeyPress:
 
323
    case KeyRelease:
 
324
#ifdef XINPUT
 
325
        if (!extension)
 
326
#endif /* XINPUT */
 
327
            dev = (DeviceIntPtr)LookupKeyboardDevice();
 
328
        if (ev->u.u.detail < dev->key->curKeySyms.minKeyCode ||
 
329
            ev->u.u.detail > dev->key->curKeySyms.maxKeyCode)
 
330
        {
 
331
            client->errorValue = ev->u.u.detail;
 
332
            return BadValue;
 
333
        }
 
334
        break;
 
335
    case MotionNotify:
 
336
#ifdef XINPUT
 
337
        if (extension)
 
338
        {
 
339
            if (ev->u.u.detail != xFalse && ev->u.u.detail != xTrue)
 
340
            {
 
341
                client->errorValue = ev->u.u.detail;
 
342
                return BadValue;
 
343
            }
 
344
            if (ev->u.u.detail == xTrue && dev->valuator->mode == Absolute)
 
345
            {
 
346
                values = dev->valuator->axisVal + dv->first_valuator;
 
347
                for (n = 1; n < nev; n++)
 
348
                {
 
349
                    dv = (deviceValuator *)(ev + n);
 
350
                    switch (dv->num_valuators)
 
351
                    {
 
352
                    case 6:
 
353
                        dv->valuator5 += values[5];
 
354
                    case 5:
 
355
                        dv->valuator4 += values[4];
 
356
                    case 4:
 
357
                        dv->valuator3 += values[3];
 
358
                    case 3:
 
359
                        dv->valuator2 += values[2];
 
360
                    case 2:
 
361
                        dv->valuator1 += values[1];
 
362
                    case 1:
 
363
                        dv->valuator0 += values[0];
 
364
                    }
 
365
                    values += 6;
 
366
                }
 
367
            }
 
368
            break;
 
369
        }
 
370
#endif /* XINPUT */
 
371
        dev = (DeviceIntPtr)LookupPointerDevice();
 
372
        if (ev->u.keyButtonPointer.root == None)
 
373
            root = GetCurrentRootWindow();
 
374
        else
 
375
        {
 
376
            root = LookupWindow(ev->u.keyButtonPointer.root, client);
 
377
            if (!root)
 
378
                return BadWindow;
 
379
            if (root->parent)
 
380
            {
 
381
                client->errorValue = ev->u.keyButtonPointer.root;
 
382
                return BadValue;
 
383
            }
 
384
        }
 
385
        if (ev->u.u.detail == xTrue)
 
386
        {
 
387
            int x, y;
 
388
            GetSpritePosition(&x, &y);
 
389
            ev->u.keyButtonPointer.rootX += x;
 
390
            ev->u.keyButtonPointer.rootY += y;
 
391
        }
 
392
        else if (ev->u.u.detail != xFalse)
 
393
        {
 
394
            client->errorValue = ev->u.u.detail;
 
395
            return BadValue;
 
396
        }
 
397
 
 
398
#ifdef PANORAMIX
 
399
        if (!noPanoramiXExtension) {
 
400
            ScreenPtr pScreen = root->drawable.pScreen;
 
401
            BoxRec    box;
 
402
            int       i;
 
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],
 
406
                                 x, y, &box)) {
 
407
                FOR_NSCREENS(i) {
 
408
                    if (i == pScreen->myNum) continue;
 
409
                    if (POINT_IN_REGION(pScreen,
 
410
                                        &XineramaScreenRegions[i],
 
411
                                        x, y, &box)) {
 
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;
 
417
                        break;
 
418
                    }
 
419
                }
 
420
            }
 
421
        }
 
422
#endif
 
423
 
 
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;
 
432
 
 
433
#ifdef PANORAMIX
 
434
        if ((!noPanoramiXExtension
 
435
             && root->drawable.pScreen->myNum != XineramaGetCursorScreen())
 
436
            || (noPanoramiXExtension && root != GetCurrentRootWindow()))
 
437
 
 
438
#else
 
439
        if (root != GetCurrentRootWindow())
 
440
#endif
 
441
        {
 
442
            NewCurrentScreen(root->drawable.pScreen,
 
443
                             ev->u.keyButtonPointer.rootX,
 
444
                             ev->u.keyButtonPointer.rootY);
 
445
            return client->noClientException;
 
446
        }
 
447
        (*root->drawable.pScreen->SetCursorPosition)
 
448
            (root->drawable.pScreen,
 
449
             ev->u.keyButtonPointer.rootX,
 
450
             ev->u.keyButtonPointer.rootY, FALSE);
 
451
        break;
 
452
    case ButtonPress:
 
453
    case ButtonRelease:
 
454
#ifdef XINPUT
 
455
        if (!extension)
 
456
#endif /* XINPUT */
 
457
            dev = (DeviceIntPtr)LookupPointerDevice();
 
458
        if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
 
459
        {
 
460
            client->errorValue = ev->u.u.detail;
 
461
            return BadValue;
 
462
        }
 
463
        break;
 
464
    }
 
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;
 
470
}
 
471
 
 
472
static int
 
473
ProcXTestGrabControl(client)
 
474
    register ClientPtr client;
 
475
{
 
476
    REQUEST(xXTestGrabControlReq);
 
477
 
 
478
    REQUEST_SIZE_MATCH(xXTestGrabControlReq);
 
479
    if ((stuff->impervious != xTrue) && (stuff->impervious != xFalse))
 
480
    {
 
481
        client->errorValue = stuff->impervious;
 
482
        return(BadValue);
 
483
    }
 
484
    if (stuff->impervious)
 
485
        MakeClientGrabImpervious(client);
 
486
    else
 
487
        MakeClientGrabPervious(client);
 
488
    return(client->noClientException);
 
489
}
 
490
 
 
491
static int
 
492
ProcXTestDispatch (client)
 
493
    register ClientPtr  client;
 
494
{
 
495
    REQUEST(xReq);
 
496
    switch (stuff->data)
 
497
    {
 
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);
 
506
    default:
 
507
        return BadRequest;
 
508
    }
 
509
}
 
510
 
 
511
static int
 
512
SProcXTestGetVersion(client)
 
513
    register ClientPtr  client;
 
514
{
 
515
    register int n;
 
516
    REQUEST(xXTestGetVersionReq);
 
517
 
 
518
    swaps(&stuff->length, n);
 
519
    REQUEST_SIZE_MATCH(xXTestGetVersionReq);
 
520
    swaps(&stuff->minorVersion, n);
 
521
    return ProcXTestGetVersion(client);
 
522
}
 
523
 
 
524
static int
 
525
SProcXTestCompareCursor(client)
 
526
    register ClientPtr  client;
 
527
{
 
528
    register int n;
 
529
    REQUEST(xXTestCompareCursorReq);
 
530
 
 
531
    swaps(&stuff->length, n);
 
532
    REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
 
533
    swapl(&stuff->window, n);
 
534
    swapl(&stuff->cursor, n);
 
535
    return ProcXTestCompareCursor(client);
 
536
}
 
537
 
 
538
static int
 
539
XTestSwapFakeInput(client, req)
 
540
    register ClientPtr  client;
 
541
    xReq *req;
 
542
{
 
543
    register int nev;
 
544
    register xEvent *ev;
 
545
    xEvent sev;
 
546
    EventSwapPtr proc;
 
547
 
 
548
    nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
 
549
    for (ev = (xEvent *)&req[1]; --nev >= 0; ev++)
 
550
    {
 
551
        /* Swap event */
 
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;
 
556
            return BadValue;
 
557
        }
 
558
        (*proc)(ev, &sev);
 
559
        *ev = sev;
 
560
    }
 
561
    return Success;
 
562
}
 
563
 
 
564
static int
 
565
SProcXTestFakeInput(client)
 
566
    register ClientPtr  client;
 
567
{
 
568
    register int n;
 
569
    REQUEST(xReq);
 
570
 
 
571
    swaps(&stuff->length, n);
 
572
    n = XTestSwapFakeInput(client, stuff);
 
573
    if (n != Success)
 
574
        return n;
 
575
    return ProcXTestFakeInput(client);
 
576
}
 
577
 
 
578
static int
 
579
SProcXTestGrabControl(client)
 
580
    register ClientPtr  client;
 
581
{
 
582
    register int n;
 
583
    REQUEST(xXTestGrabControlReq);
 
584
 
 
585
    swaps(&stuff->length, n);
 
586
    REQUEST_SIZE_MATCH(xXTestGrabControlReq);
 
587
    return ProcXTestGrabControl(client);
 
588
}
 
589
 
 
590
static int
 
591
SProcXTestDispatch (client)
 
592
    register ClientPtr  client;
 
593
{
 
594
    REQUEST(xReq);
 
595
    switch (stuff->data)
 
596
    {
 
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);
 
605
    default:
 
606
        return BadRequest;
 
607
    }
 
608
}