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