~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/dix/dispatch.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
 
2
/************************************************************
 
3
 
 
4
Copyright 1987, 1989, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 
 
26
 
 
27
Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
 
28
 
 
29
                        All Rights Reserved
 
30
 
 
31
Permission to use, copy, modify, and distribute this software and its 
 
32
documentation for any purpose and without fee is hereby granted, 
 
33
provided that the above copyright notice appear in all copies and that
 
34
both that copyright notice and this permission notice appear in 
 
35
supporting documentation, and that the name of Digital not be
 
36
used in advertising or publicity pertaining to distribution of the
 
37
software without specific, written prior permission.  
 
38
 
 
39
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
41
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
45
SOFTWARE.
 
46
 
 
47
********************************************************/
 
48
 
 
49
/* The panoramix components contained the following notice */
 
50
/****************************************************************
 
51
*                                                               *
 
52
*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
 
53
*                                                               *
 
54
*   All Rights Reserved.  Unpublished rights  reserved  under   *
 
55
*   the copyright laws of the United States.                    *
 
56
*                                                               *
 
57
*   The software contained on this media  is  proprietary  to   *
 
58
*   and  embodies  the  confidential  technology  of  Digital   *
 
59
*   Equipment Corporation.  Possession, use,  duplication  or   *
 
60
*   dissemination of the software and media is authorized only  *
 
61
*   pursuant to a valid written license from Digital Equipment  *
 
62
*   Corporation.                                                *
 
63
*                                                               *
 
64
*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
 
65
*   by the U.S. Government is subject to restrictions  as  set  *
 
66
*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
 
67
*   or  in  FAR 52.227-19, as applicable.                       *
 
68
*                                                               *
 
69
*****************************************************************/
 
70
 
 
71
/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.29 2003/01/12 02:44:26 dawes Exp $ */
 
72
 
 
73
#ifdef PANORAMIX_DEBUG
 
74
#include <stdio.h>
 
75
int ProcInitialConnection();
 
76
#endif
 
77
 
 
78
#include "windowstr.h"
 
79
#include "fontstruct.h"
 
80
#include "dixfontstr.h"
 
81
#include "gcstruct.h"
 
82
#include "selection.h"
 
83
#include "colormapst.h"
 
84
#include "cursorstr.h"
 
85
#include "scrnintstr.h"
 
86
#include "opaque.h"
 
87
#include "input.h"
 
88
#include "servermd.h"
 
89
#include "extnsionst.h"
 
90
#include "dixfont.h"
 
91
#include "dispatch.h"
 
92
#include "swaprep.h"
 
93
#include "swapreq.h"
 
94
#ifdef PANORAMIX
 
95
#include "panoramiX.h"
 
96
#include "panoramiXsrv.h"
 
97
#endif
 
98
#ifdef XCSECURITY
 
99
#define _SECURITY_SERVER
 
100
#include "security.h"
 
101
#endif
 
102
#ifdef XAPPGROUP
 
103
#include "Xagsrv.h"
 
104
#endif
 
105
#ifdef XKB
 
106
#define XKB_IN_SERVER
 
107
#include "inputstr.h"
 
108
#include "XKBsrv.h"
 
109
#endif
 
110
#ifdef LBX
 
111
#include "lbxserve.h"
 
112
#endif
 
113
 
 
114
#define mskcnt ((MAXCLIENTS + 31) / 32)
 
115
#define BITMASK(i) (1U << ((i) & 31))
 
116
#define MASKIDX(i) ((i) >> 5)
 
117
#define MASKWORD(buf, i) buf[MASKIDX(i)]
 
118
#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
 
119
#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
 
120
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
 
121
 
 
122
extern xConnSetupPrefix connSetupPrefix;
 
123
extern char *ConnectionInfo;
 
124
 
 
125
Selection *CurrentSelections;
 
126
int NumCurrentSelections;
 
127
 
 
128
static ClientPtr grabClient;
 
129
#define GrabNone 0
 
130
#define GrabActive 1
 
131
#define GrabKickout 2
 
132
static int grabState = GrabNone;
 
133
static long grabWaiters[mskcnt];
 
134
CallbackListPtr ServerGrabCallback = NULL;
 
135
HWEventQueuePtr checkForInput[2];
 
136
extern int connBlockScreenStart;
 
137
 
 
138
static void KillAllClients(
 
139
#if NeedFunctionPrototypes
 
140
    void
 
141
#endif
 
142
);
 
143
 
 
144
static void DeleteClientFromAnySelections(
 
145
#if NeedFunctionPrototypes
 
146
    ClientPtr /*client*/
 
147
#endif
 
148
);
 
149
 
 
150
static int nextFreeClientID; /* always MIN free client ID */
 
151
 
 
152
static int      nClients;       /* number of authorized clients */
 
153
 
 
154
CallbackListPtr ClientStateCallback;
 
155
char dispatchException = 0;
 
156
char isItTimeToYield;
 
157
 
 
158
/* Various of the DIX function interfaces were not designed to allow
 
159
 * the client->errorValue to be set on BadValue and other errors.
 
160
 * Rather than changing interfaces and breaking untold code we introduce
 
161
 * a new global that dispatch can use.
 
162
 */
 
163
XID clientErrorValue;   /* XXX this is a kludge */
 
164
 
 
165
#define SAME_SCREENS(a, b) (\
 
166
    (a.pScreen == b.pScreen))
 
167
 
 
168
void
 
169
SetInputCheck(c0, c1)
 
170
    HWEventQueuePtr c0, c1;
 
171
{
 
172
    checkForInput[0] = c0;
 
173
    checkForInput[1] = c1;
 
174
}
 
175
 
 
176
void
 
177
UpdateCurrentTime()
 
178
{
 
179
    TimeStamp systime;
 
180
 
 
181
    /* To avoid time running backwards, we must call GetTimeInMillis before
 
182
     * calling ProcessInputEvents.
 
183
     */
 
184
    systime.months = currentTime.months;
 
185
    systime.milliseconds = GetTimeInMillis();
 
186
    if (systime.milliseconds < currentTime.milliseconds)
 
187
        systime.months++;
 
188
    if (*checkForInput[0] != *checkForInput[1])
 
189
        ProcessInputEvents();
 
190
    if (CompareTimeStamps(systime, currentTime) == LATER)
 
191
        currentTime = systime;
 
192
}
 
193
 
 
194
/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
 
195
void
 
196
UpdateCurrentTimeIf()
 
197
{
 
198
    TimeStamp systime;
 
199
 
 
200
    systime.months = currentTime.months;
 
201
    systime.milliseconds = GetTimeInMillis();
 
202
    if (systime.milliseconds < currentTime.milliseconds)
 
203
        systime.months++;
 
204
    if (*checkForInput[0] == *checkForInput[1])
 
205
        currentTime = systime;
 
206
}
 
207
 
 
208
void
 
209
InitSelections()
 
210
{
 
211
    if (CurrentSelections)
 
212
        xfree(CurrentSelections);
 
213
    CurrentSelections = (Selection *)NULL;
 
214
    NumCurrentSelections = 0;
 
215
}
 
216
 
 
217
void 
 
218
FlushClientCaches(id)
 
219
    XID id;
 
220
{
 
221
    int i;
 
222
    register ClientPtr client;
 
223
 
 
224
    client = clients[CLIENT_ID(id)];
 
225
    if (client == NullClient)
 
226
        return ;
 
227
    for (i=0; i<currentMaxClients; i++)
 
228
    {
 
229
        client = clients[i];
 
230
        if (client != NullClient)
 
231
        {
 
232
            if (client->lastDrawableID == id)
 
233
            {
 
234
                client->lastDrawableID = WindowTable[0]->drawable.id;
 
235
                client->lastDrawable = (DrawablePtr)WindowTable[0];
 
236
            }
 
237
            else if (client->lastGCID == id)
 
238
            {
 
239
                client->lastGCID = INVALID;
 
240
                client->lastGC = (GCPtr)NULL;
 
241
            }
 
242
        }
 
243
    }
 
244
}
 
245
#ifdef SMART_SCHEDULE
 
246
 
 
247
#undef SMART_DEBUG
 
248
 
 
249
#define SMART_SCHEDULE_DEFAULT_INTERVAL 20          /* ms */
 
250
#define SMART_SCHEDULE_MAX_SLICE        200         /* ms */
 
251
 
 
252
Bool        SmartScheduleDisable;
 
253
long        SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
 
254
long        SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
 
255
long        SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
 
256
long        SmartScheduleTime;
 
257
ClientPtr   SmartLastClient;
 
258
int         SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
 
259
int         SmartScheduleClient(int *clientReady, int nready);
 
260
 
 
261
#ifdef SMART_DEBUG
 
262
long        SmartLastPrint;
 
263
#endif
 
264
 
 
265
void        Dispatch(void);
 
266
void        InitProcVectors(void);
 
267
 
 
268
int
 
269
SmartScheduleClient (int *clientReady, int nready)
 
270
{
 
271
    ClientPtr   pClient;
 
272
    int         i;
 
273
    int         client;
 
274
    int         bestPrio, best = 0;
 
275
    int         bestRobin, robin;
 
276
    long        now = SmartScheduleTime;
 
277
    long        idle;
 
278
 
 
279
    bestPrio = -0x7fffffff;
 
280
    bestRobin = 0;
 
281
    idle = 2 * SmartScheduleSlice;
 
282
    for (i = 0; i < nready; i++)
 
283
    {
 
284
        client = clientReady[i];
 
285
        pClient = clients[client];
 
286
        /* Praise clients which are idle */
 
287
        if ((now - pClient->smart_check_tick) >= idle)
 
288
        {
 
289
            if (pClient->smart_priority < 0)
 
290
                pClient->smart_priority++;
 
291
        }
 
292
        pClient->smart_check_tick = now;
 
293
        
 
294
        /* check priority to select best client */
 
295
        robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
 
296
        if (pClient->smart_priority > bestPrio ||
 
297
            (pClient->smart_priority == bestPrio && robin > bestRobin))
 
298
        {
 
299
            bestPrio = pClient->smart_priority;
 
300
            bestRobin = robin;
 
301
            best = client;
 
302
        }
 
303
#ifdef SMART_DEBUG
 
304
        if ((now - SmartLastPrint) >= 5000)
 
305
            fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
 
306
#endif
 
307
    }
 
308
#ifdef SMART_DEBUG
 
309
    if ((now - SmartLastPrint) >= 5000)
 
310
    {
 
311
        fprintf (stderr, " use %2d\n", best);
 
312
        SmartLastPrint = now;
 
313
    }
 
314
#endif
 
315
    pClient = clients[best];
 
316
    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
 
317
    /*
 
318
     * Set current client pointer
 
319
     */
 
320
    if (SmartLastClient != pClient)
 
321
    {
 
322
        pClient->smart_start_tick = now;
 
323
        SmartLastClient = pClient;
 
324
    }
 
325
    /*
 
326
     * Adjust slice
 
327
     */
 
328
    if (nready == 1)
 
329
    {
 
330
        /*
 
331
         * If it's been a long time since another client
 
332
         * has run, bump the slice up to get maximal
 
333
         * performance from a single client
 
334
         */
 
335
        if ((now - pClient->smart_start_tick) > 1000 &&
 
336
            SmartScheduleSlice < SmartScheduleMaxSlice)
 
337
        {
 
338
            SmartScheduleSlice += SmartScheduleInterval;
 
339
        }
 
340
    }
 
341
    else
 
342
    {
 
343
        SmartScheduleSlice = SmartScheduleInterval;
 
344
    }
 
345
    return best;
 
346
}
 
347
#endif
 
348
 
 
349
#define MAJOROP ((xReq *)client->requestBuffer)->reqType
 
350
 
 
351
void
 
352
Dispatch(void)
 
353
{
 
354
    register int        *clientReady;     /* array of request ready clients */
 
355
    register int        result;
 
356
    register ClientPtr  client;
 
357
    register int        nready;
 
358
    register HWEventQueuePtr* icheck = checkForInput;
 
359
#ifdef SMART_SCHEDULE
 
360
    int                 start_tick;
 
361
#endif
 
362
 
 
363
    nextFreeClientID = 1;
 
364
    InitSelections();
 
365
    nClients = 0;
 
366
 
 
367
    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
 
368
    if (!clientReady)
 
369
        return;
 
370
 
 
371
    while (!dispatchException)
 
372
    {
 
373
        if (*icheck[0] != *icheck[1])
 
374
        {
 
375
            ProcessInputEvents();
 
376
            FlushIfCriticalOutputPending();
 
377
        }
 
378
 
 
379
        nready = WaitForSomething(clientReady);
 
380
 
 
381
#ifdef SMART_SCHEDULE
 
382
        if (nready && !SmartScheduleDisable)
 
383
        {
 
384
            clientReady[0] = SmartScheduleClient (clientReady, nready);
 
385
            nready = 1;
 
386
        }
 
387
#endif
 
388
       /***************** 
 
389
        *  Handle events in round robin fashion, doing input between 
 
390
        *  each round 
 
391
        *****************/
 
392
 
 
393
        while (!dispatchException && (--nready >= 0))
 
394
        {
 
395
            client = clients[clientReady[nready]];
 
396
            if (! client)
 
397
            {
 
398
                /* KillClient can cause this to happen */
 
399
                continue;
 
400
            }
 
401
            /* GrabServer activation can cause this to be true */
 
402
            if (grabState == GrabKickout)
 
403
            {
 
404
                grabState = GrabActive;
 
405
                break;
 
406
            }
 
407
            isItTimeToYield = FALSE;
 
408
 
 
409
            requestingClient = client;
 
410
#ifdef SMART_SCHEDULE
 
411
            start_tick = SmartScheduleTime;
 
412
#endif
 
413
            while (!isItTimeToYield)
 
414
            {
 
415
                if (*icheck[0] != *icheck[1])
 
416
                {
 
417
                    ProcessInputEvents();
 
418
                    FlushIfCriticalOutputPending();
 
419
                }
 
420
#ifdef SMART_SCHEDULE
 
421
                if (!SmartScheduleDisable && 
 
422
                    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
 
423
                {
 
424
                    /* Penalize clients which consume ticks */
 
425
                    if (client->smart_priority > SMART_MIN_PRIORITY)
 
426
                        client->smart_priority--;
 
427
                    break;
 
428
                }
 
429
#endif
 
430
                /* now, finally, deal with client requests */
 
431
 
 
432
                result = ReadRequestFromClient(client);
 
433
                if (result <= 0) 
 
434
                {
 
435
                    if (result < 0)
 
436
                        CloseDownClient(client);
 
437
                    break;
 
438
                }
 
439
 
 
440
                client->sequence++;
 
441
#ifdef DEBUG
 
442
                if (client->requestLogIndex == MAX_REQUEST_LOG)
 
443
                    client->requestLogIndex = 0;
 
444
                client->requestLog[client->requestLogIndex] = MAJOROP;
 
445
                client->requestLogIndex++;
 
446
#endif
 
447
                if (result > (MAX_BIG_REQUEST_SIZE << 2))
 
448
                    result = BadLength;
 
449
                else
 
450
                    result = (* client->requestVector[MAJOROP])(client);
 
451
            
 
452
                if (result != Success) 
 
453
                {
 
454
                    if (client->noClientException != Success)
 
455
                        CloseDownClient(client);
 
456
                    else
 
457
                        SendErrorToClient(client, MAJOROP,
 
458
                                          MinorOpcodeOfRequest(client),
 
459
                                          client->errorValue, result);
 
460
                    break;
 
461
                }
 
462
            }
 
463
            FlushAllOutput();
 
464
#ifdef SMART_SCHEDULE
 
465
            client = clients[clientReady[nready]];
 
466
            if (client)
 
467
                client->smart_stop_tick = SmartScheduleTime;
 
468
#endif
 
469
            requestingClient = NULL;
 
470
        }
 
471
        dispatchException &= ~DE_PRIORITYCHANGE;
 
472
    }
 
473
    KillAllClients();
 
474
    DEALLOCATE_LOCAL(clientReady);
 
475
    dispatchException &= ~DE_RESET;
 
476
}
 
477
 
 
478
#undef MAJOROP
 
479
 
 
480
/*ARGSUSED*/
 
481
int
 
482
ProcBadRequest(client)
 
483
    ClientPtr client;
 
484
{
 
485
    return (BadRequest);
 
486
}
 
487
 
 
488
int
 
489
ProcCreateWindow(client)
 
490
    register ClientPtr client;
 
491
{
 
492
    register WindowPtr pParent, pWin;
 
493
    REQUEST(xCreateWindowReq);
 
494
    int result;
 
495
    int len;
 
496
 
 
497
    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
 
498
    
 
499
    LEGAL_NEW_RESOURCE(stuff->wid, client);
 
500
    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
 
501
                                                    SecurityWriteAccess)))
 
502
        return BadWindow;
 
503
    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
 
504
    if (Ones(stuff->mask) != len)
 
505
        return BadLength;
 
506
    if (!stuff->width || !stuff->height)
 
507
    {
 
508
        client->errorValue = 0;
 
509
        return BadValue;
 
510
    }
 
511
    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
 
512
                              stuff->y, stuff->width, stuff->height, 
 
513
                              stuff->borderWidth, stuff->class,
 
514
                              stuff->mask, (XID *) &stuff[1], 
 
515
                              (int)stuff->depth, 
 
516
                              client, stuff->visual, &result);
 
517
    if (pWin)
 
518
    {
 
519
        Mask mask = pWin->eventMask;
 
520
 
 
521
        pWin->eventMask = 0; /* subterfuge in case AddResource fails */
 
522
        if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
 
523
            return BadAlloc;
 
524
        pWin->eventMask = mask;
 
525
    }
 
526
    if (client->noClientException != Success)
 
527
        return(client->noClientException);
 
528
    else
 
529
        return(result);
 
530
}
 
531
 
 
532
int
 
533
ProcChangeWindowAttributes(client)
 
534
    register ClientPtr client;
 
535
{
 
536
    register WindowPtr pWin;
 
537
    REQUEST(xChangeWindowAttributesReq);
 
538
    register int result;
 
539
    int len;
 
540
 
 
541
    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
 
542
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
543
                                           SecurityWriteAccess);
 
544
    if (!pWin)
 
545
        return(BadWindow);
 
546
    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
 
547
    if (len != Ones(stuff->valueMask))
 
548
        return BadLength;
 
549
    result =  ChangeWindowAttributes(pWin, 
 
550
                                  stuff->valueMask, 
 
551
                                  (XID *) &stuff[1], 
 
552
                                  client);
 
553
    if (client->noClientException != Success)
 
554
        return(client->noClientException);
 
555
    else
 
556
        return(result);
 
557
}
 
558
 
 
559
int
 
560
ProcGetWindowAttributes(client)
 
561
    register ClientPtr client;
 
562
{
 
563
    register WindowPtr pWin;
 
564
    REQUEST(xResourceReq);
 
565
    xGetWindowAttributesReply wa;
 
566
 
 
567
    REQUEST_SIZE_MATCH(xResourceReq);
 
568
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 
569
                                           SecurityReadAccess);
 
570
    if (!pWin)
 
571
        return(BadWindow);
 
572
    GetWindowAttributes(pWin, client, &wa);
 
573
    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
 
574
    return(client->noClientException);
 
575
}
 
576
 
 
577
int
 
578
ProcDestroyWindow(client)
 
579
    register ClientPtr client;
 
580
{
 
581
    register WindowPtr pWin;
 
582
    REQUEST(xResourceReq);
 
583
 
 
584
    REQUEST_SIZE_MATCH(xResourceReq);
 
585
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 
586
                                           SecurityDestroyAccess);
 
587
    if (!pWin)
 
588
        return(BadWindow);
 
589
    if (pWin->parent)
 
590
        FreeResource(stuff->id, RT_NONE);
 
591
    return(client->noClientException);
 
592
}
 
593
 
 
594
int
 
595
ProcDestroySubwindows(client)
 
596
    register ClientPtr client;
 
597
{
 
598
    register WindowPtr pWin;
 
599
    REQUEST(xResourceReq);
 
600
 
 
601
    REQUEST_SIZE_MATCH(xResourceReq);
 
602
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 
603
                                           SecurityDestroyAccess);
 
604
    if (!pWin)
 
605
        return(BadWindow);
 
606
    DestroySubwindows(pWin, client);
 
607
    return(client->noClientException);
 
608
}
 
609
 
 
610
int
 
611
ProcChangeSaveSet(client)
 
612
    register ClientPtr client;
 
613
{
 
614
    register WindowPtr pWin;
 
615
    REQUEST(xChangeSaveSetReq);
 
616
    register int result;
 
617
                  
 
618
    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
 
619
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
620
                                           SecurityReadAccess);
 
621
    if (!pWin)
 
622
        return(BadWindow);
 
623
    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
 
624
        return BadMatch;
 
625
    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
 
626
    {
 
627
        result = AlterSaveSetForClient(client, pWin, stuff->mode);
 
628
        if (client->noClientException != Success)
 
629
            return(client->noClientException);
 
630
        else
 
631
            return(result);
 
632
    }
 
633
    else
 
634
    {
 
635
        client->errorValue = stuff->mode;
 
636
        return( BadValue );
 
637
    }
 
638
}
 
639
 
 
640
int
 
641
ProcReparentWindow(client)
 
642
    register ClientPtr client;
 
643
{
 
644
    register WindowPtr pWin, pParent;
 
645
    REQUEST(xReparentWindowReq);
 
646
    register int result;
 
647
 
 
648
    REQUEST_SIZE_MATCH(xReparentWindowReq);
 
649
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
650
                                           SecurityWriteAccess);
 
651
    if (!pWin)
 
652
        return(BadWindow);
 
653
    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
 
654
                                              SecurityWriteAccess);
 
655
    if (!pParent)
 
656
        return(BadWindow);
 
657
    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
 
658
    {
 
659
        if ((pWin->backgroundState == ParentRelative) &&
 
660
            (pParent->drawable.depth != pWin->drawable.depth))
 
661
            return BadMatch;
 
662
        if ((pWin->drawable.class != InputOnly) &&
 
663
            (pParent->drawable.class == InputOnly))
 
664
            return BadMatch;
 
665
        result =  ReparentWindow(pWin, pParent, 
 
666
                         (short)stuff->x, (short)stuff->y, client);
 
667
        if (client->noClientException != Success)
 
668
            return(client->noClientException);
 
669
        else
 
670
            return(result);
 
671
    }
 
672
    else 
 
673
        return (BadMatch);
 
674
}
 
675
 
 
676
int
 
677
ProcMapWindow(client)
 
678
    register ClientPtr client;
 
679
{
 
680
    register WindowPtr pWin;
 
681
    REQUEST(xResourceReq);
 
682
 
 
683
    REQUEST_SIZE_MATCH(xResourceReq);
 
684
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 
685
                                           SecurityReadAccess);
 
686
    if (!pWin)
 
687
        return(BadWindow);
 
688
    MapWindow(pWin, client);
 
689
           /* update cache to say it is mapped */
 
690
    return(client->noClientException);
 
691
}
 
692
 
 
693
int
 
694
ProcMapSubwindows(client)
 
695
    register ClientPtr client;
 
696
{
 
697
    register WindowPtr pWin;
 
698
    REQUEST(xResourceReq);
 
699
 
 
700
    REQUEST_SIZE_MATCH(xResourceReq);
 
701
    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
 
702
                                            SecurityReadAccess);
 
703
    if (!pWin)
 
704
        return(BadWindow);
 
705
    MapSubwindows(pWin, client);
 
706
           /* update cache to say it is mapped */
 
707
    return(client->noClientException);
 
708
}
 
709
 
 
710
int
 
711
ProcUnmapWindow(client)
 
712
    register ClientPtr client;
 
713
{
 
714
    register WindowPtr pWin;
 
715
    REQUEST(xResourceReq);
 
716
 
 
717
    REQUEST_SIZE_MATCH(xResourceReq);
 
718
    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
 
719
                                            SecurityReadAccess);
 
720
    if (!pWin)
 
721
        return(BadWindow);
 
722
    UnmapWindow(pWin, FALSE);
 
723
           /* update cache to say it is mapped */
 
724
    return(client->noClientException);
 
725
}
 
726
 
 
727
int
 
728
ProcUnmapSubwindows(client)
 
729
    register ClientPtr client;
 
730
{
 
731
    register WindowPtr pWin;
 
732
    REQUEST(xResourceReq);
 
733
 
 
734
    REQUEST_SIZE_MATCH(xResourceReq);
 
735
    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
 
736
                                            SecurityReadAccess);
 
737
    if (!pWin)
 
738
        return(BadWindow);
 
739
    UnmapSubwindows(pWin);
 
740
    return(client->noClientException);
 
741
}
 
742
 
 
743
int
 
744
ProcConfigureWindow(client)
 
745
    register ClientPtr client;
 
746
{
 
747
    register WindowPtr pWin;
 
748
    REQUEST(xConfigureWindowReq);
 
749
    register int result;
 
750
    int len;
 
751
 
 
752
    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
 
753
    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
 
754
                                            SecurityWriteAccess);
 
755
    if (!pWin)
 
756
        return(BadWindow);
 
757
    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
 
758
    if (Ones((Mask)stuff->mask) != len)
 
759
        return BadLength;
 
760
    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
 
761
                              client);
 
762
    if (client->noClientException != Success)
 
763
        return(client->noClientException);
 
764
    else
 
765
        return(result);
 
766
}
 
767
 
 
768
int
 
769
ProcCirculateWindow(client)
 
770
    register ClientPtr client;
 
771
{
 
772
    register WindowPtr pWin;
 
773
    REQUEST(xCirculateWindowReq);
 
774
 
 
775
    REQUEST_SIZE_MATCH(xCirculateWindowReq);
 
776
    if ((stuff->direction != RaiseLowest) &&
 
777
        (stuff->direction != LowerHighest))
 
778
    {
 
779
        client->errorValue = stuff->direction;
 
780
        return BadValue;
 
781
    }
 
782
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
783
                                           SecurityWriteAccess);
 
784
    if (!pWin)
 
785
        return(BadWindow);
 
786
    CirculateWindow(pWin, (int)stuff->direction, client);
 
787
    return(client->noClientException);
 
788
}
 
789
 
 
790
int
 
791
GetGeometry(client, rep)
 
792
    register ClientPtr client;
 
793
    xGetGeometryReply *rep;
 
794
{
 
795
    register DrawablePtr pDraw;
 
796
    REQUEST(xResourceReq);
 
797
 
 
798
    REQUEST_SIZE_MATCH(xResourceReq);
 
799
    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
 
800
    rep->type = X_Reply;
 
801
    rep->length = 0;
 
802
    rep->sequenceNumber = client->sequence;
 
803
    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
 
804
    rep->depth = pDraw->depth;
 
805
    rep->width = pDraw->width;
 
806
    rep->height = pDraw->height;
 
807
 
 
808
    /* XXX - Because the pixmap-implementation of the multibuffer extension 
 
809
     *       may have the buffer-id's drawable resource value be a pointer
 
810
     *       to the buffer's window instead of the buffer itself
 
811
     *       (this happens if the buffer is the displayed buffer),
 
812
     *       we also have to check that the id matches before we can
 
813
     *       truly say that it is a DRAWABLE_WINDOW.
 
814
     */
 
815
 
 
816
    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
 
817
        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
 
818
    {
 
819
        register WindowPtr pWin = (WindowPtr)pDraw;
 
820
        rep->x = pWin->origin.x - wBorderWidth (pWin);
 
821
        rep->y = pWin->origin.y - wBorderWidth (pWin);
 
822
        rep->borderWidth = pWin->borderWidth;
 
823
    }
 
824
    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
 
825
    {
 
826
        rep->x = rep->y = rep->borderWidth = 0;
 
827
    }
 
828
 
 
829
    return Success;
 
830
}
 
831
 
 
832
 
 
833
int
 
834
ProcGetGeometry(client)
 
835
    register ClientPtr client;
 
836
{
 
837
    xGetGeometryReply rep;
 
838
    int status;
 
839
 
 
840
    if ((status = GetGeometry(client, &rep)) != Success)
 
841
        return status;
 
842
 
 
843
    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
 
844
    return(client->noClientException);
 
845
}
 
846
 
 
847
 
 
848
int
 
849
ProcQueryTree(client)
 
850
    register ClientPtr client;
 
851
{
 
852
    xQueryTreeReply reply;
 
853
    int numChildren = 0;
 
854
    register WindowPtr pChild, pWin, pHead;
 
855
    Window  *childIDs = (Window *)NULL;
 
856
    REQUEST(xResourceReq);
 
857
 
 
858
    REQUEST_SIZE_MATCH(xResourceReq);
 
859
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 
860
                                           SecurityReadAccess);
 
861
    if (!pWin)
 
862
        return(BadWindow);
 
863
    reply.type = X_Reply;
 
864
    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
 
865
    reply.sequenceNumber = client->sequence;
 
866
    if (pWin->parent)
 
867
        reply.parent = pWin->parent->drawable.id;
 
868
    else
 
869
        reply.parent = (Window)None;
 
870
    pHead = RealChildHead(pWin);
 
871
    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
 
872
        numChildren++;
 
873
    if (numChildren)
 
874
    {
 
875
        int curChild = 0;
 
876
 
 
877
        childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
 
878
        if (!childIDs)
 
879
            return BadAlloc;
 
880
        for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
 
881
            childIDs[curChild++] = pChild->drawable.id;
 
882
    }
 
883
    
 
884
    reply.nChildren = numChildren;
 
885
    reply.length = (numChildren * sizeof(Window)) >> 2;
 
886
    
 
887
    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
 
888
    if (numChildren)
 
889
    {
 
890
        client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 
891
        WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
 
892
        DEALLOCATE_LOCAL(childIDs);
 
893
    }
 
894
 
 
895
    return(client->noClientException);
 
896
}
 
897
 
 
898
int
 
899
ProcInternAtom(client)
 
900
    register ClientPtr client;
 
901
{
 
902
    Atom atom;
 
903
    char *tchar;
 
904
    REQUEST(xInternAtomReq);
 
905
 
 
906
    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
 
907
    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
 
908
    {
 
909
        client->errorValue = stuff->onlyIfExists;
 
910
        return(BadValue);
 
911
    }
 
912
    tchar = (char *) &stuff[1];
 
913
    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
 
914
    if (atom != BAD_RESOURCE)
 
915
    {
 
916
        xInternAtomReply reply;
 
917
        reply.type = X_Reply;
 
918
        reply.length = 0;
 
919
        reply.sequenceNumber = client->sequence;
 
920
        reply.atom = atom;
 
921
        WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
 
922
        return(client->noClientException);
 
923
    }
 
924
    else
 
925
        return (BadAlloc);
 
926
}
 
927
 
 
928
int
 
929
ProcGetAtomName(client)
 
930
    register ClientPtr client;
 
931
{
 
932
    char *str;
 
933
    xGetAtomNameReply reply;
 
934
    int len;
 
935
    REQUEST(xResourceReq);
 
936
 
 
937
    REQUEST_SIZE_MATCH(xResourceReq);
 
938
    if ( (str = NameForAtom(stuff->id)) )
 
939
    {
 
940
        len = strlen(str);
 
941
        reply.type = X_Reply;
 
942
        reply.length = (len + 3) >> 2;
 
943
        reply.sequenceNumber = client->sequence;
 
944
        reply.nameLength = len;
 
945
        WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
 
946
        (void)WriteToClient(client, len, str);
 
947
        return(client->noClientException);
 
948
    }
 
949
    else 
 
950
    { 
 
951
        client->errorValue = stuff->id;
 
952
        return (BadAtom);
 
953
    }
 
954
}
 
955
 
 
956
#ifdef K5AUTH
 
957
extern int k5_bad();
 
958
#endif
 
959
 
 
960
int
 
961
ProcSetSelectionOwner(client)
 
962
    register ClientPtr client;
 
963
{
 
964
    WindowPtr pWin;
 
965
    TimeStamp time;
 
966
    REQUEST(xSetSelectionOwnerReq);
 
967
 
 
968
    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
 
969
    UpdateCurrentTime();
 
970
    time = ClientTimeToServerTime(stuff->time);
 
971
 
 
972
    /* If the client's time stamp is in the future relative to the server's
 
973
        time stamp, do not set the selection, just return success. */
 
974
    if (CompareTimeStamps(time, currentTime) == LATER)
 
975
        return Success;
 
976
    if (stuff->window != None)
 
977
    {
 
978
        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
979
                                               SecurityReadAccess);
 
980
        if (!pWin)
 
981
            return(BadWindow);
 
982
    }
 
983
    else
 
984
        pWin = (WindowPtr)None;
 
985
    if (ValidAtom(stuff->selection))
 
986
    {
 
987
        int i = 0;
 
988
 
 
989
        /*
 
990
         * First, see if the selection is already set... 
 
991
         */
 
992
        while ((i < NumCurrentSelections) && 
 
993
               CurrentSelections[i].selection != stuff->selection) 
 
994
            i++;
 
995
        if (i < NumCurrentSelections)
 
996
        {        
 
997
            xEvent event;
 
998
 
 
999
            /* If the timestamp in client's request is in the past relative
 
1000
                to the time stamp indicating the last time the owner of the
 
1001
                selection was set, do not set the selection, just return 
 
1002
                success. */
 
1003
            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
 
1004
                == EARLIER)
 
1005
                return Success;
 
1006
            if (CurrentSelections[i].client &&
 
1007
                (!pWin || (CurrentSelections[i].client != client)))
 
1008
            {
 
1009
                event.u.u.type = SelectionClear;
 
1010
                event.u.selectionClear.time = time.milliseconds;
 
1011
                event.u.selectionClear.window = CurrentSelections[i].window;
 
1012
                event.u.selectionClear.atom = CurrentSelections[i].selection;
 
1013
                (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
 
1014
                                NoEventMask, NoEventMask /* CantBeFiltered */,
 
1015
                                NullGrab);
 
1016
            }
 
1017
        }
 
1018
        else
 
1019
        {
 
1020
            /*
 
1021
             * It doesn't exist, so add it...
 
1022
             */
 
1023
            Selection *newsels;
 
1024
 
 
1025
            if (i == 0)
 
1026
                newsels = (Selection *)xalloc(sizeof(Selection));
 
1027
            else
 
1028
                newsels = (Selection *)xrealloc(CurrentSelections,
 
1029
                            (NumCurrentSelections + 1) * sizeof(Selection));
 
1030
            if (!newsels)
 
1031
                return BadAlloc;
 
1032
            NumCurrentSelections++;
 
1033
            CurrentSelections = newsels;
 
1034
            CurrentSelections[i].selection = stuff->selection;
 
1035
        }
 
1036
        CurrentSelections[i].lastTimeChanged = time;
 
1037
        CurrentSelections[i].window = stuff->window;
 
1038
        CurrentSelections[i].pWin = pWin;
 
1039
        CurrentSelections[i].client = (pWin ? client : NullClient);
 
1040
        return (client->noClientException);
 
1041
    }
 
1042
    else 
 
1043
    {
 
1044
        client->errorValue = stuff->selection;
 
1045
        return (BadAtom);
 
1046
    }
 
1047
}
 
1048
 
 
1049
int
 
1050
ProcGetSelectionOwner(client)
 
1051
    register ClientPtr client;
 
1052
{
 
1053
    REQUEST(xResourceReq);
 
1054
 
 
1055
    REQUEST_SIZE_MATCH(xResourceReq);
 
1056
    if (ValidAtom(stuff->id))
 
1057
    {
 
1058
        int i;
 
1059
        xGetSelectionOwnerReply reply;
 
1060
 
 
1061
        i = 0;
 
1062
        while ((i < NumCurrentSelections) && 
 
1063
               CurrentSelections[i].selection != stuff->id) i++;
 
1064
        reply.type = X_Reply;
 
1065
        reply.length = 0;
 
1066
        reply.sequenceNumber = client->sequence;
 
1067
        if (i < NumCurrentSelections)
 
1068
            reply.owner = CurrentSelections[i].window;
 
1069
        else
 
1070
            reply.owner = None;
 
1071
        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
 
1072
        return(client->noClientException);
 
1073
    }
 
1074
    else            
 
1075
    {
 
1076
        client->errorValue = stuff->id;
 
1077
        return (BadAtom); 
 
1078
    }
 
1079
}
 
1080
 
 
1081
int
 
1082
ProcConvertSelection(client)
 
1083
    register ClientPtr client;
 
1084
{
 
1085
    Bool paramsOkay;
 
1086
    xEvent event;
 
1087
    WindowPtr pWin;
 
1088
    REQUEST(xConvertSelectionReq);
 
1089
 
 
1090
    REQUEST_SIZE_MATCH(xConvertSelectionReq);
 
1091
    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
 
1092
                                           SecurityReadAccess);
 
1093
    if (!pWin)
 
1094
        return(BadWindow);
 
1095
 
 
1096
    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
 
1097
    if (stuff->property != None)
 
1098
        paramsOkay &= ValidAtom(stuff->property);
 
1099
    if (paramsOkay)
 
1100
    {
 
1101
        int i;
 
1102
 
 
1103
        i = 0;
 
1104
        while ((i < NumCurrentSelections) && 
 
1105
               CurrentSelections[i].selection != stuff->selection) i++;
 
1106
        if ((i < NumCurrentSelections) && 
 
1107
            (CurrentSelections[i].window != None)
 
1108
#ifdef XCSECURITY
 
1109
            && (!client->CheckAccess ||
 
1110
                (* client->CheckAccess)(client, CurrentSelections[i].window,
 
1111
                                        RT_WINDOW, SecurityReadAccess,
 
1112
                                        CurrentSelections[i].pWin))
 
1113
#endif
 
1114
            )
 
1115
        {        
 
1116
            event.u.u.type = SelectionRequest;
 
1117
            event.u.selectionRequest.time = stuff->time;
 
1118
            event.u.selectionRequest.owner = 
 
1119
                        CurrentSelections[i].window;
 
1120
            event.u.selectionRequest.requestor = stuff->requestor;
 
1121
            event.u.selectionRequest.selection = stuff->selection;
 
1122
            event.u.selectionRequest.target = stuff->target;
 
1123
            event.u.selectionRequest.property = stuff->property;
 
1124
            if (TryClientEvents(
 
1125
                CurrentSelections[i].client, &event, 1, NoEventMask,
 
1126
                NoEventMask /* CantBeFiltered */, NullGrab))
 
1127
                return (client->noClientException);
 
1128
        }
 
1129
        event.u.u.type = SelectionNotify;
 
1130
        event.u.selectionNotify.time = stuff->time;
 
1131
        event.u.selectionNotify.requestor = stuff->requestor;
 
1132
        event.u.selectionNotify.selection = stuff->selection;
 
1133
        event.u.selectionNotify.target = stuff->target;
 
1134
        event.u.selectionNotify.property = None;
 
1135
        (void) TryClientEvents(client, &event, 1, NoEventMask,
 
1136
                               NoEventMask /* CantBeFiltered */, NullGrab);
 
1137
        return (client->noClientException);
 
1138
    }
 
1139
    else 
 
1140
    {
 
1141
        client->errorValue = stuff->property;
 
1142
        return (BadAtom);
 
1143
    }
 
1144
}
 
1145
 
 
1146
int
 
1147
ProcGrabServer(client)
 
1148
    register ClientPtr client;
 
1149
{
 
1150
    REQUEST_SIZE_MATCH(xReq);
 
1151
    if (grabState != GrabNone && client != grabClient)
 
1152
    {
 
1153
        ResetCurrentRequest(client);
 
1154
        client->sequence--;
 
1155
        BITSET(grabWaiters, client->index);
 
1156
        IgnoreClient(client);
 
1157
        return(client->noClientException);
 
1158
    }
 
1159
    OnlyListenToOneClient(client);
 
1160
    grabState = GrabKickout;
 
1161
    grabClient = client;
 
1162
 
 
1163
    if (ServerGrabCallback)
 
1164
    {
 
1165
        ServerGrabInfoRec grabinfo;
 
1166
        grabinfo.client = client;
 
1167
        grabinfo.grabstate  = SERVER_GRABBED;
 
1168
        CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
 
1169
    }
 
1170
 
 
1171
    return(client->noClientException);
 
1172
}
 
1173
 
 
1174
static void
 
1175
#if NeedFunctionPrototypes
 
1176
UngrabServer(ClientPtr client)
 
1177
#else
 
1178
UngrabServer(client)
 
1179
    ClientPtr client;
 
1180
#endif
 
1181
{
 
1182
    int i;
 
1183
 
 
1184
    grabState = GrabNone;
 
1185
    ListenToAllClients();
 
1186
    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
 
1187
        ;
 
1188
    if (i >= 0)
 
1189
    {
 
1190
        i <<= 5;
 
1191
        while (!GETBIT(grabWaiters, i))
 
1192
            i++;
 
1193
        BITCLEAR(grabWaiters, i);
 
1194
        AttendClient(clients[i]);
 
1195
    }
 
1196
 
 
1197
    if (ServerGrabCallback)
 
1198
    {
 
1199
        ServerGrabInfoRec grabinfo;
 
1200
        grabinfo.client = client;
 
1201
        grabinfo.grabstate  = SERVER_UNGRABBED;
 
1202
        CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
 
1203
    }
 
1204
}
 
1205
 
 
1206
int
 
1207
ProcUngrabServer(client)
 
1208
    register ClientPtr client;
 
1209
{
 
1210
    REQUEST_SIZE_MATCH(xReq);
 
1211
    UngrabServer(client);
 
1212
    return(client->noClientException);
 
1213
}
 
1214
 
 
1215
int
 
1216
ProcTranslateCoords(client)
 
1217
    register ClientPtr client;
 
1218
{
 
1219
    REQUEST(xTranslateCoordsReq);
 
1220
 
 
1221
    register WindowPtr pWin, pDst;
 
1222
    xTranslateCoordsReply rep;
 
1223
 
 
1224
    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
 
1225
    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
 
1226
                                           SecurityReadAccess);
 
1227
    if (!pWin)
 
1228
        return(BadWindow);
 
1229
    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
 
1230
                                           SecurityReadAccess);
 
1231
    if (!pDst)
 
1232
        return(BadWindow);
 
1233
    rep.type = X_Reply;
 
1234
    rep.length = 0;
 
1235
    rep.sequenceNumber = client->sequence;
 
1236
    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
 
1237
    {
 
1238
        rep.sameScreen = xFalse;
 
1239
        rep.child = None;
 
1240
        rep.dstX = rep.dstY = 0;
 
1241
    }
 
1242
    else
 
1243
    {
 
1244
        INT16 x, y;
 
1245
        rep.sameScreen = xTrue;
 
1246
        rep.child = None;
 
1247
        /* computing absolute coordinates -- adjust to destination later */
 
1248
        x = pWin->drawable.x + stuff->srcX;
 
1249
        y = pWin->drawable.y + stuff->srcY;
 
1250
        pWin = pDst->firstChild;
 
1251
        while (pWin)
 
1252
        {
 
1253
#ifdef SHAPE
 
1254
            BoxRec  box;
 
1255
#endif
 
1256
            if ((pWin->mapped) &&
 
1257
                (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
 
1258
                (x < pWin->drawable.x + (int)pWin->drawable.width +
 
1259
                 wBorderWidth (pWin)) &&
 
1260
                (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
 
1261
                (y < pWin->drawable.y + (int)pWin->drawable.height +
 
1262
                 wBorderWidth (pWin))
 
1263
#ifdef SHAPE
 
1264
                /* When a window is shaped, a further check
 
1265
                 * is made to see if the point is inside
 
1266
                 * borderSize
 
1267
                 */
 
1268
                && (!wBoundingShape(pWin) ||
 
1269
                    POINT_IN_REGION(pWin->drawable.pScreen, 
 
1270
                                        &pWin->borderSize, x, y, &box))
 
1271
#endif
 
1272
                )
 
1273
            {
 
1274
                rep.child = pWin->drawable.id;
 
1275
                pWin = (WindowPtr) NULL;
 
1276
            }
 
1277
            else
 
1278
                pWin = pWin->nextSib;
 
1279
        }
 
1280
        /* adjust to destination coordinates */
 
1281
        rep.dstX = x - pDst->drawable.x;
 
1282
        rep.dstY = y - pDst->drawable.y;
 
1283
    }
 
1284
    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
 
1285
    return(client->noClientException);
 
1286
}
 
1287
 
 
1288
int
 
1289
ProcOpenFont(client)
 
1290
    register ClientPtr client;
 
1291
{
 
1292
    int err;
 
1293
    REQUEST(xOpenFontReq);
 
1294
 
 
1295
    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
 
1296
    client->errorValue = stuff->fid;
 
1297
    LEGAL_NEW_RESOURCE(stuff->fid, client);
 
1298
    err = OpenFont(client, stuff->fid, (Mask) 0,
 
1299
                stuff->nbytes, (char *)&stuff[1]);
 
1300
    if (err == Success)
 
1301
    {
 
1302
        return(client->noClientException);
 
1303
    }
 
1304
    else
 
1305
        return err;
 
1306
}
 
1307
 
 
1308
int
 
1309
ProcCloseFont(client)
 
1310
    register ClientPtr client;
 
1311
{
 
1312
    FontPtr pFont;
 
1313
    REQUEST(xResourceReq);
 
1314
 
 
1315
    REQUEST_SIZE_MATCH(xResourceReq);
 
1316
    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
 
1317
                                            SecurityDestroyAccess);
 
1318
    if ( pFont != (FontPtr)NULL)        /* id was valid */
 
1319
    {
 
1320
        FreeResource(stuff->id, RT_NONE);
 
1321
        return(client->noClientException);
 
1322
    }
 
1323
    else
 
1324
    {
 
1325
        client->errorValue = stuff->id;
 
1326
        return (BadFont);
 
1327
    }
 
1328
}
 
1329
 
 
1330
int
 
1331
ProcQueryFont(client)
 
1332
    register ClientPtr client;
 
1333
{
 
1334
    xQueryFontReply     *reply;
 
1335
    FontPtr pFont;
 
1336
    register GC *pGC;
 
1337
    REQUEST(xResourceReq);
 
1338
 
 
1339
    REQUEST_SIZE_MATCH(xResourceReq);
 
1340
    client->errorValue = stuff->id;             /* EITHER font or gc */
 
1341
    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
 
1342
                                            SecurityReadAccess);
 
1343
    if (!pFont)
 
1344
    {
 
1345
          /* can't use VERIFY_GC because it might return BadGC */
 
1346
        pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
 
1347
                                            SecurityReadAccess);
 
1348
        if (!pGC)
 
1349
        {
 
1350
            client->errorValue = stuff->id;
 
1351
            return(BadFont);     /* procotol spec says only error is BadFont */
 
1352
        }
 
1353
        pFont = pGC->font;
 
1354
    }
 
1355
 
 
1356
    {
 
1357
        xCharInfo       *pmax = FONTINKMAX(pFont);
 
1358
        xCharInfo       *pmin = FONTINKMIN(pFont);
 
1359
        int             nprotoxcistructs;
 
1360
        int             rlength;
 
1361
 
 
1362
        nprotoxcistructs = (
 
1363
           pmax->rightSideBearing == pmin->rightSideBearing &&
 
1364
           pmax->leftSideBearing == pmin->leftSideBearing &&
 
1365
           pmax->descent == pmin->descent &&
 
1366
           pmax->ascent == pmin->ascent &&
 
1367
           pmax->characterWidth == pmin->characterWidth) ?
 
1368
                0 : N2dChars(pFont);
 
1369
 
 
1370
        rlength = sizeof(xQueryFontReply) +
 
1371
                     FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
 
1372
                     nprotoxcistructs * sizeof(xCharInfo);
 
1373
        reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
 
1374
        if(!reply)
 
1375
        {
 
1376
            return(BadAlloc);
 
1377
        }
 
1378
 
 
1379
        reply->type = X_Reply;
 
1380
        reply->length = (rlength - sizeof(xGenericReply)) >> 2;
 
1381
        reply->sequenceNumber = client->sequence;
 
1382
        QueryFont( pFont, reply, nprotoxcistructs);
 
1383
 
 
1384
        WriteReplyToClient(client, rlength, reply);
 
1385
        DEALLOCATE_LOCAL(reply);
 
1386
        return(client->noClientException);
 
1387
    }
 
1388
}
 
1389
 
 
1390
int
 
1391
ProcQueryTextExtents(client)
 
1392
    register ClientPtr client;
 
1393
{
 
1394
    REQUEST(xQueryTextExtentsReq);
 
1395
    xQueryTextExtentsReply reply;
 
1396
    FontPtr pFont;
 
1397
    GC *pGC;
 
1398
    ExtentInfoRec info;
 
1399
    unsigned long length;
 
1400
 
 
1401
    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
 
1402
        
 
1403
    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
 
1404
                                            SecurityReadAccess);
 
1405
    if (!pFont)
 
1406
    {
 
1407
        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
 
1408
                                           SecurityReadAccess);
 
1409
        if (!pGC)
 
1410
        {
 
1411
            client->errorValue = stuff->fid;
 
1412
            return(BadFont);
 
1413
        }
 
1414
        pFont = pGC->font;
 
1415
    }
 
1416
    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
 
1417
    length = length << 1;
 
1418
    if (stuff->oddLength)
 
1419
    {
 
1420
        if (length == 0)
 
1421
            return(BadLength);
 
1422
        length--;
 
1423
    }
 
1424
    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
 
1425
        return(BadAlloc);
 
1426
    reply.type = X_Reply;
 
1427
    reply.length = 0;
 
1428
    reply.sequenceNumber = client->sequence;
 
1429
    reply.drawDirection = info.drawDirection;
 
1430
    reply.fontAscent = info.fontAscent;
 
1431
    reply.fontDescent = info.fontDescent;
 
1432
    reply.overallAscent = info.overallAscent;
 
1433
    reply.overallDescent = info.overallDescent;
 
1434
    reply.overallWidth = info.overallWidth;
 
1435
    reply.overallLeft = info.overallLeft;
 
1436
    reply.overallRight = info.overallRight;
 
1437
    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
 
1438
    return(client->noClientException);
 
1439
}
 
1440
 
 
1441
int
 
1442
ProcListFonts(client)
 
1443
    register ClientPtr client;
 
1444
{
 
1445
    REQUEST(xListFontsReq);
 
1446
 
 
1447
    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
 
1448
 
 
1449
    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
 
1450
        stuff->maxNames);
 
1451
}
 
1452
 
 
1453
int
 
1454
ProcListFontsWithInfo(client)
 
1455
    register ClientPtr client;
 
1456
{
 
1457
    REQUEST(xListFontsWithInfoReq);
 
1458
 
 
1459
    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
 
1460
 
 
1461
    return StartListFontsWithInfo(client, stuff->nbytes,
 
1462
                                  (unsigned char *) &stuff[1], stuff->maxNames);
 
1463
}
 
1464
 
 
1465
/*ARGSUSED*/
 
1466
int
 
1467
dixDestroyPixmap(value, pid)
 
1468
    pointer value; /* must conform to DeleteType */
 
1469
    XID pid;
 
1470
{
 
1471
    PixmapPtr pPixmap = (PixmapPtr)value;
 
1472
    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
 
1473
}
 
1474
 
 
1475
int
 
1476
ProcCreatePixmap(client)
 
1477
    register ClientPtr client;
 
1478
{
 
1479
    PixmapPtr pMap;
 
1480
    register DrawablePtr pDraw;
 
1481
    REQUEST(xCreatePixmapReq);
 
1482
    DepthPtr pDepth;
 
1483
    register int i;
 
1484
 
 
1485
    REQUEST_SIZE_MATCH(xCreatePixmapReq);
 
1486
    client->errorValue = stuff->pid;
 
1487
    LEGAL_NEW_RESOURCE(stuff->pid, client);
 
1488
    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
 
1489
                                 SecurityReadAccess);
 
1490
    if (!stuff->width || !stuff->height)
 
1491
    {
 
1492
        client->errorValue = 0;
 
1493
        return BadValue;
 
1494
    }
 
1495
    if (stuff->depth != 1)
 
1496
    {
 
1497
        pDepth = pDraw->pScreen->allowedDepths;
 
1498
        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
 
1499
           if (pDepth->depth == stuff->depth)
 
1500
               goto CreatePmap;
 
1501
        client->errorValue = stuff->depth;
 
1502
        return BadValue;
 
1503
    }
 
1504
CreatePmap:
 
1505
    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
 
1506
                (pDraw->pScreen, stuff->width,
 
1507
                 stuff->height, stuff->depth);
 
1508
    if (pMap)
 
1509
    {
 
1510
        pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 
1511
        pMap->drawable.id = stuff->pid;
 
1512
        if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
 
1513
            return(client->noClientException);
 
1514
    }
 
1515
    return (BadAlloc);
 
1516
}
 
1517
 
 
1518
int
 
1519
ProcFreePixmap(client)
 
1520
    register ClientPtr client;
 
1521
{
 
1522
    PixmapPtr pMap;
 
1523
 
 
1524
    REQUEST(xResourceReq);
 
1525
 
 
1526
    REQUEST_SIZE_MATCH(xResourceReq);
 
1527
    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
 
1528
                                             SecurityDestroyAccess);
 
1529
    if (pMap) 
 
1530
    {
 
1531
        FreeResource(stuff->id, RT_NONE);
 
1532
        return(client->noClientException);
 
1533
    }
 
1534
    else 
 
1535
    {
 
1536
        client->errorValue = stuff->id;
 
1537
        return (BadPixmap);
 
1538
    }
 
1539
}
 
1540
 
 
1541
int
 
1542
ProcCreateGC(client)
 
1543
    register ClientPtr client;
 
1544
{
 
1545
    int error;
 
1546
    GC *pGC;
 
1547
    register DrawablePtr pDraw;
 
1548
    unsigned len;
 
1549
    REQUEST(xCreateGCReq);
 
1550
 
 
1551
    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
 
1552
    client->errorValue = stuff->gc;
 
1553
    LEGAL_NEW_RESOURCE(stuff->gc, client);
 
1554
    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
 
1555
                              SecurityReadAccess);
 
1556
    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
 
1557
    if (len != Ones(stuff->mask))
 
1558
        return BadLength;
 
1559
    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
 
1560
                         (XID *) &stuff[1], &error);
 
1561
    if (error != Success)
 
1562
        return error;
 
1563
    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
 
1564
        return (BadAlloc);
 
1565
    return(client->noClientException);
 
1566
}
 
1567
 
 
1568
int
 
1569
ProcChangeGC(client)
 
1570
    register ClientPtr client;
 
1571
{
 
1572
    GC *pGC;
 
1573
    REQUEST(xChangeGCReq);
 
1574
    int result;
 
1575
    unsigned len;
 
1576
                
 
1577
    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
 
1578
    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
 
1579
    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
 
1580
    if (len != Ones(stuff->mask))
 
1581
        return BadLength;
 
1582
 
 
1583
    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
 
1584
    if (client->noClientException != Success)
 
1585
        return(client->noClientException);
 
1586
    else
 
1587
    {
 
1588
        client->errorValue = clientErrorValue;
 
1589
        return(result);
 
1590
    }
 
1591
}
 
1592
 
 
1593
int
 
1594
ProcCopyGC(client)
 
1595
    register ClientPtr client;
 
1596
{
 
1597
    register GC *dstGC;
 
1598
    register GC *pGC;
 
1599
    int result;
 
1600
    REQUEST(xCopyGCReq);
 
1601
 
 
1602
    REQUEST_SIZE_MATCH(xCopyGCReq);
 
1603
    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
 
1604
    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
 
1605
    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
 
1606
        return (BadMatch);    
 
1607
    result = CopyGC(pGC, dstGC, stuff->mask);
 
1608
    if (client->noClientException != Success)
 
1609
        return(client->noClientException);
 
1610
    else
 
1611
    {
 
1612
        client->errorValue = clientErrorValue;
 
1613
        return(result);
 
1614
    }
 
1615
}
 
1616
 
 
1617
int
 
1618
ProcSetDashes(client)
 
1619
    register ClientPtr client;
 
1620
{
 
1621
    register GC *pGC;
 
1622
    int result;
 
1623
    REQUEST(xSetDashesReq);
 
1624
 
 
1625
    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
 
1626
    if (stuff->nDashes == 0)
 
1627
    {
 
1628
         client->errorValue = 0;
 
1629
         return BadValue;
 
1630
    }
 
1631
 
 
1632
    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
 
1633
 
 
1634
    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
 
1635
                       (unsigned char *)&stuff[1]);
 
1636
    if (client->noClientException != Success)
 
1637
        return(client->noClientException);
 
1638
    else
 
1639
    {
 
1640
        client->errorValue = clientErrorValue;
 
1641
        return(result);
 
1642
    }
 
1643
}
 
1644
 
 
1645
int
 
1646
ProcSetClipRectangles(client)
 
1647
    register ClientPtr client;
 
1648
{
 
1649
    int nr;
 
1650
    int result;
 
1651
    register GC *pGC;
 
1652
    REQUEST(xSetClipRectanglesReq);
 
1653
 
 
1654
    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
 
1655
    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
 
1656
        (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
 
1657
    {
 
1658
        client->errorValue = stuff->ordering;
 
1659
        return BadValue;
 
1660
    }
 
1661
    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
 
1662
                 
 
1663
    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
 
1664
    if (nr & 4)
 
1665
        return(BadLength);
 
1666
    nr >>= 3;
 
1667
    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
 
1668
                          nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
 
1669
    if (client->noClientException != Success)
 
1670
        return(client->noClientException);
 
1671
    else
 
1672
        return(result);
 
1673
}
 
1674
 
 
1675
int
 
1676
ProcFreeGC(client)
 
1677
    register ClientPtr client;
 
1678
{
 
1679
    register GC *pGC;
 
1680
    REQUEST(xResourceReq);
 
1681
 
 
1682
    REQUEST_SIZE_MATCH(xResourceReq);
 
1683
    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
 
1684
    FreeResource(stuff->id, RT_NONE);
 
1685
    return(client->noClientException);
 
1686
}
 
1687
 
 
1688
int
 
1689
ProcClearToBackground(client)
 
1690
    register ClientPtr client;
 
1691
{
 
1692
    REQUEST(xClearAreaReq);
 
1693
    register WindowPtr pWin;
 
1694
 
 
1695
    REQUEST_SIZE_MATCH(xClearAreaReq);
 
1696
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
1697
                                           SecurityWriteAccess);
 
1698
    if (!pWin)
 
1699
        return(BadWindow);
 
1700
    if (pWin->drawable.class == InputOnly)
 
1701
    {
 
1702
        client->errorValue = stuff->window;
 
1703
        return (BadMatch);
 
1704
    }               
 
1705
    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
 
1706
    {
 
1707
        client->errorValue = stuff->exposures;
 
1708
        return(BadValue);
 
1709
    }
 
1710
    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
 
1711
                               stuff->width, stuff->height,
 
1712
                               (Bool)stuff->exposures);
 
1713
    return(client->noClientException);
 
1714
}
 
1715
 
 
1716
int
 
1717
ProcCopyArea(client)
 
1718
    register ClientPtr client;
 
1719
{
 
1720
    register DrawablePtr pDst;
 
1721
    register DrawablePtr pSrc;
 
1722
    register GC *pGC;
 
1723
    REQUEST(xCopyAreaReq);
 
1724
    RegionPtr pRgn;
 
1725
 
 
1726
    REQUEST_SIZE_MATCH(xCopyAreaReq);
 
1727
 
 
1728
    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
 
1729
    if (stuff->dstDrawable != stuff->srcDrawable)
 
1730
    {
 
1731
        SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
 
1732
                                 SecurityReadAccess);
 
1733
        if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
 
1734
        {
 
1735
            client->errorValue = stuff->dstDrawable;
 
1736
            return (BadMatch);
 
1737
        }
 
1738
    }
 
1739
    else
 
1740
        pSrc = pDst;
 
1741
 
 
1742
    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
 
1743
 
 
1744
    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
 
1745
                                 stuff->width, stuff->height, 
 
1746
                                 stuff->dstX, stuff->dstY);
 
1747
    if (pGC->graphicsExposures)
 
1748
    {
 
1749
        (*pDst->pScreen->SendGraphicsExpose)
 
1750
                (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
 
1751
        if (pRgn)
 
1752
            REGION_DESTROY(pDst->pScreen, pRgn);
 
1753
    }
 
1754
 
 
1755
    return(client->noClientException);
 
1756
}
 
1757
 
 
1758
int
 
1759
ProcCopyPlane(client)
 
1760
    register ClientPtr client;
 
1761
{
 
1762
    register DrawablePtr psrcDraw, pdstDraw;
 
1763
    register GC *pGC;
 
1764
    REQUEST(xCopyPlaneReq);
 
1765
    RegionPtr pRgn;
 
1766
 
 
1767
    REQUEST_SIZE_MATCH(xCopyPlaneReq);
 
1768
 
 
1769
    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
 
1770
    if (stuff->dstDrawable != stuff->srcDrawable)
 
1771
    {
 
1772
        SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
 
1773
                                 SecurityReadAccess);
 
1774
        if (pdstDraw->pScreen != psrcDraw->pScreen)
 
1775
        {
 
1776
            client->errorValue = stuff->dstDrawable;
 
1777
            return (BadMatch);
 
1778
        }
 
1779
    }
 
1780
    else
 
1781
        psrcDraw = pdstDraw;
 
1782
 
 
1783
    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
 
1784
 
 
1785
    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
 
1786
    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
 
1787
       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
 
1788
    {
 
1789
       client->errorValue = stuff->bitPlane;
 
1790
       return(BadValue);
 
1791
    }
 
1792
 
 
1793
    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
 
1794
                                 stuff->width, stuff->height, 
 
1795
                                 stuff->dstX, stuff->dstY, stuff->bitPlane);
 
1796
    if (pGC->graphicsExposures)
 
1797
    {
 
1798
        (*pdstDraw->pScreen->SendGraphicsExpose)
 
1799
                (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
 
1800
        if (pRgn)
 
1801
            REGION_DESTROY(pdstDraw->pScreen, pRgn);
 
1802
    }
 
1803
    return(client->noClientException);
 
1804
}
 
1805
 
 
1806
int
 
1807
ProcPolyPoint(client)
 
1808
    register ClientPtr client;
 
1809
{
 
1810
    int npoint;
 
1811
    register GC *pGC;
 
1812
    register DrawablePtr pDraw;
 
1813
    REQUEST(xPolyPointReq);
 
1814
 
 
1815
    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
 
1816
    if ((stuff->coordMode != CoordModeOrigin) && 
 
1817
        (stuff->coordMode != CoordModePrevious))
 
1818
    {
 
1819
        client->errorValue = stuff->coordMode;
 
1820
        return BadValue;
 
1821
    }
 
1822
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
 
1823
    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
 
1824
    if (npoint)
 
1825
        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
 
1826
                          (xPoint *) &stuff[1]);
 
1827
    return (client->noClientException);
 
1828
}
 
1829
 
 
1830
int
 
1831
ProcPolyLine(client)
 
1832
    register ClientPtr client;
 
1833
{
 
1834
    int npoint;
 
1835
    register GC *pGC;
 
1836
    register DrawablePtr pDraw;
 
1837
    REQUEST(xPolyLineReq);
 
1838
 
 
1839
    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
 
1840
    if ((stuff->coordMode != CoordModeOrigin) && 
 
1841
        (stuff->coordMode != CoordModePrevious))
 
1842
    {
 
1843
        client->errorValue = stuff->coordMode;
 
1844
        return BadValue;
 
1845
    }
 
1846
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1847
    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
 
1848
    if (npoint > 1)
 
1849
        (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
 
1850
                              (DDXPointPtr) &stuff[1]);
 
1851
    return(client->noClientException);
 
1852
}
 
1853
 
 
1854
int
 
1855
ProcPolySegment(client)
 
1856
    register ClientPtr client;
 
1857
{
 
1858
    int nsegs;
 
1859
    register GC *pGC;
 
1860
    register DrawablePtr pDraw;
 
1861
    REQUEST(xPolySegmentReq);
 
1862
 
 
1863
    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
 
1864
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1865
    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
 
1866
    if (nsegs & 4)
 
1867
        return(BadLength);
 
1868
    nsegs >>= 3;
 
1869
    if (nsegs)
 
1870
        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
 
1871
    return (client->noClientException);
 
1872
}
 
1873
 
 
1874
int
 
1875
ProcPolyRectangle (client)
 
1876
    register ClientPtr client;
 
1877
{
 
1878
    int nrects;
 
1879
    register GC *pGC;
 
1880
    register DrawablePtr pDraw;
 
1881
    REQUEST(xPolyRectangleReq);
 
1882
 
 
1883
    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
 
1884
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1885
    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
 
1886
    if (nrects & 4)
 
1887
        return(BadLength);
 
1888
    nrects >>= 3;
 
1889
    if (nrects)
 
1890
        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
 
1891
                    nrects, (xRectangle *) &stuff[1]);
 
1892
    return(client->noClientException);
 
1893
}
 
1894
 
 
1895
int
 
1896
ProcPolyArc(client)
 
1897
    register ClientPtr client;
 
1898
{
 
1899
    int         narcs;
 
1900
    register GC *pGC;
 
1901
    register DrawablePtr pDraw;
 
1902
    REQUEST(xPolyArcReq);
 
1903
 
 
1904
    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
 
1905
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1906
    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
 
1907
    if (narcs % sizeof(xArc))
 
1908
        return(BadLength);
 
1909
    narcs /= sizeof(xArc);
 
1910
    if (narcs)
 
1911
        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
 
1912
    return (client->noClientException);
 
1913
}
 
1914
 
 
1915
int
 
1916
ProcFillPoly(client)
 
1917
    register ClientPtr client;
 
1918
{
 
1919
    int          things;
 
1920
    register GC *pGC;
 
1921
    register DrawablePtr pDraw;
 
1922
    REQUEST(xFillPolyReq);
 
1923
 
 
1924
    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
 
1925
    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
 
1926
        (stuff->shape != Convex))
 
1927
    {
 
1928
        client->errorValue = stuff->shape;
 
1929
        return BadValue;
 
1930
    }
 
1931
    if ((stuff->coordMode != CoordModeOrigin) && 
 
1932
        (stuff->coordMode != CoordModePrevious))
 
1933
    {
 
1934
        client->errorValue = stuff->coordMode;
 
1935
        return BadValue;
 
1936
    }
 
1937
 
 
1938
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1939
    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
 
1940
    if (things)
 
1941
        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
 
1942
                         stuff->coordMode, things,
 
1943
                         (DDXPointPtr) &stuff[1]);
 
1944
    return(client->noClientException);
 
1945
}
 
1946
 
 
1947
int
 
1948
ProcPolyFillRectangle(client)
 
1949
    register ClientPtr client;
 
1950
{
 
1951
    int             things;
 
1952
    register GC *pGC;
 
1953
    register DrawablePtr pDraw;
 
1954
    REQUEST(xPolyFillRectangleReq);
 
1955
 
 
1956
    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
 
1957
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1958
    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
 
1959
    if (things & 4)
 
1960
        return(BadLength);
 
1961
    things >>= 3;
 
1962
 
 
1963
    if (things)
 
1964
        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
 
1965
                      (xRectangle *) &stuff[1]);
 
1966
    return (client->noClientException);
 
1967
}
 
1968
 
 
1969
int
 
1970
ProcPolyFillArc(client)
 
1971
    register ClientPtr client;
 
1972
{
 
1973
    int         narcs;
 
1974
    register GC *pGC;
 
1975
    register DrawablePtr pDraw;
 
1976
    REQUEST(xPolyFillArcReq);
 
1977
 
 
1978
    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
 
1979
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
1980
    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
 
1981
    if (narcs % sizeof(xArc))
 
1982
        return(BadLength);
 
1983
    narcs /= sizeof(xArc);
 
1984
    if (narcs)
 
1985
        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
 
1986
    return (client->noClientException);
 
1987
}
 
1988
 
 
1989
#ifdef MATCH_CLIENT_ENDIAN
 
1990
 
 
1991
int
 
1992
ServerOrder (void)
 
1993
{
 
1994
    int     whichbyte = 1;
 
1995
 
 
1996
    if (*((char *) &whichbyte))
 
1997
        return LSBFirst;
 
1998
    return MSBFirst;
 
1999
}
 
2000
 
 
2001
#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
 
2002
 
 
2003
void
 
2004
ReformatImage (char *base, int nbytes, int bpp, int order)
 
2005
{
 
2006
    switch (bpp) {
 
2007
    case 1:     /* yuck */
 
2008
        if (BITMAP_BIT_ORDER != order)
 
2009
            BitOrderInvert ((unsigned char *) base, nbytes);
 
2010
#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
 
2011
        ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
 
2012
#endif
 
2013
        break;
 
2014
    case 4:
 
2015
        break;  /* yuck */
 
2016
    case 8:
 
2017
        break;
 
2018
    case 16:
 
2019
        if (IMAGE_BYTE_ORDER != order)
 
2020
            TwoByteSwap ((unsigned char *) base, nbytes);
 
2021
        break;
 
2022
    case 32:
 
2023
        if (IMAGE_BYTE_ORDER != order)
 
2024
            FourByteSwap ((unsigned char *) base, nbytes);
 
2025
        break;
 
2026
    }
 
2027
}
 
2028
#else
 
2029
#define ReformatImage(b,n,bpp,o)
 
2030
#endif
 
2031
 
 
2032
/* 64-bit server notes: the protocol restricts padding of images to
 
2033
 * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
 
2034
 * to use internally. Removes need for internal alignment checking.
 
2035
 * All of the PutImage functions could be changed individually, but
 
2036
 * as currently written, they call other routines which require things
 
2037
 * to be 64-bit padded on scanlines, so we changed things here.
 
2038
 * If an image would be padded differently for 64- versus 32-, then
 
2039
 * copy each scanline to a 64-bit padded scanline.
 
2040
 * Also, we need to make sure that the image is aligned on a 64-bit
 
2041
 * boundary, even if the scanlines are padded to our satisfaction.
 
2042
 */
 
2043
int
 
2044
ProcPutImage(client)
 
2045
    register ClientPtr client;
 
2046
{
 
2047
    register    GC *pGC;
 
2048
    register    DrawablePtr pDraw;
 
2049
    long        length;         /* length of scanline server padded */
 
2050
    long        lengthProto;    /* length of scanline protocol padded */
 
2051
    char        *tmpImage;
 
2052
    REQUEST(xPutImageReq);
 
2053
 
 
2054
    REQUEST_AT_LEAST_SIZE(xPutImageReq);
 
2055
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
2056
    if (stuff->format == XYBitmap)
 
2057
    {
 
2058
        if ((stuff->depth != 1) ||
 
2059
            (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
 
2060
            return BadMatch;
 
2061
        length      = BitmapBytePad(stuff->width + stuff->leftPad);
 
2062
    }
 
2063
    else if (stuff->format == XYPixmap)
 
2064
    {
 
2065
        if ((pDraw->depth != stuff->depth) || 
 
2066
            (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
 
2067
            return BadMatch;
 
2068
        length      = BitmapBytePad(stuff->width + stuff->leftPad);
 
2069
        length      *= stuff->depth;
 
2070
    }
 
2071
    else if (stuff->format == ZPixmap)
 
2072
    {
 
2073
        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
 
2074
            return BadMatch;
 
2075
        length      = PixmapBytePad(stuff->width, stuff->depth);
 
2076
    }
 
2077
    else
 
2078
    {
 
2079
        client->errorValue = stuff->format;
 
2080
        return BadValue;
 
2081
    }
 
2082
 
 
2083
    tmpImage = (char *)&stuff[1];
 
2084
    lengthProto = length;
 
2085
        
 
2086
    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
 
2087
        (sizeof(xPutImageReq) >> 2)) != client->req_len)
 
2088
        return BadLength;
 
2089
 
 
2090
    ReformatImage (tmpImage, lengthProto * stuff->height, 
 
2091
                   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
 
2092
                   ClientOrder(client));
 
2093
    
 
2094
    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
 
2095
                  stuff->width, stuff->height, 
 
2096
                  stuff->leftPad, stuff->format, tmpImage);
 
2097
 
 
2098
     return (client->noClientException);
 
2099
}
 
2100
 
 
2101
 
 
2102
int
 
2103
DoGetImage(client, format, drawable, x, y, width, height, planemask, im_return)
 
2104
    register ClientPtr  client;
 
2105
    Drawable drawable;
 
2106
    int format;
 
2107
    int x, y, width, height;
 
2108
    Mask planemask;
 
2109
    xGetImageReply **im_return;
 
2110
{
 
2111
    register DrawablePtr pDraw;
 
2112
    int                 nlines, linesPerBuf;
 
2113
    register int        linesDone;
 
2114
    long                widthBytesLine, length;
 
2115
    Mask                plane = 0;
 
2116
    char                *pBuf;
 
2117
    xGetImageReply      xgi;
 
2118
    RegionPtr pVisibleRegion = NULL;
 
2119
 
 
2120
    if ((format != XYPixmap) && (format != ZPixmap))
 
2121
    {
 
2122
        client->errorValue = format;
 
2123
        return(BadValue);
 
2124
    }
 
2125
    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
 
2126
    if(pDraw->type == DRAWABLE_WINDOW)
 
2127
    {
 
2128
      if( /* check for being viewable */
 
2129
         !((WindowPtr) pDraw)->realized ||
 
2130
          /* check for being on screen */
 
2131
         pDraw->x + x < 0 ||
 
2132
         pDraw->x + x + width > pDraw->pScreen->width ||
 
2133
         pDraw->y + y < 0 ||
 
2134
         pDraw->y + y + height > pDraw->pScreen->height ||
 
2135
          /* check for being inside of border */
 
2136
         x < - wBorderWidth((WindowPtr)pDraw) ||
 
2137
         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
 
2138
         y < -wBorderWidth((WindowPtr)pDraw) ||
 
2139
         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
 
2140
        )
 
2141
            return(BadMatch);
 
2142
        xgi.visual = wVisual (((WindowPtr) pDraw));
 
2143
    }
 
2144
    else
 
2145
    {
 
2146
      if(x < 0 ||
 
2147
         x+width > (int)pDraw->width ||
 
2148
         y < 0 ||
 
2149
         y+height > (int)pDraw->height
 
2150
        )
 
2151
            return(BadMatch);
 
2152
        xgi.visual = None;
 
2153
    }
 
2154
 
 
2155
    SET_DBE_SRCBUF(pDraw, drawable);
 
2156
 
 
2157
    xgi.type = X_Reply;
 
2158
    xgi.sequenceNumber = client->sequence;
 
2159
    xgi.depth = pDraw->depth;
 
2160
    if(format == ZPixmap)
 
2161
    {
 
2162
        widthBytesLine = PixmapBytePad(width, pDraw->depth);
 
2163
        length = widthBytesLine * height;
 
2164
 
 
2165
    }
 
2166
    else 
 
2167
    {
 
2168
        widthBytesLine = BitmapBytePad(width);
 
2169
        plane = ((Mask)1) << (pDraw->depth - 1);
 
2170
        /* only planes asked for */
 
2171
        length = widthBytesLine * height *
 
2172
                 Ones(planemask & (plane | (plane - 1)));
 
2173
 
 
2174
    }
 
2175
 
 
2176
    xgi.length = length;
 
2177
 
 
2178
    if (im_return) {
 
2179
        pBuf = (char *)xalloc(sz_xGetImageReply + length);
 
2180
        if (!pBuf)
 
2181
            return (BadAlloc);
 
2182
        if (widthBytesLine == 0)
 
2183
            linesPerBuf = 0;
 
2184
        else
 
2185
            linesPerBuf = height;
 
2186
        *im_return = (xGetImageReply *)pBuf;
 
2187
        *(xGetImageReply *)pBuf = xgi;
 
2188
        pBuf += sz_xGetImageReply;
 
2189
    } else {
 
2190
        xgi.length = (xgi.length + 3) >> 2;
 
2191
        if (widthBytesLine == 0 || height == 0)
 
2192
            linesPerBuf = 0;
 
2193
        else if (widthBytesLine >= IMAGE_BUFSIZE)
 
2194
            linesPerBuf = 1;
 
2195
        else
 
2196
        {
 
2197
            linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
 
2198
            if (linesPerBuf > height)
 
2199
                linesPerBuf = height;
 
2200
        }
 
2201
        length = linesPerBuf * widthBytesLine;
 
2202
        if (linesPerBuf < height)
 
2203
        {
 
2204
            /* we have to make sure intermediate buffers don't need padding */
 
2205
            while ((linesPerBuf > 1) &&
 
2206
                   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
 
2207
            {
 
2208
                linesPerBuf--;
 
2209
                length -= widthBytesLine;
 
2210
            }
 
2211
            while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
 
2212
            {
 
2213
                linesPerBuf++;
 
2214
                length += widthBytesLine;
 
2215
            }
 
2216
        }
 
2217
        if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
 
2218
            return (BadAlloc);
 
2219
        WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
 
2220
    }
 
2221
 
 
2222
#ifdef XCSECURITY
 
2223
    if (client->trustLevel != XSecurityClientTrusted &&
 
2224
        pDraw->type == DRAWABLE_WINDOW)
 
2225
    {
 
2226
        pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
 
2227
        if (pVisibleRegion)
 
2228
        {
 
2229
            REGION_TRANSLATE(pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
 
2230
        }
 
2231
    }
 
2232
#endif
 
2233
 
 
2234
    if (linesPerBuf == 0)
 
2235
    {
 
2236
        /* nothing to do */
 
2237
    }
 
2238
    else if (format == ZPixmap)
 
2239
    {
 
2240
        linesDone = 0;
 
2241
        while (height - linesDone > 0)
 
2242
        {
 
2243
            nlines = min(linesPerBuf, height - linesDone);
 
2244
            (*pDraw->pScreen->GetImage) (pDraw,
 
2245
                                         x,
 
2246
                                         y + linesDone,
 
2247
                                         width, 
 
2248
                                         nlines,
 
2249
                                         format,
 
2250
                                         planemask,
 
2251
                                         (pointer) pBuf);
 
2252
#ifdef XCSECURITY
 
2253
            if (pVisibleRegion)
 
2254
                SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
 
2255
                        pDraw, x, y + linesDone, width, 
 
2256
                        nlines, format, pBuf);
 
2257
#endif
 
2258
 
 
2259
            /* Note that this is NOT a call to WriteSwappedDataToClient,
 
2260
               as we do NOT byte swap */
 
2261
            if (!im_return)
 
2262
            {
 
2263
                ReformatImage (pBuf, (int)(nlines * widthBytesLine),
 
2264
                               BitsPerPixel (pDraw->depth),
 
2265
                               ClientOrder(client));
 
2266
 
 
2267
/* Don't split me, gcc pukes when you do */
 
2268
                (void)WriteToClient(client,
 
2269
                                    (int)(nlines * widthBytesLine),
 
2270
                                    pBuf);
 
2271
            }
 
2272
            linesDone += nlines;
 
2273
        }
 
2274
    }
 
2275
    else /* XYPixmap */
 
2276
    {
 
2277
        for (; plane; plane >>= 1)
 
2278
        {
 
2279
            if (planemask & plane)
 
2280
            {
 
2281
                linesDone = 0;
 
2282
                while (height - linesDone > 0)
 
2283
                {
 
2284
                    nlines = min(linesPerBuf, height - linesDone);
 
2285
                    (*pDraw->pScreen->GetImage) (pDraw,
 
2286
                                                 x,
 
2287
                                                 y + linesDone,
 
2288
                                                 width, 
 
2289
                                                 nlines,
 
2290
                                                 format,
 
2291
                                                 plane,
 
2292
                                                 (pointer)pBuf);
 
2293
#ifdef XCSECURITY
 
2294
                    if (pVisibleRegion)
 
2295
                        SecurityCensorImage(client, pVisibleRegion,
 
2296
                                widthBytesLine,
 
2297
                                pDraw, x, y + linesDone, width, 
 
2298
                                nlines, format, pBuf);
 
2299
#endif
 
2300
 
 
2301
                    /* Note: NOT a call to WriteSwappedDataToClient,
 
2302
                       as we do NOT byte swap */
 
2303
                    if (im_return) {
 
2304
                        pBuf += nlines * widthBytesLine;
 
2305
                    } else {
 
2306
                        ReformatImage (pBuf, 
 
2307
                                       (int)(nlines * widthBytesLine), 
 
2308
                                       1,
 
2309
                                       ClientOrder (client));
 
2310
 
 
2311
/* Don't split me, gcc pukes when you do */
 
2312
                        (void)WriteToClient(client,
 
2313
                                        (int)(nlines * widthBytesLine),
 
2314
                                        pBuf);
 
2315
                    }
 
2316
                    linesDone += nlines;
 
2317
                }
 
2318
            }
 
2319
        }
 
2320
    }
 
2321
#ifdef XCSECURITY
 
2322
    if (pVisibleRegion)
 
2323
        REGION_DESTROY(pScreen, pVisibleRegion);
 
2324
#endif
 
2325
    if (!im_return)
 
2326
        DEALLOCATE_LOCAL(pBuf);
 
2327
    return (client->noClientException);
 
2328
}
 
2329
 
 
2330
int
 
2331
ProcGetImage(client)
 
2332
    register ClientPtr  client;
 
2333
{
 
2334
    REQUEST(xGetImageReq);
 
2335
 
 
2336
    REQUEST_SIZE_MATCH(xGetImageReq);
 
2337
 
 
2338
    return DoGetImage(client, stuff->format, stuff->drawable,
 
2339
                      stuff->x, stuff->y,
 
2340
                      (int)stuff->width, (int)stuff->height,
 
2341
                      stuff->planeMask, (xGetImageReply **)NULL);
 
2342
}
 
2343
 
 
2344
int
 
2345
ProcPolyText(client)
 
2346
    register ClientPtr client;
 
2347
{
 
2348
    int err;
 
2349
    REQUEST(xPolyTextReq);
 
2350
    DrawablePtr pDraw;
 
2351
    GC *pGC;
 
2352
 
 
2353
    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
 
2354
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
2355
 
 
2356
    err = PolyText(client,
 
2357
                   pDraw,
 
2358
                   pGC,
 
2359
                   (unsigned char *)&stuff[1],
 
2360
                   ((unsigned char *) stuff) + (client->req_len << 2),
 
2361
                   stuff->x,
 
2362
                   stuff->y,
 
2363
                   stuff->reqType,
 
2364
                   stuff->drawable);
 
2365
 
 
2366
    if (err == Success)
 
2367
    {
 
2368
        return(client->noClientException);
 
2369
    }
 
2370
    else
 
2371
        return err;
 
2372
}
 
2373
 
 
2374
int
 
2375
ProcImageText8(client)
 
2376
    register ClientPtr client;
 
2377
{
 
2378
    int err;
 
2379
    register DrawablePtr pDraw;
 
2380
    register GC *pGC;
 
2381
 
 
2382
    REQUEST(xImageTextReq);
 
2383
 
 
2384
    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
 
2385
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
2386
 
 
2387
    err = ImageText(client,
 
2388
                    pDraw,
 
2389
                    pGC,
 
2390
                    stuff->nChars,
 
2391
                    (unsigned char *)&stuff[1],
 
2392
                    stuff->x,
 
2393
                    stuff->y,
 
2394
                    stuff->reqType,
 
2395
                    stuff->drawable);
 
2396
 
 
2397
    if (err == Success)
 
2398
    {
 
2399
        return(client->noClientException);
 
2400
    }
 
2401
    else
 
2402
        return err;
 
2403
}
 
2404
 
 
2405
int
 
2406
ProcImageText16(client)
 
2407
    register ClientPtr client;
 
2408
{
 
2409
    int err;
 
2410
    register DrawablePtr pDraw;
 
2411
    register GC *pGC;
 
2412
 
 
2413
    REQUEST(xImageTextReq);
 
2414
 
 
2415
    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
 
2416
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
 
2417
 
 
2418
    err = ImageText(client,
 
2419
                    pDraw,
 
2420
                    pGC,
 
2421
                    stuff->nChars,
 
2422
                    (unsigned char *)&stuff[1],
 
2423
                    stuff->x,
 
2424
                    stuff->y,
 
2425
                    stuff->reqType,
 
2426
                    stuff->drawable);
 
2427
 
 
2428
    if (err == Success)
 
2429
    {
 
2430
        return(client->noClientException);
 
2431
    }
 
2432
    else
 
2433
        return err;
 
2434
}
 
2435
 
 
2436
 
 
2437
int
 
2438
ProcCreateColormap(client)
 
2439
    register ClientPtr client;
 
2440
{
 
2441
    VisualPtr   pVisual;
 
2442
    ColormapPtr pmap;
 
2443
    Colormap    mid;
 
2444
    register WindowPtr   pWin;
 
2445
    ScreenPtr pScreen;
 
2446
    REQUEST(xCreateColormapReq);
 
2447
    int i, result;
 
2448
 
 
2449
    REQUEST_SIZE_MATCH(xCreateColormapReq);
 
2450
 
 
2451
    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
 
2452
    {
 
2453
        client->errorValue = stuff->alloc;
 
2454
        return(BadValue);
 
2455
    }
 
2456
    mid = stuff->mid;
 
2457
    LEGAL_NEW_RESOURCE(mid, client);
 
2458
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
2459
                                           SecurityReadAccess);
 
2460
    if (!pWin)
 
2461
        return(BadWindow);
 
2462
 
 
2463
    pScreen = pWin->drawable.pScreen;
 
2464
    for (i = 0, pVisual = pScreen->visuals;
 
2465
         i < pScreen->numVisuals;
 
2466
         i++, pVisual++)
 
2467
    {
 
2468
        if (pVisual->vid != stuff->visual)
 
2469
            continue;
 
2470
        result =  CreateColormap(mid, pScreen, pVisual, &pmap,
 
2471
                                 (int)stuff->alloc, client->index);
 
2472
        if (client->noClientException != Success)
 
2473
            return(client->noClientException);
 
2474
        else
 
2475
            return(result);
 
2476
    }
 
2477
    client->errorValue = stuff->visual;
 
2478
    return(BadValue);
 
2479
}
 
2480
 
 
2481
int
 
2482
ProcFreeColormap(client)
 
2483
    register ClientPtr client;
 
2484
{
 
2485
    ColormapPtr pmap;
 
2486
    REQUEST(xResourceReq);
 
2487
 
 
2488
    REQUEST_SIZE_MATCH(xResourceReq);
 
2489
    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
 
2490
                                                SecurityDestroyAccess);
 
2491
    if (pmap) 
 
2492
    {
 
2493
        /* Freeing a default colormap is a no-op */
 
2494
        if (!(pmap->flags & IsDefault))
 
2495
            FreeResource(stuff->id, RT_NONE);
 
2496
        return (client->noClientException);
 
2497
    }
 
2498
    else 
 
2499
    {
 
2500
        client->errorValue = stuff->id;
 
2501
        return (BadColor);
 
2502
    }
 
2503
}
 
2504
 
 
2505
 
 
2506
int
 
2507
ProcCopyColormapAndFree(client)
 
2508
    register ClientPtr client;
 
2509
{
 
2510
    Colormap    mid;
 
2511
    ColormapPtr pSrcMap;
 
2512
    REQUEST(xCopyColormapAndFreeReq);
 
2513
    int result;
 
2514
 
 
2515
    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
 
2516
    mid = stuff->mid;
 
2517
    LEGAL_NEW_RESOURCE(mid, client);
 
2518
    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
 
2519
                RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
 
2520
    {
 
2521
        result = CopyColormapAndFree(mid, pSrcMap, client->index);
 
2522
        if (client->noClientException != Success)
 
2523
            return(client->noClientException);
 
2524
        else
 
2525
            return(result);
 
2526
    }
 
2527
    else
 
2528
    {
 
2529
        client->errorValue = stuff->srcCmap;
 
2530
        return(BadColor);
 
2531
    }
 
2532
}
 
2533
 
 
2534
int
 
2535
ProcInstallColormap(client)
 
2536
    register ClientPtr client;
 
2537
{
 
2538
    ColormapPtr pcmp;
 
2539
    REQUEST(xResourceReq);
 
2540
 
 
2541
    REQUEST_SIZE_MATCH(xResourceReq);
 
2542
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
 
2543
                                            RT_COLORMAP, SecurityReadAccess);
 
2544
    if (pcmp)
 
2545
    {
 
2546
        (*(pcmp->pScreen->InstallColormap)) (pcmp);
 
2547
        return (client->noClientException);        
 
2548
    }
 
2549
    else
 
2550
    {
 
2551
        client->errorValue = stuff->id;
 
2552
        return (BadColor);
 
2553
    }
 
2554
}
 
2555
 
 
2556
int
 
2557
ProcUninstallColormap(client)
 
2558
    register ClientPtr client;
 
2559
{
 
2560
    ColormapPtr pcmp;
 
2561
    REQUEST(xResourceReq);
 
2562
 
 
2563
    REQUEST_SIZE_MATCH(xResourceReq);
 
2564
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
 
2565
                                        RT_COLORMAP, SecurityReadAccess);
 
2566
    if (pcmp)
 
2567
    {
 
2568
        if(pcmp->mid != pcmp->pScreen->defColormap)
 
2569
            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
 
2570
        return (client->noClientException);        
 
2571
    }
 
2572
    else
 
2573
    {
 
2574
        client->errorValue = stuff->id;
 
2575
        return (BadColor);
 
2576
    }
 
2577
}
 
2578
 
 
2579
int
 
2580
ProcListInstalledColormaps(client)
 
2581
    register ClientPtr client;
 
2582
{
 
2583
    xListInstalledColormapsReply *preply; 
 
2584
    int nummaps;
 
2585
    WindowPtr pWin;
 
2586
    REQUEST(xResourceReq);
 
2587
 
 
2588
    REQUEST_SIZE_MATCH(xResourceReq);
 
2589
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 
2590
                                           SecurityReadAccess);
 
2591
 
 
2592
    if (!pWin)
 
2593
        return(BadWindow);
 
2594
 
 
2595
    preply = (xListInstalledColormapsReply *) 
 
2596
                ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
 
2597
                     pWin->drawable.pScreen->maxInstalledCmaps *
 
2598
                     sizeof(Colormap));
 
2599
    if(!preply)
 
2600
        return(BadAlloc);
 
2601
 
 
2602
    preply->type = X_Reply;
 
2603
    preply->sequenceNumber = client->sequence;
 
2604
    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
 
2605
        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
 
2606
    preply->nColormaps = nummaps;
 
2607
    preply->length = nummaps;
 
2608
    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
 
2609
    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 
2610
    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
 
2611
    DEALLOCATE_LOCAL(preply);
 
2612
    return(client->noClientException);
 
2613
}
 
2614
 
 
2615
int
 
2616
ProcAllocColor(client)
 
2617
    register ClientPtr client;
 
2618
{
 
2619
    ColormapPtr pmap;
 
2620
    int retval;
 
2621
    xAllocColorReply acr;
 
2622
    REQUEST(xAllocColorReq);
 
2623
 
 
2624
    REQUEST_SIZE_MATCH(xAllocColorReq);
 
2625
    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2626
                                        RT_COLORMAP, SecurityWriteAccess);
 
2627
    if (pmap)
 
2628
    {
 
2629
#ifdef LBX
 
2630
        /*
 
2631
         * If the colormap is grabbed by a proxy, the server will have
 
2632
         * to regain control over the colormap.  This AllocColor request
 
2633
         * will be handled after the server gets back the colormap control.
 
2634
         */
 
2635
        if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
 
2636
            return Success;
 
2637
#endif
 
2638
        acr.type = X_Reply;
 
2639
        acr.length = 0;
 
2640
        acr.sequenceNumber = client->sequence;
 
2641
        acr.red = stuff->red;
 
2642
        acr.green = stuff->green;
 
2643
        acr.blue = stuff->blue;
 
2644
        acr.pixel = 0;
 
2645
        if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
 
2646
                               &acr.pixel, client->index)) )
 
2647
        {
 
2648
            if (client->noClientException != Success)
 
2649
                return(client->noClientException);
 
2650
            else
 
2651
                return (retval);
 
2652
        }
 
2653
#ifdef PANORAMIX
 
2654
        if (noPanoramiXExtension || !pmap->pScreen->myNum)
 
2655
#endif
 
2656
        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
 
2657
        return (client->noClientException);
 
2658
 
 
2659
    }
 
2660
    else
 
2661
    {
 
2662
        client->errorValue = stuff->cmap;
 
2663
        return (BadColor);
 
2664
    }
 
2665
}
 
2666
 
 
2667
int
 
2668
ProcAllocNamedColor           (client)
 
2669
    register ClientPtr client;
 
2670
{
 
2671
    ColormapPtr pcmp;
 
2672
    REQUEST(xAllocNamedColorReq);
 
2673
 
 
2674
    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
 
2675
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2676
                                            RT_COLORMAP, SecurityWriteAccess);
 
2677
    if (pcmp)
 
2678
    {
 
2679
        int             retval;
 
2680
 
 
2681
        xAllocNamedColorReply ancr;
 
2682
 
 
2683
#ifdef LBX
 
2684
        /*
 
2685
         * If the colormap is grabbed by a proxy, the server will have
 
2686
         * to regain control over the colormap.  This AllocNamedColor request
 
2687
         * will be handled after the server gets back the colormap control.
 
2688
         */
 
2689
        if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
 
2690
            return Success;
 
2691
#endif
 
2692
        ancr.type = X_Reply;
 
2693
        ancr.length = 0;
 
2694
        ancr.sequenceNumber = client->sequence;
 
2695
 
 
2696
        if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
 
2697
                         &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
 
2698
        {
 
2699
            ancr.screenRed = ancr.exactRed;
 
2700
            ancr.screenGreen = ancr.exactGreen;
 
2701
            ancr.screenBlue = ancr.exactBlue;
 
2702
            ancr.pixel = 0;
 
2703
            if( (retval = AllocColor(pcmp,
 
2704
                         &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
 
2705
                         &ancr.pixel, client->index)) )
 
2706
            {
 
2707
                if (client->noClientException != Success)
 
2708
                    return(client->noClientException);
 
2709
                else
 
2710
                    return(retval);
 
2711
            }
 
2712
#ifdef PANORAMIX
 
2713
            if (noPanoramiXExtension || !pcmp->pScreen->myNum)
 
2714
#endif
 
2715
            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
 
2716
            return (client->noClientException);
 
2717
        }
 
2718
        else
 
2719
            return(BadName);
 
2720
        
 
2721
    }
 
2722
    else
 
2723
    {
 
2724
        client->errorValue = stuff->cmap;
 
2725
        return (BadColor);
 
2726
    }
 
2727
}
 
2728
 
 
2729
int
 
2730
ProcAllocColorCells           (client)
 
2731
    register ClientPtr client;
 
2732
{
 
2733
    ColormapPtr pcmp;
 
2734
    REQUEST(xAllocColorCellsReq);
 
2735
 
 
2736
    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
 
2737
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2738
                                        RT_COLORMAP, SecurityWriteAccess);
 
2739
    if (pcmp)
 
2740
    {
 
2741
        xAllocColorCellsReply   accr;
 
2742
        int                     npixels, nmasks, retval;
 
2743
        long                    length;
 
2744
        Pixel                   *ppixels, *pmasks;
 
2745
 
 
2746
#ifdef LBX
 
2747
        /*
 
2748
         * If the colormap is grabbed by a proxy, the server will have
 
2749
         * to regain control over the colormap.  This AllocColorCells request
 
2750
         * will be handled after the server gets back the colormap control.
 
2751
         */
 
2752
        if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
 
2753
            return Success;
 
2754
#endif
 
2755
        npixels = stuff->colors;
 
2756
        if (!npixels)
 
2757
        {
 
2758
            client->errorValue = npixels;
 
2759
            return (BadValue);
 
2760
        }
 
2761
        if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
 
2762
        {
 
2763
            client->errorValue = stuff->contiguous;
 
2764
            return (BadValue);
 
2765
        }
 
2766
        nmasks = stuff->planes;
 
2767
        length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
 
2768
        ppixels = (Pixel *)ALLOCATE_LOCAL(length);
 
2769
        if(!ppixels)
 
2770
            return(BadAlloc);
 
2771
        pmasks = ppixels + npixels;
 
2772
 
 
2773
        if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
 
2774
                                    (Bool)stuff->contiguous, ppixels, pmasks)) )
 
2775
        {
 
2776
            DEALLOCATE_LOCAL(ppixels);
 
2777
            if (client->noClientException != Success)
 
2778
                return(client->noClientException);
 
2779
            else
 
2780
                return(retval);
 
2781
        }
 
2782
#ifdef PANORAMIX
 
2783
        if (noPanoramiXExtension || !pcmp->pScreen->myNum)
 
2784
#endif
 
2785
        {
 
2786
            accr.type = X_Reply;
 
2787
            accr.length = length >> 2;
 
2788
            accr.sequenceNumber = client->sequence;
 
2789
            accr.nPixels = npixels;
 
2790
            accr.nMasks = nmasks;
 
2791
            WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
 
2792
            client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 
2793
            WriteSwappedDataToClient(client, length, ppixels);
 
2794
        }
 
2795
        DEALLOCATE_LOCAL(ppixels);
 
2796
        return (client->noClientException);        
 
2797
    }
 
2798
    else
 
2799
    {
 
2800
        client->errorValue = stuff->cmap;
 
2801
        return (BadColor);
 
2802
    }
 
2803
}
 
2804
 
 
2805
int
 
2806
ProcAllocColorPlanes(client)
 
2807
    register ClientPtr client;
 
2808
{
 
2809
    ColormapPtr pcmp;
 
2810
    REQUEST(xAllocColorPlanesReq);
 
2811
 
 
2812
    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
 
2813
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2814
                                        RT_COLORMAP, SecurityWriteAccess);
 
2815
    if (pcmp)
 
2816
    {
 
2817
        xAllocColorPlanesReply  acpr;
 
2818
        int                     npixels, retval;
 
2819
        long                    length;
 
2820
        Pixel                   *ppixels;
 
2821
 
 
2822
#ifdef LBX
 
2823
        /*
 
2824
         * If the colormap is grabbed by a proxy, the server will have
 
2825
         * to regain control over the colormap.  This AllocColorPlanes request
 
2826
         * will be handled after the server gets back the colormap control.
 
2827
         */
 
2828
        if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
 
2829
            return Success;
 
2830
#endif
 
2831
        npixels = stuff->colors;
 
2832
        if (!npixels)
 
2833
        {
 
2834
            client->errorValue = npixels;
 
2835
            return (BadValue);
 
2836
        }
 
2837
        if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
 
2838
        {
 
2839
            client->errorValue = stuff->contiguous;
 
2840
            return (BadValue);
 
2841
        }
 
2842
        acpr.type = X_Reply;
 
2843
        acpr.sequenceNumber = client->sequence;
 
2844
        acpr.nPixels = npixels;
 
2845
        length = (long)npixels * sizeof(Pixel);
 
2846
        ppixels = (Pixel *)ALLOCATE_LOCAL(length);
 
2847
        if(!ppixels)
 
2848
            return(BadAlloc);
 
2849
        if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
 
2850
            (int)stuff->red, (int)stuff->green, (int)stuff->blue,
 
2851
            (Bool)stuff->contiguous, ppixels,
 
2852
            &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
 
2853
        {
 
2854
            DEALLOCATE_LOCAL(ppixels);
 
2855
            if (client->noClientException != Success)
 
2856
                return(client->noClientException);
 
2857
            else
 
2858
                return(retval);
 
2859
        }
 
2860
        acpr.length = length >> 2;
 
2861
#ifdef PANORAMIX
 
2862
        if (noPanoramiXExtension || !pcmp->pScreen->myNum)
 
2863
#endif
 
2864
        {
 
2865
            WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
 
2866
            client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 
2867
            WriteSwappedDataToClient(client, length, ppixels);
 
2868
        }
 
2869
        DEALLOCATE_LOCAL(ppixels);
 
2870
        return (client->noClientException);        
 
2871
    }
 
2872
    else
 
2873
    {
 
2874
        client->errorValue = stuff->cmap;
 
2875
        return (BadColor);
 
2876
    }
 
2877
}
 
2878
 
 
2879
int
 
2880
ProcFreeColors          (client)
 
2881
    register ClientPtr client;
 
2882
{
 
2883
    ColormapPtr pcmp;
 
2884
    REQUEST(xFreeColorsReq);
 
2885
 
 
2886
    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
 
2887
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2888
                                        RT_COLORMAP, SecurityWriteAccess);
 
2889
    if (pcmp)
 
2890
    {
 
2891
        int     count;
 
2892
        int     retval;
 
2893
 
 
2894
        if(pcmp->flags & AllAllocated)
 
2895
            return(BadAccess);
 
2896
        count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
 
2897
        retval =  FreeColors(pcmp, client->index, count,
 
2898
            (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
 
2899
        if (client->noClientException != Success)
 
2900
            return(client->noClientException);
 
2901
        else
 
2902
        {
 
2903
            client->errorValue = clientErrorValue;
 
2904
            return(retval);
 
2905
        }
 
2906
 
 
2907
    }
 
2908
    else
 
2909
    {
 
2910
        client->errorValue = stuff->cmap;
 
2911
        return (BadColor);
 
2912
    }
 
2913
}
 
2914
 
 
2915
int
 
2916
ProcStoreColors               (client)
 
2917
    register ClientPtr client;
 
2918
{
 
2919
    ColormapPtr pcmp;
 
2920
    REQUEST(xStoreColorsReq);
 
2921
 
 
2922
    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
 
2923
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2924
                                        RT_COLORMAP, SecurityWriteAccess);
 
2925
    if (pcmp)
 
2926
    {
 
2927
        int     count;
 
2928
        int     retval;
 
2929
 
 
2930
        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
 
2931
        if (count % sizeof(xColorItem))
 
2932
            return(BadLength);
 
2933
        count /= sizeof(xColorItem);
 
2934
        retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
 
2935
        if (client->noClientException != Success)
 
2936
            return(client->noClientException);
 
2937
        else
 
2938
        {
 
2939
            client->errorValue = clientErrorValue;
 
2940
            return(retval);
 
2941
        }
 
2942
    }
 
2943
    else
 
2944
    {
 
2945
        client->errorValue = stuff->cmap;
 
2946
        return (BadColor);
 
2947
    }
 
2948
}
 
2949
 
 
2950
int
 
2951
ProcStoreNamedColor           (client)
 
2952
    register ClientPtr client;
 
2953
{
 
2954
    ColormapPtr pcmp;
 
2955
    REQUEST(xStoreNamedColorReq);
 
2956
 
 
2957
    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
 
2958
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2959
                                        RT_COLORMAP, SecurityWriteAccess);
 
2960
    if (pcmp)
 
2961
    {
 
2962
        xColorItem      def;
 
2963
        int             retval;
 
2964
 
 
2965
        if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
 
2966
                         stuff->nbytes, &def.red, &def.green, &def.blue))
 
2967
        {
 
2968
            def.flags = stuff->flags;
 
2969
            def.pixel = stuff->pixel;
 
2970
            retval = StoreColors(pcmp, 1, &def);
 
2971
            if (client->noClientException != Success)
 
2972
                return(client->noClientException);
 
2973
            else
 
2974
                return(retval);
 
2975
        }
 
2976
        return (BadName);        
 
2977
    }
 
2978
    else
 
2979
    {
 
2980
        client->errorValue = stuff->cmap;
 
2981
        return (BadColor);
 
2982
    }
 
2983
}
 
2984
 
 
2985
int
 
2986
ProcQueryColors(client)
 
2987
    register ClientPtr client;
 
2988
{
 
2989
    ColormapPtr pcmp;
 
2990
    REQUEST(xQueryColorsReq);
 
2991
 
 
2992
    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
 
2993
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
2994
                                        RT_COLORMAP, SecurityReadAccess);
 
2995
    if (pcmp)
 
2996
    {
 
2997
        int                     count, retval;
 
2998
        xrgb                    *prgbs;
 
2999
        xQueryColorsReply       qcr;
 
3000
 
 
3001
        count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
 
3002
        prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
 
3003
        if(!prgbs && count)
 
3004
            return(BadAlloc);
 
3005
        if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
 
3006
        {
 
3007
            if (prgbs) DEALLOCATE_LOCAL(prgbs);
 
3008
            if (client->noClientException != Success)
 
3009
                return(client->noClientException);
 
3010
            else
 
3011
            {
 
3012
                client->errorValue = clientErrorValue;
 
3013
                return (retval);
 
3014
            }
 
3015
        }
 
3016
        qcr.type = X_Reply;
 
3017
        qcr.length = (count * sizeof(xrgb)) >> 2;
 
3018
        qcr.sequenceNumber = client->sequence;
 
3019
        qcr.nColors = count;
 
3020
        WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
 
3021
        if (count)
 
3022
        {
 
3023
            client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
 
3024
            WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
 
3025
        }
 
3026
        if (prgbs) DEALLOCATE_LOCAL(prgbs);
 
3027
        return(client->noClientException);
 
3028
        
 
3029
    }
 
3030
    else
 
3031
    {
 
3032
        client->errorValue = stuff->cmap;
 
3033
        return (BadColor);
 
3034
    }
 
3035
 
3036
 
 
3037
int
 
3038
ProcLookupColor(client)
 
3039
    register ClientPtr client;
 
3040
{
 
3041
    ColormapPtr pcmp;
 
3042
    REQUEST(xLookupColorReq);
 
3043
 
 
3044
    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
 
3045
    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
 
3046
                                        RT_COLORMAP, SecurityReadAccess);
 
3047
    if (pcmp)
 
3048
    {
 
3049
        xLookupColorReply lcr;
 
3050
 
 
3051
        if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
 
3052
                         &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
 
3053
        {
 
3054
            lcr.type = X_Reply;
 
3055
            lcr.length = 0;
 
3056
            lcr.sequenceNumber = client->sequence;
 
3057
            lcr.screenRed = lcr.exactRed;
 
3058
            lcr.screenGreen = lcr.exactGreen;
 
3059
            lcr.screenBlue = lcr.exactBlue;
 
3060
            (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
 
3061
                                           &lcr.screenGreen,
 
3062
                                           &lcr.screenBlue,
 
3063
                                           pcmp->pVisual);
 
3064
            WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
 
3065
            return(client->noClientException);
 
3066
        }
 
3067
        return (BadName);        
 
3068
    }
 
3069
    else
 
3070
    {
 
3071
        client->errorValue = stuff->cmap;
 
3072
        return (BadColor);
 
3073
    }
 
3074
}
 
3075
 
 
3076
int
 
3077
ProcCreateCursor( client)
 
3078
    register ClientPtr client;
 
3079
{
 
3080
    CursorPtr   pCursor;
 
3081
 
 
3082
    register PixmapPtr  src;
 
3083
    register PixmapPtr  msk;
 
3084
    unsigned char *     srcbits;
 
3085
    unsigned char *     mskbits;
 
3086
    unsigned short      width, height;
 
3087
    long                n;
 
3088
    CursorMetricRec cm;
 
3089
 
 
3090
 
 
3091
    REQUEST(xCreateCursorReq);
 
3092
 
 
3093
    REQUEST_SIZE_MATCH(xCreateCursorReq);
 
3094
    LEGAL_NEW_RESOURCE(stuff->cid, client);
 
3095
 
 
3096
    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
 
3097
                                              RT_PIXMAP, SecurityReadAccess);
 
3098
    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
 
3099
                                              RT_PIXMAP, SecurityReadAccess);
 
3100
    if (   src == (PixmapPtr)NULL)
 
3101
    {
 
3102
        client->errorValue = stuff->source;
 
3103
        return (BadPixmap);
 
3104
    }
 
3105
    if ( msk == (PixmapPtr)NULL)
 
3106
    {
 
3107
        if (stuff->mask != None)
 
3108
        {
 
3109
            client->errorValue = stuff->mask;
 
3110
            return (BadPixmap);
 
3111
        }
 
3112
    }
 
3113
    else if (  src->drawable.width != msk->drawable.width
 
3114
            || src->drawable.height != msk->drawable.height
 
3115
            || src->drawable.depth != 1
 
3116
            || msk->drawable.depth != 1)
 
3117
        return (BadMatch);
 
3118
 
 
3119
    width = src->drawable.width;
 
3120
    height = src->drawable.height;
 
3121
 
 
3122
    if ( stuff->x > width 
 
3123
      || stuff->y > height )
 
3124
        return (BadMatch);
 
3125
 
 
3126
    n = BitmapBytePad(width)*height;
 
3127
    srcbits = (unsigned char *)xalloc(n);
 
3128
    if (!srcbits)
 
3129
        return (BadAlloc);
 
3130
    mskbits = (unsigned char *)xalloc(n);
 
3131
    if (!mskbits)
 
3132
    {
 
3133
        xfree(srcbits);
 
3134
        return (BadAlloc);
 
3135
    }
 
3136
 
 
3137
    /* zeroing the (pad) bits helps some ddx cursor handling */
 
3138
    bzero((char *)srcbits, n);
 
3139
    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
 
3140
                                         XYPixmap, 1, (pointer)srcbits);
 
3141
    if ( msk == (PixmapPtr)NULL)
 
3142
    {
 
3143
        register unsigned char *bits = mskbits;
 
3144
        while (--n >= 0)
 
3145
            *bits++ = ~0;
 
3146
    }
 
3147
    else
 
3148
    {
 
3149
        /* zeroing the (pad) bits helps some ddx cursor handling */
 
3150
        bzero((char *)mskbits, n);
 
3151
        (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
 
3152
                                        height, XYPixmap, 1, (pointer)mskbits);
 
3153
    }
 
3154
    cm.width = width;
 
3155
    cm.height = height;
 
3156
    cm.xhot = stuff->x;
 
3157
    cm.yhot = stuff->y;
 
3158
    pCursor = AllocCursor( srcbits, mskbits, &cm,
 
3159
            stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
 
3160
            stuff->backRed, stuff->backGreen, stuff->backBlue);
 
3161
 
 
3162
    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
 
3163
            return (client->noClientException);
 
3164
    return BadAlloc;
 
3165
}
 
3166
 
 
3167
int
 
3168
ProcCreateGlyphCursor( client)
 
3169
    register ClientPtr client;
 
3170
{
 
3171
    CursorPtr pCursor;
 
3172
    int res;
 
3173
 
 
3174
    REQUEST(xCreateGlyphCursorReq);
 
3175
 
 
3176
    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
 
3177
    LEGAL_NEW_RESOURCE(stuff->cid, client);
 
3178
 
 
3179
    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
 
3180
                           stuff->mask, stuff->maskChar,
 
3181
                           stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
 
3182
                           stuff->backRed, stuff->backGreen, stuff->backBlue,
 
3183
                           &pCursor, client);
 
3184
    if (res != Success)
 
3185
        return res;
 
3186
    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
 
3187
        return client->noClientException;
 
3188
    return BadAlloc;
 
3189
}
 
3190
 
 
3191
 
 
3192
int
 
3193
ProcFreeCursor(client)
 
3194
    register ClientPtr client;
 
3195
{
 
3196
    CursorPtr pCursor;
 
3197
    REQUEST(xResourceReq);
 
3198
 
 
3199
    REQUEST_SIZE_MATCH(xResourceReq);
 
3200
    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
 
3201
                                        RT_CURSOR, SecurityDestroyAccess);
 
3202
    if (pCursor) 
 
3203
    {
 
3204
        FreeResource(stuff->id, RT_NONE);
 
3205
        return (client->noClientException);
 
3206
    }
 
3207
    else 
 
3208
    {
 
3209
        client->errorValue = stuff->id;
 
3210
        return (BadCursor);
 
3211
    }
 
3212
}
 
3213
 
 
3214
int
 
3215
ProcQueryBestSize   (client)
 
3216
    register ClientPtr client;
 
3217
{
 
3218
    xQueryBestSizeReply reply;
 
3219
    register DrawablePtr pDraw;
 
3220
    ScreenPtr pScreen;
 
3221
    REQUEST(xQueryBestSizeReq);
 
3222
 
 
3223
    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
 
3224
    if ((stuff->class != CursorShape) && 
 
3225
        (stuff->class != TileShape) && 
 
3226
        (stuff->class != StippleShape))
 
3227
    {
 
3228
        client->errorValue = stuff->class;
 
3229
        return(BadValue);
 
3230
    }
 
3231
    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
 
3232
                                 SecurityReadAccess);
 
3233
    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
 
3234
        return (BadMatch);
 
3235
    pScreen = pDraw->pScreen;
 
3236
    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
 
3237
                               &stuff->height, pScreen);
 
3238
    reply.type = X_Reply;
 
3239
    reply.length = 0;
 
3240
    reply.sequenceNumber = client->sequence;
 
3241
    reply.width = stuff->width;
 
3242
    reply.height = stuff->height;
 
3243
    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
 
3244
    return (client->noClientException);
 
3245
}
 
3246
 
 
3247
 
 
3248
int
 
3249
ProcSetScreenSaver            (client)
 
3250
    register ClientPtr client;
 
3251
{
 
3252
    int blankingOption, exposureOption;
 
3253
    REQUEST(xSetScreenSaverReq);
 
3254
 
 
3255
    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
 
3256
    blankingOption = stuff->preferBlank;
 
3257
    if ((blankingOption != DontPreferBlanking) &&
 
3258
        (blankingOption != PreferBlanking) &&
 
3259
        (blankingOption != DefaultBlanking))
 
3260
    {
 
3261
        client->errorValue = blankingOption;
 
3262
        return BadValue;
 
3263
    }
 
3264
    exposureOption = stuff->allowExpose;
 
3265
    if ((exposureOption != DontAllowExposures) &&
 
3266
        (exposureOption != AllowExposures) &&
 
3267
        (exposureOption != DefaultExposures))
 
3268
    {
 
3269
        client->errorValue = exposureOption;
 
3270
        return BadValue;
 
3271
    }
 
3272
    if (stuff->timeout < -1)
 
3273
    {
 
3274
        client->errorValue = stuff->timeout;
 
3275
        return BadValue;
 
3276
    }
 
3277
    if (stuff->interval < -1)
 
3278
    {
 
3279
        client->errorValue = stuff->interval;
 
3280
        return BadValue;
 
3281
    }
 
3282
 
 
3283
    if (blankingOption == DefaultBlanking)
 
3284
        ScreenSaverBlanking = defaultScreenSaverBlanking;
 
3285
    else
 
3286
        ScreenSaverBlanking = blankingOption; 
 
3287
    if (exposureOption == DefaultExposures)
 
3288
        ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
 
3289
    else
 
3290
        ScreenSaverAllowExposures = exposureOption;
 
3291
 
 
3292
    if (stuff->timeout >= 0)
 
3293
        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
 
3294
    else 
 
3295
        ScreenSaverTime = defaultScreenSaverTime;
 
3296
    if (stuff->interval >= 0)
 
3297
        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
 
3298
    else
 
3299
        ScreenSaverInterval = defaultScreenSaverInterval;
 
3300
    return (client->noClientException);
 
3301
}
 
3302
 
 
3303
int
 
3304
ProcGetScreenSaver(client)
 
3305
    register ClientPtr client;
 
3306
{
 
3307
    xGetScreenSaverReply rep;
 
3308
 
 
3309
    REQUEST_SIZE_MATCH(xReq);
 
3310
    rep.type = X_Reply;
 
3311
    rep.length = 0;
 
3312
    rep.sequenceNumber = client->sequence;
 
3313
    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
 
3314
    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
 
3315
    rep.preferBlanking = ScreenSaverBlanking;
 
3316
    rep.allowExposures = ScreenSaverAllowExposures;
 
3317
    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
 
3318
    return (client->noClientException);
 
3319
}
 
3320
 
 
3321
int
 
3322
ProcChangeHosts(client)
 
3323
    register ClientPtr client;
 
3324
{
 
3325
    REQUEST(xChangeHostsReq);
 
3326
    int result;
 
3327
 
 
3328
    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
 
3329
 
 
3330
    if(stuff->mode == HostInsert)
 
3331
        result = AddHost(client, (int)stuff->hostFamily,
 
3332
                         stuff->hostLength, (pointer)&stuff[1]);
 
3333
    else if (stuff->mode == HostDelete)
 
3334
        result = RemoveHost(client, (int)stuff->hostFamily, 
 
3335
                            stuff->hostLength, (pointer)&stuff[1]);  
 
3336
    else
 
3337
    {
 
3338
        client->errorValue = stuff->mode;
 
3339
        return BadValue;
 
3340
    }
 
3341
    if (!result)
 
3342
        result = client->noClientException;
 
3343
    return (result);
 
3344
}
 
3345
 
 
3346
int
 
3347
ProcListHosts(client)
 
3348
    register ClientPtr client;
 
3349
{
 
3350
    xListHostsReply reply;
 
3351
    int len, nHosts, result;
 
3352
    pointer     pdata;
 
3353
    /* REQUEST(xListHostsReq); */
 
3354
 
 
3355
    REQUEST_SIZE_MATCH(xListHostsReq);
 
3356
#ifdef XCSECURITY
 
3357
    /* untrusted clients can't list hosts */
 
3358
    if (client->trustLevel != XSecurityClientTrusted)
 
3359
    {
 
3360
        SecurityAudit("client %d attempted to list hosts\n", client->index);
 
3361
        return BadAccess;
 
3362
    }
 
3363
#endif
 
3364
    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
 
3365
    if (result != Success)
 
3366
        return(result);
 
3367
    reply.type = X_Reply;
 
3368
    reply.sequenceNumber = client->sequence;
 
3369
    reply.nHosts = nHosts;
 
3370
    reply.length = len >> 2;
 
3371
    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
 
3372
    if (nHosts)
 
3373
    {
 
3374
        client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
 
3375
        WriteSwappedDataToClient(client, len, pdata);
 
3376
    }
 
3377
    xfree(pdata);
 
3378
    return (client->noClientException);
 
3379
}
 
3380
 
 
3381
int
 
3382
ProcChangeAccessControl(client)
 
3383
    register ClientPtr client;
 
3384
{
 
3385
    int result;
 
3386
    REQUEST(xSetAccessControlReq);
 
3387
 
 
3388
    REQUEST_SIZE_MATCH(xSetAccessControlReq);
 
3389
    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
 
3390
    {
 
3391
        client->errorValue = stuff->mode;
 
3392
        return BadValue;
 
3393
    }
 
3394
    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
 
3395
    if (!result)
 
3396
        result = client->noClientException;
 
3397
    return (result);
 
3398
}
 
3399
 
 
3400
int
 
3401
ProcKillClient(client)
 
3402
    register ClientPtr client;
 
3403
{
 
3404
    REQUEST(xResourceReq);
 
3405
    ClientPtr   killclient;
 
3406
 
 
3407
    REQUEST_SIZE_MATCH(xResourceReq);
 
3408
    if (stuff->id == AllTemporary)
 
3409
    {
 
3410
        CloseDownRetainedResources();
 
3411
        return (client->noClientException);
 
3412
    }
 
3413
 
 
3414
    if ((killclient = LookupClient(stuff->id, client)))
 
3415
    {
 
3416
        CloseDownClient(killclient);
 
3417
        /* if an LBX proxy gets killed, isItTimeToYield will be set */
 
3418
        if (isItTimeToYield || (client == killclient))
 
3419
        {
 
3420
            /* force yield and return Success, so that Dispatch()
 
3421
             * doesn't try to touch client
 
3422
             */
 
3423
            isItTimeToYield = TRUE;
 
3424
            return (Success);
 
3425
        }
 
3426
        return (client->noClientException);
 
3427
    }
 
3428
    else
 
3429
    {
 
3430
        client->errorValue = stuff->id;
 
3431
        return (BadValue);
 
3432
    }
 
3433
}
 
3434
 
 
3435
int
 
3436
ProcSetFontPath(client)
 
3437
    register ClientPtr client;
 
3438
{
 
3439
    unsigned char *ptr;
 
3440
    unsigned long nbytes, total;
 
3441
    long nfonts;
 
3442
    int n, result;
 
3443
    int error;
 
3444
    REQUEST(xSetFontPathReq);
 
3445
    
 
3446
    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
 
3447
    
 
3448
    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
 
3449
    total = nbytes;
 
3450
    ptr = (unsigned char *)&stuff[1];
 
3451
    nfonts = stuff->nFonts;
 
3452
    while (--nfonts >= 0)
 
3453
    {
 
3454
        if ((total == 0) || (total < (n = (*ptr + 1))))
 
3455
            return(BadLength);
 
3456
        total -= n;
 
3457
        ptr += n;
 
3458
    }
 
3459
    if (total >= 4)
 
3460
        return(BadLength);
 
3461
    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
 
3462
                         &error);
 
3463
    if (!result)
 
3464
    {
 
3465
        result = client->noClientException;
 
3466
        client->errorValue = error;
 
3467
    }
 
3468
    return (result);
 
3469
}
 
3470
 
 
3471
int
 
3472
ProcGetFontPath(client)
 
3473
    register ClientPtr client;
 
3474
{
 
3475
    xGetFontPathReply reply;
 
3476
    int stringLens, numpaths;
 
3477
    unsigned char *bufferStart;
 
3478
    /* REQUEST (xReq); */
 
3479
 
 
3480
    REQUEST_SIZE_MATCH(xReq);
 
3481
    bufferStart = GetFontPath(&numpaths, &stringLens);
 
3482
 
 
3483
    reply.type = X_Reply;
 
3484
    reply.sequenceNumber = client->sequence;
 
3485
    reply.length = (stringLens + numpaths + 3) >> 2;
 
3486
    reply.nPaths = numpaths;
 
3487
 
 
3488
    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
 
3489
    if (stringLens || numpaths)
 
3490
        (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
 
3491
    return(client->noClientException);
 
3492
}
 
3493
 
 
3494
int
 
3495
ProcChangeCloseDownMode(client)
 
3496
    register ClientPtr client;
 
3497
{
 
3498
    REQUEST(xSetCloseDownModeReq);
 
3499
 
 
3500
    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
 
3501
    if ((stuff->mode == AllTemporary) ||
 
3502
        (stuff->mode == RetainPermanent) ||
 
3503
        (stuff->mode == RetainTemporary))
 
3504
    {
 
3505
        client->closeDownMode = stuff->mode;
 
3506
        return (client->noClientException);
 
3507
    }
 
3508
    else   
 
3509
    {
 
3510
        client->errorValue = stuff->mode;
 
3511
        return (BadValue);
 
3512
    }
 
3513
}
 
3514
 
 
3515
int ProcForceScreenSaver(client)
 
3516
    register ClientPtr client;
 
3517
{    
 
3518
    REQUEST(xForceScreenSaverReq);
 
3519
 
 
3520
    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
 
3521
    
 
3522
    if ((stuff->mode != ScreenSaverReset) && 
 
3523
        (stuff->mode != ScreenSaverActive))
 
3524
    {
 
3525
        client->errorValue = stuff->mode;
 
3526
        return BadValue;
 
3527
    }
 
3528
    SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
 
3529
    return client->noClientException;
 
3530
}
 
3531
 
 
3532
int ProcNoOperation(client)
 
3533
    register ClientPtr client;
 
3534
{
 
3535
    REQUEST_AT_LEAST_SIZE(xReq);
 
3536
    
 
3537
    /* noop -- don't do anything */
 
3538
    return(client->noClientException);
 
3539
}
 
3540
 
 
3541
void
 
3542
InitProcVectors(void)
 
3543
{
 
3544
    int i;
 
3545
    for (i = 0; i<256; i++)
 
3546
    {
 
3547
        if(!ProcVector[i])
 
3548
        {
 
3549
            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
 
3550
            ReplySwapVector[i] = ReplyNotSwappd;
 
3551
        }
 
3552
#ifdef K5AUTH
 
3553
        if (!k5_Vector[i])
 
3554
        {
 
3555
            k5_Vector[i] = k5_bad;
 
3556
        }
 
3557
#endif
 
3558
    }
 
3559
    for(i = LASTEvent; i < 128; i++)
 
3560
    {
 
3561
        EventSwapVector[i] = NotImplemented;
 
3562
    }
 
3563
    
 
3564
}
 
3565
 
 
3566
/**********************
 
3567
 * CloseDownClient
 
3568
 *
 
3569
 *  Client can either mark his resources destroy or retain.  If retained and
 
3570
 *  then killed again, the client is really destroyed.
 
3571
 *********************/
 
3572
 
 
3573
char dispatchExceptionAtReset = DE_RESET;
 
3574
 
 
3575
void
 
3576
CloseDownClient(client)
 
3577
    register ClientPtr client;
 
3578
{
 
3579
    Bool really_close_down = client->clientGone ||
 
3580
                             client->closeDownMode == DestroyAll;
 
3581
 
 
3582
    if (!client->clientGone)
 
3583
    {
 
3584
        /* ungrab server if grabbing client dies */
 
3585
        if (grabState != GrabNone && grabClient == client)
 
3586
        {
 
3587
            UngrabServer(client);
 
3588
        }
 
3589
        BITCLEAR(grabWaiters, client->index);
 
3590
        DeleteClientFromAnySelections(client);
 
3591
        ReleaseActiveGrabs(client);
 
3592
        DeleteClientFontStuff(client);
 
3593
        if (!really_close_down)
 
3594
        {
 
3595
            /*  This frees resources that should never be retained
 
3596
             *  no matter what the close down mode is.  Actually we
 
3597
             *  could do this unconditionally, but it's probably
 
3598
             *  better not to traverse all the client's resources
 
3599
             *  twice (once here, once a few lines down in
 
3600
             *  FreeClientResources) in the common case of
 
3601
             *  really_close_down == TRUE.
 
3602
             */
 
3603
            FreeClientNeverRetainResources(client);
 
3604
            client->clientState = ClientStateRetained;
 
3605
            if (ClientStateCallback)
 
3606
            {
 
3607
                NewClientInfoRec clientinfo;
 
3608
 
 
3609
                clientinfo.client = client; 
 
3610
                clientinfo.prefix = (xConnSetupPrefix *)NULL;  
 
3611
                clientinfo.setup = (xConnSetup *) NULL;
 
3612
                CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
 
3613
            } 
 
3614
        }
 
3615
        client->clientGone = TRUE;  /* so events aren't sent to client */
 
3616
        if (ClientIsAsleep(client))
 
3617
            ClientSignal (client);
 
3618
        ProcessWorkQueueZombies();
 
3619
#ifdef LBX
 
3620
        ProcessQTagZombies();
 
3621
#endif
 
3622
        CloseDownConnection(client);
 
3623
 
 
3624
        /* If the client made it to the Running stage, nClients has
 
3625
         * been incremented on its behalf, so we need to decrement it
 
3626
         * now.  If it hasn't gotten to Running, nClients has *not*
 
3627
         * been incremented, so *don't* decrement it.
 
3628
         */
 
3629
        if (client->clientState != ClientStateInitial &&
 
3630
            client->clientState != ClientStateAuthenticating )
 
3631
        {
 
3632
            --nClients;
 
3633
        }
 
3634
    }
 
3635
 
 
3636
    if (really_close_down)
 
3637
    {
 
3638
        if (client->clientState == ClientStateRunning && nClients == 0)
 
3639
            dispatchException |= dispatchExceptionAtReset;
 
3640
 
 
3641
        client->clientState = ClientStateGone;
 
3642
        if (ClientStateCallback)
 
3643
        {
 
3644
            NewClientInfoRec clientinfo;
 
3645
 
 
3646
            clientinfo.client = client; 
 
3647
            clientinfo.prefix = (xConnSetupPrefix *)NULL;  
 
3648
            clientinfo.setup = (xConnSetup *) NULL;
 
3649
            CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
 
3650
        }           
 
3651
        FreeClientResources(client);
 
3652
        if (client->index < nextFreeClientID)
 
3653
            nextFreeClientID = client->index;
 
3654
        clients[client->index] = NullClient;
 
3655
#ifdef SMART_SCHEDULE
 
3656
        SmartLastClient = NullClient;
 
3657
#endif
 
3658
        xfree(client);
 
3659
 
 
3660
        while (!clients[currentMaxClients-1])
 
3661
            currentMaxClients--;
 
3662
    }
 
3663
}
 
3664
 
 
3665
static void
 
3666
KillAllClients()
 
3667
{
 
3668
    int i;
 
3669
    for (i=1; i<currentMaxClients; i++)
 
3670
        if (clients[i]) {
 
3671
            /* Make sure Retained clients are released. */
 
3672
            clients[i]->closeDownMode = DestroyAll;
 
3673
            CloseDownClient(clients[i]);     
 
3674
        }
 
3675
}
 
3676
 
 
3677
/*********************
 
3678
 * CloseDownRetainedResources
 
3679
 *
 
3680
 *    Find all clients that are gone and have terminated in RetainTemporary 
 
3681
 *    and  destroy their resources.
 
3682
 *********************/
 
3683
 
 
3684
void
 
3685
CloseDownRetainedResources()
 
3686
{
 
3687
    register int i;
 
3688
    register ClientPtr client;
 
3689
 
 
3690
    for (i=1; i<currentMaxClients; i++)
 
3691
    {
 
3692
        client = clients[i];
 
3693
        if (client && (client->closeDownMode == RetainTemporary)
 
3694
            && (client->clientGone))
 
3695
            CloseDownClient(client);
 
3696
    }
 
3697
}
 
3698
 
 
3699
void InitClient(client, i, ospriv)
 
3700
    ClientPtr client;
 
3701
    int i;
 
3702
    pointer ospriv;
 
3703
{
 
3704
    client->index = i;
 
3705
    client->sequence = 0; 
 
3706
    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
 
3707
    client->clientGone = FALSE;
 
3708
    if (i)
 
3709
    {
 
3710
        client->closeDownMode = DestroyAll;
 
3711
        client->lastDrawable = (DrawablePtr)WindowTable[0];
 
3712
        client->lastDrawableID = WindowTable[0]->drawable.id;
 
3713
    }
 
3714
    else
 
3715
    {
 
3716
        client->closeDownMode = RetainPermanent;
 
3717
        client->lastDrawable = (DrawablePtr)NULL;
 
3718
        client->lastDrawableID = INVALID;
 
3719
    }
 
3720
    client->lastGC = (GCPtr) NULL;
 
3721
    client->lastGCID = INVALID;
 
3722
    client->numSaved = 0;
 
3723
    client->saveSet = (pointer *)NULL;
 
3724
    client->noClientException = Success;
 
3725
#ifdef DEBUG
 
3726
    client->requestLogIndex = 0;
 
3727
#endif
 
3728
    client->requestVector = InitialVector;
 
3729
    client->osPrivate = ospriv;
 
3730
    client->swapped = FALSE;
 
3731
    client->big_requests = FALSE;
 
3732
    client->priority = 0;
 
3733
    client->clientState = ClientStateInitial;
 
3734
#ifdef XKB
 
3735
    if (!noXkbExtension) {
 
3736
        client->xkbClientFlags = 0;
 
3737
        client->mapNotifyMask = 0;
 
3738
        QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
 
3739
    }
 
3740
#endif
 
3741
    client->replyBytesRemaining = 0;
 
3742
#ifdef LBX
 
3743
    client->readRequest = StandardReadRequestFromClient;
 
3744
#endif
 
3745
#ifdef XCSECURITY
 
3746
    client->trustLevel = XSecurityClientTrusted;
 
3747
    client->CheckAccess = NULL;
 
3748
    client->authId = 0;
 
3749
#endif
 
3750
#ifdef XAPPGROUP
 
3751
    client->appgroup = NULL;
 
3752
#endif
 
3753
    client->fontResFunc = NULL;
 
3754
#ifdef SMART_SCHEDULE
 
3755
    client->smart_priority = 0;
 
3756
    client->smart_start_tick = SmartScheduleTime;
 
3757
    client->smart_stop_tick = SmartScheduleTime;
 
3758
    client->smart_check_tick = SmartScheduleTime;
 
3759
#endif
 
3760
}
 
3761
 
 
3762
extern int clientPrivateLen;
 
3763
extern unsigned *clientPrivateSizes;
 
3764
extern unsigned totalClientSize;
 
3765
 
 
3766
int
 
3767
InitClientPrivates(client)
 
3768
    ClientPtr client;
 
3769
{
 
3770
    register char *ptr;
 
3771
    DevUnion *ppriv;
 
3772
    register unsigned *sizes;
 
3773
    register unsigned size;
 
3774
    register int i;
 
3775
 
 
3776
    if (totalClientSize == sizeof(ClientRec))
 
3777
        ppriv = (DevUnion *)NULL;
 
3778
    else if (client->index)
 
3779
        ppriv = (DevUnion *)(client + 1);
 
3780
    else
 
3781
    {
 
3782
        ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
 
3783
        if (!ppriv)
 
3784
            return 0;
 
3785
    }
 
3786
    client->devPrivates = ppriv;
 
3787
    sizes = clientPrivateSizes;
 
3788
    ptr = (char *)(ppriv + clientPrivateLen);
 
3789
    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
 
3790
    {
 
3791
        if ( (size = *sizes) )
 
3792
        {
 
3793
            ppriv->ptr = (pointer)ptr;
 
3794
            ptr += size;
 
3795
        }
 
3796
        else
 
3797
            ppriv->ptr = (pointer)NULL;
 
3798
    }
 
3799
    return 1;
 
3800
}
 
3801
 
 
3802
/************************
 
3803
 * int NextAvailableClient(ospriv)
 
3804
 *
 
3805
 * OS dependent portion can't assign client id's because of CloseDownModes.
 
3806
 * Returns NULL if there are no free clients.
 
3807
 *************************/
 
3808
 
 
3809
ClientPtr
 
3810
NextAvailableClient(ospriv)
 
3811
    pointer ospriv;
 
3812
{
 
3813
    register int i;
 
3814
    register ClientPtr client;
 
3815
    xReq data;
 
3816
 
 
3817
    i = nextFreeClientID;
 
3818
    if (i == MAXCLIENTS)
 
3819
        return (ClientPtr)NULL;
 
3820
    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
 
3821
    if (!client)
 
3822
        return (ClientPtr)NULL;
 
3823
    InitClient(client, i, ospriv);
 
3824
    InitClientPrivates(client);
 
3825
    if (!InitClientResources(client))
 
3826
    {
 
3827
        xfree(client);
 
3828
        return (ClientPtr)NULL;
 
3829
    }
 
3830
    data.reqType = 1;
 
3831
    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
 
3832
    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
 
3833
    {
 
3834
        FreeClientResources(client);
 
3835
        xfree(client);
 
3836
        return (ClientPtr)NULL;
 
3837
    }
 
3838
    if (i == currentMaxClients)
 
3839
        currentMaxClients++;
 
3840
    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
 
3841
        nextFreeClientID++;
 
3842
    if (ClientStateCallback)
 
3843
    {
 
3844
        NewClientInfoRec clientinfo;
 
3845
 
 
3846
        clientinfo.client = client; 
 
3847
        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
 
3848
        clientinfo.setup = (xConnSetup *) NULL;
 
3849
        CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
 
3850
    }   
 
3851
    return(client);
 
3852
}
 
3853
 
 
3854
int
 
3855
ProcInitialConnection(client)
 
3856
    register ClientPtr client;
 
3857
{
 
3858
    REQUEST(xReq);
 
3859
    register xConnClientPrefix *prefix;
 
3860
    int whichbyte = 1;
 
3861
 
 
3862
    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
 
3863
    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
 
3864
        return (client->noClientException = -1);
 
3865
    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
 
3866
        (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
 
3867
    {
 
3868
        client->swapped = TRUE;
 
3869
        SwapConnClientPrefix(prefix);
 
3870
    }
 
3871
    stuff->reqType = 2;
 
3872
    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
 
3873
                     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
 
3874
    if (client->swapped)
 
3875
    {
 
3876
        swaps(&stuff->length, whichbyte);
 
3877
    }
 
3878
    ResetCurrentRequest(client);
 
3879
    return (client->noClientException);
 
3880
}
 
3881
 
 
3882
#ifdef LBX
 
3883
void
 
3884
IncrementClientCount()
 
3885
{
 
3886
    nClients++;
 
3887
}
 
3888
#endif
 
3889
 
 
3890
int
 
3891
SendConnSetup(client, reason)
 
3892
    register ClientPtr client;
 
3893
    char *reason;
 
3894
{
 
3895
    register xWindowRoot *root;
 
3896
    register int i;
 
3897
    int numScreens;
 
3898
    char* lConnectionInfo;
 
3899
    xConnSetupPrefix* lconnSetupPrefix;
 
3900
 
 
3901
    if (reason)
 
3902
    {
 
3903
        xConnSetupPrefix csp;
 
3904
 
 
3905
        csp.success = xFalse;
 
3906
        csp.lengthReason = strlen(reason);
 
3907
        csp.length = (csp.lengthReason + (unsigned)3) >> 2;
 
3908
        csp.majorVersion = X_PROTOCOL;
 
3909
        csp.minorVersion = X_PROTOCOL_REVISION;
 
3910
        if (client->swapped)
 
3911
            WriteSConnSetupPrefix(client, &csp);
 
3912
        else
 
3913
            (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
 
3914
        (void)WriteToClient(client, (int)csp.lengthReason, reason);
 
3915
        return (client->noClientException = -1);
 
3916
    }
 
3917
 
 
3918
    numScreens = screenInfo.numScreens;
 
3919
    lConnectionInfo = ConnectionInfo;
 
3920
    lconnSetupPrefix = &connSetupPrefix;
 
3921
 
 
3922
    /* We're about to start speaking X protocol back to the client by
 
3923
     * sending the connection setup info.  This means the authorization
 
3924
     * step is complete, and we can count the client as an
 
3925
     * authorized one.
 
3926
     */
 
3927
    nClients++;
 
3928
 
 
3929
    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
 
3930
    client->sequence = 0;
 
3931
#ifdef XAPPGROUP
 
3932
    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
 
3933
#endif
 
3934
    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
 
3935
    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
 
3936
#ifdef MATCH_CLIENT_ENDIAN
 
3937
    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
 
3938
    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
 
3939
#endif
 
3940
    /* fill in the "currentInputMask" */
 
3941
    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
 
3942
#ifdef PANORAMIX
 
3943
    if (noPanoramiXExtension)
 
3944
        numScreens = screenInfo.numScreens;
 
3945
    else 
 
3946
        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
 
3947
#endif
 
3948
 
 
3949
    for (i=0; i<numScreens; i++) 
 
3950
    {
 
3951
        register unsigned int j;
 
3952
        register xDepth *pDepth;
 
3953
 
 
3954
        root->currentInputMask = WindowTable[i]->eventMask |
 
3955
                                 wOtherEventMasks (WindowTable[i]);
 
3956
        pDepth = (xDepth *)(root + 1);
 
3957
        for (j = 0; j < root->nDepths; j++)
 
3958
        {
 
3959
            pDepth = (xDepth *)(((char *)(pDepth + 1)) +
 
3960
                                pDepth->nVisuals * sizeof(xVisualType));
 
3961
        }
 
3962
        root = (xWindowRoot *)pDepth;
 
3963
    }
 
3964
 
 
3965
    if (client->swapped)
 
3966
    {
 
3967
        WriteSConnSetupPrefix(client, lconnSetupPrefix);
 
3968
        WriteSConnectionInfo(client,
 
3969
                             (unsigned long)(lconnSetupPrefix->length << 2),
 
3970
                             lConnectionInfo);
 
3971
    }
 
3972
    else
 
3973
    {
 
3974
        (void)WriteToClient(client, sizeof(xConnSetupPrefix),
 
3975
                            (char *) lconnSetupPrefix);
 
3976
        (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
 
3977
                            lConnectionInfo);
 
3978
    }
 
3979
    client->clientState = ClientStateRunning;
 
3980
    if (ClientStateCallback)
 
3981
    {
 
3982
        NewClientInfoRec clientinfo;
 
3983
 
 
3984
        clientinfo.client = client; 
 
3985
        clientinfo.prefix = lconnSetupPrefix;  
 
3986
        clientinfo.setup = (xConnSetup *)lConnectionInfo;
 
3987
        CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
 
3988
    }   
 
3989
    return (client->noClientException);
 
3990
}
 
3991
 
 
3992
int
 
3993
ProcEstablishConnection(client)
 
3994
    register ClientPtr client;
 
3995
{
 
3996
    char *reason, *auth_proto, *auth_string;
 
3997
    register xConnClientPrefix *prefix;
 
3998
    REQUEST(xReq);
 
3999
 
 
4000
    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
 
4001
    auth_proto = (char *)prefix + sz_xConnClientPrefix;
 
4002
    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
 
4003
    if ((prefix->majorVersion != X_PROTOCOL) ||
 
4004
        (prefix->minorVersion != X_PROTOCOL_REVISION))
 
4005
        reason = "Protocol version mismatch";
 
4006
    else
 
4007
        reason = ClientAuthorized(client,
 
4008
                                  (unsigned short)prefix->nbytesAuthProto,
 
4009
                                  auth_proto,
 
4010
                                  (unsigned short)prefix->nbytesAuthString,
 
4011
                                  auth_string);
 
4012
    /*
 
4013
     * If Kerberos is being used for this client, the clientState
 
4014
     * will be set to ClientStateAuthenticating at this point.
 
4015
     * More messages need to be exchanged among the X server, Kerberos
 
4016
     * server, and client to figure out if everyone is authorized.
 
4017
     * So we don't want to send the connection setup info yet, since
 
4018
     * the auth step isn't really done.
 
4019
     */
 
4020
    if (client->clientState == ClientStateCheckingSecurity)
 
4021
        client->clientState = ClientStateCheckedSecurity;
 
4022
    else if (client->clientState != ClientStateAuthenticating)
 
4023
        return(SendConnSetup(client, reason));
 
4024
    return(client->noClientException);
 
4025
}
 
4026
 
 
4027
void
 
4028
SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
 
4029
    ClientPtr client;
 
4030
    unsigned int majorCode;
 
4031
    unsigned int minorCode;
 
4032
    XID resId;
 
4033
    int errorCode;
 
4034
{
 
4035
    xError rep;
 
4036
 
 
4037
    rep.type = X_Error;
 
4038
    rep.sequenceNumber = client->sequence;
 
4039
    rep.errorCode = errorCode;
 
4040
    rep.majorCode = majorCode;
 
4041
    rep.minorCode = minorCode;
 
4042
    rep.resourceID = resId;
 
4043
 
 
4044
    WriteEventsToClient (client, 1, (xEvent *)&rep);
 
4045
}
 
4046
 
 
4047
void
 
4048
DeleteWindowFromAnySelections(pWin)
 
4049
    WindowPtr pWin;
 
4050
{
 
4051
    register int i;
 
4052
 
 
4053
    for (i = 0; i< NumCurrentSelections; i++)
 
4054
        if (CurrentSelections[i].pWin == pWin)
 
4055
        {
 
4056
            CurrentSelections[i].pWin = (WindowPtr)NULL;
 
4057
            CurrentSelections[i].window = None;
 
4058
            CurrentSelections[i].client = NullClient;
 
4059
        }
 
4060
}
 
4061
 
 
4062
static void
 
4063
DeleteClientFromAnySelections(client)
 
4064
    ClientPtr client;
 
4065
{
 
4066
    register int i;
 
4067
 
 
4068
    for (i = 0; i< NumCurrentSelections; i++)
 
4069
        if (CurrentSelections[i].client == client)
 
4070
        {
 
4071
            CurrentSelections[i].pWin = (WindowPtr)NULL;
 
4072
            CurrentSelections[i].window = None;
 
4073
            CurrentSelections[i].client = NullClient;
 
4074
        }
 
4075
}
 
4076
 
 
4077
void
 
4078
MarkClientException(client)
 
4079
    ClientPtr client;
 
4080
{
 
4081
    client->noClientException = -1;
 
4082
}