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
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.
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
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
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>
104 #ifdef PANORAMIX_DEBUG
106 int ProcInitialConnection();
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"
119 #include "servermd.h"
120 #include "extnsionst.h"
122 #include "dispatch.h"
125 #include "privates.h"
127 #include "inputstr.h"
132 #ifdef XSERVER_DTRACE
133 #include "registry.h"
134 #include <sys/types.h>
135 typedef const char *string
;
137 #include "Xserver-dtrace.h"
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
;
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
176 volatile char dispatchException
= 0;
177 volatile char isItTimeToYield
;
179 #define SAME_SCREENS(a, b) (\
180 (a.pScreen == b.pScreen))
183 SetInputCheck(HWEventQueuePtr c0
, HWEventQueuePtr c1
)
185 checkForInput
[0] = c0
;
186 checkForInput
[1] = c1
;
190 UpdateCurrentTime(void)
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
)
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 */
209 UpdateCurrentTimeIf(void)
213 systime
.months
= currentTime
.months
;
214 systime
.milliseconds
= GetTimeInMillis();
215 if (systime
.milliseconds
< currentTime
.milliseconds
)
217 if (CompareTimeStamps(systime
, currentTime
) == LATER
)
218 currentTime
= systime
;
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];
242 SmartScheduleClient(int *clientReady
, int nready
)
247 int bestPrio
, best
= 0;
248 int bestRobin
, robin
;
249 long now
= SmartScheduleTime
;
252 bestPrio
= -0x7fffffff;
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 */
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
;
277 if ((now
- SmartLastPrint
) >= 5000)
278 fprintf(stderr
, " %2d: %3d", client
, pClient
->smart_priority
);
282 if ((now
- SmartLastPrint
) >= 5000) {
283 fprintf(stderr
, " use %2d\n", best
);
284 SmartLastPrint
= now
;
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
;
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
;
311 SmartScheduleSlice
= SmartScheduleInterval
;
317 EnableLimitedSchedulingLatency(void)
319 ++SmartScheduleLatencyLimited
;
320 SmartScheduleSlice
= SmartScheduleInterval
;
324 DisableLimitedSchedulingLatency(void)
326 --SmartScheduleLatencyLimited
;
328 /* protect against bugs */
329 if (SmartScheduleLatencyLimited
< 0)
330 SmartScheduleLatencyLimited
= 0;
336 int *clientReady
; /* array of request ready clients */
340 HWEventQueuePtr
*icheck
= checkForInput
;
343 nextFreeClientID
= 1;
346 clientReady
= malloc(sizeof(int) * MaxClients
);
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
);
364 * Handle events in round robin fashion, doing input between
368 while (!dispatchException
&& (--nready
>= 0)) {
369 client
= clients
[clientReady
[nready
]];
371 /* KillClient can cause this to happen */
374 /* GrabServer activation can cause this to be true */
375 if (grabState
== GrabKickout
) {
376 grabState
= GrabActive
;
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
--;
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
);
402 CloseDownClient(client
);
407 client
->majorOp
= ((xReq
*) client
->requestBuffer
)->reqType
;
409 if (client
->majorOp
>= EXTENSION_BASE
) {
410 ExtensionEntry
*ext
= GetExtensionEntry(client
->majorOp
);
413 client
->minorOp
= ext
->MinorOpcode(client
);
415 #ifdef XSERVER_DTRACE
416 if (XSERVER_REQUEST_START_ENABLED())
417 XSERVER_REQUEST_START(LookupMajorName(client
->majorOp
),
419 ((xReq
*) client
->requestBuffer
)->length
,
421 client
->requestBuffer
);
423 if (result
> (maxBigRequestSize
<< 2))
426 result
= XaceHookDispatch(client
, client
->majorOp
);
427 if (result
== Success
)
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
);
439 if (client
->noClientException
!= Success
) {
440 CloseDownClient(client
);
443 else if (result
!= Success
) {
444 SendErrorToClient(client
, client
->majorOp
,
446 client
->errorValue
, result
);
451 client
= clients
[clientReady
[nready
]];
453 client
->smart_stop_tick
= SmartScheduleTime
;
455 dispatchException
&= ~DE_PRIORITYCHANGE
;
457 #if defined(DDXBEFORERESET)
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 };
472 SetVendorRelease(int release
)
474 VendorRelease
= release
;
478 SetVendorString(char *string
)
480 VendorString
= string
;
484 CreateConnectionBlock(void)
490 xPixmapFormat format
;
492 int i
, j
, k
, lenofblock
, sizesofar
= 0;
495 memset(&setup
, 0, sizeof(xConnSetup
));
496 /* Leave off the ridBase and ridMask, these must be sent with
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
);
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];
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
++) {
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
);
581 free(ConnectionInfo
);
584 ConnectionInfo
= pBuf
;
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
;
616 ProcBadRequest(ClientPtr client
)
622 ProcCreateWindow(ClientPtr client
)
624 WindowPtr pParent
, pWin
;
626 REQUEST(xCreateWindowReq
);
629 REQUEST_AT_LEAST_SIZE(xCreateWindowReq
);
631 LEGAL_NEW_RESOURCE(stuff
->wid
, client
);
632 rc
= dixLookupWindow(&pParent
, stuff
->parent
, client
, DixAddAccess
);
635 len
= client
->req_len
- bytes_to_int32(sizeof(xCreateWindowReq
));
636 if (Ones(stuff
->mask
) != len
)
638 if (!stuff
->width
|| !stuff
->height
) {
639 client
->errorValue
= 0;
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
);
648 Mask mask
= pWin
->eventMask
;
650 pWin
->eventMask
= 0; /* subterfuge in case AddResource fails */
651 if (!AddResource(stuff
->wid
, RT_WINDOW
, (pointer
) pWin
))
653 pWin
->eventMask
= mask
;
659 ProcChangeWindowAttributes(ClientPtr client
)
663 REQUEST(xChangeWindowAttributesReq
);
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
);
673 len
= client
->req_len
- bytes_to_int32(sizeof(xChangeWindowAttributesReq
));
674 if (len
!= Ones(stuff
->valueMask
))
676 return ChangeWindowAttributes(pWin
,
677 stuff
->valueMask
, (XID
*) &stuff
[1], client
);
681 ProcGetWindowAttributes(ClientPtr client
)
685 REQUEST(xResourceReq
);
686 xGetWindowAttributesReply wa
;
689 REQUEST_SIZE_MATCH(xResourceReq
);
690 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixGetAttrAccess
);
693 memset(&wa
, 0, sizeof(xGetWindowAttributesReply
));
694 GetWindowAttributes(pWin
, client
, &wa
);
695 WriteReplyToClient(client
, sizeof(xGetWindowAttributesReply
), &wa
);
700 ProcDestroyWindow(ClientPtr client
)
704 REQUEST(xResourceReq
);
707 REQUEST_SIZE_MATCH(xResourceReq
);
708 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixDestroyAccess
);
712 rc
= dixLookupWindow(&pWin
, pWin
->parent
->drawable
.id
, client
,
716 FreeResource(stuff
->id
, RT_NONE
);
722 ProcDestroySubwindows(ClientPtr client
)
726 REQUEST(xResourceReq
);
729 REQUEST_SIZE_MATCH(xResourceReq
);
730 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixRemoveAccess
);
733 DestroySubwindows(pWin
, client
);
738 ProcChangeSaveSet(ClientPtr client
)
742 REQUEST(xChangeSaveSetReq
);
745 REQUEST_SIZE_MATCH(xChangeSaveSetReq
);
746 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixManageAccess
);
749 if (client
->clientAsMask
== (CLIENT_BITS(pWin
->drawable
.id
)))
751 if ((stuff
->mode
== SetModeInsert
) || (stuff
->mode
== SetModeDelete
))
752 return AlterSaveSetForClient(client
, pWin
, stuff
->mode
, FALSE
, TRUE
);
753 client
->errorValue
= stuff
->mode
;
758 ProcReparentWindow(ClientPtr client
)
760 WindowPtr pWin
, pParent
;
762 REQUEST(xReparentWindowReq
);
765 REQUEST_SIZE_MATCH(xReparentWindowReq
);
766 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixManageAccess
);
769 rc
= dixLookupWindow(&pParent
, stuff
->parent
, client
, DixAddAccess
);
772 if (!SAME_SCREENS(pWin
->drawable
, pParent
->drawable
))
774 if ((pWin
->backgroundState
== ParentRelative
) &&
775 (pParent
->drawable
.depth
!= pWin
->drawable
.depth
))
777 if ((pWin
->drawable
.class != InputOnly
) &&
778 (pParent
->drawable
.class == InputOnly
))
780 return ReparentWindow(pWin
, pParent
,
781 (short) stuff
->x
, (short) stuff
->y
, client
);
785 ProcMapWindow(ClientPtr client
)
789 REQUEST(xResourceReq
);
792 REQUEST_SIZE_MATCH(xResourceReq
);
793 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixShowAccess
);
796 MapWindow(pWin
, client
);
797 /* update cache to say it is mapped */
802 ProcMapSubwindows(ClientPtr client
)
806 REQUEST(xResourceReq
);
809 REQUEST_SIZE_MATCH(xResourceReq
);
810 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixListAccess
);
813 MapSubwindows(pWin
, client
);
814 /* update cache to say it is mapped */
819 ProcUnmapWindow(ClientPtr client
)
823 REQUEST(xResourceReq
);
826 REQUEST_SIZE_MATCH(xResourceReq
);
827 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixHideAccess
);
830 UnmapWindow(pWin
, FALSE
);
831 /* update cache to say it is mapped */
836 ProcUnmapSubwindows(ClientPtr client
)
840 REQUEST(xResourceReq
);
843 REQUEST_SIZE_MATCH(xResourceReq
);
844 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixListAccess
);
847 UnmapSubwindows(pWin
);
852 ProcConfigureWindow(ClientPtr client
)
856 REQUEST(xConfigureWindowReq
);
859 REQUEST_AT_LEAST_SIZE(xConfigureWindowReq
);
860 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
,
861 DixManageAccess
| DixSetAttrAccess
);
864 len
= client
->req_len
- bytes_to_int32(sizeof(xConfigureWindowReq
));
865 if (Ones((Mask
) stuff
->mask
) != len
)
867 return ConfigureWindow(pWin
, (Mask
) stuff
->mask
, (XID
*) &stuff
[1], client
);
871 ProcCirculateWindow(ClientPtr client
)
875 REQUEST(xCirculateWindowReq
);
878 REQUEST_SIZE_MATCH(xCirculateWindowReq
);
879 if ((stuff
->direction
!= RaiseLowest
) && (stuff
->direction
!= LowerHighest
)) {
880 client
->errorValue
= stuff
->direction
;
883 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixManageAccess
);
886 CirculateWindow(pWin
, (int) stuff
->direction
, client
);
891 GetGeometry(ClientPtr client
, xGetGeometryReply
* rep
)
896 REQUEST(xResourceReq
);
897 REQUEST_SIZE_MATCH(xResourceReq
);
899 rc
= dixLookupDrawable(&pDraw
, stuff
->id
, client
, M_ANY
, DixGetAttrAccess
);
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;
927 ProcGetGeometry(ClientPtr client
)
929 xGetGeometryReply rep
;
932 memset(&rep
, 0, sizeof(xGetGeometryReply
));
933 if ((status
= GetGeometry(client
, &rep
)) != Success
)
936 WriteReplyToClient(client
, sizeof(xGetGeometryReply
), &rep
);
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
);
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
;
959 reply
.parent
= pWin
->parent
->drawable
.id
;
961 reply
.parent
= (Window
) None
;
962 pHead
= RealChildHead(pWin
);
963 for (pChild
= pWin
->lastChild
; pChild
!= pHead
; pChild
= pChild
->prevSib
)
968 childIDs
= malloc(numChildren
* sizeof(Window
));
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
);
981 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
982 WriteSwappedDataToClient(client
, numChildren
* sizeof(Window
),
991 ProcInternAtom(ClientPtr client
)
996 REQUEST(xInternAtomReq
);
998 REQUEST_FIXED_SIZE(xInternAtomReq
, stuff
->nbytes
);
999 if ((stuff
->onlyIfExists
!= xTrue
) && (stuff
->onlyIfExists
!= xFalse
)) {
1000 client
->errorValue
= stuff
->onlyIfExists
;
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
;
1011 reply
.sequenceNumber
= client
->sequence
;
1013 WriteReplyToClient(client
, sizeof(xInternAtomReply
), &reply
);
1021 ProcGetAtomName(ClientPtr client
)
1024 xGetAtomNameReply reply
;
1027 REQUEST(xResourceReq
);
1029 REQUEST_SIZE_MATCH(xResourceReq
);
1030 if ((str
= NameForAtom(stuff
->id
))) {
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
);
1042 client
->errorValue
= stuff
->id
;
1048 ProcGrabServer(ClientPtr client
)
1052 REQUEST_SIZE_MATCH(xReq
);
1053 if (grabState
!= GrabNone
&& client
!= grabClient
) {
1054 ResetCurrentRequest(client
);
1056 BITSET(grabWaiters
, client
->index
);
1057 IgnoreClient(client
);
1060 rc
= OnlyListenToOneClient(client
);
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
);
1078 UngrabServer(ClientPtr client
)
1082 grabState
= GrabNone
;
1083 ListenToAllClients();
1084 for (i
= mskcnt
; --i
>= 0 && !grabWaiters
[i
];);
1087 while (!GETBIT(grabWaiters
, 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
);
1111 ProcTranslateCoords(ClientPtr client
)
1113 REQUEST(xTranslateCoordsReq
);
1115 WindowPtr pWin
, pDst
;
1116 xTranslateCoordsReply rep
;
1119 REQUEST_SIZE_MATCH(xTranslateCoordsReq
);
1120 rc
= dixLookupWindow(&pWin
, stuff
->srcWid
, client
, DixGetAttrAccess
);
1123 rc
= dixLookupWindow(&pDst
, stuff
->dstWid
, client
, DixGetAttrAccess
);
1126 memset(&rep
, 0, sizeof(xTranslateCoordsReply
));
1129 rep
.sequenceNumber
= client
->sequence
;
1130 if (!SAME_SCREENS(pWin
->drawable
, pDst
->drawable
)) {
1131 rep
.sameScreen
= xFalse
;
1133 rep
.dstX
= rep
.dstY
= 0;
1138 rep
.sameScreen
= xTrue
;
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
;
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
+
1154 /* When a window is shaped, a further check
1155 * is made to see if the point is inside
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
;
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
);
1181 ProcOpenFont(ClientPtr client
)
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
) {
1200 ProcCloseFont(ClientPtr client
)
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
);
1215 client
->errorValue
= stuff
->id
;
1221 ProcQueryFont(ClientPtr client
)
1223 xQueryFontReply
*reply
;
1227 REQUEST(xResourceReq
);
1228 REQUEST_SIZE_MATCH(xResourceReq
);
1230 rc
= dixLookupFontable(&pFont
, stuff
->id
, client
, DixGetAttrAccess
);
1235 xCharInfo
*pmax
= FONTINKMAX(pFont
);
1236 xCharInfo
*pmin
= FONTINKMIN(pFont
);
1237 int nprotoxcistructs
;
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
);
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
);
1267 ProcQueryTextExtents(ClientPtr client
)
1269 xQueryTextExtentsReply reply
;
1272 unsigned long length
;
1275 REQUEST(xQueryTextExtentsReq
);
1276 REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq
);
1278 rc
= dixLookupFontable(&pFont
, stuff
->fid
, client
, DixGetAttrAccess
);
1282 length
= client
->req_len
- bytes_to_int32(sizeof(xQueryTextExtentsReq
));
1283 length
= length
<< 1;
1284 if (stuff
->oddLength
) {
1289 if (!QueryTextExtents(pFont
, length
, (unsigned char *) &stuff
[1], &info
))
1291 reply
.type
= X_Reply
;
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
);
1307 ProcListFonts(ClientPtr client
)
1309 REQUEST(xListFontsReq
);
1311 REQUEST_FIXED_SIZE(xListFontsReq
, stuff
->nbytes
);
1313 return ListFonts(client
, (unsigned char *) &stuff
[1], stuff
->nbytes
,
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
)
1346 REQUEST(xCreatePixmapReq
);
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
,
1359 if (!stuff
->width
|| !stuff
->height
) {
1360 client
->errorValue
= 0;
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
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
)
1384 client
->errorValue
= stuff
->depth
;
1388 pMap
= (PixmapPtr
) (*pDraw
->pScreen
->CreatePixmap
)
1389 (pDraw
->pScreen
, stuff
->width
, stuff
->height
, stuff
->depth
, 0);
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
);
1400 if (AddResource(stuff
->pid
, RT_PIXMAP
, (pointer
) pMap
))
1407 ProcFreePixmap(ClientPtr client
)
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
);
1422 client
->errorValue
= stuff
->id
;
1428 ProcCreateGC(ClientPtr client
)
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,
1445 len
= client
->req_len
- bytes_to_int32(sizeof(xCreateGCReq
));
1446 if (len
!= Ones(stuff
->mask
))
1448 pGC
= (GC
*) CreateGC(pDraw
, stuff
->mask
, (XID
*) &stuff
[1], &error
,
1450 if (error
!= Success
)
1452 if (!AddResource(stuff
->gc
, RT_GC
, (pointer
) pGC
))
1458 ProcChangeGC(ClientPtr client
)
1464 REQUEST(xChangeGCReq
);
1465 REQUEST_AT_LEAST_SIZE(xChangeGCReq
);
1467 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixSetAttrAccess
);
1468 if (result
!= Success
)
1471 len
= client
->req_len
- bytes_to_int32(sizeof(xChangeGCReq
));
1472 if (len
!= Ones(stuff
->mask
))
1475 return ChangeGCXIDs(client
, pGC
, stuff
->mask
, (CARD32
*) &stuff
[1]);
1479 ProcCopyGC(ClientPtr client
)
1485 REQUEST(xCopyGCReq
);
1486 REQUEST_SIZE_MATCH(xCopyGCReq
);
1488 result
= dixLookupGC(&pGC
, stuff
->srcGC
, client
, DixGetAttrAccess
);
1489 if (result
!= Success
)
1491 result
= dixLookupGC(&dstGC
, stuff
->dstGC
, client
, DixSetAttrAccess
);
1492 if (result
!= Success
)
1494 if ((dstGC
->pScreen
!= pGC
->pScreen
) || (dstGC
->depth
!= pGC
->depth
))
1496 if (stuff
->mask
& ~GCAllBits
) {
1497 client
->errorValue
= stuff
->mask
;
1500 return CopyGC(pGC
, dstGC
, stuff
->mask
);
1504 ProcSetDashes(ClientPtr client
)
1509 REQUEST(xSetDashesReq
);
1511 REQUEST_FIXED_SIZE(xSetDashesReq
, stuff
->nDashes
);
1512 if (stuff
->nDashes
== 0) {
1513 client
->errorValue
= 0;
1517 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixSetAttrAccess
);
1518 if (result
!= Success
)
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
)
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
;
1542 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixSetAttrAccess
);
1543 if (result
!= Success
)
1546 nr
= (client
->req_len
<< 2) - sizeof(xSetClipRectanglesReq
);
1550 return SetClipRects(pGC
, stuff
->xOrigin
, stuff
->yOrigin
,
1551 nr
, (xRectangle
*) &stuff
[1], (int) stuff
->ordering
);
1555 ProcFreeGC(ClientPtr client
)
1560 REQUEST(xResourceReq
);
1561 REQUEST_SIZE_MATCH(xResourceReq
);
1563 rc
= dixLookupGC(&pGC
, stuff
->id
, client
, DixDestroyAccess
);
1567 FreeResource(stuff
->id
, RT_NONE
);
1572 ProcClearToBackground(ClientPtr client
)
1574 REQUEST(xClearAreaReq
);
1578 REQUEST_SIZE_MATCH(xClearAreaReq
);
1579 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
1582 if (pWin
->drawable
.class == InputOnly
) {
1583 client
->errorValue
= stuff
->window
;
1586 if ((stuff
->exposures
!= xTrue
) && (stuff
->exposures
!= xFalse
)) {
1587 client
->errorValue
= stuff
->exposures
;
1590 (*pWin
->drawable
.pScreen
->ClearToBackground
) (pWin
, stuff
->x
, stuff
->y
,
1591 stuff
->width
, stuff
->height
,
1592 (Bool
) stuff
->exposures
);
1597 ProcCopyArea(ClientPtr client
)
1603 REQUEST(xCopyAreaReq
);
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,
1615 if ((pDst
->pScreen
!= pSrc
->pScreen
) || (pDst
->depth
!= pSrc
->depth
)) {
1616 client
->errorValue
= stuff
->dstDrawable
;
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);
1630 RegionDestroy(pRgn
);
1637 ProcCopyPlane(ClientPtr client
)
1639 DrawablePtr psrcDraw
, pdstDraw
;
1642 REQUEST(xCopyPlaneReq
);
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,
1655 if (pdstDraw
->pScreen
!= psrcDraw
->pScreen
) {
1656 client
->errorValue
= stuff
->dstDrawable
;
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
;
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);
1678 RegionDestroy(pRgn
);
1684 ProcPolyPoint(ClientPtr client
)
1690 REQUEST(xPolyPointReq
);
1692 REQUEST_AT_LEAST_SIZE(xPolyPointReq
);
1693 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1694 (stuff
->coordMode
!= CoordModePrevious
)) {
1695 client
->errorValue
= stuff
->coordMode
;
1698 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1699 npoint
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xPolyPointReq
));
1701 (*pGC
->ops
->PolyPoint
) (pDraw
, pGC
, stuff
->coordMode
, npoint
,
1702 (xPoint
*) &stuff
[1]);
1707 ProcPolyLine(ClientPtr client
)
1713 REQUEST(xPolyLineReq
);
1715 REQUEST_AT_LEAST_SIZE(xPolyLineReq
);
1716 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1717 (stuff
->coordMode
!= CoordModePrevious
)) {
1718 client
->errorValue
= stuff
->coordMode
;
1721 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1722 npoint
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xPolyLineReq
));
1724 (*pGC
->ops
->Polylines
) (pDraw
, pGC
, stuff
->coordMode
, npoint
,
1725 (DDXPointPtr
) &stuff
[1]);
1730 ProcPolySegment(ClientPtr client
)
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
);
1745 (*pGC
->ops
->PolySegment
) (pDraw
, pGC
, nsegs
, (xSegment
*) &stuff
[1]);
1750 ProcPolyRectangle(ClientPtr client
)
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
);
1765 (*pGC
->ops
->PolyRectangle
) (pDraw
, pGC
,
1766 nrects
, (xRectangle
*) &stuff
[1]);
1771 ProcPolyArc(ClientPtr client
)
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
))
1784 narcs
/= sizeof(xArc
);
1786 (*pGC
->ops
->PolyArc
) (pDraw
, pGC
, narcs
, (xArc
*) &stuff
[1]);
1791 ProcFillPoly(ClientPtr client
)
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
;
1805 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1806 (stuff
->coordMode
!= CoordModePrevious
)) {
1807 client
->errorValue
= stuff
->coordMode
;
1811 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1812 things
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xFillPolyReq
));
1814 (*pGC
->ops
->FillPolygon
) (pDraw
, pGC
, stuff
->shape
,
1815 stuff
->coordMode
, things
,
1816 (DDXPointPtr
) &stuff
[1]);
1821 ProcPolyFillRectangle(ClientPtr client
)
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
);
1837 (*pGC
->ops
->PolyFillRect
) (pDraw
, pGC
, things
,
1838 (xRectangle
*) &stuff
[1]);
1843 ProcPolyFillArc(ClientPtr client
)
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
))
1856 narcs
/= sizeof(xArc
);
1858 (*pGC
->ops
->PolyFillArc
) (pDraw
, pGC
, narcs
, (xArc
*) &stuff
[1]);
1862 #ifdef MATCH_CLIENT_ENDIAN
1869 if (*((char *) &whichbyte
))
1874 #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
1877 ReformatImage(char *base
, int nbytes
, int bpp
, int order
)
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
);
1892 if (IMAGE_BYTE_ORDER
!= order
)
1893 TwoByteSwap((unsigned char *) base
, nbytes
);
1896 if (IMAGE_BYTE_ORDER
!= order
)
1897 FourByteSwap((unsigned char *) base
, nbytes
);
1902 #define ReformatImage(b,n,bpp,o)
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
)
1921 long length
; /* length of scanline server padded */
1922 long lengthProto
; /* length of scanline protocol padded */
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
))
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
))
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))
1945 length
= PixmapBytePad(stuff
->width
, stuff
->depth
);
1948 client
->errorValue
= stuff
->format
;
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
)
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
);
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
;
1979 /* coordinates relative to the bounding drawable */
1981 long widthBytesLine
, length
;
1985 RegionPtr pVisibleRegion
= NULL
;
1987 if ((format
!= XYPixmap
) && (format
!= ZPixmap
)) {
1988 client
->errorValue
= format
;
1991 rc
= dixLookupDrawable(&pDraw
, drawable
, client
, 0, DixReadAccess
);
1995 memset(&xgi
, 0, sizeof(xGetImageReply
));
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
)
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
)
2019 if (pDraw
->pScreen
->GetWindowPixmap
) {
2020 PixmapPtr pPix
= (*pDraw
->pScreen
->GetWindowPixmap
) (pWin
);
2022 pBoundingDraw
= &pPix
->drawable
;
2024 relx
-= pPix
->screen_x
;
2025 rely
-= pPix
->screen_y
;
2029 pBoundingDraw
= (DrawablePtr
) pDraw
->pScreen
->root
;
2032 xgi
.visual
= wVisual(pWin
);
2035 pBoundingDraw
= pDraw
;
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
)
2055 xgi
.sequenceNumber
= client
->sequence
;
2056 xgi
.depth
= pDraw
->depth
;
2057 if (format
== ZPixmap
) {
2058 widthBytesLine
= PixmapBytePad(width
, pDraw
->depth
);
2059 length
= widthBytesLine
* height
;
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
;
2074 pBuf
= calloc(1, sz_xGetImageReply
+ length
);
2077 if (widthBytesLine
== 0)
2080 linesPerBuf
= height
;
2081 *im_return
= (xGetImageReply
*) pBuf
;
2082 *(xGetImageReply
*) pBuf
= xgi
;
2083 pBuf
+= sz_xGetImageReply
;
2086 xgi
.length
= bytes_to_int32(xgi
.length
);
2087 if (widthBytesLine
== 0 || height
== 0)
2089 else if (widthBytesLine
>= IMAGE_BUFSIZE
)
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))) {
2102 length
-= widthBytesLine
;
2104 while (length
& ((1L << LOG2_BYTES_PER_SCANLINE_PAD
) - 1)) {
2106 length
+= widthBytesLine
;
2109 if (!(pBuf
= calloc(1, length
)))
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) {
2124 else if (format
== ZPixmap
) {
2126 while (height
- linesDone
> 0) {
2127 nlines
= min(linesPerBuf
, height
- linesDone
);
2128 (*pDraw
->pScreen
->GetImage
) (pDraw
,
2133 format
, planemask
, (pointer
) pBuf
);
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 */
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
) {
2157 while (height
- linesDone
> 0) {
2158 nlines
= min(linesPerBuf
, height
- linesDone
);
2159 (*pDraw
->pScreen
->GetImage
) (pDraw
,
2164 format
, plane
, (pointer
) pBuf
);
2166 XaceCensorImage(client
, pVisibleRegion
,
2168 pDraw
, x
, y
+ linesDone
, width
,
2169 nlines
, format
, pBuf
);
2171 /* Note: NOT a call to WriteSwappedDataToClient,
2172 as we do NOT byte swap */
2174 pBuf
+= nlines
* widthBytesLine
;
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
),
2186 linesDone
+= nlines
;
2192 RegionDestroy(pVisibleRegion
);
2199 ProcGetImage(ClientPtr client
)
2201 REQUEST(xGetImageReq
);
2203 REQUEST_SIZE_MATCH(xGetImageReq
);
2205 return DoGetImage(client
, stuff
->format
, stuff
->drawable
,
2207 (int) stuff
->width
, (int) stuff
->height
,
2208 stuff
->planeMask
, (xGetImageReply
**) NULL
);
2212 ProcPolyText(ClientPtr client
)
2216 REQUEST(xPolyTextReq
);
2220 REQUEST_AT_LEAST_SIZE(xPolyTextReq
);
2221 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
2223 err
= PolyText(client
,
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
) {
2238 ProcImageText8(ClientPtr client
)
2244 REQUEST(xImageTextReq
);
2246 REQUEST_FIXED_SIZE(xImageTextReq
, stuff
->nChars
);
2247 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
2249 err
= ImageText(client
,
2253 (unsigned char *) &stuff
[1],
2254 stuff
->x
, stuff
->y
, stuff
->reqType
, stuff
->drawable
);
2256 if (err
== Success
) {
2264 ProcImageText16(ClientPtr client
)
2270 REQUEST(xImageTextReq
);
2272 REQUEST_FIXED_SIZE(xImageTextReq
, stuff
->nChars
<< 1);
2273 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
2275 err
= ImageText(client
,
2279 (unsigned char *) &stuff
[1],
2280 stuff
->x
, stuff
->y
, stuff
->reqType
, stuff
->drawable
);
2282 if (err
== Success
) {
2290 ProcCreateColormap(ClientPtr client
)
2298 REQUEST(xCreateColormapReq
);
2301 REQUEST_SIZE_MATCH(xCreateColormapReq
);
2303 if ((stuff
->alloc
!= AllocNone
) && (stuff
->alloc
!= AllocAll
)) {
2304 client
->errorValue
= stuff
->alloc
;
2308 LEGAL_NEW_RESOURCE(mid
, client
);
2309 result
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
2310 if (result
!= Success
)
2313 pScreen
= pWin
->drawable
.pScreen
;
2314 for (i
= 0, pVisual
= pScreen
->visuals
;
2315 i
< pScreen
->numVisuals
; i
++, pVisual
++) {
2316 if (pVisual
->vid
!= stuff
->visual
)
2318 return CreateColormap(mid
, pScreen
, pVisual
, &pmap
,
2319 (int) stuff
->alloc
, client
->index
);
2321 client
->errorValue
= stuff
->visual
;
2326 ProcFreeColormap(ClientPtr client
)
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
);
2343 client
->errorValue
= stuff
->id
;
2349 ProcCopyColormapAndFree(ClientPtr client
)
2352 ColormapPtr pSrcMap
;
2354 REQUEST(xCopyColormapAndFreeReq
);
2357 REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq
);
2359 LEGAL_NEW_RESOURCE(mid
, client
);
2360 rc
= dixLookupResourceByType((pointer
*) &pSrcMap
, stuff
->srcCmap
,
2361 RT_COLORMAP
, client
,
2362 DixReadAccess
| DixRemoveAccess
);
2364 return CopyColormapAndFree(mid
, pSrcMap
, client
->index
);
2365 client
->errorValue
= stuff
->srcCmap
;
2370 ProcInstallColormap(ClientPtr client
)
2375 REQUEST(xResourceReq
);
2376 REQUEST_SIZE_MATCH(xResourceReq
);
2378 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->id
, RT_COLORMAP
,
2379 client
, DixInstallAccess
);
2383 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pcmp
->pScreen
, DixSetAttrAccess
);
2384 if (rc
!= Success
) {
2390 (*(pcmp
->pScreen
->InstallColormap
)) (pcmp
);
2394 client
->errorValue
= stuff
->id
;
2399 ProcUninstallColormap(ClientPtr client
)
2404 REQUEST(xResourceReq
);
2405 REQUEST_SIZE_MATCH(xResourceReq
);
2407 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->id
, RT_COLORMAP
,
2408 client
, DixUninstallAccess
);
2412 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pcmp
->pScreen
, DixSetAttrAccess
);
2413 if (rc
!= Success
) {
2419 if (pcmp
->mid
!= pcmp
->pScreen
->defColormap
)
2420 (*(pcmp
->pScreen
->UninstallColormap
)) (pcmp
);
2424 client
->errorValue
= stuff
->id
;
2429 ProcListInstalledColormaps(ClientPtr client
)
2431 xListInstalledColormapsReply
*preply
;
2435 REQUEST(xResourceReq
);
2436 REQUEST_SIZE_MATCH(xResourceReq
);
2438 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixGetAttrAccess
);
2442 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pWin
->drawable
.pScreen
,
2447 preply
= malloc(sizeof(xListInstalledColormapsReply
) +
2448 pWin
->drawable
.pScreen
->maxInstalledCmaps
*
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]);
2467 ProcAllocColor(ClientPtr client
)
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
) {
2481 acr
.sequenceNumber
= client
->sequence
;
2482 acr
.red
= stuff
->red
;
2483 acr
.green
= stuff
->green
;
2484 acr
.blue
= stuff
->blue
;
2486 if ((rc
= AllocColor(pmap
, &acr
.red
, &acr
.green
, &acr
.blue
,
2487 &acr
.pixel
, client
->index
)))
2490 if (noPanoramiXExtension
|| !pmap
->pScreen
->myNum
)
2492 WriteReplyToClient(client
, sizeof(xAllocColorReply
), &acr
);
2497 client
->errorValue
= stuff
->cmap
;
2503 ProcAllocNamedColor(ClientPtr client
)
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
;
2518 ancr
.sequenceNumber
= client
->sequence
;
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
;
2527 if ((rc
= AllocColor(pcmp
,
2528 &ancr
.screenRed
, &ancr
.screenGreen
,
2529 &ancr
.screenBlue
, &ancr
.pixel
, client
->index
)))
2532 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2534 WriteReplyToClient(client
, sizeof(xAllocNamedColorReply
),
2543 client
->errorValue
= stuff
->cmap
;
2549 ProcAllocColorCells(ClientPtr client
)
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
;
2563 Pixel
*ppixels
, *pmasks
;
2565 npixels
= stuff
->colors
;
2567 client
->errorValue
= npixels
;
2570 if (stuff
->contiguous
!= xTrue
&& stuff
->contiguous
!= xFalse
) {
2571 client
->errorValue
= stuff
->contiguous
;
2574 nmasks
= stuff
->planes
;
2575 length
= ((long) npixels
+ (long) nmasks
) * sizeof(Pixel
);
2576 ppixels
= malloc(length
);
2579 pmasks
= ppixels
+ npixels
;
2581 if ((rc
= AllocColorCells(client
->index
, pcmp
, npixels
, nmasks
,
2582 (Bool
) stuff
->contiguous
, ppixels
, pmasks
))) {
2587 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
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
);
2603 client
->errorValue
= stuff
->cmap
;
2609 ProcAllocColorPlanes(ClientPtr client
)
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
;
2625 npixels
= stuff
->colors
;
2627 client
->errorValue
= npixels
;
2630 if (stuff
->contiguous
!= xTrue
&& stuff
->contiguous
!= xFalse
) {
2631 client
->errorValue
= stuff
->contiguous
;
2634 acpr
.type
= X_Reply
;
2635 acpr
.sequenceNumber
= client
->sequence
;
2636 acpr
.nPixels
= npixels
;
2637 length
= (long) npixels
*sizeof(Pixel
);
2639 ppixels
= malloc(length
);
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
,
2650 acpr
.length
= bytes_to_int32(length
);
2652 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2655 WriteReplyToClient(client
, sizeof(xAllocColorPlanesReply
), &acpr
);
2656 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2657 WriteSwappedDataToClient(client
, length
, ppixels
);
2663 client
->errorValue
= stuff
->cmap
;
2669 ProcFreeColors(ClientPtr client
)
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
) {
2682 if (pcmp
->flags
& AllAllocated
)
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
);
2689 client
->errorValue
= stuff
->cmap
;
2695 ProcStoreColors(ClientPtr client
)
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
) {
2708 count
= (client
->req_len
<< 2) - sizeof(xStoreColorsReq
);
2709 if (count
% sizeof(xColorItem
))
2711 count
/= sizeof(xColorItem
);
2712 return StoreColors(pcmp
, count
, (xColorItem
*) &stuff
[1], client
);
2715 client
->errorValue
= stuff
->cmap
;
2721 ProcStoreNamedColor(ClientPtr client
)
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
) {
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
);
2743 client
->errorValue
= stuff
->cmap
;
2749 ProcQueryColors(ClientPtr client
)
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
) {
2762 xQueryColorsReply qcr
;
2765 bytes_to_int32((client
->req_len
<< 2) - sizeof(xQueryColorsReq
));
2766 prgbs
= calloc(1, count
* sizeof(xrgb
));
2767 if (!prgbs
&& count
)
2770 QueryColors(pcmp
, count
, (Pixel
*) &stuff
[1], prgbs
, client
))) {
2774 memset(&qcr
, 0, sizeof(xQueryColorsReply
));
2776 qcr
.length
= bytes_to_int32(count
* sizeof(xrgb
));
2777 qcr
.sequenceNumber
= client
->sequence
;
2778 qcr
.nColors
= count
;
2779 WriteReplyToClient(client
, sizeof(xQueryColorsReply
), &qcr
);
2781 client
->pSwapReplyFunc
= (ReplySwapPtr
) SQColorsExtend
;
2782 WriteSwappedDataToClient(client
, count
* sizeof(xrgb
), prgbs
);
2789 client
->errorValue
= stuff
->cmap
;
2795 ProcLookupColor(ClientPtr client
)
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
;
2809 (pcmp
->pScreen
->myNum
, (char *) &stuff
[1], stuff
->nbytes
,
2810 &lcr
.exactRed
, &lcr
.exactGreen
, &lcr
.exactBlue
)) {
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
,
2819 &lcr
.screenBlue
, pcmp
->pVisual
);
2820 WriteReplyToClient(client
, sizeof(xLookupColorReply
), &lcr
);
2826 client
->errorValue
= stuff
->cmap
;
2832 ProcCreateCursor(ClientPtr client
)
2837 unsigned char *srcbits
;
2838 unsigned char *mskbits
;
2839 unsigned short width
, height
;
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
;
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
;
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)
2869 width
= src
->drawable
.width
;
2870 height
= src
->drawable
.height
;
2872 if (stuff
->x
> width
|| stuff
->y
> height
)
2875 n
= BitmapBytePad(width
) * height
;
2876 srcbits
= calloc(1, n
);
2879 mskbits
= malloc(n
);
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
;
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,
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
);
2911 if (!AddResource(stuff
->cid
, RT_CURSOR
, (pointer
) pCursor
)) {
2924 ProcCreateGlyphCursor(ClientPtr client
)
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
);
2941 if (AddResource(stuff
->cid
, RT_CURSOR
, (pointer
) pCursor
))
2947 ProcFreeCursor(ClientPtr client
)
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
);
2962 client
->errorValue
= stuff
->id
;
2968 ProcQueryBestSize(ClientPtr client
)
2970 xQueryBestSizeReply reply
;
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;
2984 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
2988 if (stuff
->class != CursorShape
&& pDraw
->type
== UNDRAWABLE_WINDOW
)
2990 pScreen
= pDraw
->pScreen
;
2991 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pScreen
, DixGetAttrAccess
);
2994 (*pScreen
->QueryBestSize
) (stuff
->class, &stuff
->width
,
2995 &stuff
->height
, pScreen
);
2996 memset(&reply
, 0, sizeof(xQueryBestSizeReply
));
2997 reply
.type
= X_Reply
;
2999 reply
.sequenceNumber
= client
->sequence
;
3000 reply
.width
= stuff
->width
;
3001 reply
.height
= stuff
->height
;
3002 WriteReplyToClient(client
, sizeof(xQueryBestSizeReply
), &reply
);
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
],
3021 blankingOption
= stuff
->preferBlank
;
3022 if ((blankingOption
!= DontPreferBlanking
) &&
3023 (blankingOption
!= PreferBlanking
) &&
3024 (blankingOption
!= DefaultBlanking
)) {
3025 client
->errorValue
= blankingOption
;
3028 exposureOption
= stuff
->allowExpose
;
3029 if ((exposureOption
!= DontAllowExposures
) &&
3030 (exposureOption
!= AllowExposures
) &&
3031 (exposureOption
!= DefaultExposures
)) {
3032 client
->errorValue
= exposureOption
;
3035 if (stuff
->timeout
< -1) {
3036 client
->errorValue
= stuff
->timeout
;
3039 if (stuff
->interval
< -1) {
3040 client
->errorValue
= stuff
->interval
;
3044 if (blankingOption
== DefaultBlanking
)
3045 ScreenSaverBlanking
= defaultScreenSaverBlanking
;
3047 ScreenSaverBlanking
= blankingOption
;
3048 if (exposureOption
== DefaultExposures
)
3049 ScreenSaverAllowExposures
= defaultScreenSaverAllowExposures
;
3051 ScreenSaverAllowExposures
= exposureOption
;
3053 if (stuff
->timeout
>= 0)
3054 ScreenSaverTime
= stuff
->timeout
* MILLI_PER_SECOND
;
3056 ScreenSaverTime
= defaultScreenSaverTime
;
3057 if (stuff
->interval
>= 0)
3058 ScreenSaverInterval
= stuff
->interval
* MILLI_PER_SECOND
;
3060 ScreenSaverInterval
= defaultScreenSaverInterval
;
3062 SetScreenSaverTimer();
3067 ProcGetScreenSaver(ClientPtr client
)
3069 xGetScreenSaverReply rep
;
3072 REQUEST_SIZE_MATCH(xReq
);
3074 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
3075 rc
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, screenInfo
.screens
[i
],
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
);
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
;
3110 ProcListHosts(ClientPtr client
)
3112 xListHostsReply reply
;
3113 int len
, nHosts
, result
;
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
)
3125 result
= GetHosts(&pdata
, &nHosts
, &len
, &reply
.enabled
);
3126 if (result
!= Success
)
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
);
3134 client
->pSwapReplyFunc
= (ReplySwapPtr
) SLHostsExtend
;
3135 WriteSwappedDataToClient(client
, len
, pdata
);
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
;
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 *********************/
3162 CloseDownRetainedResources(void)
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
;
3182 REQUEST_SIZE_MATCH(xResourceReq
);
3183 if (stuff
->id
== AllTemporary
) {
3184 CloseDownRetainedResources();
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
;
3206 ProcSetFontPath(ClientPtr client
)
3209 unsigned long nbytes
, total
;
3213 REQUEST(xSetFontPathReq
);
3215 REQUEST_AT_LEAST_SIZE(xSetFontPathReq
);
3217 nbytes
= (client
->req_len
<< 2) - sizeof(xSetFontPathReq
);
3219 ptr
= (unsigned char *) &stuff
[1];
3220 nfonts
= stuff
->nFonts
;
3221 while (--nfonts
>= 0) {
3222 if ((total
== 0) || (total
< (n
= (*ptr
+ 1))))
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
);
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
);
3259 ProcChangeCloseDownMode(ClientPtr client
)
3263 REQUEST(xSetCloseDownModeReq
);
3264 REQUEST_SIZE_MATCH(xSetCloseDownModeReq
);
3266 rc
= XaceHook(XACE_CLIENT_ACCESS
, client
, client
, DixManageAccess
);
3270 if ((stuff
->mode
== AllTemporary
) ||
3271 (stuff
->mode
== RetainPermanent
) || (stuff
->mode
== RetainTemporary
)) {
3272 client
->closeDownMode
= stuff
->mode
;
3276 client
->errorValue
= stuff
->mode
;
3282 ProcForceScreenSaver(ClientPtr client
)
3286 REQUEST(xForceScreenSaverReq
);
3288 REQUEST_SIZE_MATCH(xForceScreenSaverReq
);
3290 if ((stuff
->mode
!= ScreenSaverReset
) && (stuff
->mode
!= ScreenSaverActive
)) {
3291 client
->errorValue
= stuff
->mode
;
3294 rc
= dixSaveScreens(client
, SCREEN_SAVER_FORCER
, (int) stuff
->mode
);
3301 ProcNoOperation(ClientPtr client
)
3303 REQUEST_AT_LEAST_SIZE(xReq
);
3305 /* noop -- don't do anything */
3309 /**********************
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
;
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
) {
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
);
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
--;
3401 KillAllClients(void)
3405 for (i
= 1; i
< currentMaxClients
; i
++)
3407 /* Make sure Retained clients are released. */
3408 clients
[i
]->closeDownMode
= DestroyAll
;
3409 CloseDownClient(clients
[i
]);
3414 InitClient(ClientPtr client
, int i
, pointer ospriv
)
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 *************************/
3436 NextAvailableClient(pointer ospriv
)
3442 i
= nextFreeClientID
;
3443 if (i
== MAXCLIENTS
)
3444 return (ClientPtr
) NULL
;
3445 clients
[i
] = client
=
3446 dixAllocateObjectWithPrivates(ClientRec
, PRIVATE_CLIENT
);
3448 return (ClientPtr
) NULL
;
3449 InitClient(client
, i
, ospriv
);
3450 if (!InitClientResources(client
)) {
3451 dixFreeObjectWithPrivates(client
, PRIVATE_CLIENT
);
3452 return (ClientPtr
) NULL
;
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
])
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
);
3482 ProcInitialConnection(ClientPtr client
)
3485 xConnClientPrefix
*prefix
;
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
);
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
);
3507 SendConnSetup(ClientPtr client
, const char *reason
)
3512 char *lConnectionInfo
;
3513 xConnSetupPrefix
*lconnSetupPrefix
;
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
);
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
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
);
3550 /* fill in the "currentInputMask" */
3551 root
= (xWindowRoot
*) (lConnectionInfo
+ connBlockScreenStart
);
3553 if (noPanoramiXExtension
)
3554 numScreens
= screenInfo
.numScreens
;
3556 numScreens
= ((xConnSetup
*) ConnectionInfo
)->numRoots
;
3559 for (i
= 0; i
< numScreens
; i
++) {
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),
3580 (void) WriteToClient(client
, sizeof(xConnSetupPrefix
),
3581 (char *) lconnSetupPrefix
);
3582 (void) WriteToClient(client
, (int) (lconnSetupPrefix
->length
<< 2),
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
);
3598 ProcEstablishConnection(ClientPtr client
)
3601 char *auth_proto
, *auth_string
;
3602 xConnClientPrefix
*prefix
;
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";
3613 reason
= ClientAuthorized(client
,
3614 (unsigned short) prefix
->nbytesAuthProto
,
3616 (unsigned short) prefix
->nbytesAuthString
,
3619 return (SendConnSetup(client
, reason
));
3623 SendErrorToClient(ClientPtr client
, unsigned majorCode
, unsigned minorCode
,
3624 XID resId
, int errorCode
)
3628 memset(&rep
, 0, sizeof(xError
));
3630 rep
.errorCode
= errorCode
;
3631 rep
.majorCode
= majorCode
;
3632 rep
.minorCode
= minorCode
;
3633 rep
.resourceID
= resId
;
3635 WriteEventsToClient(client
, 1, (xEvent
*) &rep
);
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 */
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 */
3671 3, ~0, ~0, ~0, /* 16 bits per pixel */
3673 4, ~0, ~0, ~0, /* 24 bits per pixel */
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 */
3687 0, ~0, ~0, ~0, /* 16 bits per pixel */
3689 3, ~0, ~0, ~0, /* 24 bits per pixel */
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] = {
3702 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
3704 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
3708 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
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 */ ,
3732 ), int argc
, char **argv
)
3736 int scanlinepad
, format
, depth
, bitsPerPixel
, j
, k
;
3739 i
= screenInfo
.numScreens
;
3740 if (i
== MAXSCREENS
)
3743 pScreen
= (ScreenPtr
) calloc(1, sizeof(ScreenRec
));
3747 if (!dixAllocatePrivates(&pScreen
->devPrivates
, PRIVATE_SCREEN
)) {
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
];
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
3795 screenInfo
.screens
[i
] = pScreen
;
3796 screenInfo
.numScreens
++;
3797 if (!(*pfnInit
) (i
, pScreen
, argc
, argv
)) {
3798 dixFreePrivates(pScreen
->devPrivates
, PRIVATE_SCREEN
);
3800 screenInfo
.numScreens
--;
3804 update_desktop_dimensions();
3806 dixRegisterScreenPrivateKey(&cursorScreenDevPriv
, pScreen
, PRIVATE_CURSOR
,