os: Add CryptoAPI as a choice of SHA1 implementation
[xserver/hramrach.git] / dix / dispatch.c
blobd971805488c547ef08f74d635431efb1af00a0c6
1 /************************************************************
3 Copyright 1987, 1989, 1998 The Open Group
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.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
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.
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.
25 Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
27 All Rights Reserved
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Digital not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
37 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 SOFTWARE.
45 ********************************************************/
47 /* The panoramix components contained the following notice */
48 /*****************************************************************
50 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
52 Permission is hereby granted, free of charge, to any person obtaining a copy
53 of this software and associated documentation files (the "Software"), to deal
54 in the Software without restriction, including without limitation the rights
55 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
56 copies of the Software.
58 The above copyright notice and this permission notice shall be included in
59 all copies or substantial portions of the Software.
61 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
64 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
65 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
66 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
67 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69 Except as contained in this notice, the name of Digital Equipment Corporation
70 shall not be used in advertising or otherwise to promote the sale, use or other
71 dealings in this Software without prior written authorization from Digital
72 Equipment Corporation.
74 ******************************************************************/
76 /* XSERVER_DTRACE additions:
77 * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
79 * Permission is hereby granted, free of charge, to any person obtaining a
80 * copy of this software and associated documentation files (the "Software"),
81 * to deal in the Software without restriction, including without limitation
82 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
83 * and/or sell copies of the Software, and to permit persons to whom the
84 * Software is furnished to do so, subject to the following conditions:
86 * The above copyright notice and this permission notice (including the next
87 * paragraph) shall be included in all copies or substantial portions of the
88 * Software.
90 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
91 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
92 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
93 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
94 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
95 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
96 * DEALINGS IN THE SOFTWARE.
99 #ifdef HAVE_DIX_CONFIG_H
100 #include <dix-config.h>
101 #include <version-config.h>
102 #endif
104 #ifdef PANORAMIX_DEBUG
105 #include <stdio.h>
106 int ProcInitialConnection();
107 #endif
109 #include "windowstr.h"
110 #include <X11/fonts/fontstruct.h>
111 #include "dixfontstr.h"
112 #include "gcstruct.h"
113 #include "selection.h"
114 #include "colormapst.h"
115 #include "cursorstr.h"
116 #include "scrnintstr.h"
117 #include "opaque.h"
118 #include "input.h"
119 #include "servermd.h"
120 #include "extnsionst.h"
121 #include "dixfont.h"
122 #include "dispatch.h"
123 #include "swaprep.h"
124 #include "swapreq.h"
125 #include "privates.h"
126 #include "xace.h"
127 #include "inputstr.h"
128 #include "xkbsrv.h"
129 #include "site.h"
130 #include "client.h"
132 #ifdef XSERVER_DTRACE
133 #include "registry.h"
134 #include <sys/types.h>
135 typedef const char *string;
137 #include "Xserver-dtrace.h"
138 #endif
140 #define mskcnt ((MAXCLIENTS + 31) / 32)
141 #define BITMASK(i) (1U << ((i) & 31))
142 #define MASKIDX(i) ((i) >> 5)
143 #define MASKWORD(buf, i) buf[MASKIDX(i)]
144 #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
145 #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
146 #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
148 xConnSetupPrefix connSetupPrefix;
150 PaddingInfo PixmapWidthPaddingInfo[33];
152 static ClientPtr grabClient;
154 #define GrabNone 0
155 #define GrabActive 1
156 #define GrabKickout 2
157 static int grabState = GrabNone;
158 static long grabWaiters[mskcnt];
159 CallbackListPtr ServerGrabCallback = NULL;
160 HWEventQueuePtr checkForInput[2];
161 int connBlockScreenStart;
163 static void KillAllClients(void);
165 static int nextFreeClientID; /* always MIN free client ID */
167 static int nClients; /* number of authorized clients */
169 CallbackListPtr ClientStateCallback;
171 /* dispatchException & isItTimeToYield must be declared volatile since they
172 * are modified by signal handlers - otherwise optimizer may assume it doesn't
173 * need to actually check value in memory when used and may miss changes from
174 * signal handlers.
176 volatile char dispatchException = 0;
177 volatile char isItTimeToYield;
179 #define SAME_SCREENS(a, b) (\
180 (a.pScreen == b.pScreen))
182 void
183 SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
185 checkForInput[0] = c0;
186 checkForInput[1] = c1;
189 void
190 UpdateCurrentTime(void)
192 TimeStamp systime;
194 /* To avoid time running backwards, we must call GetTimeInMillis before
195 * calling ProcessInputEvents.
197 systime.months = currentTime.months;
198 systime.milliseconds = GetTimeInMillis();
199 if (systime.milliseconds < currentTime.milliseconds)
200 systime.months++;
201 if (*checkForInput[0] != *checkForInput[1])
202 ProcessInputEvents();
203 if (CompareTimeStamps(systime, currentTime) == LATER)
204 currentTime = systime;
207 /* Like UpdateCurrentTime, but can't call ProcessInputEvents */
208 void
209 UpdateCurrentTimeIf(void)
211 TimeStamp systime;
213 systime.months = currentTime.months;
214 systime.milliseconds = GetTimeInMillis();
215 if (systime.milliseconds < currentTime.milliseconds)
216 systime.months++;
217 if (CompareTimeStamps(systime, currentTime) == LATER)
218 currentTime = systime;
221 #undef SMART_DEBUG
223 #define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
224 #define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
226 Bool SmartScheduleDisable = FALSE;
227 long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
228 long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
229 long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
230 long SmartScheduleTime;
231 int SmartScheduleLatencyLimited = 0;
232 static ClientPtr SmartLastClient;
233 static int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1];
235 #ifdef SMART_DEBUG
236 long SmartLastPrint;
237 #endif
239 void Dispatch(void);
241 static int
242 SmartScheduleClient(int *clientReady, int nready)
244 ClientPtr pClient;
245 int i;
246 int client;
247 int bestPrio, best = 0;
248 int bestRobin, robin;
249 long now = SmartScheduleTime;
250 long idle;
252 bestPrio = -0x7fffffff;
253 bestRobin = 0;
254 idle = 2 * SmartScheduleSlice;
255 for (i = 0; i < nready; i++) {
256 client = clientReady[i];
257 pClient = clients[client];
258 /* Praise clients which are idle */
259 if ((now - pClient->smart_check_tick) >= idle) {
260 if (pClient->smart_priority < 0)
261 pClient->smart_priority++;
263 pClient->smart_check_tick = now;
265 /* check priority to select best client */
266 robin =
267 (pClient->index -
268 SmartLastIndex[pClient->smart_priority -
269 SMART_MIN_PRIORITY]) & 0xff;
270 if (pClient->smart_priority > bestPrio ||
271 (pClient->smart_priority == bestPrio && robin > bestRobin)) {
272 bestPrio = pClient->smart_priority;
273 bestRobin = robin;
274 best = client;
276 #ifdef SMART_DEBUG
277 if ((now - SmartLastPrint) >= 5000)
278 fprintf(stderr, " %2d: %3d", client, pClient->smart_priority);
279 #endif
281 #ifdef SMART_DEBUG
282 if ((now - SmartLastPrint) >= 5000) {
283 fprintf(stderr, " use %2d\n", best);
284 SmartLastPrint = now;
286 #endif
287 pClient = clients[best];
288 SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index;
290 * Set current client pointer
292 if (SmartLastClient != pClient) {
293 pClient->smart_start_tick = now;
294 SmartLastClient = pClient;
297 * Adjust slice
299 if (nready == 1 && SmartScheduleLatencyLimited == 0) {
301 * If it's been a long time since another client
302 * has run, bump the slice up to get maximal
303 * performance from a single client
305 if ((now - pClient->smart_start_tick) > 1000 &&
306 SmartScheduleSlice < SmartScheduleMaxSlice) {
307 SmartScheduleSlice += SmartScheduleInterval;
310 else {
311 SmartScheduleSlice = SmartScheduleInterval;
313 return best;
316 void
317 EnableLimitedSchedulingLatency(void)
319 ++SmartScheduleLatencyLimited;
320 SmartScheduleSlice = SmartScheduleInterval;
323 void
324 DisableLimitedSchedulingLatency(void)
326 --SmartScheduleLatencyLimited;
328 /* protect against bugs */
329 if (SmartScheduleLatencyLimited < 0)
330 SmartScheduleLatencyLimited = 0;
333 void
334 Dispatch(void)
336 int *clientReady; /* array of request ready clients */
337 int result;
338 ClientPtr client;
339 int nready;
340 HWEventQueuePtr *icheck = checkForInput;
341 long start_tick;
343 nextFreeClientID = 1;
344 nClients = 0;
346 clientReady = malloc(sizeof(int) * MaxClients);
347 if (!clientReady)
348 return;
350 SmartScheduleSlice = SmartScheduleInterval;
351 while (!dispatchException) {
352 if (*icheck[0] != *icheck[1]) {
353 ProcessInputEvents();
354 FlushIfCriticalOutputPending();
357 nready = WaitForSomething(clientReady);
359 if (nready && !SmartScheduleDisable) {
360 clientReady[0] = SmartScheduleClient(clientReady, nready);
361 nready = 1;
363 /*****************
364 * Handle events in round robin fashion, doing input between
365 * each round
366 *****************/
368 while (!dispatchException && (--nready >= 0)) {
369 client = clients[clientReady[nready]];
370 if (!client) {
371 /* KillClient can cause this to happen */
372 continue;
374 /* GrabServer activation can cause this to be true */
375 if (grabState == GrabKickout) {
376 grabState = GrabActive;
377 break;
379 isItTimeToYield = FALSE;
381 start_tick = SmartScheduleTime;
382 while (!isItTimeToYield) {
383 if (*icheck[0] != *icheck[1])
384 ProcessInputEvents();
386 FlushIfCriticalOutputPending();
387 if (!SmartScheduleDisable &&
388 (SmartScheduleTime - start_tick) >= SmartScheduleSlice) {
389 /* Penalize clients which consume ticks */
390 if (client->smart_priority > SMART_MIN_PRIORITY)
391 client->smart_priority--;
392 break;
394 /* now, finally, deal with client requests */
396 /* Update currentTime so request time checks, such as for input
397 * device grabs, are calculated correctly */
398 UpdateCurrentTimeIf();
399 result = ReadRequestFromClient(client);
400 if (result <= 0) {
401 if (result < 0)
402 CloseDownClient(client);
403 break;
406 client->sequence++;
407 client->majorOp = ((xReq *) client->requestBuffer)->reqType;
408 client->minorOp = 0;
409 if (client->majorOp >= EXTENSION_BASE) {
410 ExtensionEntry *ext = GetExtensionEntry(client->majorOp);
412 if (ext)
413 client->minorOp = ext->MinorOpcode(client);
415 #ifdef XSERVER_DTRACE
416 if (XSERVER_REQUEST_START_ENABLED())
417 XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
418 client->majorOp,
419 ((xReq *) client->requestBuffer)->length,
420 client->index,
421 client->requestBuffer);
422 #endif
423 if (result > (maxBigRequestSize << 2))
424 result = BadLength;
425 else {
426 result = XaceHookDispatch(client, client->majorOp);
427 if (result == Success)
428 result =
429 (*client->requestVector[client->majorOp]) (client);
430 XaceHookAuditEnd(client, result);
432 #ifdef XSERVER_DTRACE
433 if (XSERVER_REQUEST_DONE_ENABLED())
434 XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
435 client->majorOp, client->sequence,
436 client->index, result);
437 #endif
439 if (client->noClientException != Success) {
440 CloseDownClient(client);
441 break;
443 else if (result != Success) {
444 SendErrorToClient(client, client->majorOp,
445 client->minorOp,
446 client->errorValue, result);
447 break;
450 FlushAllOutput();
451 client = clients[clientReady[nready]];
452 if (client)
453 client->smart_stop_tick = SmartScheduleTime;
455 dispatchException &= ~DE_PRIORITYCHANGE;
457 #if defined(DDXBEFORERESET)
458 ddxBeforeReset();
459 #endif
460 KillAllClients();
461 free(clientReady);
462 dispatchException &= ~DE_RESET;
463 SmartScheduleLatencyLimited = 0;
466 static int VendorRelease = VENDOR_RELEASE;
467 static char *VendorString = VENDOR_NAME;
469 static const int padlength[4] = { 0, 3, 2, 1 };
471 void
472 SetVendorRelease(int release)
474 VendorRelease = release;
477 void
478 SetVendorString(char *string)
480 VendorString = string;
483 Bool
484 CreateConnectionBlock(void)
486 xConnSetup setup;
487 xWindowRoot root;
488 xDepth depth;
489 xVisualType visual;
490 xPixmapFormat format;
491 unsigned long vid;
492 int i, j, k, lenofblock, sizesofar = 0;
493 char *pBuf;
495 memset(&setup, 0, sizeof(xConnSetup));
496 /* Leave off the ridBase and ridMask, these must be sent with
497 connection */
499 setup.release = VendorRelease;
501 * per-server image and bitmap parameters are defined in Xmd.h
503 setup.imageByteOrder = screenInfo.imageByteOrder;
505 setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
506 setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
508 setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
509 setup.motionBufferSize = NumMotionEvents();
510 setup.numRoots = screenInfo.numScreens;
511 setup.nbytesVendor = strlen(VendorString);
512 setup.numFormats = screenInfo.numPixmapFormats;
513 setup.maxRequestSize = MAX_REQUEST_SIZE;
514 QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
516 lenofblock = sizeof(xConnSetup) +
517 pad_to_int32(setup.nbytesVendor) +
518 (setup.numFormats * sizeof(xPixmapFormat)) +
519 (setup.numRoots * sizeof(xWindowRoot));
520 ConnectionInfo = malloc(lenofblock);
521 if (!ConnectionInfo)
522 return FALSE;
524 memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup));
525 sizesofar = sizeof(xConnSetup);
526 pBuf = ConnectionInfo + sizeof(xConnSetup);
528 memmove(pBuf, VendorString, (int) setup.nbytesVendor);
529 sizesofar += setup.nbytesVendor;
530 pBuf += setup.nbytesVendor;
531 i = padlength[setup.nbytesVendor & 3];
532 sizesofar += i;
533 while (--i >= 0)
534 *pBuf++ = 0;
536 memset(&format, 0, sizeof(xPixmapFormat));
537 for (i = 0; i < screenInfo.numPixmapFormats; i++) {
538 format.depth = screenInfo.formats[i].depth;
539 format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
540 format.scanLinePad = screenInfo.formats[i].scanlinePad;
541 memmove(pBuf, (char *) &format, sizeof(xPixmapFormat));
542 pBuf += sizeof(xPixmapFormat);
543 sizesofar += sizeof(xPixmapFormat);
546 connBlockScreenStart = sizesofar;
547 memset(&depth, 0, sizeof(xDepth));
548 memset(&visual, 0, sizeof(xVisualType));
549 for (i = 0; i < screenInfo.numScreens; i++) {
550 ScreenPtr pScreen;
551 DepthPtr pDepth;
552 VisualPtr pVisual;
554 pScreen = screenInfo.screens[i];
555 root.windowId = pScreen->root->drawable.id;
556 root.defaultColormap = pScreen->defColormap;
557 root.whitePixel = pScreen->whitePixel;
558 root.blackPixel = pScreen->blackPixel;
559 root.currentInputMask = 0; /* filled in when sent */
560 root.pixWidth = pScreen->width;
561 root.pixHeight = pScreen->height;
562 root.mmWidth = pScreen->mmWidth;
563 root.mmHeight = pScreen->mmHeight;
564 root.minInstalledMaps = pScreen->minInstalledCmaps;
565 root.maxInstalledMaps = pScreen->maxInstalledCmaps;
566 root.rootVisualID = pScreen->rootVisual;
567 root.backingStore = pScreen->backingStoreSupport;
568 root.saveUnders = FALSE;
569 root.rootDepth = pScreen->rootDepth;
570 root.nDepths = pScreen->numDepths;
571 memmove(pBuf, (char *) &root, sizeof(xWindowRoot));
572 sizesofar += sizeof(xWindowRoot);
573 pBuf += sizeof(xWindowRoot);
575 pDepth = pScreen->allowedDepths;
576 for (j = 0; j < pScreen->numDepths; j++, pDepth++) {
577 lenofblock += sizeof(xDepth) +
578 (pDepth->numVids * sizeof(xVisualType));
579 pBuf = (char *) realloc(ConnectionInfo, lenofblock);
580 if (!pBuf) {
581 free(ConnectionInfo);
582 return FALSE;
584 ConnectionInfo = pBuf;
585 pBuf += sizesofar;
586 depth.depth = pDepth->depth;
587 depth.nVisuals = pDepth->numVids;
588 memmove(pBuf, (char *) &depth, sizeof(xDepth));
589 pBuf += sizeof(xDepth);
590 sizesofar += sizeof(xDepth);
591 for (k = 0; k < pDepth->numVids; k++) {
592 vid = pDepth->vids[k];
593 for (pVisual = pScreen->visuals;
594 pVisual->vid != vid; pVisual++);
595 visual.visualID = vid;
596 visual.class = pVisual->class;
597 visual.bitsPerRGB = pVisual->bitsPerRGBValue;
598 visual.colormapEntries = pVisual->ColormapEntries;
599 visual.redMask = pVisual->redMask;
600 visual.greenMask = pVisual->greenMask;
601 visual.blueMask = pVisual->blueMask;
602 memmove(pBuf, (char *) &visual, sizeof(xVisualType));
603 pBuf += sizeof(xVisualType);
604 sizesofar += sizeof(xVisualType);
608 connSetupPrefix.success = xTrue;
609 connSetupPrefix.length = lenofblock / 4;
610 connSetupPrefix.majorVersion = X_PROTOCOL;
611 connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
612 return TRUE;
616 ProcBadRequest(ClientPtr client)
618 return BadRequest;
622 ProcCreateWindow(ClientPtr client)
624 WindowPtr pParent, pWin;
626 REQUEST(xCreateWindowReq);
627 int len, rc;
629 REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
631 LEGAL_NEW_RESOURCE(stuff->wid, client);
632 rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
633 if (rc != Success)
634 return rc;
635 len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
636 if (Ones(stuff->mask) != len)
637 return BadLength;
638 if (!stuff->width || !stuff->height) {
639 client->errorValue = 0;
640 return BadValue;
642 pWin = CreateWindow(stuff->wid, pParent, stuff->x,
643 stuff->y, stuff->width, stuff->height,
644 stuff->borderWidth, stuff->class,
645 stuff->mask, (XID *) &stuff[1],
646 (int) stuff->depth, client, stuff->visual, &rc);
647 if (pWin) {
648 Mask mask = pWin->eventMask;
650 pWin->eventMask = 0; /* subterfuge in case AddResource fails */
651 if (!AddResource(stuff->wid, RT_WINDOW, (pointer) pWin))
652 return BadAlloc;
653 pWin->eventMask = mask;
655 return rc;
659 ProcChangeWindowAttributes(ClientPtr client)
661 WindowPtr pWin;
663 REQUEST(xChangeWindowAttributesReq);
664 int len, rc;
665 Mask access_mode = 0;
667 REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
668 access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
669 access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
670 rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
671 if (rc != Success)
672 return rc;
673 len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
674 if (len != Ones(stuff->valueMask))
675 return BadLength;
676 return ChangeWindowAttributes(pWin,
677 stuff->valueMask, (XID *) &stuff[1], client);
681 ProcGetWindowAttributes(ClientPtr client)
683 WindowPtr pWin;
685 REQUEST(xResourceReq);
686 xGetWindowAttributesReply wa;
687 int rc;
689 REQUEST_SIZE_MATCH(xResourceReq);
690 rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
691 if (rc != Success)
692 return rc;
693 memset(&wa, 0, sizeof(xGetWindowAttributesReply));
694 GetWindowAttributes(pWin, client, &wa);
695 WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
696 return Success;
700 ProcDestroyWindow(ClientPtr client)
702 WindowPtr pWin;
704 REQUEST(xResourceReq);
705 int rc;
707 REQUEST_SIZE_MATCH(xResourceReq);
708 rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
709 if (rc != Success)
710 return rc;
711 if (pWin->parent) {
712 rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
713 DixRemoveAccess);
714 if (rc != Success)
715 return rc;
716 FreeResource(stuff->id, RT_NONE);
718 return Success;
722 ProcDestroySubwindows(ClientPtr client)
724 WindowPtr pWin;
726 REQUEST(xResourceReq);
727 int rc;
729 REQUEST_SIZE_MATCH(xResourceReq);
730 rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
731 if (rc != Success)
732 return rc;
733 DestroySubwindows(pWin, client);
734 return Success;
738 ProcChangeSaveSet(ClientPtr client)
740 WindowPtr pWin;
742 REQUEST(xChangeSaveSetReq);
743 int rc;
745 REQUEST_SIZE_MATCH(xChangeSaveSetReq);
746 rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
747 if (rc != Success)
748 return rc;
749 if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
750 return BadMatch;
751 if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
752 return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
753 client->errorValue = stuff->mode;
754 return BadValue;
758 ProcReparentWindow(ClientPtr client)
760 WindowPtr pWin, pParent;
762 REQUEST(xReparentWindowReq);
763 int rc;
765 REQUEST_SIZE_MATCH(xReparentWindowReq);
766 rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
767 if (rc != Success)
768 return rc;
769 rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
770 if (rc != Success)
771 return rc;
772 if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
773 return BadMatch;
774 if ((pWin->backgroundState == ParentRelative) &&
775 (pParent->drawable.depth != pWin->drawable.depth))
776 return BadMatch;
777 if ((pWin->drawable.class != InputOnly) &&
778 (pParent->drawable.class == InputOnly))
779 return BadMatch;
780 return ReparentWindow(pWin, pParent,
781 (short) stuff->x, (short) stuff->y, client);
785 ProcMapWindow(ClientPtr client)
787 WindowPtr pWin;
789 REQUEST(xResourceReq);
790 int rc;
792 REQUEST_SIZE_MATCH(xResourceReq);
793 rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
794 if (rc != Success)
795 return rc;
796 MapWindow(pWin, client);
797 /* update cache to say it is mapped */
798 return Success;
802 ProcMapSubwindows(ClientPtr client)
804 WindowPtr pWin;
806 REQUEST(xResourceReq);
807 int rc;
809 REQUEST_SIZE_MATCH(xResourceReq);
810 rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
811 if (rc != Success)
812 return rc;
813 MapSubwindows(pWin, client);
814 /* update cache to say it is mapped */
815 return Success;
819 ProcUnmapWindow(ClientPtr client)
821 WindowPtr pWin;
823 REQUEST(xResourceReq);
824 int rc;
826 REQUEST_SIZE_MATCH(xResourceReq);
827 rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
828 if (rc != Success)
829 return rc;
830 UnmapWindow(pWin, FALSE);
831 /* update cache to say it is mapped */
832 return Success;
836 ProcUnmapSubwindows(ClientPtr client)
838 WindowPtr pWin;
840 REQUEST(xResourceReq);
841 int rc;
843 REQUEST_SIZE_MATCH(xResourceReq);
844 rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
845 if (rc != Success)
846 return rc;
847 UnmapSubwindows(pWin);
848 return Success;
852 ProcConfigureWindow(ClientPtr client)
854 WindowPtr pWin;
856 REQUEST(xConfigureWindowReq);
857 int len, rc;
859 REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
860 rc = dixLookupWindow(&pWin, stuff->window, client,
861 DixManageAccess | DixSetAttrAccess);
862 if (rc != Success)
863 return rc;
864 len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
865 if (Ones((Mask) stuff->mask) != len)
866 return BadLength;
867 return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client);
871 ProcCirculateWindow(ClientPtr client)
873 WindowPtr pWin;
875 REQUEST(xCirculateWindowReq);
876 int rc;
878 REQUEST_SIZE_MATCH(xCirculateWindowReq);
879 if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) {
880 client->errorValue = stuff->direction;
881 return BadValue;
883 rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
884 if (rc != Success)
885 return rc;
886 CirculateWindow(pWin, (int) stuff->direction, client);
887 return Success;
890 static int
891 GetGeometry(ClientPtr client, xGetGeometryReply * rep)
893 DrawablePtr pDraw;
894 int rc;
896 REQUEST(xResourceReq);
897 REQUEST_SIZE_MATCH(xResourceReq);
899 rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
900 if (rc != Success)
901 return rc;
903 rep->type = X_Reply;
904 rep->length = 0;
905 rep->sequenceNumber = client->sequence;
906 rep->root = pDraw->pScreen->root->drawable.id;
907 rep->depth = pDraw->depth;
908 rep->width = pDraw->width;
909 rep->height = pDraw->height;
911 if (WindowDrawable(pDraw->type)) {
912 WindowPtr pWin = (WindowPtr) pDraw;
914 rep->x = pWin->origin.x - wBorderWidth(pWin);
915 rep->y = pWin->origin.y - wBorderWidth(pWin);
916 rep->borderWidth = pWin->borderWidth;
918 else { /* DRAWABLE_PIXMAP */
920 rep->x = rep->y = rep->borderWidth = 0;
923 return Success;
927 ProcGetGeometry(ClientPtr client)
929 xGetGeometryReply rep;
930 int status;
932 memset(&rep, 0, sizeof(xGetGeometryReply));
933 if ((status = GetGeometry(client, &rep)) != Success)
934 return status;
936 WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
937 return Success;
941 ProcQueryTree(ClientPtr client)
943 xQueryTreeReply reply;
944 int rc, numChildren = 0;
945 WindowPtr pChild, pWin, pHead;
946 Window *childIDs = (Window *) NULL;
948 REQUEST(xResourceReq);
950 REQUEST_SIZE_MATCH(xResourceReq);
951 rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
952 if (rc != Success)
953 return rc;
954 memset(&reply, 0, sizeof(xQueryTreeReply));
955 reply.type = X_Reply;
956 reply.root = pWin->drawable.pScreen->root->drawable.id;
957 reply.sequenceNumber = client->sequence;
958 if (pWin->parent)
959 reply.parent = pWin->parent->drawable.id;
960 else
961 reply.parent = (Window) None;
962 pHead = RealChildHead(pWin);
963 for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
964 numChildren++;
965 if (numChildren) {
966 int curChild = 0;
968 childIDs = malloc(numChildren * sizeof(Window));
969 if (!childIDs)
970 return BadAlloc;
971 for (pChild = pWin->lastChild; pChild != pHead;
972 pChild = pChild->prevSib)
973 childIDs[curChild++] = pChild->drawable.id;
976 reply.nChildren = numChildren;
977 reply.length = bytes_to_int32(numChildren * sizeof(Window));
979 WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
980 if (numChildren) {
981 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
982 WriteSwappedDataToClient(client, numChildren * sizeof(Window),
983 childIDs);
984 free(childIDs);
987 return Success;
991 ProcInternAtom(ClientPtr client)
993 Atom atom;
994 char *tchar;
996 REQUEST(xInternAtomReq);
998 REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
999 if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) {
1000 client->errorValue = stuff->onlyIfExists;
1001 return BadValue;
1003 tchar = (char *) &stuff[1];
1004 atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
1005 if (atom != BAD_RESOURCE) {
1006 xInternAtomReply reply;
1008 memset(&reply, 0, sizeof(xInternAtomReply));
1009 reply.type = X_Reply;
1010 reply.length = 0;
1011 reply.sequenceNumber = client->sequence;
1012 reply.atom = atom;
1013 WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
1014 return Success;
1016 else
1017 return BadAlloc;
1021 ProcGetAtomName(ClientPtr client)
1023 const char *str;
1024 xGetAtomNameReply reply;
1025 int len;
1027 REQUEST(xResourceReq);
1029 REQUEST_SIZE_MATCH(xResourceReq);
1030 if ((str = NameForAtom(stuff->id))) {
1031 len = strlen(str);
1032 memset(&reply, 0, sizeof(xGetAtomNameReply));
1033 reply.type = X_Reply;
1034 reply.length = bytes_to_int32(len);
1035 reply.sequenceNumber = client->sequence;
1036 reply.nameLength = len;
1037 WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
1038 (void) WriteToClient(client, len, str);
1039 return Success;
1041 else {
1042 client->errorValue = stuff->id;
1043 return BadAtom;
1048 ProcGrabServer(ClientPtr client)
1050 int rc;
1052 REQUEST_SIZE_MATCH(xReq);
1053 if (grabState != GrabNone && client != grabClient) {
1054 ResetCurrentRequest(client);
1055 client->sequence--;
1056 BITSET(grabWaiters, client->index);
1057 IgnoreClient(client);
1058 return Success;
1060 rc = OnlyListenToOneClient(client);
1061 if (rc != Success)
1062 return rc;
1063 grabState = GrabKickout;
1064 grabClient = client;
1066 if (ServerGrabCallback) {
1067 ServerGrabInfoRec grabinfo;
1069 grabinfo.client = client;
1070 grabinfo.grabstate = SERVER_GRABBED;
1071 CallCallbacks(&ServerGrabCallback, (pointer) &grabinfo);
1074 return Success;
1077 static void
1078 UngrabServer(ClientPtr client)
1080 int i;
1082 grabState = GrabNone;
1083 ListenToAllClients();
1084 for (i = mskcnt; --i >= 0 && !grabWaiters[i];);
1085 if (i >= 0) {
1086 i <<= 5;
1087 while (!GETBIT(grabWaiters, i))
1088 i++;
1089 BITCLEAR(grabWaiters, i);
1090 AttendClient(clients[i]);
1093 if (ServerGrabCallback) {
1094 ServerGrabInfoRec grabinfo;
1096 grabinfo.client = client;
1097 grabinfo.grabstate = SERVER_UNGRABBED;
1098 CallCallbacks(&ServerGrabCallback, (pointer) &grabinfo);
1103 ProcUngrabServer(ClientPtr client)
1105 REQUEST_SIZE_MATCH(xReq);
1106 UngrabServer(client);
1107 return Success;
1111 ProcTranslateCoords(ClientPtr client)
1113 REQUEST(xTranslateCoordsReq);
1115 WindowPtr pWin, pDst;
1116 xTranslateCoordsReply rep;
1117 int rc;
1119 REQUEST_SIZE_MATCH(xTranslateCoordsReq);
1120 rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
1121 if (rc != Success)
1122 return rc;
1123 rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
1124 if (rc != Success)
1125 return rc;
1126 memset(&rep, 0, sizeof(xTranslateCoordsReply));
1127 rep.type = X_Reply;
1128 rep.length = 0;
1129 rep.sequenceNumber = client->sequence;
1130 if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) {
1131 rep.sameScreen = xFalse;
1132 rep.child = None;
1133 rep.dstX = rep.dstY = 0;
1135 else {
1136 INT16 x, y;
1138 rep.sameScreen = xTrue;
1139 rep.child = None;
1140 /* computing absolute coordinates -- adjust to destination later */
1141 x = pWin->drawable.x + stuff->srcX;
1142 y = pWin->drawable.y + stuff->srcY;
1143 pWin = pDst->firstChild;
1144 while (pWin) {
1145 BoxRec box;
1147 if ((pWin->mapped) &&
1148 (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
1149 (x < pWin->drawable.x + (int) pWin->drawable.width +
1150 wBorderWidth(pWin)) &&
1151 (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
1152 (y < pWin->drawable.y + (int) pWin->drawable.height +
1153 wBorderWidth(pWin))
1154 /* When a window is shaped, a further check
1155 * is made to see if the point is inside
1156 * borderSize
1158 && (!wBoundingShape(pWin) ||
1159 RegionContainsPoint(&pWin->borderSize, x, y, &box))
1161 && (!wInputShape(pWin) ||
1162 RegionContainsPoint(wInputShape(pWin),
1163 x - pWin->drawable.x,
1164 y - pWin->drawable.y, &box))
1166 rep.child = pWin->drawable.id;
1167 pWin = (WindowPtr) NULL;
1169 else
1170 pWin = pWin->nextSib;
1172 /* adjust to destination coordinates */
1173 rep.dstX = x - pDst->drawable.x;
1174 rep.dstY = y - pDst->drawable.y;
1176 WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
1177 return Success;
1181 ProcOpenFont(ClientPtr client)
1183 int err;
1185 REQUEST(xOpenFontReq);
1187 REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
1188 client->errorValue = stuff->fid;
1189 LEGAL_NEW_RESOURCE(stuff->fid, client);
1190 err = OpenFont(client, stuff->fid, (Mask) 0,
1191 stuff->nbytes, (char *) &stuff[1]);
1192 if (err == Success) {
1193 return Success;
1195 else
1196 return err;
1200 ProcCloseFont(ClientPtr client)
1202 FontPtr pFont;
1203 int rc;
1205 REQUEST(xResourceReq);
1207 REQUEST_SIZE_MATCH(xResourceReq);
1208 rc = dixLookupResourceByType((pointer *) &pFont, stuff->id, RT_FONT,
1209 client, DixDestroyAccess);
1210 if (rc == Success) {
1211 FreeResource(stuff->id, RT_NONE);
1212 return Success;
1214 else {
1215 client->errorValue = stuff->id;
1216 return rc;
1221 ProcQueryFont(ClientPtr client)
1223 xQueryFontReply *reply;
1224 FontPtr pFont;
1225 int rc;
1227 REQUEST(xResourceReq);
1228 REQUEST_SIZE_MATCH(xResourceReq);
1230 rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
1231 if (rc != Success)
1232 return rc;
1235 xCharInfo *pmax = FONTINKMAX(pFont);
1236 xCharInfo *pmin = FONTINKMIN(pFont);
1237 int nprotoxcistructs;
1238 int rlength;
1240 nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing &&
1241 pmax->leftSideBearing == pmin->leftSideBearing &&
1242 pmax->descent == pmin->descent &&
1243 pmax->ascent == pmin->ascent &&
1244 pmax->characterWidth == pmin->characterWidth) ?
1245 0 : N2dChars(pFont);
1247 rlength = sizeof(xQueryFontReply) +
1248 FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
1249 nprotoxcistructs * sizeof(xCharInfo);
1250 reply = calloc(1, rlength);
1251 if (!reply) {
1252 return BadAlloc;
1255 reply->type = X_Reply;
1256 reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
1257 reply->sequenceNumber = client->sequence;
1258 QueryFont(pFont, reply, nprotoxcistructs);
1260 WriteReplyToClient(client, rlength, reply);
1261 free(reply);
1262 return Success;
1267 ProcQueryTextExtents(ClientPtr client)
1269 xQueryTextExtentsReply reply;
1270 FontPtr pFont;
1271 ExtentInfoRec info;
1272 unsigned long length;
1273 int rc;
1275 REQUEST(xQueryTextExtentsReq);
1276 REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
1278 rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
1279 if (rc != Success)
1280 return rc;
1282 length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
1283 length = length << 1;
1284 if (stuff->oddLength) {
1285 if (length == 0)
1286 return BadLength;
1287 length--;
1289 if (!QueryTextExtents(pFont, length, (unsigned char *) &stuff[1], &info))
1290 return BadAlloc;
1291 reply.type = X_Reply;
1292 reply.length = 0;
1293 reply.sequenceNumber = client->sequence;
1294 reply.drawDirection = info.drawDirection;
1295 reply.fontAscent = info.fontAscent;
1296 reply.fontDescent = info.fontDescent;
1297 reply.overallAscent = info.overallAscent;
1298 reply.overallDescent = info.overallDescent;
1299 reply.overallWidth = info.overallWidth;
1300 reply.overallLeft = info.overallLeft;
1301 reply.overallRight = info.overallRight;
1302 WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
1303 return Success;
1307 ProcListFonts(ClientPtr client)
1309 REQUEST(xListFontsReq);
1311 REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
1313 return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
1314 stuff->maxNames);
1318 ProcListFontsWithInfo(ClientPtr client)
1320 REQUEST(xListFontsWithInfoReq);
1322 REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
1324 return StartListFontsWithInfo(client, stuff->nbytes,
1325 (unsigned char *) &stuff[1], stuff->maxNames);
1330 * \param value must conform to DeleteType
1333 dixDestroyPixmap(pointer value, XID pid)
1335 PixmapPtr pPixmap = (PixmapPtr) value;
1337 return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
1341 ProcCreatePixmap(ClientPtr client)
1343 PixmapPtr pMap;
1344 DrawablePtr pDraw;
1346 REQUEST(xCreatePixmapReq);
1347 DepthPtr pDepth;
1348 int i, rc;
1350 REQUEST_SIZE_MATCH(xCreatePixmapReq);
1351 client->errorValue = stuff->pid;
1352 LEGAL_NEW_RESOURCE(stuff->pid, client);
1354 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
1355 DixGetAttrAccess);
1356 if (rc != Success)
1357 return rc;
1359 if (!stuff->width || !stuff->height) {
1360 client->errorValue = 0;
1361 return BadValue;
1363 if (stuff->width > 32767 || stuff->height > 32767) {
1364 /* It is allowed to try and allocate a pixmap which is larger than
1365 * 32767 in either dimension. However, all of the framebuffer code
1366 * is buggy and does not reliably draw to such big pixmaps, basically
1367 * because the Region data structure operates with signed shorts
1368 * for the rectangles in it.
1370 * Furthermore, several places in the X server computes the
1371 * size in bytes of the pixmap and tries to store it in an
1372 * integer. This integer can overflow and cause the allocated size
1373 * to be much smaller.
1375 * So, such big pixmaps are rejected here with a BadAlloc
1377 return BadAlloc;
1379 if (stuff->depth != 1) {
1380 pDepth = pDraw->pScreen->allowedDepths;
1381 for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
1382 if (pDepth->depth == stuff->depth)
1383 goto CreatePmap;
1384 client->errorValue = stuff->depth;
1385 return BadValue;
1387 CreatePmap:
1388 pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap)
1389 (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0);
1390 if (pMap) {
1391 pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
1392 pMap->drawable.id = stuff->pid;
1393 /* security creation/labeling check */
1394 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
1395 pMap, RT_NONE, NULL, DixCreateAccess);
1396 if (rc != Success) {
1397 (*pDraw->pScreen->DestroyPixmap) (pMap);
1398 return rc;
1400 if (AddResource(stuff->pid, RT_PIXMAP, (pointer) pMap))
1401 return Success;
1403 return BadAlloc;
1407 ProcFreePixmap(ClientPtr client)
1409 PixmapPtr pMap;
1410 int rc;
1412 REQUEST(xResourceReq);
1413 REQUEST_SIZE_MATCH(xResourceReq);
1415 rc = dixLookupResourceByType((pointer *) &pMap, stuff->id, RT_PIXMAP,
1416 client, DixDestroyAccess);
1417 if (rc == Success) {
1418 FreeResource(stuff->id, RT_NONE);
1419 return Success;
1421 else {
1422 client->errorValue = stuff->id;
1423 return rc;
1428 ProcCreateGC(ClientPtr client)
1430 int error, rc;
1431 GC *pGC;
1432 DrawablePtr pDraw;
1433 unsigned len;
1435 REQUEST(xCreateGCReq);
1437 REQUEST_AT_LEAST_SIZE(xCreateGCReq);
1438 client->errorValue = stuff->gc;
1439 LEGAL_NEW_RESOURCE(stuff->gc, client);
1440 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
1441 DixGetAttrAccess);
1442 if (rc != Success)
1443 return rc;
1445 len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
1446 if (len != Ones(stuff->mask))
1447 return BadLength;
1448 pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
1449 stuff->gc, client);
1450 if (error != Success)
1451 return error;
1452 if (!AddResource(stuff->gc, RT_GC, (pointer) pGC))
1453 return BadAlloc;
1454 return Success;
1458 ProcChangeGC(ClientPtr client)
1460 GC *pGC;
1461 int result;
1462 unsigned len;
1464 REQUEST(xChangeGCReq);
1465 REQUEST_AT_LEAST_SIZE(xChangeGCReq);
1467 result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1468 if (result != Success)
1469 return result;
1471 len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
1472 if (len != Ones(stuff->mask))
1473 return BadLength;
1475 return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
1479 ProcCopyGC(ClientPtr client)
1481 GC *dstGC;
1482 GC *pGC;
1483 int result;
1485 REQUEST(xCopyGCReq);
1486 REQUEST_SIZE_MATCH(xCopyGCReq);
1488 result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
1489 if (result != Success)
1490 return result;
1491 result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
1492 if (result != Success)
1493 return result;
1494 if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
1495 return BadMatch;
1496 if (stuff->mask & ~GCAllBits) {
1497 client->errorValue = stuff->mask;
1498 return BadValue;
1500 return CopyGC(pGC, dstGC, stuff->mask);
1504 ProcSetDashes(ClientPtr client)
1506 GC *pGC;
1507 int result;
1509 REQUEST(xSetDashesReq);
1511 REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
1512 if (stuff->nDashes == 0) {
1513 client->errorValue = 0;
1514 return BadValue;
1517 result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1518 if (result != Success)
1519 return result;
1521 /* If there's an error, either there's no sensible errorValue,
1522 * or there was a dash segment of 0. */
1523 client->errorValue = 0;
1524 return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
1525 (unsigned char *) &stuff[1]);
1529 ProcSetClipRectangles(ClientPtr client)
1531 int nr, result;
1532 GC *pGC;
1534 REQUEST(xSetClipRectanglesReq);
1536 REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
1537 if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
1538 (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) {
1539 client->errorValue = stuff->ordering;
1540 return BadValue;
1542 result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1543 if (result != Success)
1544 return result;
1546 nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
1547 if (nr & 4)
1548 return BadLength;
1549 nr >>= 3;
1550 return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
1551 nr, (xRectangle *) &stuff[1], (int) stuff->ordering);
1555 ProcFreeGC(ClientPtr client)
1557 GC *pGC;
1558 int rc;
1560 REQUEST(xResourceReq);
1561 REQUEST_SIZE_MATCH(xResourceReq);
1563 rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
1564 if (rc != Success)
1565 return rc;
1567 FreeResource(stuff->id, RT_NONE);
1568 return Success;
1572 ProcClearToBackground(ClientPtr client)
1574 REQUEST(xClearAreaReq);
1575 WindowPtr pWin;
1576 int rc;
1578 REQUEST_SIZE_MATCH(xClearAreaReq);
1579 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
1580 if (rc != Success)
1581 return rc;
1582 if (pWin->drawable.class == InputOnly) {
1583 client->errorValue = stuff->window;
1584 return BadMatch;
1586 if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) {
1587 client->errorValue = stuff->exposures;
1588 return BadValue;
1590 (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y,
1591 stuff->width, stuff->height,
1592 (Bool) stuff->exposures);
1593 return Success;
1597 ProcCopyArea(ClientPtr client)
1599 DrawablePtr pDst;
1600 DrawablePtr pSrc;
1601 GC *pGC;
1603 REQUEST(xCopyAreaReq);
1604 RegionPtr pRgn;
1605 int rc;
1607 REQUEST_SIZE_MATCH(xCopyAreaReq);
1609 VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
1610 if (stuff->dstDrawable != stuff->srcDrawable) {
1611 rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
1612 DixReadAccess);
1613 if (rc != Success)
1614 return rc;
1615 if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) {
1616 client->errorValue = stuff->dstDrawable;
1617 return BadMatch;
1620 else
1621 pSrc = pDst;
1623 pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
1624 stuff->width, stuff->height,
1625 stuff->dstX, stuff->dstY);
1626 if (pGC->graphicsExposures) {
1627 (*pDst->pScreen->SendGraphicsExpose)
1628 (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
1629 if (pRgn)
1630 RegionDestroy(pRgn);
1633 return Success;
1637 ProcCopyPlane(ClientPtr client)
1639 DrawablePtr psrcDraw, pdstDraw;
1640 GC *pGC;
1642 REQUEST(xCopyPlaneReq);
1643 RegionPtr pRgn;
1644 int rc;
1646 REQUEST_SIZE_MATCH(xCopyPlaneReq);
1648 VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
1649 if (stuff->dstDrawable != stuff->srcDrawable) {
1650 rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
1651 DixReadAccess);
1652 if (rc != Success)
1653 return rc;
1655 if (pdstDraw->pScreen != psrcDraw->pScreen) {
1656 client->errorValue = stuff->dstDrawable;
1657 return BadMatch;
1660 else
1661 psrcDraw = pdstDraw;
1663 /* Check to see if stuff->bitPlane has exactly ONE good bit set */
1664 if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
1665 (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
1666 client->errorValue = stuff->bitPlane;
1667 return BadValue;
1670 pRgn =
1671 (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX,
1672 stuff->srcY, stuff->width, stuff->height,
1673 stuff->dstX, stuff->dstY, stuff->bitPlane);
1674 if (pGC->graphicsExposures) {
1675 (*pdstDraw->pScreen->SendGraphicsExpose)
1676 (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
1677 if (pRgn)
1678 RegionDestroy(pRgn);
1680 return Success;
1684 ProcPolyPoint(ClientPtr client)
1686 int npoint;
1687 GC *pGC;
1688 DrawablePtr pDraw;
1690 REQUEST(xPolyPointReq);
1692 REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1693 if ((stuff->coordMode != CoordModeOrigin) &&
1694 (stuff->coordMode != CoordModePrevious)) {
1695 client->errorValue = stuff->coordMode;
1696 return BadValue;
1698 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1699 npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
1700 if (npoint)
1701 (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint,
1702 (xPoint *) &stuff[1]);
1703 return Success;
1707 ProcPolyLine(ClientPtr client)
1709 int npoint;
1710 GC *pGC;
1711 DrawablePtr pDraw;
1713 REQUEST(xPolyLineReq);
1715 REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1716 if ((stuff->coordMode != CoordModeOrigin) &&
1717 (stuff->coordMode != CoordModePrevious)) {
1718 client->errorValue = stuff->coordMode;
1719 return BadValue;
1721 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1722 npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
1723 if (npoint > 1)
1724 (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint,
1725 (DDXPointPtr) &stuff[1]);
1726 return Success;
1730 ProcPolySegment(ClientPtr client)
1732 int nsegs;
1733 GC *pGC;
1734 DrawablePtr pDraw;
1736 REQUEST(xPolySegmentReq);
1738 REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
1739 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1740 nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
1741 if (nsegs & 4)
1742 return BadLength;
1743 nsegs >>= 3;
1744 if (nsegs)
1745 (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
1746 return Success;
1750 ProcPolyRectangle(ClientPtr client)
1752 int nrects;
1753 GC *pGC;
1754 DrawablePtr pDraw;
1756 REQUEST(xPolyRectangleReq);
1758 REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
1759 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1760 nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
1761 if (nrects & 4)
1762 return BadLength;
1763 nrects >>= 3;
1764 if (nrects)
1765 (*pGC->ops->PolyRectangle) (pDraw, pGC,
1766 nrects, (xRectangle *) &stuff[1]);
1767 return Success;
1771 ProcPolyArc(ClientPtr client)
1773 int narcs;
1774 GC *pGC;
1775 DrawablePtr pDraw;
1777 REQUEST(xPolyArcReq);
1779 REQUEST_AT_LEAST_SIZE(xPolyArcReq);
1780 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1781 narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
1782 if (narcs % sizeof(xArc))
1783 return BadLength;
1784 narcs /= sizeof(xArc);
1785 if (narcs)
1786 (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
1787 return Success;
1791 ProcFillPoly(ClientPtr client)
1793 int things;
1794 GC *pGC;
1795 DrawablePtr pDraw;
1797 REQUEST(xFillPolyReq);
1799 REQUEST_AT_LEAST_SIZE(xFillPolyReq);
1800 if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
1801 (stuff->shape != Convex)) {
1802 client->errorValue = stuff->shape;
1803 return BadValue;
1805 if ((stuff->coordMode != CoordModeOrigin) &&
1806 (stuff->coordMode != CoordModePrevious)) {
1807 client->errorValue = stuff->coordMode;
1808 return BadValue;
1811 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1812 things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
1813 if (things)
1814 (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
1815 stuff->coordMode, things,
1816 (DDXPointPtr) &stuff[1]);
1817 return Success;
1821 ProcPolyFillRectangle(ClientPtr client)
1823 int things;
1824 GC *pGC;
1825 DrawablePtr pDraw;
1827 REQUEST(xPolyFillRectangleReq);
1829 REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
1830 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1831 things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
1832 if (things & 4)
1833 return BadLength;
1834 things >>= 3;
1836 if (things)
1837 (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
1838 (xRectangle *) &stuff[1]);
1839 return Success;
1843 ProcPolyFillArc(ClientPtr client)
1845 int narcs;
1846 GC *pGC;
1847 DrawablePtr pDraw;
1849 REQUEST(xPolyFillArcReq);
1851 REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
1852 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1853 narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
1854 if (narcs % sizeof(xArc))
1855 return BadLength;
1856 narcs /= sizeof(xArc);
1857 if (narcs)
1858 (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
1859 return Success;
1862 #ifdef MATCH_CLIENT_ENDIAN
1865 ServerOrder(void)
1867 int whichbyte = 1;
1869 if (*((char *) &whichbyte))
1870 return LSBFirst;
1871 return MSBFirst;
1874 #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
1876 void
1877 ReformatImage(char *base, int nbytes, int bpp, int order)
1879 switch (bpp) {
1880 case 1: /* yuck */
1881 if (BITMAP_BIT_ORDER != order)
1882 BitOrderInvert((unsigned char *) base, nbytes);
1883 #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
1884 ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order);
1885 #endif
1886 break;
1887 case 4:
1888 break; /* yuck */
1889 case 8:
1890 break;
1891 case 16:
1892 if (IMAGE_BYTE_ORDER != order)
1893 TwoByteSwap((unsigned char *) base, nbytes);
1894 break;
1895 case 32:
1896 if (IMAGE_BYTE_ORDER != order)
1897 FourByteSwap((unsigned char *) base, nbytes);
1898 break;
1901 #else
1902 #define ReformatImage(b,n,bpp,o)
1903 #endif
1905 /* 64-bit server notes: the protocol restricts padding of images to
1906 * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
1907 * to use internally. Removes need for internal alignment checking.
1908 * All of the PutImage functions could be changed individually, but
1909 * as currently written, they call other routines which require things
1910 * to be 64-bit padded on scanlines, so we changed things here.
1911 * If an image would be padded differently for 64- versus 32-, then
1912 * copy each scanline to a 64-bit padded scanline.
1913 * Also, we need to make sure that the image is aligned on a 64-bit
1914 * boundary, even if the scanlines are padded to our satisfaction.
1917 ProcPutImage(ClientPtr client)
1919 GC *pGC;
1920 DrawablePtr pDraw;
1921 long length; /* length of scanline server padded */
1922 long lengthProto; /* length of scanline protocol padded */
1923 char *tmpImage;
1925 REQUEST(xPutImageReq);
1927 REQUEST_AT_LEAST_SIZE(xPutImageReq);
1928 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1929 if (stuff->format == XYBitmap) {
1930 if ((stuff->depth != 1) ||
1931 (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
1932 return BadMatch;
1933 length = BitmapBytePad(stuff->width + stuff->leftPad);
1935 else if (stuff->format == XYPixmap) {
1936 if ((pDraw->depth != stuff->depth) ||
1937 (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
1938 return BadMatch;
1939 length = BitmapBytePad(stuff->width + stuff->leftPad);
1940 length *= stuff->depth;
1942 else if (stuff->format == ZPixmap) {
1943 if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
1944 return BadMatch;
1945 length = PixmapBytePad(stuff->width, stuff->depth);
1947 else {
1948 client->errorValue = stuff->format;
1949 return BadValue;
1952 tmpImage = (char *) &stuff[1];
1953 lengthProto = length;
1955 if ((bytes_to_int32(lengthProto * stuff->height) +
1956 bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
1957 return BadLength;
1959 ReformatImage(tmpImage, lengthProto * stuff->height,
1960 stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1,
1961 ClientOrder(client));
1963 (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
1964 stuff->width, stuff->height,
1965 stuff->leftPad, stuff->format, tmpImage);
1967 return Success;
1970 static int
1971 DoGetImage(ClientPtr client, int format, Drawable drawable,
1972 int x, int y, int width, int height,
1973 Mask planemask, xGetImageReply ** im_return)
1975 DrawablePtr pDraw, pBoundingDraw;
1976 int nlines, linesPerBuf, rc;
1977 int linesDone;
1979 /* coordinates relative to the bounding drawable */
1980 int relx, rely;
1981 long widthBytesLine, length;
1982 Mask plane = 0;
1983 char *pBuf;
1984 xGetImageReply xgi;
1985 RegionPtr pVisibleRegion = NULL;
1987 if ((format != XYPixmap) && (format != ZPixmap)) {
1988 client->errorValue = format;
1989 return BadValue;
1991 rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
1992 if (rc != Success)
1993 return rc;
1995 memset(&xgi, 0, sizeof(xGetImageReply));
1997 relx = x;
1998 rely = y;
2000 if (pDraw->type == DRAWABLE_WINDOW) {
2001 WindowPtr pWin = (WindowPtr) pDraw;
2003 /* "If the drawable is a window, the window must be viewable ... or a
2004 * BadMatch error results" */
2005 if (!pWin->viewable)
2006 return BadMatch;
2008 /* If the drawable is a window, the rectangle must be contained within
2009 * its bounds (including the border). */
2010 if (x < -wBorderWidth(pWin) ||
2011 x + width > wBorderWidth(pWin) + (int) pDraw->width ||
2012 y < -wBorderWidth(pWin) ||
2013 y + height > wBorderWidth(pWin) + (int) pDraw->height)
2014 return BadMatch;
2016 relx += pDraw->x;
2017 rely += pDraw->y;
2019 if (pDraw->pScreen->GetWindowPixmap) {
2020 PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
2022 pBoundingDraw = &pPix->drawable;
2023 #ifdef COMPOSITE
2024 relx -= pPix->screen_x;
2025 rely -= pPix->screen_y;
2026 #endif
2028 else {
2029 pBoundingDraw = (DrawablePtr) pDraw->pScreen->root;
2032 xgi.visual = wVisual(pWin);
2034 else {
2035 pBoundingDraw = pDraw;
2036 xgi.visual = None;
2039 /* "If the drawable is a pixmap, the given rectangle must be wholly
2040 * contained within the pixmap, or a BadMatch error results. If the
2041 * drawable is a window [...] it must be the case that if there were no
2042 * inferiors or overlapping windows, the specified rectangle of the window
2043 * would be fully visible on the screen and wholly contained within the
2044 * outside edges of the window, or a BadMatch error results."
2046 * We relax the window case slightly to mean that the rectangle must exist
2047 * within the bounds of the window's backing pixmap. In particular, this
2048 * means that a GetImage request may succeed or fail with BadMatch depending
2049 * on whether any of its ancestor windows are redirected. */
2050 if (relx < 0 || relx + width > (int) pBoundingDraw->width ||
2051 rely < 0 || rely + height > (int) pBoundingDraw->height)
2052 return BadMatch;
2054 xgi.type = X_Reply;
2055 xgi.sequenceNumber = client->sequence;
2056 xgi.depth = pDraw->depth;
2057 if (format == ZPixmap) {
2058 widthBytesLine = PixmapBytePad(width, pDraw->depth);
2059 length = widthBytesLine * height;
2062 else {
2063 widthBytesLine = BitmapBytePad(width);
2064 plane = ((Mask) 1) << (pDraw->depth - 1);
2065 /* only planes asked for */
2066 length = widthBytesLine * height *
2067 Ones(planemask & (plane | (plane - 1)));
2071 xgi.length = length;
2073 if (im_return) {
2074 pBuf = calloc(1, sz_xGetImageReply + length);
2075 if (!pBuf)
2076 return BadAlloc;
2077 if (widthBytesLine == 0)
2078 linesPerBuf = 0;
2079 else
2080 linesPerBuf = height;
2081 *im_return = (xGetImageReply *) pBuf;
2082 *(xGetImageReply *) pBuf = xgi;
2083 pBuf += sz_xGetImageReply;
2085 else {
2086 xgi.length = bytes_to_int32(xgi.length);
2087 if (widthBytesLine == 0 || height == 0)
2088 linesPerBuf = 0;
2089 else if (widthBytesLine >= IMAGE_BUFSIZE)
2090 linesPerBuf = 1;
2091 else {
2092 linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
2093 if (linesPerBuf > height)
2094 linesPerBuf = height;
2096 length = linesPerBuf * widthBytesLine;
2097 if (linesPerBuf < height) {
2098 /* we have to make sure intermediate buffers don't need padding */
2099 while ((linesPerBuf > 1) &&
2100 (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) {
2101 linesPerBuf--;
2102 length -= widthBytesLine;
2104 while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) {
2105 linesPerBuf++;
2106 length += widthBytesLine;
2109 if (!(pBuf = calloc(1, length)))
2110 return BadAlloc;
2111 WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
2114 if (pDraw->type == DRAWABLE_WINDOW) {
2115 pVisibleRegion = NotClippedByChildren((WindowPtr) pDraw);
2116 if (pVisibleRegion) {
2117 RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
2121 if (linesPerBuf == 0) {
2122 /* nothing to do */
2124 else if (format == ZPixmap) {
2125 linesDone = 0;
2126 while (height - linesDone > 0) {
2127 nlines = min(linesPerBuf, height - linesDone);
2128 (*pDraw->pScreen->GetImage) (pDraw,
2130 y + linesDone,
2131 width,
2132 nlines,
2133 format, planemask, (pointer) pBuf);
2134 if (pVisibleRegion)
2135 XaceCensorImage(client, pVisibleRegion, widthBytesLine,
2136 pDraw, x, y + linesDone, width,
2137 nlines, format, pBuf);
2139 /* Note that this is NOT a call to WriteSwappedDataToClient,
2140 as we do NOT byte swap */
2141 if (!im_return) {
2142 ReformatImage(pBuf, (int) (nlines * widthBytesLine),
2143 BitsPerPixel(pDraw->depth), ClientOrder(client));
2145 /* Don't split me, gcc pukes when you do */
2146 (void) WriteToClient(client,
2147 (int) (nlines * widthBytesLine), pBuf);
2149 linesDone += nlines;
2152 else { /* XYPixmap */
2154 for (; plane; plane >>= 1) {
2155 if (planemask & plane) {
2156 linesDone = 0;
2157 while (height - linesDone > 0) {
2158 nlines = min(linesPerBuf, height - linesDone);
2159 (*pDraw->pScreen->GetImage) (pDraw,
2161 y + linesDone,
2162 width,
2163 nlines,
2164 format, plane, (pointer) pBuf);
2165 if (pVisibleRegion)
2166 XaceCensorImage(client, pVisibleRegion,
2167 widthBytesLine,
2168 pDraw, x, y + linesDone, width,
2169 nlines, format, pBuf);
2171 /* Note: NOT a call to WriteSwappedDataToClient,
2172 as we do NOT byte swap */
2173 if (im_return) {
2174 pBuf += nlines * widthBytesLine;
2176 else {
2177 ReformatImage(pBuf,
2178 (int) (nlines * widthBytesLine),
2179 1, ClientOrder(client));
2181 /* Don't split me, gcc pukes when you do */
2182 (void) WriteToClient(client,
2183 (int) (nlines * widthBytesLine),
2184 pBuf);
2186 linesDone += nlines;
2191 if (pVisibleRegion)
2192 RegionDestroy(pVisibleRegion);
2193 if (!im_return)
2194 free(pBuf);
2195 return Success;
2199 ProcGetImage(ClientPtr client)
2201 REQUEST(xGetImageReq);
2203 REQUEST_SIZE_MATCH(xGetImageReq);
2205 return DoGetImage(client, stuff->format, stuff->drawable,
2206 stuff->x, stuff->y,
2207 (int) stuff->width, (int) stuff->height,
2208 stuff->planeMask, (xGetImageReply **) NULL);
2212 ProcPolyText(ClientPtr client)
2214 int err;
2216 REQUEST(xPolyTextReq);
2217 DrawablePtr pDraw;
2218 GC *pGC;
2220 REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2221 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2223 err = PolyText(client,
2224 pDraw,
2225 pGC,
2226 (unsigned char *) &stuff[1],
2227 ((unsigned char *) stuff) + (client->req_len << 2),
2228 stuff->x, stuff->y, stuff->reqType, stuff->drawable);
2230 if (err == Success) {
2231 return Success;
2233 else
2234 return err;
2238 ProcImageText8(ClientPtr client)
2240 int err;
2241 DrawablePtr pDraw;
2242 GC *pGC;
2244 REQUEST(xImageTextReq);
2246 REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2247 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2249 err = ImageText(client,
2250 pDraw,
2251 pGC,
2252 stuff->nChars,
2253 (unsigned char *) &stuff[1],
2254 stuff->x, stuff->y, stuff->reqType, stuff->drawable);
2256 if (err == Success) {
2257 return Success;
2259 else
2260 return err;
2264 ProcImageText16(ClientPtr client)
2266 int err;
2267 DrawablePtr pDraw;
2268 GC *pGC;
2270 REQUEST(xImageTextReq);
2272 REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
2273 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2275 err = ImageText(client,
2276 pDraw,
2277 pGC,
2278 stuff->nChars,
2279 (unsigned char *) &stuff[1],
2280 stuff->x, stuff->y, stuff->reqType, stuff->drawable);
2282 if (err == Success) {
2283 return Success;
2285 else
2286 return err;
2290 ProcCreateColormap(ClientPtr client)
2292 VisualPtr pVisual;
2293 ColormapPtr pmap;
2294 Colormap mid;
2295 WindowPtr pWin;
2296 ScreenPtr pScreen;
2298 REQUEST(xCreateColormapReq);
2299 int i, result;
2301 REQUEST_SIZE_MATCH(xCreateColormapReq);
2303 if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) {
2304 client->errorValue = stuff->alloc;
2305 return BadValue;
2307 mid = stuff->mid;
2308 LEGAL_NEW_RESOURCE(mid, client);
2309 result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2310 if (result != Success)
2311 return result;
2313 pScreen = pWin->drawable.pScreen;
2314 for (i = 0, pVisual = pScreen->visuals;
2315 i < pScreen->numVisuals; i++, pVisual++) {
2316 if (pVisual->vid != stuff->visual)
2317 continue;
2318 return CreateColormap(mid, pScreen, pVisual, &pmap,
2319 (int) stuff->alloc, client->index);
2321 client->errorValue = stuff->visual;
2322 return BadMatch;
2326 ProcFreeColormap(ClientPtr client)
2328 ColormapPtr pmap;
2329 int rc;
2331 REQUEST(xResourceReq);
2333 REQUEST_SIZE_MATCH(xResourceReq);
2334 rc = dixLookupResourceByType((pointer *) &pmap, stuff->id, RT_COLORMAP,
2335 client, DixDestroyAccess);
2336 if (rc == Success) {
2337 /* Freeing a default colormap is a no-op */
2338 if (!(pmap->flags & IsDefault))
2339 FreeResource(stuff->id, RT_NONE);
2340 return Success;
2342 else {
2343 client->errorValue = stuff->id;
2344 return rc;
2349 ProcCopyColormapAndFree(ClientPtr client)
2351 Colormap mid;
2352 ColormapPtr pSrcMap;
2354 REQUEST(xCopyColormapAndFreeReq);
2355 int rc;
2357 REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2358 mid = stuff->mid;
2359 LEGAL_NEW_RESOURCE(mid, client);
2360 rc = dixLookupResourceByType((pointer *) &pSrcMap, stuff->srcCmap,
2361 RT_COLORMAP, client,
2362 DixReadAccess | DixRemoveAccess);
2363 if (rc == Success)
2364 return CopyColormapAndFree(mid, pSrcMap, client->index);
2365 client->errorValue = stuff->srcCmap;
2366 return rc;
2370 ProcInstallColormap(ClientPtr client)
2372 ColormapPtr pcmp;
2373 int rc;
2375 REQUEST(xResourceReq);
2376 REQUEST_SIZE_MATCH(xResourceReq);
2378 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->id, RT_COLORMAP,
2379 client, DixInstallAccess);
2380 if (rc != Success)
2381 goto out;
2383 rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2384 if (rc != Success) {
2385 if (rc == BadValue)
2386 rc = BadColor;
2387 goto out;
2390 (*(pcmp->pScreen->InstallColormap)) (pcmp);
2391 return Success;
2393 out:
2394 client->errorValue = stuff->id;
2395 return rc;
2399 ProcUninstallColormap(ClientPtr client)
2401 ColormapPtr pcmp;
2402 int rc;
2404 REQUEST(xResourceReq);
2405 REQUEST_SIZE_MATCH(xResourceReq);
2407 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->id, RT_COLORMAP,
2408 client, DixUninstallAccess);
2409 if (rc != Success)
2410 goto out;
2412 rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2413 if (rc != Success) {
2414 if (rc == BadValue)
2415 rc = BadColor;
2416 goto out;
2419 if (pcmp->mid != pcmp->pScreen->defColormap)
2420 (*(pcmp->pScreen->UninstallColormap)) (pcmp);
2421 return Success;
2423 out:
2424 client->errorValue = stuff->id;
2425 return rc;
2429 ProcListInstalledColormaps(ClientPtr client)
2431 xListInstalledColormapsReply *preply;
2432 int nummaps, rc;
2433 WindowPtr pWin;
2435 REQUEST(xResourceReq);
2436 REQUEST_SIZE_MATCH(xResourceReq);
2438 rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
2439 if (rc != Success)
2440 return rc;
2442 rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
2443 DixGetAttrAccess);
2444 if (rc != Success)
2445 return rc;
2447 preply = malloc(sizeof(xListInstalledColormapsReply) +
2448 pWin->drawable.pScreen->maxInstalledCmaps *
2449 sizeof(Colormap));
2450 if (!preply)
2451 return BadAlloc;
2453 preply->type = X_Reply;
2454 preply->sequenceNumber = client->sequence;
2455 nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
2456 (pWin->drawable.pScreen, (Colormap *) & preply[1]);
2457 preply->nColormaps = nummaps;
2458 preply->length = nummaps;
2459 WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply);
2460 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2461 WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
2462 free(preply);
2463 return Success;
2467 ProcAllocColor(ClientPtr client)
2469 ColormapPtr pmap;
2470 int rc;
2471 xAllocColorReply acr;
2473 REQUEST(xAllocColorReq);
2475 REQUEST_SIZE_MATCH(xAllocColorReq);
2476 rc = dixLookupResourceByType((pointer *) &pmap, stuff->cmap, RT_COLORMAP,
2477 client, DixAddAccess);
2478 if (rc == Success) {
2479 acr.type = X_Reply;
2480 acr.length = 0;
2481 acr.sequenceNumber = client->sequence;
2482 acr.red = stuff->red;
2483 acr.green = stuff->green;
2484 acr.blue = stuff->blue;
2485 acr.pixel = 0;
2486 if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
2487 &acr.pixel, client->index)))
2488 return rc;
2489 #ifdef PANORAMIX
2490 if (noPanoramiXExtension || !pmap->pScreen->myNum)
2491 #endif
2492 WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
2493 return Success;
2496 else {
2497 client->errorValue = stuff->cmap;
2498 return rc;
2503 ProcAllocNamedColor(ClientPtr client)
2505 ColormapPtr pcmp;
2506 int rc;
2508 REQUEST(xAllocNamedColorReq);
2510 REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2511 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2512 client, DixAddAccess);
2513 if (rc == Success) {
2514 xAllocNamedColorReply ancr;
2516 ancr.type = X_Reply;
2517 ancr.length = 0;
2518 ancr.sequenceNumber = client->sequence;
2520 if (OsLookupColor
2521 (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
2522 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) {
2523 ancr.screenRed = ancr.exactRed;
2524 ancr.screenGreen = ancr.exactGreen;
2525 ancr.screenBlue = ancr.exactBlue;
2526 ancr.pixel = 0;
2527 if ((rc = AllocColor(pcmp,
2528 &ancr.screenRed, &ancr.screenGreen,
2529 &ancr.screenBlue, &ancr.pixel, client->index)))
2530 return rc;
2531 #ifdef PANORAMIX
2532 if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2533 #endif
2534 WriteReplyToClient(client, sizeof(xAllocNamedColorReply),
2535 &ancr);
2536 return Success;
2538 else
2539 return BadName;
2542 else {
2543 client->errorValue = stuff->cmap;
2544 return rc;
2549 ProcAllocColorCells(ClientPtr client)
2551 ColormapPtr pcmp;
2552 int rc;
2554 REQUEST(xAllocColorCellsReq);
2556 REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2557 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2558 client, DixAddAccess);
2559 if (rc == Success) {
2560 xAllocColorCellsReply accr;
2561 int npixels, nmasks;
2562 long length;
2563 Pixel *ppixels, *pmasks;
2565 npixels = stuff->colors;
2566 if (!npixels) {
2567 client->errorValue = npixels;
2568 return BadValue;
2570 if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
2571 client->errorValue = stuff->contiguous;
2572 return BadValue;
2574 nmasks = stuff->planes;
2575 length = ((long) npixels + (long) nmasks) * sizeof(Pixel);
2576 ppixels = malloc(length);
2577 if (!ppixels)
2578 return BadAlloc;
2579 pmasks = ppixels + npixels;
2581 if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
2582 (Bool) stuff->contiguous, ppixels, pmasks))) {
2583 free(ppixels);
2584 return rc;
2586 #ifdef PANORAMIX
2587 if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2588 #endif
2590 accr.type = X_Reply;
2591 accr.length = bytes_to_int32(length);
2592 accr.sequenceNumber = client->sequence;
2593 accr.nPixels = npixels;
2594 accr.nMasks = nmasks;
2595 WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr);
2596 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2597 WriteSwappedDataToClient(client, length, ppixels);
2599 free(ppixels);
2600 return Success;
2602 else {
2603 client->errorValue = stuff->cmap;
2604 return rc;
2609 ProcAllocColorPlanes(ClientPtr client)
2611 ColormapPtr pcmp;
2612 int rc;
2614 REQUEST(xAllocColorPlanesReq);
2616 REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2617 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2618 client, DixAddAccess);
2619 if (rc == Success) {
2620 xAllocColorPlanesReply acpr;
2621 int npixels;
2622 long length;
2623 Pixel *ppixels;
2625 npixels = stuff->colors;
2626 if (!npixels) {
2627 client->errorValue = npixels;
2628 return BadValue;
2630 if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
2631 client->errorValue = stuff->contiguous;
2632 return BadValue;
2634 acpr.type = X_Reply;
2635 acpr.sequenceNumber = client->sequence;
2636 acpr.nPixels = npixels;
2637 length = (long) npixels *sizeof(Pixel);
2639 ppixels = malloc(length);
2640 if (!ppixels)
2641 return BadAlloc;
2642 if ((rc = AllocColorPlanes(client->index, pcmp, npixels,
2643 (int) stuff->red, (int) stuff->green,
2644 (int) stuff->blue, (Bool) stuff->contiguous,
2645 ppixels, &acpr.redMask, &acpr.greenMask,
2646 &acpr.blueMask))) {
2647 free(ppixels);
2648 return rc;
2650 acpr.length = bytes_to_int32(length);
2651 #ifdef PANORAMIX
2652 if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2653 #endif
2655 WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
2656 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2657 WriteSwappedDataToClient(client, length, ppixels);
2659 free(ppixels);
2660 return Success;
2662 else {
2663 client->errorValue = stuff->cmap;
2664 return rc;
2669 ProcFreeColors(ClientPtr client)
2671 ColormapPtr pcmp;
2672 int rc;
2674 REQUEST(xFreeColorsReq);
2676 REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2677 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2678 client, DixRemoveAccess);
2679 if (rc == Success) {
2680 int count;
2682 if (pcmp->flags & AllAllocated)
2683 return BadAccess;
2684 count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
2685 return FreeColors(pcmp, client->index, count,
2686 (Pixel *) &stuff[1], (Pixel) stuff->planeMask);
2688 else {
2689 client->errorValue = stuff->cmap;
2690 return rc;
2695 ProcStoreColors(ClientPtr client)
2697 ColormapPtr pcmp;
2698 int rc;
2700 REQUEST(xStoreColorsReq);
2702 REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2703 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2704 client, DixWriteAccess);
2705 if (rc == Success) {
2706 int count;
2708 count = (client->req_len << 2) - sizeof(xStoreColorsReq);
2709 if (count % sizeof(xColorItem))
2710 return BadLength;
2711 count /= sizeof(xColorItem);
2712 return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client);
2714 else {
2715 client->errorValue = stuff->cmap;
2716 return rc;
2721 ProcStoreNamedColor(ClientPtr client)
2723 ColormapPtr pcmp;
2724 int rc;
2726 REQUEST(xStoreNamedColorReq);
2728 REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2729 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2730 client, DixWriteAccess);
2731 if (rc == Success) {
2732 xColorItem def;
2734 if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1],
2735 stuff->nbytes, &def.red, &def.green, &def.blue)) {
2736 def.flags = stuff->flags;
2737 def.pixel = stuff->pixel;
2738 return StoreColors(pcmp, 1, &def, client);
2740 return BadName;
2742 else {
2743 client->errorValue = stuff->cmap;
2744 return rc;
2749 ProcQueryColors(ClientPtr client)
2751 ColormapPtr pcmp;
2752 int rc;
2754 REQUEST(xQueryColorsReq);
2756 REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2757 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2758 client, DixReadAccess);
2759 if (rc == Success) {
2760 int count;
2761 xrgb *prgbs;
2762 xQueryColorsReply qcr;
2764 count =
2765 bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
2766 prgbs = calloc(1, count * sizeof(xrgb));
2767 if (!prgbs && count)
2768 return BadAlloc;
2769 if ((rc =
2770 QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) {
2771 free(prgbs);
2772 return rc;
2774 memset(&qcr, 0, sizeof(xQueryColorsReply));
2775 qcr.type = X_Reply;
2776 qcr.length = bytes_to_int32(count * sizeof(xrgb));
2777 qcr.sequenceNumber = client->sequence;
2778 qcr.nColors = count;
2779 WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
2780 if (count) {
2781 client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
2782 WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
2784 free(prgbs);
2785 return Success;
2788 else {
2789 client->errorValue = stuff->cmap;
2790 return rc;
2795 ProcLookupColor(ClientPtr client)
2797 ColormapPtr pcmp;
2798 int rc;
2800 REQUEST(xLookupColorReq);
2802 REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2803 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->cmap, RT_COLORMAP,
2804 client, DixReadAccess);
2805 if (rc == Success) {
2806 xLookupColorReply lcr;
2808 if (OsLookupColor
2809 (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
2810 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) {
2811 lcr.type = X_Reply;
2812 lcr.length = 0;
2813 lcr.sequenceNumber = client->sequence;
2814 lcr.screenRed = lcr.exactRed;
2815 lcr.screenGreen = lcr.exactGreen;
2816 lcr.screenBlue = lcr.exactBlue;
2817 (*pcmp->pScreen->ResolveColor) (&lcr.screenRed,
2818 &lcr.screenGreen,
2819 &lcr.screenBlue, pcmp->pVisual);
2820 WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
2821 return Success;
2823 return BadName;
2825 else {
2826 client->errorValue = stuff->cmap;
2827 return rc;
2832 ProcCreateCursor(ClientPtr client)
2834 CursorPtr pCursor;
2835 PixmapPtr src;
2836 PixmapPtr msk;
2837 unsigned char *srcbits;
2838 unsigned char *mskbits;
2839 unsigned short width, height;
2840 long n;
2841 CursorMetricRec cm;
2842 int rc;
2844 REQUEST(xCreateCursorReq);
2846 REQUEST_SIZE_MATCH(xCreateCursorReq);
2847 LEGAL_NEW_RESOURCE(stuff->cid, client);
2849 rc = dixLookupResourceByType((pointer *) &src, stuff->source, RT_PIXMAP,
2850 client, DixReadAccess);
2851 if (rc != Success) {
2852 client->errorValue = stuff->source;
2853 return rc;
2856 rc = dixLookupResourceByType((pointer *) &msk, stuff->mask, RT_PIXMAP,
2857 client, DixReadAccess);
2858 if (rc != Success) {
2859 if (stuff->mask != None) {
2860 client->errorValue = stuff->mask;
2861 return rc;
2864 else if (src->drawable.width != msk->drawable.width
2865 || src->drawable.height != msk->drawable.height
2866 || src->drawable.depth != 1 || msk->drawable.depth != 1)
2867 return BadMatch;
2869 width = src->drawable.width;
2870 height = src->drawable.height;
2872 if (stuff->x > width || stuff->y > height)
2873 return BadMatch;
2875 n = BitmapBytePad(width) * height;
2876 srcbits = calloc(1, n);
2877 if (!srcbits)
2878 return BadAlloc;
2879 mskbits = malloc(n);
2880 if (!mskbits) {
2881 free(srcbits);
2882 return BadAlloc;
2885 (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height,
2886 XYPixmap, 1, (pointer) srcbits);
2887 if (msk == (PixmapPtr) NULL) {
2888 unsigned char *bits = mskbits;
2890 while (--n >= 0)
2891 *bits++ = ~0;
2893 else {
2894 /* zeroing the (pad) bits helps some ddx cursor handling */
2895 memset((char *) mskbits, 0, n);
2896 (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width,
2897 height, XYPixmap, 1,
2898 (pointer) mskbits);
2900 cm.width = width;
2901 cm.height = height;
2902 cm.xhot = stuff->x;
2903 cm.yhot = stuff->y;
2904 rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
2905 stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
2906 stuff->backRed, stuff->backGreen, stuff->backBlue,
2907 &pCursor, client, stuff->cid);
2909 if (rc != Success)
2910 goto bail;
2911 if (!AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor)) {
2912 rc = BadAlloc;
2913 goto bail;
2916 return Success;
2917 bail:
2918 free(srcbits);
2919 free(mskbits);
2920 return rc;
2924 ProcCreateGlyphCursor(ClientPtr client)
2926 CursorPtr pCursor;
2927 int res;
2929 REQUEST(xCreateGlyphCursorReq);
2931 REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
2932 LEGAL_NEW_RESOURCE(stuff->cid, client);
2934 res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
2935 stuff->mask, stuff->maskChar,
2936 stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
2937 stuff->backRed, stuff->backGreen, stuff->backBlue,
2938 &pCursor, client, stuff->cid);
2939 if (res != Success)
2940 return res;
2941 if (AddResource(stuff->cid, RT_CURSOR, (pointer) pCursor))
2942 return Success;
2943 return BadAlloc;
2947 ProcFreeCursor(ClientPtr client)
2949 CursorPtr pCursor;
2950 int rc;
2952 REQUEST(xResourceReq);
2954 REQUEST_SIZE_MATCH(xResourceReq);
2955 rc = dixLookupResourceByType((pointer *) &pCursor, stuff->id, RT_CURSOR,
2956 client, DixDestroyAccess);
2957 if (rc == Success) {
2958 FreeResource(stuff->id, RT_NONE);
2959 return Success;
2961 else {
2962 client->errorValue = stuff->id;
2963 return rc;
2968 ProcQueryBestSize(ClientPtr client)
2970 xQueryBestSizeReply reply;
2971 DrawablePtr pDraw;
2972 ScreenPtr pScreen;
2973 int rc;
2975 REQUEST(xQueryBestSizeReq);
2976 REQUEST_SIZE_MATCH(xQueryBestSizeReq);
2978 if ((stuff->class != CursorShape) &&
2979 (stuff->class != TileShape) && (stuff->class != StippleShape)) {
2980 client->errorValue = stuff->class;
2981 return BadValue;
2984 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
2985 DixGetAttrAccess);
2986 if (rc != Success)
2987 return rc;
2988 if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
2989 return BadMatch;
2990 pScreen = pDraw->pScreen;
2991 rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
2992 if (rc != Success)
2993 return rc;
2994 (*pScreen->QueryBestSize) (stuff->class, &stuff->width,
2995 &stuff->height, pScreen);
2996 memset(&reply, 0, sizeof(xQueryBestSizeReply));
2997 reply.type = X_Reply;
2998 reply.length = 0;
2999 reply.sequenceNumber = client->sequence;
3000 reply.width = stuff->width;
3001 reply.height = stuff->height;
3002 WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
3003 return Success;
3007 ProcSetScreenSaver(ClientPtr client)
3009 int rc, i, blankingOption, exposureOption;
3011 REQUEST(xSetScreenSaverReq);
3012 REQUEST_SIZE_MATCH(xSetScreenSaverReq);
3014 for (i = 0; i < screenInfo.numScreens; i++) {
3015 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3016 DixSetAttrAccess);
3017 if (rc != Success)
3018 return rc;
3021 blankingOption = stuff->preferBlank;
3022 if ((blankingOption != DontPreferBlanking) &&
3023 (blankingOption != PreferBlanking) &&
3024 (blankingOption != DefaultBlanking)) {
3025 client->errorValue = blankingOption;
3026 return BadValue;
3028 exposureOption = stuff->allowExpose;
3029 if ((exposureOption != DontAllowExposures) &&
3030 (exposureOption != AllowExposures) &&
3031 (exposureOption != DefaultExposures)) {
3032 client->errorValue = exposureOption;
3033 return BadValue;
3035 if (stuff->timeout < -1) {
3036 client->errorValue = stuff->timeout;
3037 return BadValue;
3039 if (stuff->interval < -1) {
3040 client->errorValue = stuff->interval;
3041 return BadValue;
3044 if (blankingOption == DefaultBlanking)
3045 ScreenSaverBlanking = defaultScreenSaverBlanking;
3046 else
3047 ScreenSaverBlanking = blankingOption;
3048 if (exposureOption == DefaultExposures)
3049 ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
3050 else
3051 ScreenSaverAllowExposures = exposureOption;
3053 if (stuff->timeout >= 0)
3054 ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
3055 else
3056 ScreenSaverTime = defaultScreenSaverTime;
3057 if (stuff->interval >= 0)
3058 ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
3059 else
3060 ScreenSaverInterval = defaultScreenSaverInterval;
3062 SetScreenSaverTimer();
3063 return Success;
3067 ProcGetScreenSaver(ClientPtr client)
3069 xGetScreenSaverReply rep;
3070 int rc, i;
3072 REQUEST_SIZE_MATCH(xReq);
3074 for (i = 0; i < screenInfo.numScreens; i++) {
3075 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3076 DixGetAttrAccess);
3077 if (rc != Success)
3078 return rc;
3081 rep.type = X_Reply;
3082 rep.length = 0;
3083 rep.sequenceNumber = client->sequence;
3084 rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
3085 rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
3086 rep.preferBlanking = ScreenSaverBlanking;
3087 rep.allowExposures = ScreenSaverAllowExposures;
3088 WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
3089 return Success;
3093 ProcChangeHosts(ClientPtr client)
3095 REQUEST(xChangeHostsReq);
3097 REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
3099 if (stuff->mode == HostInsert)
3100 return AddHost(client, (int) stuff->hostFamily,
3101 stuff->hostLength, (pointer) &stuff[1]);
3102 if (stuff->mode == HostDelete)
3103 return RemoveHost(client, (int) stuff->hostFamily,
3104 stuff->hostLength, (pointer) &stuff[1]);
3105 client->errorValue = stuff->mode;
3106 return BadValue;
3110 ProcListHosts(ClientPtr client)
3112 xListHostsReply reply;
3113 int len, nHosts, result;
3114 pointer pdata;
3116 /* REQUEST(xListHostsReq); */
3118 REQUEST_SIZE_MATCH(xListHostsReq);
3120 /* untrusted clients can't list hosts */
3121 result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
3122 if (result != Success)
3123 return result;
3125 result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
3126 if (result != Success)
3127 return result;
3128 reply.type = X_Reply;
3129 reply.sequenceNumber = client->sequence;
3130 reply.nHosts = nHosts;
3131 reply.length = bytes_to_int32(len);
3132 WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
3133 if (nHosts) {
3134 client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
3135 WriteSwappedDataToClient(client, len, pdata);
3137 free(pdata);
3138 return Success;
3142 ProcChangeAccessControl(ClientPtr client)
3144 REQUEST(xSetAccessControlReq);
3146 REQUEST_SIZE_MATCH(xSetAccessControlReq);
3147 if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) {
3148 client->errorValue = stuff->mode;
3149 return BadValue;
3151 return ChangeAccessControl(client, stuff->mode == EnableAccess);
3154 /*********************
3155 * CloseDownRetainedResources
3157 * Find all clients that are gone and have terminated in RetainTemporary
3158 * and destroy their resources.
3159 *********************/
3161 static void
3162 CloseDownRetainedResources(void)
3164 int i;
3165 ClientPtr client;
3167 for (i = 1; i < currentMaxClients; i++) {
3168 client = clients[i];
3169 if (client && (client->closeDownMode == RetainTemporary)
3170 && (client->clientGone))
3171 CloseDownClient(client);
3176 ProcKillClient(ClientPtr client)
3178 REQUEST(xResourceReq);
3179 ClientPtr killclient;
3180 int rc;
3182 REQUEST_SIZE_MATCH(xResourceReq);
3183 if (stuff->id == AllTemporary) {
3184 CloseDownRetainedResources();
3185 return Success;
3188 rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
3189 if (rc == Success) {
3190 CloseDownClient(killclient);
3191 /* if an LBX proxy gets killed, isItTimeToYield will be set */
3192 if (isItTimeToYield || (client == killclient)) {
3193 /* force yield and return Success, so that Dispatch()
3194 * doesn't try to touch client
3196 isItTimeToYield = TRUE;
3197 return Success;
3199 return Success;
3201 else
3202 return rc;
3206 ProcSetFontPath(ClientPtr client)
3208 unsigned char *ptr;
3209 unsigned long nbytes, total;
3210 long nfonts;
3211 int n;
3213 REQUEST(xSetFontPathReq);
3215 REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
3217 nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
3218 total = nbytes;
3219 ptr = (unsigned char *) &stuff[1];
3220 nfonts = stuff->nFonts;
3221 while (--nfonts >= 0) {
3222 if ((total == 0) || (total < (n = (*ptr + 1))))
3223 return BadLength;
3224 total -= n;
3225 ptr += n;
3227 if (total >= 4)
3228 return BadLength;
3229 return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]);
3233 ProcGetFontPath(ClientPtr client)
3235 xGetFontPathReply reply;
3236 int rc, stringLens, numpaths;
3237 unsigned char *bufferStart;
3239 /* REQUEST (xReq); */
3241 REQUEST_SIZE_MATCH(xReq);
3242 rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
3243 if (rc != Success)
3244 return rc;
3246 reply.type = X_Reply;
3247 reply.sequenceNumber = client->sequence;
3248 reply.length = bytes_to_int32(stringLens + numpaths);
3249 reply.nPaths = numpaths;
3251 WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
3252 if (stringLens || numpaths)
3253 (void) WriteToClient(client, stringLens + numpaths,
3254 (char *) bufferStart);
3255 return Success;
3259 ProcChangeCloseDownMode(ClientPtr client)
3261 int rc;
3263 REQUEST(xSetCloseDownModeReq);
3264 REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
3266 rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
3267 if (rc != Success)
3268 return rc;
3270 if ((stuff->mode == AllTemporary) ||
3271 (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) {
3272 client->closeDownMode = stuff->mode;
3273 return Success;
3275 else {
3276 client->errorValue = stuff->mode;
3277 return BadValue;
3282 ProcForceScreenSaver(ClientPtr client)
3284 int rc;
3286 REQUEST(xForceScreenSaverReq);
3288 REQUEST_SIZE_MATCH(xForceScreenSaverReq);
3290 if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) {
3291 client->errorValue = stuff->mode;
3292 return BadValue;
3294 rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode);
3295 if (rc != Success)
3296 return rc;
3297 return Success;
3301 ProcNoOperation(ClientPtr client)
3303 REQUEST_AT_LEAST_SIZE(xReq);
3305 /* noop -- don't do anything */
3306 return Success;
3309 /**********************
3310 * CloseDownClient
3312 * Client can either mark his resources destroy or retain. If retained and
3313 * then killed again, the client is really destroyed.
3314 *********************/
3316 char dispatchExceptionAtReset = DE_RESET;
3318 void
3319 CloseDownClient(ClientPtr client)
3321 Bool really_close_down = client->clientGone ||
3322 client->closeDownMode == DestroyAll;
3324 if (!client->clientGone) {
3325 /* ungrab server if grabbing client dies */
3326 if (grabState != GrabNone && grabClient == client) {
3327 UngrabServer(client);
3329 BITCLEAR(grabWaiters, client->index);
3330 DeleteClientFromAnySelections(client);
3331 ReleaseActiveGrabs(client);
3332 DeleteClientFontStuff(client);
3333 if (!really_close_down) {
3334 /* This frees resources that should never be retained
3335 * no matter what the close down mode is. Actually we
3336 * could do this unconditionally, but it's probably
3337 * better not to traverse all the client's resources
3338 * twice (once here, once a few lines down in
3339 * FreeClientResources) in the common case of
3340 * really_close_down == TRUE.
3342 FreeClientNeverRetainResources(client);
3343 client->clientState = ClientStateRetained;
3344 if (ClientStateCallback) {
3345 NewClientInfoRec clientinfo;
3347 clientinfo.client = client;
3348 clientinfo.prefix = (xConnSetupPrefix *) NULL;
3349 clientinfo.setup = (xConnSetup *) NULL;
3350 CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
3353 client->clientGone = TRUE; /* so events aren't sent to client */
3354 if (ClientIsAsleep(client))
3355 ClientSignal(client);
3356 ProcessWorkQueueZombies();
3357 CloseDownConnection(client);
3359 /* If the client made it to the Running stage, nClients has
3360 * been incremented on its behalf, so we need to decrement it
3361 * now. If it hasn't gotten to Running, nClients has *not*
3362 * been incremented, so *don't* decrement it.
3364 if (client->clientState != ClientStateInitial) {
3365 --nClients;
3369 if (really_close_down) {
3370 if (client->clientState == ClientStateRunning && nClients == 0)
3371 dispatchException |= dispatchExceptionAtReset;
3373 client->clientState = ClientStateGone;
3374 if (ClientStateCallback) {
3375 NewClientInfoRec clientinfo;
3377 clientinfo.client = client;
3378 clientinfo.prefix = (xConnSetupPrefix *) NULL;
3379 clientinfo.setup = (xConnSetup *) NULL;
3380 CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
3382 FreeClientResources(client);
3383 /* Disable client ID tracking. This must be done after
3384 * ClientStateCallback. */
3385 ReleaseClientIds(client);
3386 #ifdef XSERVER_DTRACE
3387 XSERVER_CLIENT_DISCONNECT(client->index);
3388 #endif
3389 if (client->index < nextFreeClientID)
3390 nextFreeClientID = client->index;
3391 clients[client->index] = NullClient;
3392 SmartLastClient = NullClient;
3393 dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3395 while (!clients[currentMaxClients - 1])
3396 currentMaxClients--;
3400 static void
3401 KillAllClients(void)
3403 int i;
3405 for (i = 1; i < currentMaxClients; i++)
3406 if (clients[i]) {
3407 /* Make sure Retained clients are released. */
3408 clients[i]->closeDownMode = DestroyAll;
3409 CloseDownClient(clients[i]);
3413 void
3414 InitClient(ClientPtr client, int i, pointer ospriv)
3416 client->index = i;
3417 client->clientAsMask = ((Mask) i) << CLIENTOFFSET;
3418 client->closeDownMode = i ? DestroyAll : RetainPermanent;
3419 client->requestVector = InitialVector;
3420 client->osPrivate = ospriv;
3421 QueryMinMaxKeyCodes(&client->minKC, &client->maxKC);
3422 client->smart_start_tick = SmartScheduleTime;
3423 client->smart_stop_tick = SmartScheduleTime;
3424 client->smart_check_tick = SmartScheduleTime;
3425 client->clientIds = NULL;
3428 /************************
3429 * int NextAvailableClient(ospriv)
3431 * OS dependent portion can't assign client id's because of CloseDownModes.
3432 * Returns NULL if there are no free clients.
3433 *************************/
3435 ClientPtr
3436 NextAvailableClient(pointer ospriv)
3438 int i;
3439 ClientPtr client;
3440 xReq data;
3442 i = nextFreeClientID;
3443 if (i == MAXCLIENTS)
3444 return (ClientPtr) NULL;
3445 clients[i] = client =
3446 dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
3447 if (!client)
3448 return (ClientPtr) NULL;
3449 InitClient(client, i, ospriv);
3450 if (!InitClientResources(client)) {
3451 dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3452 return (ClientPtr) NULL;
3454 data.reqType = 1;
3455 data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
3456 if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) {
3457 FreeClientResources(client);
3458 dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3459 return (ClientPtr) NULL;
3461 if (i == currentMaxClients)
3462 currentMaxClients++;
3463 while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
3464 nextFreeClientID++;
3466 /* Enable client ID tracking. This must be done before
3467 * ClientStateCallback. */
3468 ReserveClientIds(client);
3470 if (ClientStateCallback) {
3471 NewClientInfoRec clientinfo;
3473 clientinfo.client = client;
3474 clientinfo.prefix = (xConnSetupPrefix *) NULL;
3475 clientinfo.setup = (xConnSetup *) NULL;
3476 CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
3478 return client;
3482 ProcInitialConnection(ClientPtr client)
3484 REQUEST(xReq);
3485 xConnClientPrefix *prefix;
3486 int whichbyte = 1;
3488 prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
3489 if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
3490 return client->noClientException = -1;
3491 if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
3492 (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) {
3493 client->swapped = TRUE;
3494 SwapConnClientPrefix(prefix);
3496 stuff->reqType = 2;
3497 stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
3498 bytes_to_int32(prefix->nbytesAuthString);
3499 if (client->swapped) {
3500 swaps(&stuff->length);
3502 ResetCurrentRequest(client);
3503 return Success;
3506 static int
3507 SendConnSetup(ClientPtr client, const char *reason)
3509 xWindowRoot *root;
3510 int i;
3511 int numScreens;
3512 char *lConnectionInfo;
3513 xConnSetupPrefix *lconnSetupPrefix;
3515 if (reason) {
3516 xConnSetupPrefix csp;
3518 csp.success = xFalse;
3519 csp.lengthReason = strlen(reason);
3520 csp.length = bytes_to_int32(csp.lengthReason);
3521 csp.majorVersion = X_PROTOCOL;
3522 csp.minorVersion = X_PROTOCOL_REVISION;
3523 if (client->swapped)
3524 WriteSConnSetupPrefix(client, &csp);
3525 else
3526 (void) WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
3527 (void) WriteToClient(client, (int) csp.lengthReason, reason);
3528 return client->noClientException = -1;
3531 numScreens = screenInfo.numScreens;
3532 lConnectionInfo = ConnectionInfo;
3533 lconnSetupPrefix = &connSetupPrefix;
3535 /* We're about to start speaking X protocol back to the client by
3536 * sending the connection setup info. This means the authorization
3537 * step is complete, and we can count the client as an
3538 * authorized one.
3540 nClients++;
3542 client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
3543 client->sequence = 0;
3544 ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask;
3545 ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
3546 #ifdef MATCH_CLIENT_ENDIAN
3547 ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client);
3548 ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client);
3549 #endif
3550 /* fill in the "currentInputMask" */
3551 root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart);
3552 #ifdef PANORAMIX
3553 if (noPanoramiXExtension)
3554 numScreens = screenInfo.numScreens;
3555 else
3556 numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
3557 #endif
3559 for (i = 0; i < numScreens; i++) {
3560 unsigned int j;
3561 xDepth *pDepth;
3562 WindowPtr pRoot = screenInfo.screens[i]->root;
3564 root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
3565 pDepth = (xDepth *) (root + 1);
3566 for (j = 0; j < root->nDepths; j++) {
3567 pDepth = (xDepth *) (((char *) (pDepth + 1)) +
3568 pDepth->nVisuals * sizeof(xVisualType));
3570 root = (xWindowRoot *) pDepth;
3573 if (client->swapped) {
3574 WriteSConnSetupPrefix(client, lconnSetupPrefix);
3575 WriteSConnectionInfo(client,
3576 (unsigned long) (lconnSetupPrefix->length << 2),
3577 lConnectionInfo);
3579 else {
3580 (void) WriteToClient(client, sizeof(xConnSetupPrefix),
3581 (char *) lconnSetupPrefix);
3582 (void) WriteToClient(client, (int) (lconnSetupPrefix->length << 2),
3583 lConnectionInfo);
3585 client->clientState = ClientStateRunning;
3586 if (ClientStateCallback) {
3587 NewClientInfoRec clientinfo;
3589 clientinfo.client = client;
3590 clientinfo.prefix = lconnSetupPrefix;
3591 clientinfo.setup = (xConnSetup *) lConnectionInfo;
3592 CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
3594 return Success;
3598 ProcEstablishConnection(ClientPtr client)
3600 const char *reason;
3601 char *auth_proto, *auth_string;
3602 xConnClientPrefix *prefix;
3604 REQUEST(xReq);
3606 prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
3607 auth_proto = (char *) prefix + sz_xConnClientPrefix;
3608 auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
3609 if ((prefix->majorVersion != X_PROTOCOL) ||
3610 (prefix->minorVersion != X_PROTOCOL_REVISION))
3611 reason = "Protocol version mismatch";
3612 else
3613 reason = ClientAuthorized(client,
3614 (unsigned short) prefix->nbytesAuthProto,
3615 auth_proto,
3616 (unsigned short) prefix->nbytesAuthString,
3617 auth_string);
3619 return (SendConnSetup(client, reason));
3622 void
3623 SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
3624 XID resId, int errorCode)
3626 xError rep;
3628 memset(&rep, 0, sizeof(xError));
3629 rep.type = X_Error;
3630 rep.errorCode = errorCode;
3631 rep.majorCode = majorCode;
3632 rep.minorCode = minorCode;
3633 rep.resourceID = resId;
3635 WriteEventsToClient(client, 1, (xEvent *) &rep);
3638 void
3639 MarkClientException(ClientPtr client)
3641 client->noClientException = -1;
3645 * This array encodes the answer to the question "what is the log base 2
3646 * of the number of pixels that fit in a scanline pad unit?"
3647 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3649 static int answer[6][4] = {
3650 /* pad pad pad pad */
3651 /* 8 16 32 64 */
3653 {3, 4, 5, 6}, /* 1 bit per pixel */
3654 {1, 2, 3, 4}, /* 4 bits per pixel */
3655 {0, 1, 2, 3}, /* 8 bits per pixel */
3656 {~0, 0, 1, 2}, /* 16 bits per pixel */
3657 {~0, ~0, 0, 1}, /* 24 bits per pixel */
3658 {~0, ~0, 0, 1} /* 32 bits per pixel */
3662 * This array gives the answer to the question "what is the first index for
3663 * the answer array above given the number of bits per pixel?"
3664 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3666 static int indexForBitsPerPixel[33] = {
3667 ~0, 0, ~0, ~0, /* 1 bit per pixel */
3668 1, ~0, ~0, ~0, /* 4 bits per pixel */
3669 2, ~0, ~0, ~0, /* 8 bits per pixel */
3670 ~0, ~0, ~0, ~0,
3671 3, ~0, ~0, ~0, /* 16 bits per pixel */
3672 ~0, ~0, ~0, ~0,
3673 4, ~0, ~0, ~0, /* 24 bits per pixel */
3674 ~0, ~0, ~0, ~0,
3675 5 /* 32 bits per pixel */
3679 * This array gives the bytesperPixel value for cases where the number
3680 * of bits per pixel is a multiple of 8 but not a power of 2.
3682 static int answerBytesPerPixel[33] = {
3683 ~0, 0, ~0, ~0, /* 1 bit per pixel */
3684 0, ~0, ~0, ~0, /* 4 bits per pixel */
3685 0, ~0, ~0, ~0, /* 8 bits per pixel */
3686 ~0, ~0, ~0, ~0,
3687 0, ~0, ~0, ~0, /* 16 bits per pixel */
3688 ~0, ~0, ~0, ~0,
3689 3, ~0, ~0, ~0, /* 24 bits per pixel */
3690 ~0, ~0, ~0, ~0,
3691 0 /* 32 bits per pixel */
3695 * This array gives the answer to the question "what is the second index for
3696 * the answer array above given the number of bits per scanline pad unit?"
3697 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3699 static int indexForScanlinePad[65] = {
3700 ~0, ~0, ~0, ~0,
3701 ~0, ~0, ~0, ~0,
3702 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
3703 ~0, ~0, ~0, ~0,
3704 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
3705 ~0, ~0, ~0, ~0,
3706 ~0, ~0, ~0, ~0,
3707 ~0, ~0, ~0, ~0,
3708 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
3709 ~0, ~0, ~0, ~0,
3710 ~0, ~0, ~0, ~0,
3711 ~0, ~0, ~0, ~0,
3712 ~0, ~0, ~0, ~0,
3713 ~0, ~0, ~0, ~0,
3714 ~0, ~0, ~0, ~0,
3715 ~0, ~0, ~0, ~0,
3716 3 /* 64 bits per scanline pad unit */
3720 grow the array of screenRecs if necessary.
3721 call the device-supplied initialization procedure
3722 with its screen number, a pointer to its ScreenRec, argc, and argv.
3723 return the number of successfully installed screens.
3728 AddScreen(Bool (*pfnInit) (int /*index */ ,
3729 ScreenPtr /*pScreen */ ,
3730 int /*argc */ ,
3731 char ** /*argv */
3732 ), int argc, char **argv)
3735 int i;
3736 int scanlinepad, format, depth, bitsPerPixel, j, k;
3737 ScreenPtr pScreen;
3739 i = screenInfo.numScreens;
3740 if (i == MAXSCREENS)
3741 return -1;
3743 pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
3744 if (!pScreen)
3745 return -1;
3747 if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
3748 free(pScreen);
3749 return -1;
3751 pScreen->myNum = i;
3752 pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */
3753 pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
3754 pScreen->CreateScreenResources = 0;
3757 * This loop gets run once for every Screen that gets added,
3758 * but thats ok. If the ddx layer initializes the formats
3759 * one at a time calling AddScreen() after each, then each
3760 * iteration will make it a little more accurate. Worst case
3761 * we do this loop N * numPixmapFormats where N is # of screens.
3762 * Anyway, this must be called after InitOutput and before the
3763 * screen init routine is called.
3765 for (format = 0; format < screenInfo.numPixmapFormats; format++) {
3766 depth = screenInfo.formats[format].depth;
3767 bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
3768 scanlinepad = screenInfo.formats[format].scanlinePad;
3769 j = indexForBitsPerPixel[bitsPerPixel];
3770 k = indexForScanlinePad[scanlinepad];
3771 PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k];
3772 PixmapWidthPaddingInfo[depth].padRoundUp =
3773 (scanlinepad / bitsPerPixel) - 1;
3774 j = indexForBitsPerPixel[8]; /* bits per byte */
3775 PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k];
3776 PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel;
3777 if (answerBytesPerPixel[bitsPerPixel]) {
3778 PixmapWidthPaddingInfo[depth].notPower2 = 1;
3779 PixmapWidthPaddingInfo[depth].bytesPerPixel =
3780 answerBytesPerPixel[bitsPerPixel];
3782 else {
3783 PixmapWidthPaddingInfo[depth].notPower2 = 0;
3787 /* This is where screen specific stuff gets initialized. Load the
3788 screen structure, call the hardware, whatever.
3789 This is also where the default colormap should be allocated and
3790 also pixel values for blackPixel, whitePixel, and the cursor
3791 Note that InitScreen is NOT allowed to modify argc, argv, or
3792 any of the strings pointed to by argv. They may be passed to
3793 multiple screens.
3795 screenInfo.screens[i] = pScreen;
3796 screenInfo.numScreens++;
3797 if (!(*pfnInit) (i, pScreen, argc, argv)) {
3798 dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
3799 free(pScreen);
3800 screenInfo.numScreens--;
3801 return -1;
3804 update_desktop_dimensions();
3806 dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR,
3809 return i;