Remove unused ClientStateAuthenticating
[gstreamer-omap:xserver.git] / dix / dispatch.c
1 /************************************************************
2
3 Copyright 1987, 1989, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25
26 Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                         All Rights Reserved
29
30 Permission to use, copy, modify, and distribute this software and its 
31 documentation for any purpose and without fee is hereby granted, 
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in 
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.  
37
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
45
46 ********************************************************/
47
48 /* The panoramix components contained the following notice */
49 /*****************************************************************
50
51 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
52
53 Permission is hereby granted, free of charge, to any person obtaining a copy
54 of this software and associated documentation files (the "Software"), to deal
55 in the Software without restriction, including without limitation the rights
56 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57 copies of the Software.
58
59 The above copyright notice and this permission notice shall be included in
60 all copies or substantial portions of the Software.
61
62 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
65 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
66 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
67 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
68 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69
70 Except as contained in this notice, the name of Digital Equipment Corporation
71 shall not be used in advertising or otherwise to promote the sale, use or other
72 dealings in this Software without prior written authorization from Digital
73 Equipment Corporation.
74
75 ******************************************************************/
76
77 /* XSERVER_DTRACE additions:
78  * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
79  *
80  * Permission is hereby granted, free of charge, to any person obtaining a
81  * copy of this software and associated documentation files (the "Software"),
82  * to deal in the Software without restriction, including without limitation
83  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84  * and/or sell copies of the Software, and to permit persons to whom the
85  * Software is furnished to do so, subject to the following conditions:
86  *
87  * The above copyright notice and this permission notice (including the next
88  * paragraph) shall be included in all copies or substantial portions of the
89  * Software.
90  *
91  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
92  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
93  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
94  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
95  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
96  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
97  * DEALINGS IN THE SOFTWARE.
98  */
99
100
101
102 #ifdef HAVE_DIX_CONFIG_H
103 #include <dix-config.h>
104 #include <version-config.h>
105 #endif
106
107 #ifdef PANORAMIX_DEBUG
108 #include <stdio.h>
109 int ProcInitialConnection();
110 #endif
111
112 #include "windowstr.h"
113 #include <X11/fonts/fontstruct.h>
114 #include "dixfontstr.h"
115 #include "gcstruct.h"
116 #include "selection.h"
117 #include "colormapst.h"
118 #include "cursorstr.h"
119 #include "scrnintstr.h"
120 #include "opaque.h"
121 #include "input.h"
122 #include "servermd.h"
123 #include "extnsionst.h"
124 #include "dixfont.h"
125 #include "dispatch.h"
126 #include "swaprep.h"
127 #include "swapreq.h"
128 #include "privates.h"
129 #include "xace.h"
130 #include "inputstr.h"
131 #include "xkbsrv.h"
132 #include "site.h"
133 #include "client.h"
134
135 #ifdef XSERVER_DTRACE
136 #include "registry.h"
137 #include <sys/types.h>
138 typedef const char *string;
139 #include "Xserver-dtrace.h"
140 #endif
141
142 #define mskcnt ((MAXCLIENTS + 31) / 32)
143 #define BITMASK(i) (1U << ((i) & 31))
144 #define MASKIDX(i) ((i) >> 5)
145 #define MASKWORD(buf, i) buf[MASKIDX(i)]
146 #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
147 #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
148 #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
149
150 xConnSetupPrefix connSetupPrefix;
151
152 PaddingInfo PixmapWidthPaddingInfo[33];
153
154 static ClientPtr grabClient;
155 #define GrabNone 0
156 #define GrabActive 1
157 #define GrabKickout 2
158 static int grabState = GrabNone;
159 static long grabWaiters[mskcnt];
160 CallbackListPtr ServerGrabCallback = NULL;
161 HWEventQueuePtr checkForInput[2];
162 int connBlockScreenStart;
163
164 static void KillAllClients(void);
165
166 static int nextFreeClientID; /* always MIN free client ID */
167
168 static int      nClients;       /* number of authorized clients */
169
170 CallbackListPtr ClientStateCallback;
171
172 /* dispatchException & isItTimeToYield must be declared volatile since they
173  * are modified by signal handlers - otherwise optimizer may assume it doesn't
174  * need to actually check value in memory when used and may miss changes from
175  * signal handlers.
176  */
177 volatile char dispatchException = 0;
178 volatile char isItTimeToYield;
179
180 #define SAME_SCREENS(a, b) (\
181     (a.pScreen == b.pScreen))
182
183 void
184 SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
185 {
186     checkForInput[0] = c0;
187     checkForInput[1] = c1;
188 }
189
190 void
191 UpdateCurrentTime(void)
192 {
193     TimeStamp systime;
194
195     /* To avoid time running backwards, we must call GetTimeInMillis before
196      * calling ProcessInputEvents.
197      */
198     systime.months = currentTime.months;
199     systime.milliseconds = GetTimeInMillis();
200     if (systime.milliseconds < currentTime.milliseconds)
201         systime.months++;
202     if (*checkForInput[0] != *checkForInput[1])
203         ProcessInputEvents();
204     if (CompareTimeStamps(systime, currentTime) == LATER)
205         currentTime = systime;
206 }
207
208 /* Like UpdateCurrentTime, but can't call ProcessInputEvents */
209 void
210 UpdateCurrentTimeIf(void)
211 {
212     TimeStamp systime;
213
214     systime.months = currentTime.months;
215     systime.milliseconds = GetTimeInMillis();
216     if (systime.milliseconds < currentTime.milliseconds)
217         systime.months++;
218     if (*checkForInput[0] == *checkForInput[1])
219         currentTime = systime;
220 }
221
222
223 #undef SMART_DEBUG
224
225 #define SMART_SCHEDULE_DEFAULT_INTERVAL 20          /* ms */
226 #define SMART_SCHEDULE_MAX_SLICE        200         /* ms */
227
228 Bool SmartScheduleDisable = FALSE;
229 long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
230 long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
231 long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
232 long SmartScheduleTime;
233 int SmartScheduleLatencyLimited = 0;
234 static ClientPtr   SmartLastClient;
235 static int         SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
236
237 #ifdef SMART_DEBUG
238 long        SmartLastPrint;
239 #endif
240
241 void        Dispatch(void);
242
243 static int
244 SmartScheduleClient (int *clientReady, int nready)
245 {
246     ClientPtr   pClient;
247     int         i;
248     int         client;
249     int         bestPrio, best = 0;
250     int         bestRobin, robin;
251     long        now = SmartScheduleTime;
252     long        idle;
253
254     bestPrio = -0x7fffffff;
255     bestRobin = 0;
256     idle = 2 * SmartScheduleSlice;
257     for (i = 0; i < nready; i++)
258     {
259         client = clientReady[i];
260         pClient = clients[client];
261         /* Praise clients which are idle */
262         if ((now - pClient->smart_check_tick) >= idle)
263         {
264             if (pClient->smart_priority < 0)
265                 pClient->smart_priority++;
266         }
267         pClient->smart_check_tick = now;
268         
269         /* check priority to select best client */
270         robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
271         if (pClient->smart_priority > bestPrio ||
272             (pClient->smart_priority == bestPrio && robin > bestRobin))
273         {
274             bestPrio = pClient->smart_priority;
275             bestRobin = robin;
276             best = client;
277         }
278 #ifdef SMART_DEBUG
279         if ((now - SmartLastPrint) >= 5000)
280             fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
281 #endif
282     }
283 #ifdef SMART_DEBUG
284     if ((now - SmartLastPrint) >= 5000)
285     {
286         fprintf (stderr, " use %2d\n", best);
287         SmartLastPrint = now;
288     }
289 #endif
290     pClient = clients[best];
291     SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
292     /*
293      * Set current client pointer
294      */
295     if (SmartLastClient != pClient)
296     {
297         pClient->smart_start_tick = now;
298         SmartLastClient = pClient;
299     }
300     /*
301      * Adjust slice
302      */
303     if (nready == 1 && SmartScheduleLatencyLimited == 0)
304     {
305         /*
306          * If it's been a long time since another client
307          * has run, bump the slice up to get maximal
308          * performance from a single client
309          */
310         if ((now - pClient->smart_start_tick) > 1000 &&
311             SmartScheduleSlice < SmartScheduleMaxSlice)
312         {
313             SmartScheduleSlice += SmartScheduleInterval;
314         }
315     }
316     else
317     {
318         SmartScheduleSlice = SmartScheduleInterval;
319     }
320     return best;
321 }
322
323 void
324 EnableLimitedSchedulingLatency(void)
325 {
326     ++SmartScheduleLatencyLimited;
327     SmartScheduleSlice = SmartScheduleInterval;
328 }
329
330 void
331 DisableLimitedSchedulingLatency(void)
332 {
333     --SmartScheduleLatencyLimited;
334
335     /* protect against bugs */
336     if (SmartScheduleLatencyLimited < 0)
337         SmartScheduleLatencyLimited = 0;
338 }
339
340 #define MAJOROP ((xReq *)client->requestBuffer)->reqType
341
342 void
343 Dispatch(void)
344 {
345     int        *clientReady;     /* array of request ready clients */
346     int result;
347     ClientPtr   client;
348     int nready;
349     HWEventQueuePtr* icheck = checkForInput;
350     long                        start_tick;
351
352     nextFreeClientID = 1;
353     nClients = 0;
354
355     clientReady = malloc(sizeof(int) * MaxClients);
356     if (!clientReady)
357         return;
358
359     SmartScheduleSlice = SmartScheduleInterval;
360     while (!dispatchException)
361     {
362         if (*icheck[0] != *icheck[1])
363         {
364             ProcessInputEvents();
365             FlushIfCriticalOutputPending();
366         }
367
368         nready = WaitForSomething(clientReady);
369
370         if (nready && !SmartScheduleDisable)
371         {
372             clientReady[0] = SmartScheduleClient (clientReady, nready);
373             nready = 1;
374         }
375        /***************** 
376         *  Handle events in round robin fashion, doing input between 
377         *  each round 
378         *****************/
379
380         while (!dispatchException && (--nready >= 0))
381         {
382             client = clients[clientReady[nready]];
383             if (! client)
384             {
385                 /* KillClient can cause this to happen */
386                 continue;
387             }
388             /* GrabServer activation can cause this to be true */
389             if (grabState == GrabKickout)
390             {
391                 grabState = GrabActive;
392                 break;
393             }
394             isItTimeToYield = FALSE;
395  
396             start_tick = SmartScheduleTime;
397             while (!isItTimeToYield)
398             {
399                 if (*icheck[0] != *icheck[1])
400                     ProcessInputEvents();
401                 
402                 FlushIfCriticalOutputPending();
403                 if (!SmartScheduleDisable && 
404                     (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
405                 {
406                     /* Penalize clients which consume ticks */
407                     if (client->smart_priority > SMART_MIN_PRIORITY)
408                         client->smart_priority--;
409                     break;
410                 }
411                 /* now, finally, deal with client requests */
412
413                 result = ReadRequestFromClient(client);
414                 if (result <= 0) 
415                 {
416                     if (result < 0)
417                         CloseDownClient(client);
418                     break;
419                 }
420
421                 client->sequence++;
422 #ifdef XSERVER_DTRACE
423                 XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
424                               ((xReq *)client->requestBuffer)->length,
425                               client->index, client->requestBuffer);
426 #endif
427                 if (result > (maxBigRequestSize << 2))
428                     result = BadLength;
429                 else {
430                     result = XaceHookDispatch(client, MAJOROP);
431                     if (result == Success)
432                         result = (* client->requestVector[MAJOROP])(client);
433                     XaceHookAuditEnd(client, result);
434                 }
435 #ifdef XSERVER_DTRACE
436                 XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
437                               client->sequence, client->index, result);
438 #endif
439
440                 if (client->noClientException != Success)
441                 {
442                     CloseDownClient(client);
443                     break;
444                 }
445                 else if (result != Success)
446                 {
447                     SendErrorToClient(client, MAJOROP,
448                                       MinorOpcodeOfRequest(client),
449                                       client->errorValue, result);
450                     break;
451                 }
452             }
453             FlushAllOutput();
454             client = clients[clientReady[nready]];
455             if (client)
456                 client->smart_stop_tick = SmartScheduleTime;
457         }
458         dispatchException &= ~DE_PRIORITYCHANGE;
459     }
460 #if defined(DDXBEFORERESET)
461     ddxBeforeReset ();
462 #endif
463     KillAllClients();
464     free(clientReady);
465     dispatchException &= ~DE_RESET;
466     SmartScheduleLatencyLimited = 0;
467 }
468
469 #undef MAJOROP
470
471 static int  VendorRelease = VENDOR_RELEASE;
472 static char *VendorString = VENDOR_NAME;
473
474 static const int padlength[4] = {0, 3, 2, 1};
475
476 void
477 SetVendorRelease(int release)
478 {
479     VendorRelease = release;
480 }
481
482 void
483 SetVendorString(char *string)
484 {
485     VendorString = string;
486 }
487
488 Bool
489 CreateConnectionBlock(void)
490 {
491     xConnSetup setup;
492     xWindowRoot root;
493     xDepth      depth;
494     xVisualType visual;
495     xPixmapFormat format;
496     unsigned long vid;
497     int i, j, k,
498         lenofblock,
499         sizesofar = 0;
500     char *pBuf;
501
502
503     memset(&setup, 0, sizeof(xConnSetup));
504     /* Leave off the ridBase and ridMask, these must be sent with
505        connection */
506
507     setup.release = VendorRelease;
508     /*
509      * per-server image and bitmap parameters are defined in Xmd.h
510      */
511     setup.imageByteOrder = screenInfo.imageByteOrder;
512
513     setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
514     setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
515
516     setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
517     setup.motionBufferSize = NumMotionEvents();
518     setup.numRoots = screenInfo.numScreens;
519     setup.nbytesVendor = strlen(VendorString);
520     setup.numFormats = screenInfo.numPixmapFormats;
521     setup.maxRequestSize = MAX_REQUEST_SIZE;
522     QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
523
524     lenofblock = sizeof(xConnSetup) +
525             pad_to_int32(setup.nbytesVendor) +
526             (setup.numFormats * sizeof(xPixmapFormat)) +
527             (setup.numRoots * sizeof(xWindowRoot));
528     ConnectionInfo = malloc(lenofblock);
529     if (!ConnectionInfo)
530         return FALSE;
531
532     memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
533     sizesofar = sizeof(xConnSetup);
534     pBuf = ConnectionInfo + sizeof(xConnSetup);
535
536     memmove(pBuf, VendorString, (int)setup.nbytesVendor);
537     sizesofar += setup.nbytesVendor;
538     pBuf += setup.nbytesVendor;
539     i = padlength[setup.nbytesVendor & 3];
540     sizesofar += i;
541     while (--i >= 0)
542         *pBuf++ = 0;
543
544     memset(&format, 0, sizeof(xPixmapFormat));
545     for (i=0; i<screenInfo.numPixmapFormats; i++)
546     {
547         format.depth = screenInfo.formats[i].depth;
548         format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
549         format.scanLinePad = screenInfo.formats[i].scanlinePad;
550         memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
551         pBuf += sizeof(xPixmapFormat);
552         sizesofar += sizeof(xPixmapFormat);
553     }
554
555     connBlockScreenStart = sizesofar;
556     memset(&depth, 0, sizeof(xDepth));
557     memset(&visual, 0, sizeof(xVisualType));
558     for (i=0; i<screenInfo.numScreens; i++)
559     {
560         ScreenPtr       pScreen;
561         DepthPtr        pDepth;
562         VisualPtr       pVisual;
563
564         pScreen = screenInfo.screens[i];
565         root.windowId = pScreen->root->drawable.id;
566         root.defaultColormap = pScreen->defColormap;
567         root.whitePixel = pScreen->whitePixel;
568         root.blackPixel = pScreen->blackPixel;
569         root.currentInputMask = 0;    /* filled in when sent */
570         root.pixWidth = pScreen->width;
571         root.pixHeight = pScreen->height;
572         root.mmWidth = pScreen->mmWidth;
573         root.mmHeight = pScreen->mmHeight;
574         root.minInstalledMaps = pScreen->minInstalledCmaps;
575         root.maxInstalledMaps = pScreen->maxInstalledCmaps;
576         root.rootVisualID = pScreen->rootVisual;
577         root.backingStore = pScreen->backingStoreSupport;
578         root.saveUnders = FALSE;
579         root.rootDepth = pScreen->rootDepth;
580         root.nDepths = pScreen->numDepths;
581         memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
582         sizesofar += sizeof(xWindowRoot);
583         pBuf += sizeof(xWindowRoot);
584
585         pDepth = pScreen->allowedDepths;
586         for(j = 0; j < pScreen->numDepths; j++, pDepth++)
587         {
588             lenofblock += sizeof(xDepth) +
589                     (pDepth->numVids * sizeof(xVisualType));
590             pBuf = (char *)realloc(ConnectionInfo, lenofblock);
591             if (!pBuf)
592             {
593                 free(ConnectionInfo);
594                 return FALSE;
595             }
596             ConnectionInfo = pBuf;
597             pBuf += sizesofar;
598             depth.depth = pDepth->depth;
599             depth.nVisuals = pDepth->numVids;
600             memmove(pBuf, (char *)&depth, sizeof(xDepth));
601             pBuf += sizeof(xDepth);
602             sizesofar += sizeof(xDepth);
603             for(k = 0; k < pDepth->numVids; k++)
604             {
605                 vid = pDepth->vids[k];
606                 for (pVisual = pScreen->visuals;
607                      pVisual->vid != vid;
608                      pVisual++)
609                     ;
610                 visual.visualID = vid;
611                 visual.class = pVisual->class;
612                 visual.bitsPerRGB = pVisual->bitsPerRGBValue;
613                 visual.colormapEntries = pVisual->ColormapEntries;
614                 visual.redMask = pVisual->redMask;
615                 visual.greenMask = pVisual->greenMask;
616                 visual.blueMask = pVisual->blueMask;
617                 memmove(pBuf, (char *)&visual, sizeof(xVisualType));
618                 pBuf += sizeof(xVisualType);
619                 sizesofar += sizeof(xVisualType);
620             }
621         }
622     }
623     connSetupPrefix.success = xTrue;
624     connSetupPrefix.length = lenofblock/4;
625     connSetupPrefix.majorVersion = X_PROTOCOL;
626     connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
627     return TRUE;
628 }
629
630
631 int
632 ProcBadRequest(ClientPtr client)
633 {
634     return BadRequest;
635 }
636
637 int
638 ProcCreateWindow(ClientPtr client)
639 {
640     WindowPtr pParent, pWin;
641     REQUEST(xCreateWindowReq);
642     int len, rc;
643
644     REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
645     
646     LEGAL_NEW_RESOURCE(stuff->wid, client);
647     rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
648     if (rc != Success)
649         return rc;
650     len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
651     if (Ones(stuff->mask) != len)
652         return BadLength;
653     if (!stuff->width || !stuff->height)
654     {
655         client->errorValue = 0;
656         return BadValue;
657     }
658     pWin = CreateWindow(stuff->wid, pParent, stuff->x,
659                               stuff->y, stuff->width, stuff->height, 
660                               stuff->borderWidth, stuff->class,
661                               stuff->mask, (XID *) &stuff[1], 
662                               (int)stuff->depth, 
663                               client, stuff->visual, &rc);
664     if (pWin)
665     {
666         Mask mask = pWin->eventMask;
667
668         pWin->eventMask = 0; /* subterfuge in case AddResource fails */
669         if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
670             return BadAlloc;
671         pWin->eventMask = mask;
672     }
673     return rc;
674 }
675
676 int
677 ProcChangeWindowAttributes(ClientPtr client)
678 {
679     WindowPtr pWin;
680     REQUEST(xChangeWindowAttributesReq);
681     int len, rc;
682     Mask access_mode = 0;
683
684     REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
685     access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
686     access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
687     rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
688     if (rc != Success)
689         return rc;
690     len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
691     if (len != Ones(stuff->valueMask))
692         return BadLength;
693     return ChangeWindowAttributes(pWin,
694                                   stuff->valueMask, 
695                                   (XID *) &stuff[1], 
696                                   client);
697 }
698
699 int
700 ProcGetWindowAttributes(ClientPtr client)
701 {
702     WindowPtr pWin;
703     REQUEST(xResourceReq);
704     xGetWindowAttributesReply wa;
705     int rc;
706
707     REQUEST_SIZE_MATCH(xResourceReq);
708     rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
709     if (rc != Success)
710         return rc;
711     memset(&wa, 0, sizeof(xGetWindowAttributesReply));
712     GetWindowAttributes(pWin, client, &wa);
713     WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
714     return Success;
715 }
716
717 int
718 ProcDestroyWindow(ClientPtr client)
719 {
720     WindowPtr pWin;
721     REQUEST(xResourceReq);
722     int rc;
723
724     REQUEST_SIZE_MATCH(xResourceReq);
725     rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
726     if (rc != Success)
727         return rc;
728     if (pWin->parent) {
729         rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
730                              DixRemoveAccess);
731         if (rc != Success)
732             return rc;
733         FreeResource(stuff->id, RT_NONE);
734     }
735     return Success;
736 }
737
738 int
739 ProcDestroySubwindows(ClientPtr client)
740 {
741     WindowPtr pWin;
742     REQUEST(xResourceReq);
743     int rc;
744
745     REQUEST_SIZE_MATCH(xResourceReq);
746     rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
747     if (rc != Success)
748         return rc;
749     DestroySubwindows(pWin, client);
750     return Success;
751 }
752
753 int
754 ProcChangeSaveSet(ClientPtr client)
755 {
756     WindowPtr pWin;
757     REQUEST(xChangeSaveSetReq);
758     int rc;
759                   
760     REQUEST_SIZE_MATCH(xChangeSaveSetReq);
761     rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
762     if (rc != Success)
763         return rc;
764     if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
765         return BadMatch;
766     if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
767         return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
768     client->errorValue = stuff->mode;
769     return BadValue;
770 }
771
772 int
773 ProcReparentWindow(ClientPtr client)
774 {
775     WindowPtr pWin, pParent;
776     REQUEST(xReparentWindowReq);
777     int rc;
778
779     REQUEST_SIZE_MATCH(xReparentWindowReq);
780     rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
781     if (rc != Success)
782         return rc;
783     rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
784     if (rc != Success)
785         return rc;
786     if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
787         return BadMatch;
788     if ((pWin->backgroundState == ParentRelative) &&
789         (pParent->drawable.depth != pWin->drawable.depth))
790         return BadMatch;
791     if ((pWin->drawable.class != InputOnly) &&
792         (pParent->drawable.class == InputOnly))
793         return BadMatch;
794     return ReparentWindow(pWin, pParent,
795                      (short)stuff->x, (short)stuff->y, client);
796 }
797
798 int
799 ProcMapWindow(ClientPtr client)
800 {
801     WindowPtr pWin;
802     REQUEST(xResourceReq);
803     int rc;
804
805     REQUEST_SIZE_MATCH(xResourceReq);
806     rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
807     if (rc != Success)
808         return rc;
809     MapWindow(pWin, client);
810            /* update cache to say it is mapped */
811     return Success;
812 }
813
814 int
815 ProcMapSubwindows(ClientPtr client)
816 {
817     WindowPtr pWin;
818     REQUEST(xResourceReq);
819     int rc;
820
821     REQUEST_SIZE_MATCH(xResourceReq);
822     rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
823     if (rc != Success)
824         return rc;
825     MapSubwindows(pWin, client);
826            /* update cache to say it is mapped */
827     return Success;
828 }
829
830 int
831 ProcUnmapWindow(ClientPtr client)
832 {
833     WindowPtr pWin;
834     REQUEST(xResourceReq);
835     int rc;
836
837     REQUEST_SIZE_MATCH(xResourceReq);
838     rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
839     if (rc != Success)
840         return rc;
841     UnmapWindow(pWin, FALSE);
842            /* update cache to say it is mapped */
843     return Success;
844 }
845
846 int
847 ProcUnmapSubwindows(ClientPtr client)
848 {
849     WindowPtr pWin;
850     REQUEST(xResourceReq);
851     int rc;
852
853     REQUEST_SIZE_MATCH(xResourceReq);
854     rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
855     if (rc != Success)
856         return rc;
857     UnmapSubwindows(pWin);
858     return Success;
859 }
860
861 int
862 ProcConfigureWindow(ClientPtr client)
863 {
864     WindowPtr pWin;
865     REQUEST(xConfigureWindowReq);
866     int len, rc;
867
868     REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
869     rc = dixLookupWindow(&pWin, stuff->window, client,
870                          DixManageAccess|DixSetAttrAccess);
871     if (rc != Success)
872         return rc;
873     len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
874     if (Ones((Mask)stuff->mask) != len)
875         return BadLength;
876     return ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], client);
877 }
878
879 int
880 ProcCirculateWindow(ClientPtr client)
881 {
882     WindowPtr pWin;
883     REQUEST(xCirculateWindowReq);
884     int rc;
885
886     REQUEST_SIZE_MATCH(xCirculateWindowReq);
887     if ((stuff->direction != RaiseLowest) &&
888         (stuff->direction != LowerHighest))
889     {
890         client->errorValue = stuff->direction;
891         return BadValue;
892     }
893     rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
894     if (rc != Success)
895         return rc;
896     CirculateWindow(pWin, (int)stuff->direction, client);
897     return Success;
898 }
899
900 static int
901 GetGeometry(ClientPtr client, xGetGeometryReply *rep)
902 {
903     DrawablePtr pDraw;
904     int rc;
905     REQUEST(xResourceReq);
906     REQUEST_SIZE_MATCH(xResourceReq);
907
908     rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
909     if (rc != Success)
910         return rc;
911
912     rep->type = X_Reply;
913     rep->length = 0;
914     rep->sequenceNumber = client->sequence;
915     rep->root = pDraw->pScreen->root->drawable.id;
916     rep->depth = pDraw->depth;
917     rep->width = pDraw->width;
918     rep->height = pDraw->height;
919
920     if (WindowDrawable(pDraw->type))
921     {
922         WindowPtr pWin = (WindowPtr)pDraw;
923         rep->x = pWin->origin.x - wBorderWidth (pWin);
924         rep->y = pWin->origin.y - wBorderWidth (pWin);
925         rep->borderWidth = pWin->borderWidth;
926     }
927     else /* DRAWABLE_PIXMAP */
928     {
929         rep->x = rep->y = rep->borderWidth = 0;
930     }
931
932     return Success;
933 }
934
935
936 int
937 ProcGetGeometry(ClientPtr client)
938 {
939     xGetGeometryReply rep;
940     int status;
941
942     memset(&rep, 0, sizeof(xGetGeometryReply));
943     if ((status = GetGeometry(client, &rep)) != Success)
944         return status;
945
946     WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
947     return Success;
948 }
949
950
951 int
952 ProcQueryTree(ClientPtr client)
953 {
954     xQueryTreeReply reply;
955     int rc, numChildren = 0;
956     WindowPtr pChild, pWin, pHead;
957     Window  *childIDs = (Window *)NULL;
958     REQUEST(xResourceReq);
959
960     REQUEST_SIZE_MATCH(xResourceReq);
961     rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
962     if (rc != Success)
963         return rc;
964     memset(&reply, 0, sizeof(xQueryTreeReply));
965     reply.type = X_Reply;
966     reply.root = pWin->drawable.pScreen->root->drawable.id;
967     reply.sequenceNumber = client->sequence;
968     if (pWin->parent)
969         reply.parent = pWin->parent->drawable.id;
970     else
971         reply.parent = (Window)None;
972     pHead = RealChildHead(pWin);
973     for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
974         numChildren++;
975     if (numChildren)
976     {
977         int curChild = 0;
978
979         childIDs = malloc(numChildren * sizeof(Window));
980         if (!childIDs)
981             return BadAlloc;
982         for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
983             childIDs[curChild++] = pChild->drawable.id;
984     }
985     
986     reply.nChildren = numChildren;
987     reply.length = bytes_to_int32(numChildren * sizeof(Window));
988     
989     WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
990     if (numChildren)
991     {
992         client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
993         WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
994         free(childIDs);
995     }
996
997     return Success;
998 }
999
1000 int
1001 ProcInternAtom(ClientPtr client)
1002 {
1003     Atom atom;
1004     char *tchar;
1005     REQUEST(xInternAtomReq);
1006
1007     REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
1008     if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
1009     {
1010         client->errorValue = stuff->onlyIfExists;
1011         return BadValue;
1012     }
1013     tchar = (char *) &stuff[1];
1014     atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
1015     if (atom != BAD_RESOURCE)
1016     {
1017         xInternAtomReply reply;
1018         memset(&reply, 0, sizeof(xInternAtomReply));
1019         reply.type = X_Reply;
1020         reply.length = 0;
1021         reply.sequenceNumber = client->sequence;
1022         reply.atom = atom;
1023         WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
1024         return Success;
1025     }
1026     else
1027         return BadAlloc;
1028 }
1029
1030 int
1031 ProcGetAtomName(ClientPtr client)
1032 {
1033     const char *str;
1034     xGetAtomNameReply reply;
1035     int len;
1036     REQUEST(xResourceReq);
1037
1038     REQUEST_SIZE_MATCH(xResourceReq);
1039     if ( (str = NameForAtom(stuff->id)) )
1040     {
1041         len = strlen(str);
1042         memset(&reply, 0, sizeof(xGetAtomNameReply));
1043         reply.type = X_Reply;
1044         reply.length = bytes_to_int32(len);
1045         reply.sequenceNumber = client->sequence;
1046         reply.nameLength = len;
1047         WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
1048         (void)WriteToClient(client, len, str);
1049         return Success;
1050     }
1051     else 
1052     { 
1053         client->errorValue = stuff->id;
1054         return BadAtom;
1055     }
1056 }
1057
1058 int
1059 ProcGrabServer(ClientPtr client)
1060 {
1061     int rc;
1062     REQUEST_SIZE_MATCH(xReq);
1063     if (grabState != GrabNone && client != grabClient)
1064     {
1065         ResetCurrentRequest(client);
1066         client->sequence--;
1067         BITSET(grabWaiters, client->index);
1068         IgnoreClient(client);
1069         return Success;
1070     }
1071     rc = OnlyListenToOneClient(client);
1072     if (rc != Success)
1073         return rc;
1074     grabState = GrabKickout;
1075     grabClient = client;
1076
1077     if (ServerGrabCallback)
1078     {
1079         ServerGrabInfoRec grabinfo;
1080         grabinfo.client = client;
1081         grabinfo.grabstate  = SERVER_GRABBED;
1082         CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
1083     }
1084
1085     return Success;
1086 }
1087
1088 static void
1089 UngrabServer(ClientPtr client)
1090 {
1091     int i;
1092
1093     grabState = GrabNone;
1094     ListenToAllClients();
1095     for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
1096         ;
1097     if (i >= 0)
1098     {
1099         i <<= 5;
1100         while (!GETBIT(grabWaiters, i))
1101             i++;
1102         BITCLEAR(grabWaiters, i);
1103         AttendClient(clients[i]);
1104     }
1105
1106     if (ServerGrabCallback)
1107     {
1108         ServerGrabInfoRec grabinfo;
1109         grabinfo.client = client;
1110         grabinfo.grabstate  = SERVER_UNGRABBED;
1111         CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
1112     }
1113 }
1114
1115 int
1116 ProcUngrabServer(ClientPtr client)
1117 {
1118     REQUEST_SIZE_MATCH(xReq);
1119     UngrabServer(client);
1120     return Success;
1121 }
1122
1123 int
1124 ProcTranslateCoords(ClientPtr client)
1125 {
1126     REQUEST(xTranslateCoordsReq);
1127
1128     WindowPtr pWin, pDst;
1129     xTranslateCoordsReply rep;
1130     int rc;
1131
1132     REQUEST_SIZE_MATCH(xTranslateCoordsReq);
1133     rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
1134     if (rc != Success)
1135         return rc;
1136     rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
1137     if (rc != Success)
1138         return rc;
1139     memset(&rep, 0, sizeof(xTranslateCoordsReply));
1140     rep.type = X_Reply;
1141     rep.length = 0;
1142     rep.sequenceNumber = client->sequence;
1143     if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
1144     {
1145         rep.sameScreen = xFalse;
1146         rep.child = None;
1147         rep.dstX = rep.dstY = 0;
1148     }
1149     else
1150     {
1151         INT16 x, y;
1152         rep.sameScreen = xTrue;
1153         rep.child = None;
1154         /* computing absolute coordinates -- adjust to destination later */
1155         x = pWin->drawable.x + stuff->srcX;
1156         y = pWin->drawable.y + stuff->srcY;
1157         pWin = pDst->firstChild;
1158         while (pWin)
1159         {
1160             BoxRec  box;
1161             if ((pWin->mapped) &&
1162                 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
1163                 (x < pWin->drawable.x + (int)pWin->drawable.width +
1164                  wBorderWidth (pWin)) &&
1165                 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
1166                 (y < pWin->drawable.y + (int)pWin->drawable.height +
1167                  wBorderWidth (pWin))
1168                 /* When a window is shaped, a further check
1169                  * is made to see if the point is inside
1170                  * borderSize
1171                  */
1172                 && (!wBoundingShape(pWin) ||
1173                     RegionContainsPoint(&pWin->borderSize, x, y, &box))
1174                 
1175                 && (!wInputShape(pWin) ||
1176                     RegionContainsPoint(wInputShape(pWin),
1177                                         x - pWin->drawable.x,
1178                                         y - pWin->drawable.y, &box))
1179                 )
1180             {
1181                 rep.child = pWin->drawable.id;
1182                 pWin = (WindowPtr) NULL;
1183             }
1184             else
1185                 pWin = pWin->nextSib;
1186         }
1187         /* adjust to destination coordinates */
1188         rep.dstX = x - pDst->drawable.x;
1189         rep.dstY = y - pDst->drawable.y;
1190     }
1191     WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
1192     return Success;
1193 }
1194
1195 int
1196 ProcOpenFont(ClientPtr client)
1197 {
1198     int err;
1199     REQUEST(xOpenFontReq);
1200
1201     REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
1202     client->errorValue = stuff->fid;
1203     LEGAL_NEW_RESOURCE(stuff->fid, client);
1204     err = OpenFont(client, stuff->fid, (Mask) 0,
1205                 stuff->nbytes, (char *)&stuff[1]);
1206     if (err == Success)
1207     {
1208         return Success;
1209     }
1210     else
1211         return err;
1212 }
1213
1214 int
1215 ProcCloseFont(ClientPtr client)
1216 {
1217     FontPtr pFont;
1218     int rc;
1219     REQUEST(xResourceReq);
1220
1221     REQUEST_SIZE_MATCH(xResourceReq);
1222     rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT,
1223                                  client, DixDestroyAccess);
1224     if (rc == Success)
1225     {
1226         FreeResource(stuff->id, RT_NONE);
1227         return Success;
1228     }
1229     else
1230     {
1231         client->errorValue = stuff->id;
1232         return rc;
1233     }
1234 }
1235
1236 int
1237 ProcQueryFont(ClientPtr client)
1238 {
1239     xQueryFontReply     *reply;
1240     FontPtr pFont;
1241     int rc;
1242     REQUEST(xResourceReq);
1243     REQUEST_SIZE_MATCH(xResourceReq);
1244
1245     rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
1246     if (rc != Success)
1247         return rc;
1248
1249     {
1250         xCharInfo       *pmax = FONTINKMAX(pFont);
1251         xCharInfo       *pmin = FONTINKMIN(pFont);
1252         int             nprotoxcistructs;
1253         int             rlength;
1254
1255         nprotoxcistructs = (
1256            pmax->rightSideBearing == pmin->rightSideBearing &&
1257            pmax->leftSideBearing == pmin->leftSideBearing &&
1258            pmax->descent == pmin->descent &&
1259            pmax->ascent == pmin->ascent &&
1260            pmax->characterWidth == pmin->characterWidth) ?
1261                 0 : N2dChars(pFont);
1262
1263         rlength = sizeof(xQueryFontReply) +
1264                      FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
1265                      nprotoxcistructs * sizeof(xCharInfo);
1266         reply = calloc(1, rlength);
1267         if(!reply)
1268         {
1269             return BadAlloc;
1270         }
1271
1272         reply->type = X_Reply;
1273         reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
1274         reply->sequenceNumber = client->sequence;
1275         QueryFont( pFont, reply, nprotoxcistructs);
1276
1277         WriteReplyToClient(client, rlength, reply);
1278         free(reply);
1279         return Success;
1280     }
1281 }
1282
1283 int
1284 ProcQueryTextExtents(ClientPtr client)
1285 {
1286     xQueryTextExtentsReply reply;
1287     FontPtr pFont;
1288     ExtentInfoRec info;
1289     unsigned long length;
1290     int rc;
1291     REQUEST(xQueryTextExtentsReq);
1292     REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
1293         
1294     rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
1295     if (rc != Success)
1296         return rc;
1297
1298     length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
1299     length = length << 1;
1300     if (stuff->oddLength)
1301     {
1302         if (length == 0)
1303             return BadLength;
1304         length--;
1305     }
1306     if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
1307         return BadAlloc;
1308     reply.type = X_Reply;
1309     reply.length = 0;
1310     reply.sequenceNumber = client->sequence;
1311     reply.drawDirection = info.drawDirection;
1312     reply.fontAscent = info.fontAscent;
1313     reply.fontDescent = info.fontDescent;
1314     reply.overallAscent = info.overallAscent;
1315     reply.overallDescent = info.overallDescent;
1316     reply.overallWidth = info.overallWidth;
1317     reply.overallLeft = info.overallLeft;
1318     reply.overallRight = info.overallRight;
1319     WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
1320     return Success;
1321 }
1322
1323 int
1324 ProcListFonts(ClientPtr client)
1325 {
1326     REQUEST(xListFontsReq);
1327
1328     REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
1329
1330     return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
1331         stuff->maxNames);
1332 }
1333
1334 int
1335 ProcListFontsWithInfo(ClientPtr client)
1336 {
1337     REQUEST(xListFontsWithInfoReq);
1338
1339     REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
1340
1341     return StartListFontsWithInfo(client, stuff->nbytes,
1342                                   (unsigned char *) &stuff[1], stuff->maxNames);
1343 }
1344
1345 /**
1346  *
1347  *  \param value must conform to DeleteType
1348  */
1349 int
1350 dixDestroyPixmap(pointer value, XID pid)
1351 {
1352     PixmapPtr pPixmap = (PixmapPtr)value;
1353     return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
1354 }
1355
1356 int
1357 ProcCreatePixmap(ClientPtr client)
1358 {
1359     PixmapPtr pMap;
1360     DrawablePtr pDraw;
1361     REQUEST(xCreatePixmapReq);
1362     DepthPtr pDepth;
1363     int i, rc;
1364
1365     REQUEST_SIZE_MATCH(xCreatePixmapReq);
1366     client->errorValue = stuff->pid;
1367     LEGAL_NEW_RESOURCE(stuff->pid, client);
1368     
1369     rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
1370                            DixGetAttrAccess);
1371     if (rc != Success)
1372         return rc;
1373
1374     if (!stuff->width || !stuff->height)
1375     {
1376         client->errorValue = 0;
1377         return BadValue;
1378     }
1379     if (stuff->width > 32767 || stuff->height > 32767)
1380     {
1381         /* It is allowed to try and allocate a pixmap which is larger than
1382          * 32767 in either dimension. However, all of the framebuffer code
1383          * is buggy and does not reliably draw to such big pixmaps, basically
1384          * because the Region data structure operates with signed shorts
1385          * for the rectangles in it.
1386          *
1387          * Furthermore, several places in the X server computes the
1388          * size in bytes of the pixmap and tries to store it in an
1389          * integer. This integer can overflow and cause the allocated size
1390          * to be much smaller.
1391          *
1392          * So, such big pixmaps are rejected here with a BadAlloc
1393          */
1394         return BadAlloc;
1395     }
1396     if (stuff->depth != 1)
1397     {
1398         pDepth = pDraw->pScreen->allowedDepths;
1399         for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
1400            if (pDepth->depth == stuff->depth)
1401                goto CreatePmap;
1402         client->errorValue = stuff->depth;
1403         return BadValue;
1404     }
1405 CreatePmap:
1406     pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
1407                 (pDraw->pScreen, stuff->width,
1408                  stuff->height, stuff->depth, 0);
1409     if (pMap)
1410     {
1411         pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
1412         pMap->drawable.id = stuff->pid;
1413         /* security creation/labeling check */
1414         rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
1415                       pMap, RT_NONE, NULL, DixCreateAccess);
1416         if (rc != Success) {
1417             (*pDraw->pScreen->DestroyPixmap)(pMap);
1418             return rc;
1419         }
1420         if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
1421             return Success;
1422         (*pDraw->pScreen->DestroyPixmap)(pMap);
1423     }
1424     return BadAlloc;
1425 }
1426
1427 int
1428 ProcFreePixmap(ClientPtr client)
1429 {
1430     PixmapPtr pMap;
1431     int rc;
1432     REQUEST(xResourceReq);
1433     REQUEST_SIZE_MATCH(xResourceReq);
1434
1435     rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client,
1436                            DixDestroyAccess);
1437     if (rc == Success)
1438     {
1439         FreeResource(stuff->id, RT_NONE);
1440         return Success;
1441     }
1442     else 
1443     {
1444         client->errorValue = stuff->id;
1445         return rc;
1446     }
1447 }
1448
1449 int
1450 ProcCreateGC(ClientPtr client)
1451 {
1452     int error, rc;
1453     GC *pGC;
1454     DrawablePtr pDraw;
1455     unsigned len;
1456     REQUEST(xCreateGCReq);
1457
1458     REQUEST_AT_LEAST_SIZE(xCreateGCReq);
1459     client->errorValue = stuff->gc;
1460     LEGAL_NEW_RESOURCE(stuff->gc, client);
1461     rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
1462                            DixGetAttrAccess);
1463     if (rc != Success)
1464         return rc;
1465
1466     len = client->req_len -  bytes_to_int32(sizeof(xCreateGCReq));
1467     if (len != Ones(stuff->mask))
1468         return BadLength;
1469     pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
1470                          stuff->gc, client);
1471     if (error != Success)
1472         return error;
1473     if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
1474         return BadAlloc;
1475     return Success;
1476 }
1477
1478 int
1479 ProcChangeGC(ClientPtr client)
1480 {
1481     GC *pGC;
1482     int result;
1483     unsigned len;
1484     REQUEST(xChangeGCReq);
1485     REQUEST_AT_LEAST_SIZE(xChangeGCReq);
1486
1487     result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1488     if (result != Success)
1489         return result;
1490
1491     len = client->req_len -  bytes_to_int32(sizeof(xChangeGCReq));
1492     if (len != Ones(stuff->mask))
1493         return BadLength;
1494
1495     return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
1496 }
1497
1498 int
1499 ProcCopyGC(ClientPtr client)
1500 {
1501     GC *dstGC;
1502     GC *pGC;
1503     int result;
1504     REQUEST(xCopyGCReq);
1505     REQUEST_SIZE_MATCH(xCopyGCReq);
1506
1507     result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
1508     if (result != Success)
1509         return result;
1510     result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
1511     if (result != Success)
1512         return result;
1513     if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
1514         return BadMatch;
1515     if (stuff->mask & ~GCAllBits)
1516     {
1517         client->errorValue = stuff->mask;
1518         return BadValue;
1519     }
1520     return CopyGC(pGC, dstGC, stuff->mask);
1521 }
1522
1523 int
1524 ProcSetDashes(ClientPtr client)
1525 {
1526     GC *pGC;
1527     int result;
1528     REQUEST(xSetDashesReq);
1529
1530     REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
1531     if (stuff->nDashes == 0)
1532     {
1533          client->errorValue = 0;
1534          return BadValue;
1535     }
1536
1537     result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
1538     if (result != Success)
1539         return result;
1540
1541     /* If there's an error, either there's no sensible errorValue,
1542      * or there was a dash segment of 0. */
1543     client->errorValue = 0;
1544     return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
1545                        (unsigned char *)&stuff[1]);
1546 }
1547
1548 int
1549 ProcSetClipRectangles(ClientPtr client)
1550 {
1551     int nr, result;
1552     GC *pGC;
1553     REQUEST(xSetClipRectanglesReq);
1554
1555     REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
1556     if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
1557         (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
1558     {
1559         client->errorValue = stuff->ordering;
1560         return BadValue;
1561     }
1562     result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
1563     if (result != Success)
1564         return result;
1565                  
1566     nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
1567     if (nr & 4)
1568         return BadLength;
1569     nr >>= 3;
1570     return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
1571                           nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
1572 }
1573
1574 int
1575 ProcFreeGC(ClientPtr client)
1576 {
1577     GC *pGC;
1578     int rc;
1579     REQUEST(xResourceReq);
1580     REQUEST_SIZE_MATCH(xResourceReq);
1581
1582     rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
1583     if (rc != Success)
1584         return rc;
1585
1586     FreeResource(stuff->id, RT_NONE);
1587     return Success;
1588 }
1589
1590 int
1591 ProcClearToBackground(ClientPtr client)
1592 {
1593     REQUEST(xClearAreaReq);
1594     WindowPtr pWin;
1595     int rc;
1596
1597     REQUEST_SIZE_MATCH(xClearAreaReq);
1598     rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
1599     if (rc != Success)
1600         return rc;
1601     if (pWin->drawable.class == InputOnly)
1602     {
1603         client->errorValue = stuff->window;
1604         return BadMatch;
1605     }               
1606     if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
1607     {
1608         client->errorValue = stuff->exposures;
1609         return BadValue;
1610     }
1611     (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
1612                                stuff->width, stuff->height,
1613                                (Bool)stuff->exposures);
1614     return Success;
1615 }
1616
1617 int
1618 ProcCopyArea(ClientPtr client)
1619 {
1620     DrawablePtr pDst;
1621     DrawablePtr pSrc;
1622     GC *pGC;
1623     REQUEST(xCopyAreaReq);
1624     RegionPtr pRgn;
1625     int rc;
1626
1627     REQUEST_SIZE_MATCH(xCopyAreaReq);
1628
1629     VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 
1630     if (stuff->dstDrawable != stuff->srcDrawable)
1631     {
1632         rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
1633                                  DixReadAccess);
1634         if (rc != Success)
1635             return rc;
1636         if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
1637         {
1638             client->errorValue = stuff->dstDrawable;
1639             return BadMatch;
1640         }
1641     }
1642     else
1643         pSrc = pDst;
1644
1645     pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
1646                                  stuff->width, stuff->height, 
1647                                  stuff->dstX, stuff->dstY);
1648     if (pGC->graphicsExposures)
1649     {
1650         (*pDst->pScreen->SendGraphicsExpose)
1651                 (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
1652         if (pRgn)
1653             RegionDestroy(pRgn);
1654     }
1655
1656     return Success;
1657 }
1658
1659 int
1660 ProcCopyPlane(ClientPtr client)
1661 {
1662     DrawablePtr psrcDraw, pdstDraw;
1663     GC *pGC;
1664     REQUEST(xCopyPlaneReq);
1665     RegionPtr pRgn;
1666     int rc;
1667
1668     REQUEST_SIZE_MATCH(xCopyPlaneReq);
1669
1670     VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
1671     if (stuff->dstDrawable != stuff->srcDrawable)
1672     {
1673         rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
1674                                DixReadAccess);
1675         if (rc != Success)
1676             return rc;
1677
1678         if (pdstDraw->pScreen != psrcDraw->pScreen)
1679         {
1680             client->errorValue = stuff->dstDrawable;
1681             return BadMatch;
1682         }
1683     }
1684     else
1685         psrcDraw = pdstDraw;
1686
1687     /* Check to see if stuff->bitPlane has exactly ONE good bit set */
1688     if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
1689        (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
1690     {
1691        client->errorValue = stuff->bitPlane;
1692        return BadValue;
1693     }
1694
1695     pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
1696                                  stuff->width, stuff->height, 
1697                                  stuff->dstX, stuff->dstY, stuff->bitPlane);
1698     if (pGC->graphicsExposures)
1699     {
1700         (*pdstDraw->pScreen->SendGraphicsExpose)
1701                 (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
1702         if (pRgn)
1703             RegionDestroy(pRgn);
1704     }
1705     return Success;
1706 }
1707
1708 int
1709 ProcPolyPoint(ClientPtr client)
1710 {
1711     int npoint;
1712     GC *pGC;
1713     DrawablePtr pDraw;
1714     REQUEST(xPolyPointReq);
1715
1716     REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1717     if ((stuff->coordMode != CoordModeOrigin) && 
1718         (stuff->coordMode != CoordModePrevious))
1719     {
1720         client->errorValue = stuff->coordMode;
1721         return BadValue;
1722     }
1723     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 
1724     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
1725     if (npoint)
1726         (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
1727                           (xPoint *) &stuff[1]);
1728     return Success;
1729 }
1730
1731 int
1732 ProcPolyLine(ClientPtr client)
1733 {
1734     int npoint;
1735     GC *pGC;
1736     DrawablePtr pDraw;
1737     REQUEST(xPolyLineReq);
1738
1739     REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1740     if ((stuff->coordMode != CoordModeOrigin) && 
1741         (stuff->coordMode != CoordModePrevious))
1742     {
1743         client->errorValue = stuff->coordMode;
1744         return BadValue;
1745     }
1746     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1747     npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
1748     if (npoint > 1)
1749         (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
1750                               (DDXPointPtr) &stuff[1]);
1751     return Success;
1752 }
1753
1754 int
1755 ProcPolySegment(ClientPtr client)
1756 {
1757     int nsegs;
1758     GC *pGC;
1759     DrawablePtr pDraw;
1760     REQUEST(xPolySegmentReq);
1761
1762     REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
1763     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1764     nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
1765     if (nsegs & 4)
1766         return BadLength;
1767     nsegs >>= 3;
1768     if (nsegs)
1769         (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
1770     return Success;
1771 }
1772
1773 int
1774 ProcPolyRectangle (ClientPtr client)
1775 {
1776     int nrects;
1777     GC *pGC;
1778     DrawablePtr pDraw;
1779     REQUEST(xPolyRectangleReq);
1780
1781     REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
1782     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1783     nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
1784     if (nrects & 4)
1785         return BadLength;
1786     nrects >>= 3;
1787     if (nrects)
1788         (*pGC->ops->PolyRectangle)(pDraw, pGC, 
1789                     nrects, (xRectangle *) &stuff[1]);
1790     return Success;
1791 }
1792
1793 int
1794 ProcPolyArc(ClientPtr client)
1795 {
1796     int         narcs;
1797     GC *pGC;
1798     DrawablePtr pDraw;
1799     REQUEST(xPolyArcReq);
1800
1801     REQUEST_AT_LEAST_SIZE(xPolyArcReq);
1802     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1803     narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
1804     if (narcs % sizeof(xArc))
1805         return BadLength;
1806     narcs /= sizeof(xArc);
1807     if (narcs)
1808         (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
1809     return Success;
1810 }
1811
1812 int
1813 ProcFillPoly(ClientPtr client)
1814 {
1815     int          things;
1816     GC *pGC;
1817     DrawablePtr pDraw;
1818     REQUEST(xFillPolyReq);
1819
1820     REQUEST_AT_LEAST_SIZE(xFillPolyReq);
1821     if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
1822         (stuff->shape != Convex))
1823     {
1824         client->errorValue = stuff->shape;
1825         return BadValue;
1826     }
1827     if ((stuff->coordMode != CoordModeOrigin) && 
1828         (stuff->coordMode != CoordModePrevious))
1829     {
1830         client->errorValue = stuff->coordMode;
1831         return BadValue;
1832     }
1833
1834     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1835     things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
1836     if (things)
1837         (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
1838                          stuff->coordMode, things,
1839                          (DDXPointPtr) &stuff[1]);
1840     return Success;
1841 }
1842
1843 int
1844 ProcPolyFillRectangle(ClientPtr client)
1845 {
1846     int             things;
1847     GC *pGC;
1848     DrawablePtr pDraw;
1849     REQUEST(xPolyFillRectangleReq);
1850
1851     REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
1852     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1853     things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
1854     if (things & 4)
1855         return BadLength;
1856     things >>= 3;
1857
1858     if (things)
1859         (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
1860                       (xRectangle *) &stuff[1]);
1861     return Success;
1862 }
1863
1864 int
1865 ProcPolyFillArc(ClientPtr client)
1866 {
1867     int         narcs;
1868     GC *pGC;
1869     DrawablePtr pDraw;
1870     REQUEST(xPolyFillArcReq);
1871
1872     REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
1873     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1874     narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
1875     if (narcs % sizeof(xArc))
1876         return BadLength;
1877     narcs /= sizeof(xArc);
1878     if (narcs)
1879         (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
1880     return Success;
1881 }
1882
1883 #ifdef MATCH_CLIENT_ENDIAN
1884
1885 int
1886 ServerOrder (void)
1887 {
1888     int     whichbyte = 1;
1889
1890     if (*((char *) &whichbyte))
1891         return LSBFirst;
1892     return MSBFirst;
1893 }
1894
1895 #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
1896
1897 void
1898 ReformatImage (char *base, int nbytes, int bpp, int order)
1899 {
1900     switch (bpp) {
1901     case 1:     /* yuck */
1902         if (BITMAP_BIT_ORDER != order)
1903             BitOrderInvert ((unsigned char *) base, nbytes);
1904 #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
1905         ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
1906 #endif
1907         break;
1908     case 4:
1909         break;  /* yuck */
1910     case 8:
1911         break;
1912     case 16:
1913         if (IMAGE_BYTE_ORDER != order)
1914             TwoByteSwap ((unsigned char *) base, nbytes);
1915         break;
1916     case 32:
1917         if (IMAGE_BYTE_ORDER != order)
1918             FourByteSwap ((unsigned char *) base, nbytes);
1919         break;
1920     }
1921 }
1922 #else
1923 #define ReformatImage(b,n,bpp,o)
1924 #endif
1925
1926 /* 64-bit server notes: the protocol restricts padding of images to
1927  * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
1928  * to use internally. Removes need for internal alignment checking.
1929  * All of the PutImage functions could be changed individually, but
1930  * as currently written, they call other routines which require things
1931  * to be 64-bit padded on scanlines, so we changed things here.
1932  * If an image would be padded differently for 64- versus 32-, then
1933  * copy each scanline to a 64-bit padded scanline.
1934  * Also, we need to make sure that the image is aligned on a 64-bit
1935  * boundary, even if the scanlines are padded to our satisfaction.
1936  */
1937 int
1938 ProcPutImage(ClientPtr client)
1939 {
1940     GC *pGC;
1941     DrawablePtr pDraw;
1942     long        length;         /* length of scanline server padded */
1943     long        lengthProto;    /* length of scanline protocol padded */
1944     char        *tmpImage;
1945     REQUEST(xPutImageReq);
1946
1947     REQUEST_AT_LEAST_SIZE(xPutImageReq);
1948     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1949     if (stuff->format == XYBitmap)
1950     {
1951         if ((stuff->depth != 1) ||
1952             (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
1953             return BadMatch;
1954         length      = BitmapBytePad(stuff->width + stuff->leftPad);
1955     }
1956     else if (stuff->format == XYPixmap)
1957     {
1958         if ((pDraw->depth != stuff->depth) || 
1959             (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
1960             return BadMatch;
1961         length      = BitmapBytePad(stuff->width + stuff->leftPad);
1962         length      *= stuff->depth;
1963     }
1964     else if (stuff->format == ZPixmap)
1965     {
1966         if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
1967             return BadMatch;
1968         length      = PixmapBytePad(stuff->width, stuff->depth);
1969     }
1970     else
1971     {
1972         client->errorValue = stuff->format;
1973         return BadValue;
1974     }
1975
1976     tmpImage = (char *)&stuff[1];
1977     lengthProto = length;
1978         
1979     if ((bytes_to_int32(lengthProto * stuff->height) +
1980         bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
1981         return BadLength;
1982
1983     ReformatImage (tmpImage, lengthProto * stuff->height, 
1984                    stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
1985                    ClientOrder(client));
1986     
1987     (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
1988                   stuff->width, stuff->height, 
1989                   stuff->leftPad, stuff->format, tmpImage);
1990
1991      return Success;
1992 }
1993
1994 static int
1995 DoGetImage(ClientPtr client, int format, Drawable drawable, 
1996            int x, int y, int width, int height, 
1997            Mask planemask, xGetImageReply **im_return)
1998 {
1999     DrawablePtr         pDraw, pBoundingDraw;
2000     int                 nlines, linesPerBuf, rc;
2001     int                 linesDone;
2002     /* coordinates relative to the bounding drawable */
2003     int                 relx, rely;
2004     long                widthBytesLine, length;
2005     Mask                plane = 0;
2006     char                *pBuf;
2007     xGetImageReply      xgi;
2008     RegionPtr pVisibleRegion = NULL;
2009
2010     if ((format != XYPixmap) && (format != ZPixmap))
2011     {
2012         client->errorValue = format;
2013         return BadValue;
2014     }
2015     rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
2016     if (rc != Success)
2017         return rc;
2018
2019     memset(&xgi, 0, sizeof(xGetImageReply));
2020
2021     relx = x;
2022     rely = y;
2023
2024     if(pDraw->type == DRAWABLE_WINDOW)
2025     {
2026         WindowPtr pWin = (WindowPtr)pDraw;
2027
2028         /* "If the drawable is a window, the window must be viewable ... or a
2029          * BadMatch error results" */
2030         if (!pWin->viewable)
2031             return BadMatch;
2032
2033         relx += pDraw->x;
2034         rely += pDraw->y;
2035
2036         if (pDraw->pScreen->GetWindowPixmap) {
2037             PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
2038
2039             pBoundingDraw = &pPix->drawable;
2040 #ifdef COMPOSITE
2041             relx -= pPix->screen_x;
2042             rely -= pPix->screen_y;
2043 #endif
2044         }
2045         else
2046         {
2047             pBoundingDraw = (DrawablePtr)pDraw->pScreen->root;
2048         }
2049
2050         xgi.visual = wVisual (pWin);
2051     }
2052     else
2053     {
2054         pBoundingDraw = pDraw;
2055         xgi.visual = None;
2056     }
2057
2058     /* "If the drawable is a pixmap, the given rectangle must be wholly
2059      *  contained within the pixmap, or a BadMatch error results.  If the
2060      *  drawable is a window [...] it must be the case that if there were no
2061      *  inferiors or overlapping windows, the specified rectangle of the window
2062      *  would be fully visible on the screen and wholly contained within the
2063      *  outside edges of the window, or a BadMatch error results."
2064      *
2065      * We relax the window case slightly to mean that the rectangle must exist
2066      * within the bounds of the window's backing pixmap.  In particular, this
2067      * means that a GetImage request may succeed or fail with BadMatch depending
2068      * on whether any of its ancestor windows are redirected.  */
2069     if(relx < 0 || relx + width > (int)pBoundingDraw->width ||
2070        rely < 0 || rely + height > (int)pBoundingDraw->height)
2071         return BadMatch;
2072
2073     xgi.type = X_Reply;
2074     xgi.sequenceNumber = client->sequence;
2075     xgi.depth = pDraw->depth;
2076     if(format == ZPixmap)
2077     {
2078         widthBytesLine = PixmapBytePad(width, pDraw->depth);
2079         length = widthBytesLine * height;
2080
2081     }
2082     else 
2083     {
2084         widthBytesLine = BitmapBytePad(width);
2085         plane = ((Mask)1) << (pDraw->depth - 1);
2086         /* only planes asked for */
2087         length = widthBytesLine * height *
2088                  Ones(planemask & (plane | (plane - 1)));
2089
2090     }
2091
2092     xgi.length = length;
2093
2094     if (im_return) {
2095         pBuf = calloc(1, sz_xGetImageReply + length);
2096         if (!pBuf)
2097             return BadAlloc;
2098         if (widthBytesLine == 0)
2099             linesPerBuf = 0;
2100         else
2101             linesPerBuf = height;
2102         *im_return = (xGetImageReply *)pBuf;
2103         *(xGetImageReply *)pBuf = xgi;
2104         pBuf += sz_xGetImageReply;
2105     } else {
2106         xgi.length = bytes_to_int32(xgi.length);
2107         if (widthBytesLine == 0 || height == 0)
2108             linesPerBuf = 0;
2109         else if (widthBytesLine >= IMAGE_BUFSIZE)
2110             linesPerBuf = 1;
2111         else
2112         {
2113             linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
2114             if (linesPerBuf > height)
2115                 linesPerBuf = height;
2116         }
2117         length = linesPerBuf * widthBytesLine;
2118         if (linesPerBuf < height)
2119         {
2120             /* we have to make sure intermediate buffers don't need padding */
2121             while ((linesPerBuf > 1) &&
2122                    (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
2123             {
2124                 linesPerBuf--;
2125                 length -= widthBytesLine;
2126             }
2127             while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
2128             {
2129                 linesPerBuf++;
2130                 length += widthBytesLine;
2131             }
2132         }
2133         if(!(pBuf = calloc(1, length)))
2134             return BadAlloc;
2135         WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
2136     }
2137
2138     if (pDraw->type == DRAWABLE_WINDOW)
2139     {
2140         pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
2141         if (pVisibleRegion)
2142         {
2143             RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
2144         }
2145     }
2146
2147     if (linesPerBuf == 0)
2148     {
2149         /* nothing to do */
2150     }
2151     else if (format == ZPixmap)
2152     {
2153         linesDone = 0;
2154         while (height - linesDone > 0)
2155         {
2156             nlines = min(linesPerBuf, height - linesDone);
2157             (*pDraw->pScreen->GetImage) (pDraw,
2158                                          x,
2159                                          y + linesDone,
2160                                          width, 
2161                                          nlines,
2162                                          format,
2163                                          planemask,
2164                                          (pointer) pBuf);
2165             if (pVisibleRegion)
2166                 XaceCensorImage(client, pVisibleRegion, widthBytesLine,
2167                         pDraw, x, y + linesDone, width, 
2168                         nlines, format, pBuf);
2169
2170             /* Note that this is NOT a call to WriteSwappedDataToClient,
2171                as we do NOT byte swap */
2172             if (!im_return)
2173             {
2174                 ReformatImage (pBuf, (int)(nlines * widthBytesLine),
2175                                BitsPerPixel (pDraw->depth),
2176                                ClientOrder(client));
2177
2178 /* Don't split me, gcc pukes when you do */
2179                 (void)WriteToClient(client,
2180                                     (int)(nlines * widthBytesLine),
2181                                     pBuf);
2182             }
2183             linesDone += nlines;
2184         }
2185     }
2186     else /* XYPixmap */
2187     {
2188         for (; plane; plane >>= 1)
2189         {
2190             if (planemask & plane)
2191             {
2192                 linesDone = 0;
2193                 while (height - linesDone > 0)
2194                 {
2195                     nlines = min(linesPerBuf, height - linesDone);
2196                     (*pDraw->pScreen->GetImage) (pDraw,
2197                                                  x,
2198                                                  y + linesDone,
2199                                                  width, 
2200                                                  nlines,
2201                                                  format,
2202                                                  plane,
2203                                                  (pointer)pBuf);
2204                     if (pVisibleRegion)
2205                         XaceCensorImage(client, pVisibleRegion,
2206                                 widthBytesLine,
2207                                 pDraw, x, y + linesDone, width, 
2208                                 nlines, format, pBuf);
2209
2210                     /* Note: NOT a call to WriteSwappedDataToClient,
2211                        as we do NOT byte swap */
2212                     if (im_return) {
2213                         pBuf += nlines * widthBytesLine;
2214                     } else {
2215                         ReformatImage (pBuf, 
2216                                        (int)(nlines * widthBytesLine), 
2217                                        1,
2218                                        ClientOrder (client));
2219
2220 /* Don't split me, gcc pukes when you do */
2221                         (void)WriteToClient(client,
2222                                         (int)(nlines * widthBytesLine),
2223                                         pBuf);
2224                     }
2225                     linesDone += nlines;
2226                 }
2227             }
2228         }
2229     }
2230     if (pVisibleRegion)
2231         RegionDestroy(pVisibleRegion);
2232     if (!im_return)
2233         free(pBuf);
2234     return Success;
2235 }
2236
2237 int
2238 ProcGetImage(ClientPtr client)
2239 {
2240     REQUEST(xGetImageReq);
2241
2242     REQUEST_SIZE_MATCH(xGetImageReq);
2243
2244     return DoGetImage(client, stuff->format, stuff->drawable,
2245                       stuff->x, stuff->y,
2246                       (int)stuff->width, (int)stuff->height,
2247                       stuff->planeMask, (xGetImageReply **)NULL);
2248 }
2249
2250 int
2251 ProcPolyText(ClientPtr client)
2252 {
2253     int err;
2254     REQUEST(xPolyTextReq);
2255     DrawablePtr pDraw;
2256     GC *pGC;
2257
2258     REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2259     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2260
2261     err = PolyText(client,
2262                    pDraw,
2263                    pGC,
2264                    (unsigned char *)&stuff[1],
2265                    ((unsigned char *) stuff) + (client->req_len << 2),
2266                    stuff->x,
2267                    stuff->y,
2268                    stuff->reqType,
2269                    stuff->drawable);
2270
2271     if (err == Success)
2272     {
2273         return Success;
2274     }
2275     else
2276         return err;
2277 }
2278
2279 int
2280 ProcImageText8(ClientPtr client)
2281 {
2282     int err;
2283     DrawablePtr pDraw;
2284     GC *pGC;
2285
2286     REQUEST(xImageTextReq);
2287
2288     REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2289     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2290
2291     err = ImageText(client,
2292                     pDraw,
2293                     pGC,
2294                     stuff->nChars,
2295                     (unsigned char *)&stuff[1],
2296                     stuff->x,
2297                     stuff->y,
2298                     stuff->reqType,
2299                     stuff->drawable);
2300
2301     if (err == Success)
2302     {
2303         return Success;
2304     }
2305     else
2306         return err;
2307 }
2308
2309 int
2310 ProcImageText16(ClientPtr client)
2311 {
2312     int err;
2313     DrawablePtr pDraw;
2314     GC *pGC;
2315
2316     REQUEST(xImageTextReq);
2317
2318     REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
2319     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2320
2321     err = ImageText(client,
2322                     pDraw,
2323                     pGC,
2324                     stuff->nChars,
2325                     (unsigned char *)&stuff[1],
2326                     stuff->x,
2327                     stuff->y,
2328                     stuff->reqType,
2329                     stuff->drawable);
2330
2331     if (err == Success)
2332     {
2333         return Success;
2334     }
2335     else
2336         return err;
2337 }
2338
2339
2340 int
2341 ProcCreateColormap(ClientPtr client)
2342 {
2343     VisualPtr   pVisual;
2344     ColormapPtr pmap;
2345     Colormap    mid;
2346     WindowPtr   pWin;
2347     ScreenPtr pScreen;
2348     REQUEST(xCreateColormapReq);
2349     int i, result;
2350
2351     REQUEST_SIZE_MATCH(xCreateColormapReq);
2352
2353     if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
2354     {
2355         client->errorValue = stuff->alloc;
2356         return BadValue;
2357     }
2358     mid = stuff->mid;
2359     LEGAL_NEW_RESOURCE(mid, client);
2360     result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2361     if (result != Success)
2362         return result;
2363
2364     pScreen = pWin->drawable.pScreen;
2365     for (i = 0, pVisual = pScreen->visuals;
2366          i < pScreen->numVisuals;
2367          i++, pVisual++)
2368     {
2369         if (pVisual->vid != stuff->visual)
2370             continue;
2371         return CreateColormap(mid, pScreen, pVisual, &pmap,
2372                                  (int)stuff->alloc, client->index);
2373     }
2374     client->errorValue = stuff->visual;
2375     return BadMatch;
2376 }
2377
2378 int
2379 ProcFreeColormap(ClientPtr client)
2380 {
2381     ColormapPtr pmap;
2382     int rc;
2383     REQUEST(xResourceReq);
2384
2385     REQUEST_SIZE_MATCH(xResourceReq);
2386     rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client,
2387                            DixDestroyAccess);
2388     if (rc == Success)
2389     {
2390         /* Freeing a default colormap is a no-op */
2391         if (!(pmap->flags & IsDefault))
2392             FreeResource(stuff->id, RT_NONE);
2393         return Success;
2394     }
2395     else 
2396     {
2397         client->errorValue = stuff->id;
2398         return rc;
2399     }
2400 }
2401
2402
2403 int
2404 ProcCopyColormapAndFree(ClientPtr client)
2405 {
2406     Colormap    mid;
2407     ColormapPtr pSrcMap;
2408     REQUEST(xCopyColormapAndFreeReq);
2409     int rc;
2410
2411     REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2412     mid = stuff->mid;
2413     LEGAL_NEW_RESOURCE(mid, client);
2414     rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP,
2415                            client, DixReadAccess|DixRemoveAccess);
2416     if (rc == Success)
2417         return CopyColormapAndFree(mid, pSrcMap, client->index);
2418     client->errorValue = stuff->srcCmap;
2419     return rc;
2420 }
2421
2422 int
2423 ProcInstallColormap(ClientPtr client)
2424 {
2425     ColormapPtr pcmp;
2426     int rc;
2427     REQUEST(xResourceReq);
2428     REQUEST_SIZE_MATCH(xResourceReq);
2429
2430     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
2431                            DixInstallAccess);
2432     if (rc != Success)
2433         goto out;
2434
2435     rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2436     if (rc != Success) {
2437         if (rc == BadValue)
2438             rc = BadColor;
2439         goto out;
2440     }
2441
2442     (*(pcmp->pScreen->InstallColormap)) (pcmp);
2443     return Success;
2444
2445 out:
2446     client->errorValue = stuff->id;
2447     return rc;
2448 }
2449
2450 int
2451 ProcUninstallColormap(ClientPtr client)
2452 {
2453     ColormapPtr pcmp;
2454     int rc;
2455     REQUEST(xResourceReq);
2456     REQUEST_SIZE_MATCH(xResourceReq);
2457
2458     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
2459                            DixUninstallAccess);
2460     if (rc != Success)
2461         goto out;
2462
2463     rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2464     if (rc != Success) {
2465         if (rc == BadValue)
2466             rc = BadColor;
2467         goto out;
2468     }
2469
2470     if(pcmp->mid != pcmp->pScreen->defColormap)
2471         (*(pcmp->pScreen->UninstallColormap)) (pcmp);
2472     return Success;
2473
2474 out:
2475     client->errorValue = stuff->id;
2476     return rc;
2477 }
2478
2479 int
2480 ProcListInstalledColormaps(ClientPtr client)
2481 {
2482     xListInstalledColormapsReply *preply; 
2483     int nummaps, rc;
2484     WindowPtr pWin;
2485     REQUEST(xResourceReq);
2486     REQUEST_SIZE_MATCH(xResourceReq);
2487
2488     rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
2489     if (rc != Success)
2490         return rc;
2491
2492     rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
2493                   DixGetAttrAccess);
2494     if (rc != Success)
2495         return rc;
2496
2497     preply = malloc(sizeof(xListInstalledColormapsReply) +
2498                      pWin->drawable.pScreen->maxInstalledCmaps *
2499                      sizeof(Colormap));
2500     if(!preply)
2501         return BadAlloc;
2502
2503     preply->type = X_Reply;
2504     preply->sequenceNumber = client->sequence;
2505     nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
2506         (pWin->drawable.pScreen, (Colormap *)&preply[1]);
2507     preply->nColormaps = nummaps;
2508     preply->length = nummaps;
2509     WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
2510     client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2511     WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
2512     free(preply);
2513     return Success;
2514 }
2515
2516 int
2517 ProcAllocColor (ClientPtr client)
2518 {
2519     ColormapPtr pmap;
2520     int rc;
2521     xAllocColorReply acr;
2522     REQUEST(xAllocColorReq);
2523
2524     REQUEST_SIZE_MATCH(xAllocColorReq);
2525     rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client,
2526                            DixAddAccess);
2527     if (rc == Success)
2528     {
2529         acr.type = X_Reply;
2530         acr.length = 0;
2531         acr.sequenceNumber = client->sequence;
2532         acr.red = stuff->red;
2533         acr.green = stuff->green;
2534         acr.blue = stuff->blue;
2535         acr.pixel = 0;
2536         if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
2537                                &acr.pixel, client->index)) )
2538             return rc;
2539 #ifdef PANORAMIX
2540         if (noPanoramiXExtension || !pmap->pScreen->myNum)
2541 #endif
2542         WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
2543         return Success;
2544
2545     }
2546     else
2547     {
2548         client->errorValue = stuff->cmap;
2549         return rc;
2550     }
2551 }
2552
2553 int
2554 ProcAllocNamedColor (ClientPtr client)
2555 {
2556     ColormapPtr pcmp;
2557     int rc;
2558     REQUEST(xAllocNamedColorReq);
2559
2560     REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2561     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2562                            DixAddAccess);
2563     if (rc == Success)
2564     {
2565         xAllocNamedColorReply ancr;
2566
2567         ancr.type = X_Reply;
2568         ancr.length = 0;
2569         ancr.sequenceNumber = client->sequence;
2570
2571         if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
2572                          &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
2573         {
2574             ancr.screenRed = ancr.exactRed;
2575             ancr.screenGreen = ancr.exactGreen;
2576             ancr.screenBlue = ancr.exactBlue;
2577             ancr.pixel = 0;
2578             if( (rc = AllocColor(pcmp,
2579                          &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
2580                          &ancr.pixel, client->index)) )
2581                 return rc;
2582 #ifdef PANORAMIX
2583             if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2584 #endif
2585             WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
2586             return Success;
2587         }
2588         else
2589             return BadName;
2590         
2591     }
2592     else
2593     {
2594         client->errorValue = stuff->cmap;
2595         return rc;
2596     }
2597 }
2598
2599 int
2600 ProcAllocColorCells (ClientPtr client)
2601 {
2602     ColormapPtr pcmp;
2603     int rc;
2604     REQUEST(xAllocColorCellsReq);
2605
2606     REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2607     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2608                            DixAddAccess);
2609     if (rc == Success)
2610     {
2611         xAllocColorCellsReply   accr;
2612         int                     npixels, nmasks;
2613         long                    length;
2614         Pixel                   *ppixels, *pmasks;
2615
2616         npixels = stuff->colors;
2617         if (!npixels)
2618         {
2619             client->errorValue = npixels;
2620             return BadValue;
2621         }
2622         if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
2623         {
2624             client->errorValue = stuff->contiguous;
2625             return BadValue;
2626         }
2627         nmasks = stuff->planes;
2628         length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
2629         ppixels = malloc(length);
2630         if(!ppixels)
2631             return BadAlloc;
2632         pmasks = ppixels + npixels;
2633
2634         if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 
2635                                     (Bool)stuff->contiguous, ppixels, pmasks)) )
2636         {
2637             free(ppixels);
2638             return rc;
2639         }
2640 #ifdef PANORAMIX
2641         if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2642 #endif
2643         {
2644             accr.type = X_Reply;
2645             accr.length = bytes_to_int32(length);
2646             accr.sequenceNumber = client->sequence;
2647             accr.nPixels = npixels;
2648             accr.nMasks = nmasks;
2649             WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
2650             client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2651             WriteSwappedDataToClient(client, length, ppixels);
2652         }
2653         free(ppixels);
2654         return Success;
2655     }
2656     else
2657     {
2658         client->errorValue = stuff->cmap;
2659         return rc;
2660     }
2661 }
2662
2663 int
2664 ProcAllocColorPlanes(ClientPtr client)
2665 {
2666     ColormapPtr pcmp;
2667     int rc;
2668     REQUEST(xAllocColorPlanesReq);
2669
2670     REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2671     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2672                            DixAddAccess);
2673     if (rc == Success)
2674     {
2675         xAllocColorPlanesReply  acpr;
2676         int                     npixels;
2677         long                    length;
2678         Pixel                   *ppixels;
2679
2680         npixels = stuff->colors;
2681         if (!npixels)
2682         {
2683             client->errorValue = npixels;
2684             return BadValue;
2685         }
2686         if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
2687         {
2688             client->errorValue = stuff->contiguous;
2689             return BadValue;
2690         }
2691         acpr.type = X_Reply;
2692         acpr.sequenceNumber = client->sequence;
2693         acpr.nPixels = npixels;
2694         length = (long)npixels * sizeof(Pixel);
2695         ppixels = malloc(length);
2696         if(!ppixels)
2697             return BadAlloc;
2698         if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
2699             (int)stuff->red, (int)stuff->green, (int)stuff->blue,
2700             (Bool)stuff->contiguous, ppixels,
2701             &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
2702         {
2703             free(ppixels);
2704             return rc;
2705         }
2706         acpr.length = bytes_to_int32(length);
2707 #ifdef PANORAMIX
2708         if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2709 #endif
2710         {
2711             WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
2712             client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2713             WriteSwappedDataToClient(client, length, ppixels);
2714         }
2715         free(ppixels);
2716         return Success;
2717     }
2718     else
2719     {
2720         client->errorValue = stuff->cmap;
2721         return rc;
2722     }
2723 }
2724
2725 int
2726 ProcFreeColors(ClientPtr client)
2727 {
2728     ColormapPtr pcmp;
2729     int rc;
2730     REQUEST(xFreeColorsReq);
2731
2732     REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2733     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2734                            DixRemoveAccess);
2735     if (rc == Success)
2736     {
2737         int     count;
2738
2739         if(pcmp->flags & AllAllocated)
2740             return BadAccess;
2741         count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
2742         return FreeColors(pcmp, client->index, count,
2743             (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
2744     }
2745     else
2746     {
2747         client->errorValue = stuff->cmap;
2748         return rc;
2749     }
2750 }
2751
2752 int
2753 ProcStoreColors (ClientPtr client)
2754 {
2755     ColormapPtr pcmp;
2756     int rc;
2757     REQUEST(xStoreColorsReq);
2758
2759     REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2760     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2761                            DixWriteAccess);
2762     if (rc == Success)
2763     {
2764         int     count;
2765
2766         count = (client->req_len << 2) - sizeof(xStoreColorsReq);
2767         if (count % sizeof(xColorItem))
2768             return BadLength;
2769         count /= sizeof(xColorItem);
2770         return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client);
2771     }
2772     else
2773     {
2774         client->errorValue = stuff->cmap;
2775         return rc;
2776     }
2777 }
2778
2779 int
2780 ProcStoreNamedColor (ClientPtr client)
2781 {
2782     ColormapPtr pcmp;
2783     int rc;
2784     REQUEST(xStoreNamedColorReq);
2785
2786     REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2787     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2788                            DixWriteAccess);
2789     if (rc == Success)
2790     {
2791         xColorItem      def;
2792
2793         if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
2794                          stuff->nbytes, &def.red, &def.green, &def.blue))
2795         {
2796             def.flags = stuff->flags;
2797             def.pixel = stuff->pixel;
2798             return StoreColors(pcmp, 1, &def, client);
2799         }
2800         return BadName;
2801     }
2802     else
2803     {
2804         client->errorValue = stuff->cmap;
2805         return rc;
2806     }
2807 }
2808
2809 int
2810 ProcQueryColors(ClientPtr client)
2811 {
2812     ColormapPtr pcmp;
2813     int rc;
2814     REQUEST(xQueryColorsReq);
2815
2816     REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2817     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2818                            DixReadAccess);
2819     if (rc == Success)
2820     {
2821         int                     count;
2822         xrgb                    *prgbs;
2823         xQueryColorsReply       qcr;
2824
2825         count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
2826         prgbs = calloc(1, count * sizeof(xrgb));
2827         if(!prgbs && count)
2828             return BadAlloc;
2829         if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) )
2830         {
2831             free(prgbs);
2832             return rc;
2833         }
2834         memset(&qcr, 0, sizeof(xQueryColorsReply));
2835         qcr.type = X_Reply;
2836         qcr.length = bytes_to_int32(count * sizeof(xrgb));
2837         qcr.sequenceNumber = client->sequence;
2838         qcr.nColors = count;
2839         WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
2840         if (count)
2841         {
2842             client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
2843             WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
2844         }
2845         free(prgbs);
2846         return Success;
2847         
2848     }
2849     else
2850     {
2851         client->errorValue = stuff->cmap;
2852         return rc;
2853     }
2854
2855
2856 int
2857 ProcLookupColor(ClientPtr client)
2858 {
2859     ColormapPtr pcmp;
2860     int rc;
2861     REQUEST(xLookupColorReq);
2862
2863     REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2864     rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2865                            DixReadAccess);
2866     if (rc == Success)
2867     {
2868         xLookupColorReply lcr;
2869
2870         if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
2871                          &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
2872         {
2873             lcr.type = X_Reply;
2874             lcr.length = 0;
2875             lcr.sequenceNumber = client->sequence;
2876             lcr.screenRed = lcr.exactRed;
2877             lcr.screenGreen = lcr.exactGreen;
2878             lcr.screenBlue = lcr.exactBlue;
2879             (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
2880                                            &lcr.screenGreen,
2881                                            &lcr.screenBlue,
2882                                            pcmp->pVisual);
2883             WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
2884             return Success;
2885         }
2886         return BadName;
2887     }
2888     else
2889     {
2890         client->errorValue = stuff->cmap;
2891         return rc;
2892     }
2893 }
2894
2895 int
2896 ProcCreateCursor (ClientPtr client)
2897 {
2898     CursorPtr           pCursor;
2899     PixmapPtr           src;
2900     PixmapPtr           msk;
2901     unsigned char *     srcbits;
2902     unsigned char *     mskbits;
2903     unsigned short      width, height;
2904     long                n;
2905     CursorMetricRec     cm;
2906     int rc;
2907
2908     REQUEST(xCreateCursorReq);
2909
2910     REQUEST_SIZE_MATCH(xCreateCursorReq);
2911     LEGAL_NEW_RESOURCE(stuff->cid, client);
2912
2913     rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client,
2914                            DixReadAccess);
2915     if (rc != Success) {
2916         client->errorValue = stuff->source;
2917         return rc;
2918     }
2919
2920     rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
2921                            DixReadAccess);
2922     if (rc != Success)
2923     {
2924         if (stuff->mask != None)
2925         {
2926             client->errorValue = stuff->mask;
2927             return rc;
2928         }
2929 &n