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 /* in milliseconds */
224 #define SMART_SCHEDULE_DEFAULT_INTERVAL 5
225 #define SMART_SCHEDULE_MAX_SLICE 15
227 #if defined(WIN32) && !defined(__CYGWIN__)
228 Bool SmartScheduleDisable
= TRUE
;
230 Bool SmartScheduleDisable
= FALSE
;
232 long SmartScheduleSlice
= SMART_SCHEDULE_DEFAULT_INTERVAL
;
233 long SmartScheduleInterval
= SMART_SCHEDULE_DEFAULT_INTERVAL
;
234 long SmartScheduleMaxSlice
= SMART_SCHEDULE_MAX_SLICE
;
235 long SmartScheduleTime
;
236 int SmartScheduleLatencyLimited
= 0;
237 static ClientPtr SmartLastClient
;
238 static int SmartLastIndex
[SMART_MAX_PRIORITY
- SMART_MIN_PRIORITY
+ 1];
247 SmartScheduleClient(int *clientReady
, int nready
)
252 int bestPrio
, best
= 0;
253 int bestRobin
, robin
;
254 long now
= SmartScheduleTime
;
257 bestPrio
= -0x7fffffff;
259 idle
= 2 * SmartScheduleSlice
;
260 for (i
= 0; i
< nready
; i
++) {
261 client
= clientReady
[i
];
262 pClient
= clients
[client
];
263 /* Praise clients which are idle */
264 if ((now
- pClient
->smart_check_tick
) >= idle
) {
265 if (pClient
->smart_priority
< 0)
266 pClient
->smart_priority
++;
268 pClient
->smart_check_tick
= now
;
270 /* check priority to select best client */
273 SmartLastIndex
[pClient
->smart_priority
-
274 SMART_MIN_PRIORITY
]) & 0xff;
275 if (pClient
->smart_priority
> bestPrio
||
276 (pClient
->smart_priority
== bestPrio
&& robin
> bestRobin
)) {
277 bestPrio
= pClient
->smart_priority
;
282 if ((now
- SmartLastPrint
) >= 5000)
283 fprintf(stderr
, " %2d: %3d", client
, pClient
->smart_priority
);
287 if ((now
- SmartLastPrint
) >= 5000) {
288 fprintf(stderr
, " use %2d\n", best
);
289 SmartLastPrint
= now
;
292 pClient
= clients
[best
];
293 SmartLastIndex
[bestPrio
- SMART_MIN_PRIORITY
] = pClient
->index
;
295 * Set current client pointer
297 if (SmartLastClient
!= pClient
) {
298 pClient
->smart_start_tick
= now
;
299 SmartLastClient
= pClient
;
304 if (nready
== 1 && SmartScheduleLatencyLimited
== 0) {
306 * If it's been a long time since another client
307 * has run, bump the slice up to get maximal
308 * performance from a single client
310 if ((now
- pClient
->smart_start_tick
) > 1000 &&
311 SmartScheduleSlice
< SmartScheduleMaxSlice
) {
312 SmartScheduleSlice
+= SmartScheduleInterval
;
316 SmartScheduleSlice
= SmartScheduleInterval
;
322 EnableLimitedSchedulingLatency(void)
324 ++SmartScheduleLatencyLimited
;
325 SmartScheduleSlice
= SmartScheduleInterval
;
329 DisableLimitedSchedulingLatency(void)
331 --SmartScheduleLatencyLimited
;
333 /* protect against bugs */
334 if (SmartScheduleLatencyLimited
< 0)
335 SmartScheduleLatencyLimited
= 0;
341 int *clientReady
; /* array of request ready clients */
345 HWEventQueuePtr
*icheck
= checkForInput
;
348 nextFreeClientID
= 1;
351 clientReady
= malloc(sizeof(int) * MaxClients
);
355 SmartScheduleSlice
= SmartScheduleInterval
;
356 while (!dispatchException
) {
357 if (*icheck
[0] != *icheck
[1]) {
358 ProcessInputEvents();
359 FlushIfCriticalOutputPending();
362 nready
= WaitForSomething(clientReady
);
364 if (nready
&& !SmartScheduleDisable
) {
365 clientReady
[0] = SmartScheduleClient(clientReady
, nready
);
369 * Handle events in round robin fashion, doing input between
373 while (!dispatchException
&& (--nready
>= 0)) {
374 client
= clients
[clientReady
[nready
]];
376 /* KillClient can cause this to happen */
379 /* GrabServer activation can cause this to be true */
380 if (grabState
== GrabKickout
) {
381 grabState
= GrabActive
;
384 isItTimeToYield
= FALSE
;
386 start_tick
= SmartScheduleTime
;
387 while (!isItTimeToYield
) {
388 if (*icheck
[0] != *icheck
[1])
389 ProcessInputEvents();
391 FlushIfCriticalOutputPending();
392 if (!SmartScheduleDisable
&&
393 (SmartScheduleTime
- start_tick
) >= SmartScheduleSlice
) {
394 /* Penalize clients which consume ticks */
395 if (client
->smart_priority
> SMART_MIN_PRIORITY
)
396 client
->smart_priority
--;
399 /* now, finally, deal with client requests */
401 /* Update currentTime so request time checks, such as for input
402 * device grabs, are calculated correctly */
403 UpdateCurrentTimeIf();
404 result
= ReadRequestFromClient(client
);
407 CloseDownClient(client
);
412 client
->majorOp
= ((xReq
*) client
->requestBuffer
)->reqType
;
414 if (client
->majorOp
>= EXTENSION_BASE
) {
415 ExtensionEntry
*ext
= GetExtensionEntry(client
->majorOp
);
418 client
->minorOp
= ext
->MinorOpcode(client
);
420 #ifdef XSERVER_DTRACE
421 if (XSERVER_REQUEST_START_ENABLED())
422 XSERVER_REQUEST_START(LookupMajorName(client
->majorOp
),
424 ((xReq
*) client
->requestBuffer
)->length
,
426 client
->requestBuffer
);
428 if (result
> (maxBigRequestSize
<< 2))
431 result
= XaceHookDispatch(client
, client
->majorOp
);
432 if (result
== Success
)
434 (*client
->requestVector
[client
->majorOp
]) (client
);
435 XaceHookAuditEnd(client
, result
);
437 #ifdef XSERVER_DTRACE
438 if (XSERVER_REQUEST_DONE_ENABLED())
439 XSERVER_REQUEST_DONE(LookupMajorName(client
->majorOp
),
440 client
->majorOp
, client
->sequence
,
441 client
->index
, result
);
444 if (client
->noClientException
!= Success
) {
445 CloseDownClient(client
);
448 else if (result
!= Success
) {
449 SendErrorToClient(client
, client
->majorOp
,
451 client
->errorValue
, result
);
456 client
= clients
[clientReady
[nready
]];
458 client
->smart_stop_tick
= SmartScheduleTime
;
460 dispatchException
&= ~DE_PRIORITYCHANGE
;
462 #if defined(DDXBEFORERESET)
467 dispatchException
&= ~DE_RESET
;
468 SmartScheduleLatencyLimited
= 0;
472 static int VendorRelease
= VENDOR_RELEASE
;
473 static char *VendorString
= VENDOR_NAME
;
476 SetVendorRelease(int release
)
478 VendorRelease
= release
;
482 SetVendorString(char *string
)
484 VendorString
= string
;
488 CreateConnectionBlock(void)
494 xPixmapFormat format
;
496 int i
, j
, k
, lenofblock
, sizesofar
= 0;
499 memset(&setup
, 0, sizeof(xConnSetup
));
500 /* Leave off the ridBase and ridMask, these must be sent with
503 setup
.release
= VendorRelease
;
505 * per-server image and bitmap parameters are defined in Xmd.h
507 setup
.imageByteOrder
= screenInfo
.imageByteOrder
;
509 setup
.bitmapScanlineUnit
= screenInfo
.bitmapScanlineUnit
;
510 setup
.bitmapScanlinePad
= screenInfo
.bitmapScanlinePad
;
512 setup
.bitmapBitOrder
= screenInfo
.bitmapBitOrder
;
513 setup
.motionBufferSize
= NumMotionEvents();
514 setup
.numRoots
= screenInfo
.numScreens
;
515 setup
.nbytesVendor
= strlen(VendorString
);
516 setup
.numFormats
= screenInfo
.numPixmapFormats
;
517 setup
.maxRequestSize
= MAX_REQUEST_SIZE
;
518 QueryMinMaxKeyCodes(&setup
.minKeyCode
, &setup
.maxKeyCode
);
520 lenofblock
= sizeof(xConnSetup
) +
521 pad_to_int32(setup
.nbytesVendor
) +
522 (setup
.numFormats
* sizeof(xPixmapFormat
)) +
523 (setup
.numRoots
* sizeof(xWindowRoot
));
524 ConnectionInfo
= malloc(lenofblock
);
528 memmove(ConnectionInfo
, (char *) &setup
, sizeof(xConnSetup
));
529 sizesofar
= sizeof(xConnSetup
);
530 pBuf
= ConnectionInfo
+ sizeof(xConnSetup
);
532 memmove(pBuf
, VendorString
, (int) setup
.nbytesVendor
);
533 sizesofar
+= setup
.nbytesVendor
;
534 pBuf
+= setup
.nbytesVendor
;
535 i
= padding_for_int32(setup
.nbytesVendor
);
540 memset(&format
, 0, sizeof(xPixmapFormat
));
541 for (i
= 0; i
< screenInfo
.numPixmapFormats
; i
++) {
542 format
.depth
= screenInfo
.formats
[i
].depth
;
543 format
.bitsPerPixel
= screenInfo
.formats
[i
].bitsPerPixel
;
544 format
.scanLinePad
= screenInfo
.formats
[i
].scanlinePad
;
545 memmove(pBuf
, (char *) &format
, sizeof(xPixmapFormat
));
546 pBuf
+= sizeof(xPixmapFormat
);
547 sizesofar
+= sizeof(xPixmapFormat
);
550 connBlockScreenStart
= sizesofar
;
551 memset(&depth
, 0, sizeof(xDepth
));
552 memset(&visual
, 0, sizeof(xVisualType
));
553 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
558 pScreen
= screenInfo
.screens
[i
];
559 root
.windowId
= pScreen
->root
->drawable
.id
;
560 root
.defaultColormap
= pScreen
->defColormap
;
561 root
.whitePixel
= pScreen
->whitePixel
;
562 root
.blackPixel
= pScreen
->blackPixel
;
563 root
.currentInputMask
= 0; /* filled in when sent */
564 root
.pixWidth
= pScreen
->width
;
565 root
.pixHeight
= pScreen
->height
;
566 root
.mmWidth
= pScreen
->mmWidth
;
567 root
.mmHeight
= pScreen
->mmHeight
;
568 root
.minInstalledMaps
= pScreen
->minInstalledCmaps
;
569 root
.maxInstalledMaps
= pScreen
->maxInstalledCmaps
;
570 root
.rootVisualID
= pScreen
->rootVisual
;
571 root
.backingStore
= pScreen
->backingStoreSupport
;
572 root
.saveUnders
= FALSE
;
573 root
.rootDepth
= pScreen
->rootDepth
;
574 root
.nDepths
= pScreen
->numDepths
;
575 memmove(pBuf
, (char *) &root
, sizeof(xWindowRoot
));
576 sizesofar
+= sizeof(xWindowRoot
);
577 pBuf
+= sizeof(xWindowRoot
);
579 pDepth
= pScreen
->allowedDepths
;
580 for (j
= 0; j
< pScreen
->numDepths
; j
++, pDepth
++) {
581 lenofblock
+= sizeof(xDepth
) +
582 (pDepth
->numVids
* sizeof(xVisualType
));
583 pBuf
= (char *) realloc(ConnectionInfo
, lenofblock
);
585 free(ConnectionInfo
);
588 ConnectionInfo
= pBuf
;
590 depth
.depth
= pDepth
->depth
;
591 depth
.nVisuals
= pDepth
->numVids
;
592 memmove(pBuf
, (char *) &depth
, sizeof(xDepth
));
593 pBuf
+= sizeof(xDepth
);
594 sizesofar
+= sizeof(xDepth
);
595 for (k
= 0; k
< pDepth
->numVids
; k
++) {
596 vid
= pDepth
->vids
[k
];
597 for (pVisual
= pScreen
->visuals
;
598 pVisual
->vid
!= vid
; pVisual
++);
599 visual
.visualID
= vid
;
600 visual
.class = pVisual
->class;
601 visual
.bitsPerRGB
= pVisual
->bitsPerRGBValue
;
602 visual
.colormapEntries
= pVisual
->ColormapEntries
;
603 visual
.redMask
= pVisual
->redMask
;
604 visual
.greenMask
= pVisual
->greenMask
;
605 visual
.blueMask
= pVisual
->blueMask
;
606 memmove(pBuf
, (char *) &visual
, sizeof(xVisualType
));
607 pBuf
+= sizeof(xVisualType
);
608 sizesofar
+= sizeof(xVisualType
);
612 connSetupPrefix
.success
= xTrue
;
613 connSetupPrefix
.length
= lenofblock
/ 4;
614 connSetupPrefix
.majorVersion
= X_PROTOCOL
;
615 connSetupPrefix
.minorVersion
= X_PROTOCOL_REVISION
;
620 ProcBadRequest(ClientPtr client
)
626 ProcCreateWindow(ClientPtr client
)
628 WindowPtr pParent
, pWin
;
630 REQUEST(xCreateWindowReq
);
633 REQUEST_AT_LEAST_SIZE(xCreateWindowReq
);
635 LEGAL_NEW_RESOURCE(stuff
->wid
, client
);
636 rc
= dixLookupWindow(&pParent
, stuff
->parent
, client
, DixAddAccess
);
639 len
= client
->req_len
- bytes_to_int32(sizeof(xCreateWindowReq
));
640 if (Ones(stuff
->mask
) != len
)
642 if (!stuff
->width
|| !stuff
->height
) {
643 client
->errorValue
= 0;
646 pWin
= CreateWindow(stuff
->wid
, pParent
, stuff
->x
,
647 stuff
->y
, stuff
->width
, stuff
->height
,
648 stuff
->borderWidth
, stuff
->class,
649 stuff
->mask
, (XID
*) &stuff
[1],
650 (int) stuff
->depth
, client
, stuff
->visual
, &rc
);
652 Mask mask
= pWin
->eventMask
;
654 pWin
->eventMask
= 0; /* subterfuge in case AddResource fails */
655 if (!AddResource(stuff
->wid
, RT_WINDOW
, (pointer
) pWin
))
657 pWin
->eventMask
= mask
;
663 ProcChangeWindowAttributes(ClientPtr client
)
667 REQUEST(xChangeWindowAttributesReq
);
669 Mask access_mode
= 0;
671 REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq
);
672 access_mode
|= (stuff
->valueMask
& CWEventMask
) ? DixReceiveAccess
: 0;
673 access_mode
|= (stuff
->valueMask
& ~CWEventMask
) ? DixSetAttrAccess
: 0;
674 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, access_mode
);
677 len
= client
->req_len
- bytes_to_int32(sizeof(xChangeWindowAttributesReq
));
678 if (len
!= Ones(stuff
->valueMask
))
680 return ChangeWindowAttributes(pWin
,
681 stuff
->valueMask
, (XID
*) &stuff
[1], client
);
685 ProcGetWindowAttributes(ClientPtr client
)
689 REQUEST(xResourceReq
);
690 xGetWindowAttributesReply wa
;
693 REQUEST_SIZE_MATCH(xResourceReq
);
694 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixGetAttrAccess
);
697 memset(&wa
, 0, sizeof(xGetWindowAttributesReply
));
698 GetWindowAttributes(pWin
, client
, &wa
);
699 WriteReplyToClient(client
, sizeof(xGetWindowAttributesReply
), &wa
);
704 ProcDestroyWindow(ClientPtr client
)
708 REQUEST(xResourceReq
);
711 REQUEST_SIZE_MATCH(xResourceReq
);
712 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixDestroyAccess
);
716 rc
= dixLookupWindow(&pWin
, pWin
->parent
->drawable
.id
, client
,
720 FreeResource(stuff
->id
, RT_NONE
);
726 ProcDestroySubwindows(ClientPtr client
)
730 REQUEST(xResourceReq
);
733 REQUEST_SIZE_MATCH(xResourceReq
);
734 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixRemoveAccess
);
737 DestroySubwindows(pWin
, client
);
742 ProcChangeSaveSet(ClientPtr client
)
746 REQUEST(xChangeSaveSetReq
);
749 REQUEST_SIZE_MATCH(xChangeSaveSetReq
);
750 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixManageAccess
);
753 if (client
->clientAsMask
== (CLIENT_BITS(pWin
->drawable
.id
)))
755 if ((stuff
->mode
== SetModeInsert
) || (stuff
->mode
== SetModeDelete
))
756 return AlterSaveSetForClient(client
, pWin
, stuff
->mode
, FALSE
, TRUE
);
757 client
->errorValue
= stuff
->mode
;
762 ProcReparentWindow(ClientPtr client
)
764 WindowPtr pWin
, pParent
;
766 REQUEST(xReparentWindowReq
);
769 REQUEST_SIZE_MATCH(xReparentWindowReq
);
770 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixManageAccess
);
773 rc
= dixLookupWindow(&pParent
, stuff
->parent
, client
, DixAddAccess
);
776 if (!SAME_SCREENS(pWin
->drawable
, pParent
->drawable
))
778 if ((pWin
->backgroundState
== ParentRelative
) &&
779 (pParent
->drawable
.depth
!= pWin
->drawable
.depth
))
781 if ((pWin
->drawable
.class != InputOnly
) &&
782 (pParent
->drawable
.class == InputOnly
))
784 return ReparentWindow(pWin
, pParent
,
785 (short) stuff
->x
, (short) stuff
->y
, client
);
789 ProcMapWindow(ClientPtr client
)
793 REQUEST(xResourceReq
);
796 REQUEST_SIZE_MATCH(xResourceReq
);
797 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixShowAccess
);
800 MapWindow(pWin
, client
);
801 /* update cache to say it is mapped */
806 ProcMapSubwindows(ClientPtr client
)
810 REQUEST(xResourceReq
);
813 REQUEST_SIZE_MATCH(xResourceReq
);
814 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixListAccess
);
817 MapSubwindows(pWin
, client
);
818 /* update cache to say it is mapped */
823 ProcUnmapWindow(ClientPtr client
)
827 REQUEST(xResourceReq
);
830 REQUEST_SIZE_MATCH(xResourceReq
);
831 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixHideAccess
);
834 UnmapWindow(pWin
, FALSE
);
835 /* update cache to say it is mapped */
840 ProcUnmapSubwindows(ClientPtr client
)
844 REQUEST(xResourceReq
);
847 REQUEST_SIZE_MATCH(xResourceReq
);
848 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixListAccess
);
851 UnmapSubwindows(pWin
);
856 ProcConfigureWindow(ClientPtr client
)
860 REQUEST(xConfigureWindowReq
);
863 REQUEST_AT_LEAST_SIZE(xConfigureWindowReq
);
864 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
,
865 DixManageAccess
| DixSetAttrAccess
);
868 len
= client
->req_len
- bytes_to_int32(sizeof(xConfigureWindowReq
));
869 if (Ones((Mask
) stuff
->mask
) != len
)
871 return ConfigureWindow(pWin
, (Mask
) stuff
->mask
, (XID
*) &stuff
[1], client
);
875 ProcCirculateWindow(ClientPtr client
)
879 REQUEST(xCirculateWindowReq
);
882 REQUEST_SIZE_MATCH(xCirculateWindowReq
);
883 if ((stuff
->direction
!= RaiseLowest
) && (stuff
->direction
!= LowerHighest
)) {
884 client
->errorValue
= stuff
->direction
;
887 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixManageAccess
);
890 CirculateWindow(pWin
, (int) stuff
->direction
, client
);
895 GetGeometry(ClientPtr client
, xGetGeometryReply
* rep
)
900 REQUEST(xResourceReq
);
901 REQUEST_SIZE_MATCH(xResourceReq
);
903 rc
= dixLookupDrawable(&pDraw
, stuff
->id
, client
, M_ANY
, DixGetAttrAccess
);
909 rep
->sequenceNumber
= client
->sequence
;
910 rep
->root
= pDraw
->pScreen
->root
->drawable
.id
;
911 rep
->depth
= pDraw
->depth
;
912 rep
->width
= pDraw
->width
;
913 rep
->height
= pDraw
->height
;
915 if (WindowDrawable(pDraw
->type
)) {
916 WindowPtr pWin
= (WindowPtr
) pDraw
;
918 rep
->x
= pWin
->origin
.x
- wBorderWidth(pWin
);
919 rep
->y
= pWin
->origin
.y
- wBorderWidth(pWin
);
920 rep
->borderWidth
= pWin
->borderWidth
;
922 else { /* DRAWABLE_PIXMAP */
924 rep
->x
= rep
->y
= rep
->borderWidth
= 0;
931 ProcGetGeometry(ClientPtr client
)
933 xGetGeometryReply rep
= { .type
= X_Reply
};
936 if ((status
= GetGeometry(client
, &rep
)) != Success
)
939 WriteReplyToClient(client
, sizeof(xGetGeometryReply
), &rep
);
944 ProcQueryTree(ClientPtr client
)
946 xQueryTreeReply reply
;
947 int rc
, numChildren
= 0;
948 WindowPtr pChild
, pWin
, pHead
;
949 Window
*childIDs
= (Window
*) NULL
;
951 REQUEST(xResourceReq
);
953 REQUEST_SIZE_MATCH(xResourceReq
);
954 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixListAccess
);
958 reply
= (xQueryTreeReply
) {
960 .sequenceNumber
= client
->sequence
,
961 .root
= pWin
->drawable
.pScreen
->root
->drawable
.id
,
962 .parent
= (pWin
->parent
) ? pWin
->parent
->drawable
.id
: (Window
) None
964 pHead
= RealChildHead(pWin
);
965 for (pChild
= pWin
->lastChild
; pChild
!= pHead
; pChild
= pChild
->prevSib
)
970 childIDs
= malloc(numChildren
* sizeof(Window
));
973 for (pChild
= pWin
->lastChild
; pChild
!= pHead
;
974 pChild
= pChild
->prevSib
)
975 childIDs
[curChild
++] = pChild
->drawable
.id
;
978 reply
.nChildren
= numChildren
;
979 reply
.length
= bytes_to_int32(numChildren
* sizeof(Window
));
981 WriteReplyToClient(client
, sizeof(xQueryTreeReply
), &reply
);
983 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
984 WriteSwappedDataToClient(client
, numChildren
* sizeof(Window
),
993 ProcInternAtom(ClientPtr client
)
998 REQUEST(xInternAtomReq
);
1000 REQUEST_FIXED_SIZE(xInternAtomReq
, stuff
->nbytes
);
1001 if ((stuff
->onlyIfExists
!= xTrue
) && (stuff
->onlyIfExists
!= xFalse
)) {
1002 client
->errorValue
= stuff
->onlyIfExists
;
1005 tchar
= (char *) &stuff
[1];
1006 atom
= MakeAtom(tchar
, stuff
->nbytes
, !stuff
->onlyIfExists
);
1007 if (atom
!= BAD_RESOURCE
) {
1008 xInternAtomReply reply
= {
1010 .sequenceNumber
= client
->sequence
,
1014 WriteReplyToClient(client
, sizeof(xInternAtomReply
), &reply
);
1022 ProcGetAtomName(ClientPtr client
)
1026 REQUEST(xResourceReq
);
1028 REQUEST_SIZE_MATCH(xResourceReq
);
1029 if ((str
= NameForAtom(stuff
->id
))) {
1030 int len
= strlen(str
);
1031 xGetAtomNameReply reply
= {
1033 .sequenceNumber
= client
->sequence
,
1034 .length
= bytes_to_int32(len
),
1038 WriteReplyToClient(client
, sizeof(xGetAtomNameReply
), &reply
);
1039 WriteToClient(client
, len
, str
);
1043 client
->errorValue
= stuff
->id
;
1049 ProcGrabServer(ClientPtr client
)
1053 REQUEST_SIZE_MATCH(xReq
);
1054 if (grabState
!= GrabNone
&& client
!= grabClient
) {
1055 ResetCurrentRequest(client
);
1057 BITSET(grabWaiters
, client
->index
);
1058 IgnoreClient(client
);
1061 rc
= OnlyListenToOneClient(client
);
1064 grabState
= GrabKickout
;
1065 grabClient
= client
;
1067 if (ServerGrabCallback
) {
1068 ServerGrabInfoRec grabinfo
;
1070 grabinfo
.client
= client
;
1071 grabinfo
.grabstate
= SERVER_GRABBED
;
1072 CallCallbacks(&ServerGrabCallback
, (pointer
) &grabinfo
);
1079 UngrabServer(ClientPtr client
)
1083 grabState
= GrabNone
;
1084 ListenToAllClients();
1085 for (i
= mskcnt
; --i
>= 0 && !grabWaiters
[i
];);
1088 while (!GETBIT(grabWaiters
, i
))
1090 BITCLEAR(grabWaiters
, i
);
1091 AttendClient(clients
[i
]);
1094 if (ServerGrabCallback
) {
1095 ServerGrabInfoRec grabinfo
;
1097 grabinfo
.client
= client
;
1098 grabinfo
.grabstate
= SERVER_UNGRABBED
;
1099 CallCallbacks(&ServerGrabCallback
, (pointer
) &grabinfo
);
1104 ProcUngrabServer(ClientPtr client
)
1106 REQUEST_SIZE_MATCH(xReq
);
1107 UngrabServer(client
);
1112 ProcTranslateCoords(ClientPtr client
)
1114 REQUEST(xTranslateCoordsReq
);
1116 WindowPtr pWin
, pDst
;
1117 xTranslateCoordsReply rep
;
1120 REQUEST_SIZE_MATCH(xTranslateCoordsReq
);
1121 rc
= dixLookupWindow(&pWin
, stuff
->srcWid
, client
, DixGetAttrAccess
);
1124 rc
= dixLookupWindow(&pDst
, stuff
->dstWid
, client
, DixGetAttrAccess
);
1128 rep
= (xTranslateCoordsReply
) {
1130 .sequenceNumber
= client
->sequence
,
1133 if (!SAME_SCREENS(pWin
->drawable
, pDst
->drawable
)) {
1134 rep
.sameScreen
= xFalse
;
1136 rep
.dstX
= rep
.dstY
= 0;
1141 rep
.sameScreen
= xTrue
;
1143 /* computing absolute coordinates -- adjust to destination later */
1144 x
= pWin
->drawable
.x
+ stuff
->srcX
;
1145 y
= pWin
->drawable
.y
+ stuff
->srcY
;
1146 pWin
= pDst
->firstChild
;
1150 if ((pWin
->mapped
) &&
1151 (x
>= pWin
->drawable
.x
- wBorderWidth(pWin
)) &&
1152 (x
< pWin
->drawable
.x
+ (int) pWin
->drawable
.width
+
1153 wBorderWidth(pWin
)) &&
1154 (y
>= pWin
->drawable
.y
- wBorderWidth(pWin
)) &&
1155 (y
< pWin
->drawable
.y
+ (int) pWin
->drawable
.height
+
1157 /* When a window is shaped, a further check
1158 * is made to see if the point is inside
1161 && (!wBoundingShape(pWin
) ||
1162 RegionContainsPoint(&pWin
->borderSize
, x
, y
, &box
))
1164 && (!wInputShape(pWin
) ||
1165 RegionContainsPoint(wInputShape(pWin
),
1166 x
- pWin
->drawable
.x
,
1167 y
- pWin
->drawable
.y
, &box
))
1169 rep
.child
= pWin
->drawable
.id
;
1170 pWin
= (WindowPtr
) NULL
;
1173 pWin
= pWin
->nextSib
;
1175 /* adjust to destination coordinates */
1176 rep
.dstX
= x
- pDst
->drawable
.x
;
1177 rep
.dstY
= y
- pDst
->drawable
.y
;
1179 WriteReplyToClient(client
, sizeof(xTranslateCoordsReply
), &rep
);
1184 ProcOpenFont(ClientPtr client
)
1188 REQUEST(xOpenFontReq
);
1190 REQUEST_FIXED_SIZE(xOpenFontReq
, stuff
->nbytes
);
1191 client
->errorValue
= stuff
->fid
;
1192 LEGAL_NEW_RESOURCE(stuff
->fid
, client
);
1193 err
= OpenFont(client
, stuff
->fid
, (Mask
) 0,
1194 stuff
->nbytes
, (char *) &stuff
[1]);
1195 if (err
== Success
) {
1203 ProcCloseFont(ClientPtr client
)
1208 REQUEST(xResourceReq
);
1210 REQUEST_SIZE_MATCH(xResourceReq
);
1211 rc
= dixLookupResourceByType((pointer
*) &pFont
, stuff
->id
, RT_FONT
,
1212 client
, DixDestroyAccess
);
1213 if (rc
== Success
) {
1214 FreeResource(stuff
->id
, RT_NONE
);
1218 client
->errorValue
= stuff
->id
;
1224 ProcQueryFont(ClientPtr client
)
1226 xQueryFontReply
*reply
;
1230 REQUEST(xResourceReq
);
1231 REQUEST_SIZE_MATCH(xResourceReq
);
1233 rc
= dixLookupFontable(&pFont
, stuff
->id
, client
, DixGetAttrAccess
);
1238 xCharInfo
*pmax
= FONTINKMAX(pFont
);
1239 xCharInfo
*pmin
= FONTINKMIN(pFont
);
1240 int nprotoxcistructs
;
1243 nprotoxcistructs
= (pmax
->rightSideBearing
== pmin
->rightSideBearing
&&
1244 pmax
->leftSideBearing
== pmin
->leftSideBearing
&&
1245 pmax
->descent
== pmin
->descent
&&
1246 pmax
->ascent
== pmin
->ascent
&&
1247 pmax
->characterWidth
== pmin
->characterWidth
) ?
1248 0 : N2dChars(pFont
);
1250 rlength
= sizeof(xQueryFontReply
) +
1251 FONTINFONPROPS(FONTCHARSET(pFont
)) * sizeof(xFontProp
) +
1252 nprotoxcistructs
* sizeof(xCharInfo
);
1253 reply
= calloc(1, rlength
);
1258 reply
->type
= X_Reply
;
1259 reply
->length
= bytes_to_int32(rlength
- sizeof(xGenericReply
));
1260 reply
->sequenceNumber
= client
->sequence
;
1261 QueryFont(pFont
, reply
, nprotoxcistructs
);
1263 WriteReplyToClient(client
, rlength
, reply
);
1270 ProcQueryTextExtents(ClientPtr client
)
1272 xQueryTextExtentsReply reply
;
1275 unsigned long length
;
1278 REQUEST(xQueryTextExtentsReq
);
1279 REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq
);
1281 rc
= dixLookupFontable(&pFont
, stuff
->fid
, client
, DixGetAttrAccess
);
1285 length
= client
->req_len
- bytes_to_int32(sizeof(xQueryTextExtentsReq
));
1286 length
= length
<< 1;
1287 if (stuff
->oddLength
) {
1292 if (!QueryTextExtents(pFont
, length
, (unsigned char *) &stuff
[1], &info
))
1294 reply
= (xQueryTextExtentsReply
) {
1296 .drawDirection
= info
.drawDirection
,
1297 .sequenceNumber
= client
->sequence
,
1299 .fontAscent
= info
.fontAscent
,
1300 .fontDescent
= info
.fontDescent
,
1301 .overallAscent
= info
.overallAscent
,
1302 .overallDescent
= info
.overallDescent
,
1303 .overallWidth
= info
.overallWidth
,
1304 .overallLeft
= info
.overallLeft
,
1305 .overallRight
= info
.overallRight
1307 WriteReplyToClient(client
, sizeof(xQueryTextExtentsReply
), &reply
);
1312 ProcListFonts(ClientPtr client
)
1314 REQUEST(xListFontsReq
);
1316 REQUEST_FIXED_SIZE(xListFontsReq
, stuff
->nbytes
);
1318 return ListFonts(client
, (unsigned char *) &stuff
[1], stuff
->nbytes
,
1323 ProcListFontsWithInfo(ClientPtr client
)
1325 REQUEST(xListFontsWithInfoReq
);
1327 REQUEST_FIXED_SIZE(xListFontsWithInfoReq
, stuff
->nbytes
);
1329 return StartListFontsWithInfo(client
, stuff
->nbytes
,
1330 (unsigned char *) &stuff
[1], stuff
->maxNames
);
1335 * \param value must conform to DeleteType
1338 dixDestroyPixmap(pointer value
, XID pid
)
1340 PixmapPtr pPixmap
= (PixmapPtr
) value
;
1342 return (*pPixmap
->drawable
.pScreen
->DestroyPixmap
) (pPixmap
);
1346 ProcCreatePixmap(ClientPtr client
)
1351 REQUEST(xCreatePixmapReq
);
1355 REQUEST_SIZE_MATCH(xCreatePixmapReq
);
1356 client
->errorValue
= stuff
->pid
;
1357 LEGAL_NEW_RESOURCE(stuff
->pid
, client
);
1359 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
1364 if (!stuff
->width
|| !stuff
->height
) {
1365 client
->errorValue
= 0;
1368 if (stuff
->width
> 32767 || stuff
->height
> 32767) {
1369 /* It is allowed to try and allocate a pixmap which is larger than
1370 * 32767 in either dimension. However, all of the framebuffer code
1371 * is buggy and does not reliably draw to such big pixmaps, basically
1372 * because the Region data structure operates with signed shorts
1373 * for the rectangles in it.
1375 * Furthermore, several places in the X server computes the
1376 * size in bytes of the pixmap and tries to store it in an
1377 * integer. This integer can overflow and cause the allocated size
1378 * to be much smaller.
1380 * So, such big pixmaps are rejected here with a BadAlloc
1384 if (stuff
->depth
!= 1) {
1385 pDepth
= pDraw
->pScreen
->allowedDepths
;
1386 for (i
= 0; i
< pDraw
->pScreen
->numDepths
; i
++, pDepth
++)
1387 if (pDepth
->depth
== stuff
->depth
)
1389 client
->errorValue
= stuff
->depth
;
1393 pMap
= (PixmapPtr
) (*pDraw
->pScreen
->CreatePixmap
)
1394 (pDraw
->pScreen
, stuff
->width
, stuff
->height
, stuff
->depth
, 0);
1396 pMap
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
1397 pMap
->drawable
.id
= stuff
->pid
;
1398 /* security creation/labeling check */
1399 rc
= XaceHook(XACE_RESOURCE_ACCESS
, client
, stuff
->pid
, RT_PIXMAP
,
1400 pMap
, RT_NONE
, NULL
, DixCreateAccess
);
1401 if (rc
!= Success
) {
1402 (*pDraw
->pScreen
->DestroyPixmap
) (pMap
);
1405 if (AddResource(stuff
->pid
, RT_PIXMAP
, (pointer
) pMap
))
1412 ProcFreePixmap(ClientPtr client
)
1417 REQUEST(xResourceReq
);
1418 REQUEST_SIZE_MATCH(xResourceReq
);
1420 rc
= dixLookupResourceByType((pointer
*) &pMap
, stuff
->id
, RT_PIXMAP
,
1421 client
, DixDestroyAccess
);
1422 if (rc
== Success
) {
1423 FreeResource(stuff
->id
, RT_NONE
);
1427 client
->errorValue
= stuff
->id
;
1433 ProcCreateGC(ClientPtr client
)
1440 REQUEST(xCreateGCReq
);
1442 REQUEST_AT_LEAST_SIZE(xCreateGCReq
);
1443 client
->errorValue
= stuff
->gc
;
1444 LEGAL_NEW_RESOURCE(stuff
->gc
, client
);
1445 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0,
1450 len
= client
->req_len
- bytes_to_int32(sizeof(xCreateGCReq
));
1451 if (len
!= Ones(stuff
->mask
))
1453 pGC
= (GC
*) CreateGC(pDraw
, stuff
->mask
, (XID
*) &stuff
[1], &error
,
1455 if (error
!= Success
)
1457 if (!AddResource(stuff
->gc
, RT_GC
, (pointer
) pGC
))
1463 ProcChangeGC(ClientPtr client
)
1469 REQUEST(xChangeGCReq
);
1470 REQUEST_AT_LEAST_SIZE(xChangeGCReq
);
1472 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixSetAttrAccess
);
1473 if (result
!= Success
)
1476 len
= client
->req_len
- bytes_to_int32(sizeof(xChangeGCReq
));
1477 if (len
!= Ones(stuff
->mask
))
1480 return ChangeGCXIDs(client
, pGC
, stuff
->mask
, (CARD32
*) &stuff
[1]);
1484 ProcCopyGC(ClientPtr client
)
1490 REQUEST(xCopyGCReq
);
1491 REQUEST_SIZE_MATCH(xCopyGCReq
);
1493 result
= dixLookupGC(&pGC
, stuff
->srcGC
, client
, DixGetAttrAccess
);
1494 if (result
!= Success
)
1496 result
= dixLookupGC(&dstGC
, stuff
->dstGC
, client
, DixSetAttrAccess
);
1497 if (result
!= Success
)
1499 if ((dstGC
->pScreen
!= pGC
->pScreen
) || (dstGC
->depth
!= pGC
->depth
))
1501 if (stuff
->mask
& ~GCAllBits
) {
1502 client
->errorValue
= stuff
->mask
;
1505 return CopyGC(pGC
, dstGC
, stuff
->mask
);
1509 ProcSetDashes(ClientPtr client
)
1514 REQUEST(xSetDashesReq
);
1516 REQUEST_FIXED_SIZE(xSetDashesReq
, stuff
->nDashes
);
1517 if (stuff
->nDashes
== 0) {
1518 client
->errorValue
= 0;
1522 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixSetAttrAccess
);
1523 if (result
!= Success
)
1526 /* If there's an error, either there's no sensible errorValue,
1527 * or there was a dash segment of 0. */
1528 client
->errorValue
= 0;
1529 return SetDashes(pGC
, stuff
->dashOffset
, stuff
->nDashes
,
1530 (unsigned char *) &stuff
[1]);
1534 ProcSetClipRectangles(ClientPtr client
)
1539 REQUEST(xSetClipRectanglesReq
);
1541 REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq
);
1542 if ((stuff
->ordering
!= Unsorted
) && (stuff
->ordering
!= YSorted
) &&
1543 (stuff
->ordering
!= YXSorted
) && (stuff
->ordering
!= YXBanded
)) {
1544 client
->errorValue
= stuff
->ordering
;
1547 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixSetAttrAccess
);
1548 if (result
!= Success
)
1551 nr
= (client
->req_len
<< 2) - sizeof(xSetClipRectanglesReq
);
1555 return SetClipRects(pGC
, stuff
->xOrigin
, stuff
->yOrigin
,
1556 nr
, (xRectangle
*) &stuff
[1], (int) stuff
->ordering
);
1560 ProcFreeGC(ClientPtr client
)
1565 REQUEST(xResourceReq
);
1566 REQUEST_SIZE_MATCH(xResourceReq
);
1568 rc
= dixLookupGC(&pGC
, stuff
->id
, client
, DixDestroyAccess
);
1572 FreeResource(stuff
->id
, RT_NONE
);
1577 ProcClearToBackground(ClientPtr client
)
1579 REQUEST(xClearAreaReq
);
1583 REQUEST_SIZE_MATCH(xClearAreaReq
);
1584 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
1587 if (pWin
->drawable
.class == InputOnly
) {
1588 client
->errorValue
= stuff
->window
;
1591 if ((stuff
->exposures
!= xTrue
) && (stuff
->exposures
!= xFalse
)) {
1592 client
->errorValue
= stuff
->exposures
;
1595 (*pWin
->drawable
.pScreen
->ClearToBackground
) (pWin
, stuff
->x
, stuff
->y
,
1596 stuff
->width
, stuff
->height
,
1597 (Bool
) stuff
->exposures
);
1602 ProcCopyArea(ClientPtr client
)
1608 REQUEST(xCopyAreaReq
);
1612 REQUEST_SIZE_MATCH(xCopyAreaReq
);
1614 VALIDATE_DRAWABLE_AND_GC(stuff
->dstDrawable
, pDst
, DixWriteAccess
);
1615 if (stuff
->dstDrawable
!= stuff
->srcDrawable
) {
1616 rc
= dixLookupDrawable(&pSrc
, stuff
->srcDrawable
, client
, 0,
1620 if ((pDst
->pScreen
!= pSrc
->pScreen
) || (pDst
->depth
!= pSrc
->depth
)) {
1621 client
->errorValue
= stuff
->dstDrawable
;
1628 pRgn
= (*pGC
->ops
->CopyArea
) (pSrc
, pDst
, pGC
, stuff
->srcX
, stuff
->srcY
,
1629 stuff
->width
, stuff
->height
,
1630 stuff
->dstX
, stuff
->dstY
);
1631 if (pGC
->graphicsExposures
) {
1632 (*pDst
->pScreen
->SendGraphicsExpose
)
1633 (client
, pRgn
, stuff
->dstDrawable
, X_CopyArea
, 0);
1635 RegionDestroy(pRgn
);
1642 ProcCopyPlane(ClientPtr client
)
1644 DrawablePtr psrcDraw
, pdstDraw
;
1647 REQUEST(xCopyPlaneReq
);
1651 REQUEST_SIZE_MATCH(xCopyPlaneReq
);
1653 VALIDATE_DRAWABLE_AND_GC(stuff
->dstDrawable
, pdstDraw
, DixWriteAccess
);
1654 if (stuff
->dstDrawable
!= stuff
->srcDrawable
) {
1655 rc
= dixLookupDrawable(&psrcDraw
, stuff
->srcDrawable
, client
, 0,
1660 if (pdstDraw
->pScreen
!= psrcDraw
->pScreen
) {
1661 client
->errorValue
= stuff
->dstDrawable
;
1666 psrcDraw
= pdstDraw
;
1668 /* Check to see if stuff->bitPlane has exactly ONE good bit set */
1669 if (stuff
->bitPlane
== 0 || (stuff
->bitPlane
& (stuff
->bitPlane
- 1)) ||
1670 (stuff
->bitPlane
> (1L << (psrcDraw
->depth
- 1)))) {
1671 client
->errorValue
= stuff
->bitPlane
;
1676 (*pGC
->ops
->CopyPlane
) (psrcDraw
, pdstDraw
, pGC
, stuff
->srcX
,
1677 stuff
->srcY
, stuff
->width
, stuff
->height
,
1678 stuff
->dstX
, stuff
->dstY
, stuff
->bitPlane
);
1679 if (pGC
->graphicsExposures
) {
1680 (*pdstDraw
->pScreen
->SendGraphicsExpose
)
1681 (client
, pRgn
, stuff
->dstDrawable
, X_CopyPlane
, 0);
1683 RegionDestroy(pRgn
);
1689 ProcPolyPoint(ClientPtr client
)
1695 REQUEST(xPolyPointReq
);
1697 REQUEST_AT_LEAST_SIZE(xPolyPointReq
);
1698 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1699 (stuff
->coordMode
!= CoordModePrevious
)) {
1700 client
->errorValue
= stuff
->coordMode
;
1703 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1704 npoint
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xPolyPointReq
));
1706 (*pGC
->ops
->PolyPoint
) (pDraw
, pGC
, stuff
->coordMode
, npoint
,
1707 (xPoint
*) &stuff
[1]);
1712 ProcPolyLine(ClientPtr client
)
1718 REQUEST(xPolyLineReq
);
1720 REQUEST_AT_LEAST_SIZE(xPolyLineReq
);
1721 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1722 (stuff
->coordMode
!= CoordModePrevious
)) {
1723 client
->errorValue
= stuff
->coordMode
;
1726 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1727 npoint
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xPolyLineReq
));
1729 (*pGC
->ops
->Polylines
) (pDraw
, pGC
, stuff
->coordMode
, npoint
,
1730 (DDXPointPtr
) &stuff
[1]);
1735 ProcPolySegment(ClientPtr client
)
1741 REQUEST(xPolySegmentReq
);
1743 REQUEST_AT_LEAST_SIZE(xPolySegmentReq
);
1744 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1745 nsegs
= (client
->req_len
<< 2) - sizeof(xPolySegmentReq
);
1750 (*pGC
->ops
->PolySegment
) (pDraw
, pGC
, nsegs
, (xSegment
*) &stuff
[1]);
1755 ProcPolyRectangle(ClientPtr client
)
1761 REQUEST(xPolyRectangleReq
);
1763 REQUEST_AT_LEAST_SIZE(xPolyRectangleReq
);
1764 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1765 nrects
= (client
->req_len
<< 2) - sizeof(xPolyRectangleReq
);
1770 (*pGC
->ops
->PolyRectangle
) (pDraw
, pGC
,
1771 nrects
, (xRectangle
*) &stuff
[1]);
1776 ProcPolyArc(ClientPtr client
)
1782 REQUEST(xPolyArcReq
);
1784 REQUEST_AT_LEAST_SIZE(xPolyArcReq
);
1785 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1786 narcs
= (client
->req_len
<< 2) - sizeof(xPolyArcReq
);
1787 if (narcs
% sizeof(xArc
))
1789 narcs
/= sizeof(xArc
);
1791 (*pGC
->ops
->PolyArc
) (pDraw
, pGC
, narcs
, (xArc
*) &stuff
[1]);
1796 ProcFillPoly(ClientPtr client
)
1802 REQUEST(xFillPolyReq
);
1804 REQUEST_AT_LEAST_SIZE(xFillPolyReq
);
1805 if ((stuff
->shape
!= Complex
) && (stuff
->shape
!= Nonconvex
) &&
1806 (stuff
->shape
!= Convex
)) {
1807 client
->errorValue
= stuff
->shape
;
1810 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1811 (stuff
->coordMode
!= CoordModePrevious
)) {
1812 client
->errorValue
= stuff
->coordMode
;
1816 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1817 things
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xFillPolyReq
));
1819 (*pGC
->ops
->FillPolygon
) (pDraw
, pGC
, stuff
->shape
,
1820 stuff
->coordMode
, things
,
1821 (DDXPointPtr
) &stuff
[1]);
1826 ProcPolyFillRectangle(ClientPtr client
)
1832 REQUEST(xPolyFillRectangleReq
);
1834 REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq
);
1835 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1836 things
= (client
->req_len
<< 2) - sizeof(xPolyFillRectangleReq
);
1842 (*pGC
->ops
->PolyFillRect
) (pDraw
, pGC
, things
,
1843 (xRectangle
*) &stuff
[1]);
1848 ProcPolyFillArc(ClientPtr client
)
1854 REQUEST(xPolyFillArcReq
);
1856 REQUEST_AT_LEAST_SIZE(xPolyFillArcReq
);
1857 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1858 narcs
= (client
->req_len
<< 2) - sizeof(xPolyFillArcReq
);
1859 if (narcs
% sizeof(xArc
))
1861 narcs
/= sizeof(xArc
);
1863 (*pGC
->ops
->PolyFillArc
) (pDraw
, pGC
, narcs
, (xArc
*) &stuff
[1]);
1867 #ifdef MATCH_CLIENT_ENDIAN
1874 if (*((char *) &whichbyte
))
1879 #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
1882 ReformatImage(char *base
, int nbytes
, int bpp
, int order
)
1886 if (BITMAP_BIT_ORDER
!= order
)
1887 BitOrderInvert((unsigned char *) base
, nbytes
);
1888 #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
1889 ReformatImage(base
, nbytes
, BITMAP_SCANLINE_UNIT
, order
);
1897 if (IMAGE_BYTE_ORDER
!= order
)
1898 TwoByteSwap((unsigned char *) base
, nbytes
);
1901 if (IMAGE_BYTE_ORDER
!= order
)
1902 FourByteSwap((unsigned char *) base
, nbytes
);
1907 #define ReformatImage(b,n,bpp,o)
1910 /* 64-bit server notes: the protocol restricts padding of images to
1911 * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
1912 * to use internally. Removes need for internal alignment checking.
1913 * All of the PutImage functions could be changed individually, but
1914 * as currently written, they call other routines which require things
1915 * to be 64-bit padded on scanlines, so we changed things here.
1916 * If an image would be padded differently for 64- versus 32-, then
1917 * copy each scanline to a 64-bit padded scanline.
1918 * Also, we need to make sure that the image is aligned on a 64-bit
1919 * boundary, even if the scanlines are padded to our satisfaction.
1922 ProcPutImage(ClientPtr client
)
1926 long length
; /* length of scanline server padded */
1927 long lengthProto
; /* length of scanline protocol padded */
1930 REQUEST(xPutImageReq
);
1932 REQUEST_AT_LEAST_SIZE(xPutImageReq
);
1933 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
1934 if (stuff
->format
== XYBitmap
) {
1935 if ((stuff
->depth
!= 1) ||
1936 (stuff
->leftPad
>= (unsigned int) screenInfo
.bitmapScanlinePad
))
1938 length
= BitmapBytePad(stuff
->width
+ stuff
->leftPad
);
1940 else if (stuff
->format
== XYPixmap
) {
1941 if ((pDraw
->depth
!= stuff
->depth
) ||
1942 (stuff
->leftPad
>= (unsigned int) screenInfo
.bitmapScanlinePad
))
1944 length
= BitmapBytePad(stuff
->width
+ stuff
->leftPad
);
1945 length
*= stuff
->depth
;
1947 else if (stuff
->format
== ZPixmap
) {
1948 if ((pDraw
->depth
!= stuff
->depth
) || (stuff
->leftPad
!= 0))
1950 length
= PixmapBytePad(stuff
->width
, stuff
->depth
);
1953 client
->errorValue
= stuff
->format
;
1957 tmpImage
= (char *) &stuff
[1];
1958 lengthProto
= length
;
1960 if ((bytes_to_int32(lengthProto
* stuff
->height
) +
1961 bytes_to_int32(sizeof(xPutImageReq
))) != client
->req_len
)
1964 ReformatImage(tmpImage
, lengthProto
* stuff
->height
,
1965 stuff
->format
== ZPixmap
? BitsPerPixel(stuff
->depth
) : 1,
1966 ClientOrder(client
));
1968 (*pGC
->ops
->PutImage
) (pDraw
, pGC
, stuff
->depth
, stuff
->dstX
, stuff
->dstY
,
1969 stuff
->width
, stuff
->height
,
1970 stuff
->leftPad
, stuff
->format
, tmpImage
);
1976 DoGetImage(ClientPtr client
, int format
, Drawable drawable
,
1977 int x
, int y
, int width
, int height
,
1980 DrawablePtr pDraw
, pBoundingDraw
;
1981 int nlines
, linesPerBuf
, rc
;
1984 /* coordinates relative to the bounding drawable */
1986 long widthBytesLine
, length
;
1990 RegionPtr pVisibleRegion
= NULL
;
1992 if ((format
!= XYPixmap
) && (format
!= ZPixmap
)) {
1993 client
->errorValue
= format
;
1996 rc
= dixLookupDrawable(&pDraw
, drawable
, client
, 0, DixReadAccess
);
2000 memset(&xgi
, 0, sizeof(xGetImageReply
));
2005 if (pDraw
->type
== DRAWABLE_WINDOW
) {
2006 WindowPtr pWin
= (WindowPtr
) pDraw
;
2008 /* "If the drawable is a window, the window must be viewable ... or a
2009 * BadMatch error results" */
2010 if (!pWin
->viewable
)
2013 /* If the drawable is a window, the rectangle must be contained within
2014 * its bounds (including the border). */
2015 if (x
< -wBorderWidth(pWin
) ||
2016 x
+ width
> wBorderWidth(pWin
) + (int) pDraw
->width
||
2017 y
< -wBorderWidth(pWin
) ||
2018 y
+ height
> wBorderWidth(pWin
) + (int) pDraw
->height
)
2024 if (pDraw
->pScreen
->GetWindowPixmap
) {
2025 PixmapPtr pPix
= (*pDraw
->pScreen
->GetWindowPixmap
) (pWin
);
2027 pBoundingDraw
= &pPix
->drawable
;
2029 relx
-= pPix
->screen_x
;
2030 rely
-= pPix
->screen_y
;
2034 pBoundingDraw
= (DrawablePtr
) pDraw
->pScreen
->root
;
2037 xgi
.visual
= wVisual(pWin
);
2040 pBoundingDraw
= pDraw
;
2044 /* "If the drawable is a pixmap, the given rectangle must be wholly
2045 * contained within the pixmap, or a BadMatch error results. If the
2046 * drawable is a window [...] it must be the case that if there were no
2047 * inferiors or overlapping windows, the specified rectangle of the window
2048 * would be fully visible on the screen and wholly contained within the
2049 * outside edges of the window, or a BadMatch error results."
2051 * We relax the window case slightly to mean that the rectangle must exist
2052 * within the bounds of the window's backing pixmap. In particular, this
2053 * means that a GetImage request may succeed or fail with BadMatch depending
2054 * on whether any of its ancestor windows are redirected. */
2055 if (relx
< 0 || relx
+ width
> (int) pBoundingDraw
->width
||
2056 rely
< 0 || rely
+ height
> (int) pBoundingDraw
->height
)
2060 xgi
.sequenceNumber
= client
->sequence
;
2061 xgi
.depth
= pDraw
->depth
;
2062 if (format
== ZPixmap
) {
2063 widthBytesLine
= PixmapBytePad(width
, pDraw
->depth
);
2064 length
= widthBytesLine
* height
;
2068 widthBytesLine
= BitmapBytePad(width
);
2069 plane
= ((Mask
) 1) << (pDraw
->depth
- 1);
2070 /* only planes asked for */
2071 length
= widthBytesLine
* height
*
2072 Ones(planemask
& (plane
| (plane
- 1)));
2076 xgi
.length
= length
;
2078 xgi
.length
= bytes_to_int32(xgi
.length
);
2079 if (widthBytesLine
== 0 || height
== 0)
2081 else if (widthBytesLine
>= IMAGE_BUFSIZE
)
2084 linesPerBuf
= IMAGE_BUFSIZE
/ widthBytesLine
;
2085 if (linesPerBuf
> height
)
2086 linesPerBuf
= height
;
2088 length
= linesPerBuf
* widthBytesLine
;
2089 if (linesPerBuf
< height
) {
2090 /* we have to make sure intermediate buffers don't need padding */
2091 while ((linesPerBuf
> 1) &&
2092 (length
& ((1L << LOG2_BYTES_PER_SCANLINE_PAD
) - 1))) {
2094 length
-= widthBytesLine
;
2096 while (length
& ((1L << LOG2_BYTES_PER_SCANLINE_PAD
) - 1)) {
2098 length
+= widthBytesLine
;
2101 if (!(pBuf
= calloc(1, length
)))
2103 WriteReplyToClient(client
, sizeof(xGetImageReply
), &xgi
);
2105 if (pDraw
->type
== DRAWABLE_WINDOW
) {
2106 pVisibleRegion
= NotClippedByChildren((WindowPtr
) pDraw
);
2107 if (pVisibleRegion
) {
2108 RegionTranslate(pVisibleRegion
, -pDraw
->x
, -pDraw
->y
);
2112 if (linesPerBuf
== 0) {
2115 else if (format
== ZPixmap
) {
2117 while (height
- linesDone
> 0) {
2118 nlines
= min(linesPerBuf
, height
- linesDone
);
2119 (*pDraw
->pScreen
->GetImage
) (pDraw
,
2124 format
, planemask
, (pointer
) pBuf
);
2126 XaceCensorImage(client
, pVisibleRegion
, widthBytesLine
,
2127 pDraw
, x
, y
+ linesDone
, width
,
2128 nlines
, format
, pBuf
);
2130 /* Note that this is NOT a call to WriteSwappedDataToClient,
2131 as we do NOT byte swap */
2132 ReformatImage(pBuf
, (int) (nlines
* widthBytesLine
),
2133 BitsPerPixel(pDraw
->depth
), ClientOrder(client
));
2135 WriteToClient(client
, (int) (nlines
* widthBytesLine
), pBuf
);
2136 linesDone
+= nlines
;
2139 else { /* XYPixmap */
2141 for (; plane
; plane
>>= 1) {
2142 if (planemask
& plane
) {
2144 while (height
- linesDone
> 0) {
2145 nlines
= min(linesPerBuf
, height
- linesDone
);
2146 (*pDraw
->pScreen
->GetImage
) (pDraw
,
2151 format
, plane
, (pointer
) pBuf
);
2153 XaceCensorImage(client
, pVisibleRegion
,
2155 pDraw
, x
, y
+ linesDone
, width
,
2156 nlines
, format
, pBuf
);
2158 /* Note: NOT a call to WriteSwappedDataToClient,
2159 as we do NOT byte swap */
2160 ReformatImage(pBuf
, (int) (nlines
* widthBytesLine
),
2161 1, ClientOrder(client
));
2163 WriteToClient(client
, (int)(nlines
* widthBytesLine
), pBuf
);
2164 linesDone
+= nlines
;
2170 RegionDestroy(pVisibleRegion
);
2176 ProcGetImage(ClientPtr client
)
2178 REQUEST(xGetImageReq
);
2180 REQUEST_SIZE_MATCH(xGetImageReq
);
2182 return DoGetImage(client
, stuff
->format
, stuff
->drawable
,
2184 (int) stuff
->width
, (int) stuff
->height
,
2189 ProcPolyText(ClientPtr client
)
2193 REQUEST(xPolyTextReq
);
2197 REQUEST_AT_LEAST_SIZE(xPolyTextReq
);
2198 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
2200 err
= PolyText(client
,
2203 (unsigned char *) &stuff
[1],
2204 ((unsigned char *) stuff
) + (client
->req_len
<< 2),
2205 stuff
->x
, stuff
->y
, stuff
->reqType
, stuff
->drawable
);
2207 if (err
== Success
) {
2215 ProcImageText8(ClientPtr client
)
2221 REQUEST(xImageTextReq
);
2223 REQUEST_FIXED_SIZE(xImageTextReq
, stuff
->nChars
);
2224 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
2226 err
= ImageText(client
,
2230 (unsigned char *) &stuff
[1],
2231 stuff
->x
, stuff
->y
, stuff
->reqType
, stuff
->drawable
);
2233 if (err
== Success
) {
2241 ProcImageText16(ClientPtr client
)
2247 REQUEST(xImageTextReq
);
2249 REQUEST_FIXED_SIZE(xImageTextReq
, stuff
->nChars
<< 1);
2250 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
2252 err
= ImageText(client
,
2256 (unsigned char *) &stuff
[1],
2257 stuff
->x
, stuff
->y
, stuff
->reqType
, stuff
->drawable
);
2259 if (err
== Success
) {
2267 ProcCreateColormap(ClientPtr client
)
2275 REQUEST(xCreateColormapReq
);
2278 REQUEST_SIZE_MATCH(xCreateColormapReq
);
2280 if ((stuff
->alloc
!= AllocNone
) && (stuff
->alloc
!= AllocAll
)) {
2281 client
->errorValue
= stuff
->alloc
;
2285 LEGAL_NEW_RESOURCE(mid
, client
);
2286 result
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
2287 if (result
!= Success
)
2290 pScreen
= pWin
->drawable
.pScreen
;
2291 for (i
= 0, pVisual
= pScreen
->visuals
;
2292 i
< pScreen
->numVisuals
; i
++, pVisual
++) {
2293 if (pVisual
->vid
!= stuff
->visual
)
2295 return CreateColormap(mid
, pScreen
, pVisual
, &pmap
,
2296 (int) stuff
->alloc
, client
->index
);
2298 client
->errorValue
= stuff
->visual
;
2303 ProcFreeColormap(ClientPtr client
)
2308 REQUEST(xResourceReq
);
2310 REQUEST_SIZE_MATCH(xResourceReq
);
2311 rc
= dixLookupResourceByType((pointer
*) &pmap
, stuff
->id
, RT_COLORMAP
,
2312 client
, DixDestroyAccess
);
2313 if (rc
== Success
) {
2314 /* Freeing a default colormap is a no-op */
2315 if (!(pmap
->flags
& IsDefault
))
2316 FreeResource(stuff
->id
, RT_NONE
);
2320 client
->errorValue
= stuff
->id
;
2326 ProcCopyColormapAndFree(ClientPtr client
)
2329 ColormapPtr pSrcMap
;
2331 REQUEST(xCopyColormapAndFreeReq
);
2334 REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq
);
2336 LEGAL_NEW_RESOURCE(mid
, client
);
2337 rc
= dixLookupResourceByType((pointer
*) &pSrcMap
, stuff
->srcCmap
,
2338 RT_COLORMAP
, client
,
2339 DixReadAccess
| DixRemoveAccess
);
2341 return CopyColormapAndFree(mid
, pSrcMap
, client
->index
);
2342 client
->errorValue
= stuff
->srcCmap
;
2347 ProcInstallColormap(ClientPtr client
)
2352 REQUEST(xResourceReq
);
2353 REQUEST_SIZE_MATCH(xResourceReq
);
2355 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->id
, RT_COLORMAP
,
2356 client
, DixInstallAccess
);
2360 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pcmp
->pScreen
, DixSetAttrAccess
);
2361 if (rc
!= Success
) {
2367 (*(pcmp
->pScreen
->InstallColormap
)) (pcmp
);
2371 client
->errorValue
= stuff
->id
;
2376 ProcUninstallColormap(ClientPtr client
)
2381 REQUEST(xResourceReq
);
2382 REQUEST_SIZE_MATCH(xResourceReq
);
2384 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->id
, RT_COLORMAP
,
2385 client
, DixUninstallAccess
);
2389 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pcmp
->pScreen
, DixSetAttrAccess
);
2390 if (rc
!= Success
) {
2396 if (pcmp
->mid
!= pcmp
->pScreen
->defColormap
)
2397 (*(pcmp
->pScreen
->UninstallColormap
)) (pcmp
);
2401 client
->errorValue
= stuff
->id
;
2406 ProcListInstalledColormaps(ClientPtr client
)
2408 xListInstalledColormapsReply
*preply
;
2412 REQUEST(xResourceReq
);
2413 REQUEST_SIZE_MATCH(xResourceReq
);
2415 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixGetAttrAccess
);
2419 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pWin
->drawable
.pScreen
,
2424 preply
= malloc(sizeof(xListInstalledColormapsReply
) +
2425 pWin
->drawable
.pScreen
->maxInstalledCmaps
*
2430 preply
->type
= X_Reply
;
2431 preply
->sequenceNumber
= client
->sequence
;
2432 nummaps
= (*pWin
->drawable
.pScreen
->ListInstalledColormaps
)
2433 (pWin
->drawable
.pScreen
, (Colormap
*) &preply
[1]);
2434 preply
->nColormaps
= nummaps
;
2435 preply
->length
= nummaps
;
2436 WriteReplyToClient(client
, sizeof(xListInstalledColormapsReply
), preply
);
2437 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2438 WriteSwappedDataToClient(client
, nummaps
* sizeof(Colormap
), &preply
[1]);
2444 ProcAllocColor(ClientPtr client
)
2449 REQUEST(xAllocColorReq
);
2451 REQUEST_SIZE_MATCH(xAllocColorReq
);
2452 rc
= dixLookupResourceByType((pointer
*) &pmap
, stuff
->cmap
, RT_COLORMAP
,
2453 client
, DixAddAccess
);
2454 if (rc
== Success
) {
2455 xAllocColorReply acr
= {
2457 .sequenceNumber
= client
->sequence
,
2460 .green
= stuff
->green
,
2461 .blue
= stuff
->blue
,
2464 if ((rc
= AllocColor(pmap
, &acr
.red
, &acr
.green
, &acr
.blue
,
2465 &acr
.pixel
, client
->index
)))
2468 if (noPanoramiXExtension
|| !pmap
->pScreen
->myNum
)
2470 WriteReplyToClient(client
, sizeof(xAllocColorReply
), &acr
);
2475 client
->errorValue
= stuff
->cmap
;
2481 ProcAllocNamedColor(ClientPtr client
)
2486 REQUEST(xAllocNamedColorReq
);
2488 REQUEST_FIXED_SIZE(xAllocNamedColorReq
, stuff
->nbytes
);
2489 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2490 client
, DixAddAccess
);
2491 if (rc
== Success
) {
2492 xAllocNamedColorReply ancr
= {
2494 .sequenceNumber
= client
->sequence
,
2498 (pcmp
->pScreen
->myNum
, (char *) &stuff
[1], stuff
->nbytes
,
2499 &ancr
.exactRed
, &ancr
.exactGreen
, &ancr
.exactBlue
)) {
2500 ancr
.screenRed
= ancr
.exactRed
;
2501 ancr
.screenGreen
= ancr
.exactGreen
;
2502 ancr
.screenBlue
= ancr
.exactBlue
;
2504 if ((rc
= AllocColor(pcmp
,
2505 &ancr
.screenRed
, &ancr
.screenGreen
,
2506 &ancr
.screenBlue
, &ancr
.pixel
, client
->index
)))
2509 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2511 WriteReplyToClient(client
, sizeof(xAllocNamedColorReply
),
2520 client
->errorValue
= stuff
->cmap
;
2526 ProcAllocColorCells(ClientPtr client
)
2531 REQUEST(xAllocColorCellsReq
);
2533 REQUEST_SIZE_MATCH(xAllocColorCellsReq
);
2534 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2535 client
, DixAddAccess
);
2536 if (rc
== Success
) {
2537 int npixels
, nmasks
;
2539 Pixel
*ppixels
, *pmasks
;
2541 npixels
= stuff
->colors
;
2543 client
->errorValue
= npixels
;
2546 if (stuff
->contiguous
!= xTrue
&& stuff
->contiguous
!= xFalse
) {
2547 client
->errorValue
= stuff
->contiguous
;
2550 nmasks
= stuff
->planes
;
2551 length
= ((long) npixels
+ (long) nmasks
) * sizeof(Pixel
);
2552 ppixels
= malloc(length
);
2555 pmasks
= ppixels
+ npixels
;
2557 if ((rc
= AllocColorCells(client
->index
, pcmp
, npixels
, nmasks
,
2558 (Bool
) stuff
->contiguous
, ppixels
, pmasks
))) {
2563 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2566 xAllocColorCellsReply accr
= {
2568 .sequenceNumber
= client
->sequence
,
2569 .length
= bytes_to_int32(length
),
2573 WriteReplyToClient(client
, sizeof(xAllocColorCellsReply
), &accr
);
2574 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2575 WriteSwappedDataToClient(client
, length
, ppixels
);
2581 client
->errorValue
= stuff
->cmap
;
2587 ProcAllocColorPlanes(ClientPtr client
)
2592 REQUEST(xAllocColorPlanesReq
);
2594 REQUEST_SIZE_MATCH(xAllocColorPlanesReq
);
2595 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2596 client
, DixAddAccess
);
2597 if (rc
== Success
) {
2598 xAllocColorPlanesReply acpr
;
2603 npixels
= stuff
->colors
;
2605 client
->errorValue
= npixels
;
2608 if (stuff
->contiguous
!= xTrue
&& stuff
->contiguous
!= xFalse
) {
2609 client
->errorValue
= stuff
->contiguous
;
2612 acpr
= (xAllocColorPlanesReply
) {
2614 .sequenceNumber
= client
->sequence
,
2617 length
= (long) npixels
*sizeof(Pixel
);
2619 ppixels
= malloc(length
);
2622 if ((rc
= AllocColorPlanes(client
->index
, pcmp
, npixels
,
2623 (int) stuff
->red
, (int) stuff
->green
,
2624 (int) stuff
->blue
, (Bool
) stuff
->contiguous
,
2625 ppixels
, &acpr
.redMask
, &acpr
.greenMask
,
2630 acpr
.length
= bytes_to_int32(length
);
2632 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2635 WriteReplyToClient(client
, sizeof(xAllocColorPlanesReply
), &acpr
);
2636 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2637 WriteSwappedDataToClient(client
, length
, ppixels
);
2643 client
->errorValue
= stuff
->cmap
;
2649 ProcFreeColors(ClientPtr client
)
2654 REQUEST(xFreeColorsReq
);
2656 REQUEST_AT_LEAST_SIZE(xFreeColorsReq
);
2657 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2658 client
, DixRemoveAccess
);
2659 if (rc
== Success
) {
2662 if (pcmp
->flags
& AllAllocated
)
2664 count
= bytes_to_int32((client
->req_len
<< 2) - sizeof(xFreeColorsReq
));
2665 return FreeColors(pcmp
, client
->index
, count
,
2666 (Pixel
*) &stuff
[1], (Pixel
) stuff
->planeMask
);
2669 client
->errorValue
= stuff
->cmap
;
2675 ProcStoreColors(ClientPtr client
)
2680 REQUEST(xStoreColorsReq
);
2682 REQUEST_AT_LEAST_SIZE(xStoreColorsReq
);
2683 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2684 client
, DixWriteAccess
);
2685 if (rc
== Success
) {
2688 count
= (client
->req_len
<< 2) - sizeof(xStoreColorsReq
);
2689 if (count
% sizeof(xColorItem
))
2691 count
/= sizeof(xColorItem
);
2692 return StoreColors(pcmp
, count
, (xColorItem
*) &stuff
[1], client
);
2695 client
->errorValue
= stuff
->cmap
;
2701 ProcStoreNamedColor(ClientPtr client
)
2706 REQUEST(xStoreNamedColorReq
);
2708 REQUEST_FIXED_SIZE(xStoreNamedColorReq
, stuff
->nbytes
);
2709 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2710 client
, DixWriteAccess
);
2711 if (rc
== Success
) {
2714 if (OsLookupColor(pcmp
->pScreen
->myNum
, (char *) &stuff
[1],
2715 stuff
->nbytes
, &def
.red
, &def
.green
, &def
.blue
)) {
2716 def
.flags
= stuff
->flags
;
2717 def
.pixel
= stuff
->pixel
;
2718 return StoreColors(pcmp
, 1, &def
, client
);
2723 client
->errorValue
= stuff
->cmap
;
2729 ProcQueryColors(ClientPtr client
)
2734 REQUEST(xQueryColorsReq
);
2736 REQUEST_AT_LEAST_SIZE(xQueryColorsReq
);
2737 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2738 client
, DixReadAccess
);
2739 if (rc
== Success
) {
2742 xQueryColorsReply qcr
;
2745 bytes_to_int32((client
->req_len
<< 2) - sizeof(xQueryColorsReq
));
2746 prgbs
= calloc(1, count
* sizeof(xrgb
));
2747 if (!prgbs
&& count
)
2750 QueryColors(pcmp
, count
, (Pixel
*) &stuff
[1], prgbs
, client
))) {
2754 qcr
= (xQueryColorsReply
) {
2756 .sequenceNumber
= client
->sequence
,
2757 .length
= bytes_to_int32(count
* sizeof(xrgb
)),
2760 WriteReplyToClient(client
, sizeof(xQueryColorsReply
), &qcr
);
2762 client
->pSwapReplyFunc
= (ReplySwapPtr
) SQColorsExtend
;
2763 WriteSwappedDataToClient(client
, count
* sizeof(xrgb
), prgbs
);
2770 client
->errorValue
= stuff
->cmap
;
2776 ProcLookupColor(ClientPtr client
)
2781 REQUEST(xLookupColorReq
);
2783 REQUEST_FIXED_SIZE(xLookupColorReq
, stuff
->nbytes
);
2784 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->cmap
, RT_COLORMAP
,
2785 client
, DixReadAccess
);
2786 if (rc
== Success
) {
2787 CARD16 exactRed
, exactGreen
, exactBlue
;
2790 (pcmp
->pScreen
->myNum
, (char *) &stuff
[1], stuff
->nbytes
,
2791 &exactRed
, &exactGreen
, &exactBlue
)) {
2792 xLookupColorReply lcr
= {
2794 .sequenceNumber
= client
->sequence
,
2796 .exactRed
= exactRed
,
2797 .exactGreen
= exactGreen
,
2798 .exactBlue
= exactBlue
,
2799 .screenRed
= exactRed
,
2800 .screenGreen
= exactGreen
,
2801 .screenBlue
= exactBlue
2803 (*pcmp
->pScreen
->ResolveColor
) (&lcr
.screenRed
,
2805 &lcr
.screenBlue
, pcmp
->pVisual
);
2806 WriteReplyToClient(client
, sizeof(xLookupColorReply
), &lcr
);
2812 client
->errorValue
= stuff
->cmap
;
2818 ProcCreateCursor(ClientPtr client
)
2823 unsigned char *srcbits
;
2824 unsigned char *mskbits
;
2825 unsigned short width
, height
;
2830 REQUEST(xCreateCursorReq
);
2832 REQUEST_SIZE_MATCH(xCreateCursorReq
);
2833 LEGAL_NEW_RESOURCE(stuff
->cid
, client
);
2835 rc
= dixLookupResourceByType((pointer
*) &src
, stuff
->source
, RT_PIXMAP
,
2836 client
, DixReadAccess
);
2837 if (rc
!= Success
) {
2838 client
->errorValue
= stuff
->source
;
2842 if (src
->drawable
.depth
!= 1)
2845 /* Find and validate cursor mask pixmap, if one is provided */
2846 if (stuff
->mask
!= None
) {
2847 rc
= dixLookupResourceByType((pointer
*) &msk
, stuff
->mask
, RT_PIXMAP
,
2848 client
, DixReadAccess
);
2849 if (rc
!= Success
) {
2850 client
->errorValue
= stuff
->mask
;
2854 if (src
->drawable
.width
!= msk
->drawable
.width
2855 || src
->drawable
.height
!= msk
->drawable
.height
2856 || src
->drawable
.depth
!= 1 || msk
->drawable
.depth
!= 1)
2862 width
= src
->drawable
.width
;
2863 height
= src
->drawable
.height
;
2865 if (stuff
->x
> width
|| stuff
->y
> height
)
2868 n
= BitmapBytePad(width
) * height
;
2869 srcbits
= calloc(1, n
);
2872 mskbits
= malloc(n
);
2878 (*src
->drawable
.pScreen
->GetImage
) ((DrawablePtr
) src
, 0, 0, width
, height
,
2879 XYPixmap
, 1, (pointer
) srcbits
);
2880 if (msk
== (PixmapPtr
) NULL
) {
2881 unsigned char *bits
= mskbits
;
2887 /* zeroing the (pad) bits helps some ddx cursor handling */
2888 memset((char *) mskbits
, 0, n
);
2889 (*msk
->drawable
.pScreen
->GetImage
) ((DrawablePtr
) msk
, 0, 0, width
,
2890 height
, XYPixmap
, 1,
2897 rc
= AllocARGBCursor(srcbits
, mskbits
, NULL
, &cm
,
2898 stuff
->foreRed
, stuff
->foreGreen
, stuff
->foreBlue
,
2899 stuff
->backRed
, stuff
->backGreen
, stuff
->backBlue
,
2900 &pCursor
, client
, stuff
->cid
);
2904 if (!AddResource(stuff
->cid
, RT_CURSOR
, (pointer
) pCursor
)) {
2917 ProcCreateGlyphCursor(ClientPtr client
)
2922 REQUEST(xCreateGlyphCursorReq
);
2924 REQUEST_SIZE_MATCH(xCreateGlyphCursorReq
);
2925 LEGAL_NEW_RESOURCE(stuff
->cid
, client
);
2927 res
= AllocGlyphCursor(stuff
->source
, stuff
->sourceChar
,
2928 stuff
->mask
, stuff
->maskChar
,
2929 stuff
->foreRed
, stuff
->foreGreen
, stuff
->foreBlue
,
2930 stuff
->backRed
, stuff
->backGreen
, stuff
->backBlue
,
2931 &pCursor
, client
, stuff
->cid
);
2934 if (AddResource(stuff
->cid
, RT_CURSOR
, (pointer
) pCursor
))
2940 ProcFreeCursor(ClientPtr client
)
2945 REQUEST(xResourceReq
);
2947 REQUEST_SIZE_MATCH(xResourceReq
);
2948 rc
= dixLookupResourceByType((pointer
*) &pCursor
, stuff
->id
, RT_CURSOR
,
2949 client
, DixDestroyAccess
);
2950 if (rc
== Success
) {
2951 FreeResource(stuff
->id
, RT_NONE
);
2955 client
->errorValue
= stuff
->id
;
2961 ProcQueryBestSize(ClientPtr client
)
2963 xQueryBestSizeReply reply
;
2968 REQUEST(xQueryBestSizeReq
);
2969 REQUEST_SIZE_MATCH(xQueryBestSizeReq
);
2971 if ((stuff
->class != CursorShape
) &&
2972 (stuff
->class != TileShape
) && (stuff
->class != StippleShape
)) {
2973 client
->errorValue
= stuff
->class;
2977 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
2981 if (stuff
->class != CursorShape
&& pDraw
->type
== UNDRAWABLE_WINDOW
)
2983 pScreen
= pDraw
->pScreen
;
2984 rc
= XaceHook(XACE_SCREEN_ACCESS
, client
, pScreen
, DixGetAttrAccess
);
2987 (*pScreen
->QueryBestSize
) (stuff
->class, &stuff
->width
,
2988 &stuff
->height
, pScreen
);
2989 reply
= (xQueryBestSizeReply
) {
2991 .sequenceNumber
= client
->sequence
,
2993 .width
= stuff
->width
,
2994 .height
= stuff
->height
2996 WriteReplyToClient(client
, sizeof(xQueryBestSizeReply
), &reply
);
3001 ProcSetScreenSaver(ClientPtr client
)
3003 int rc
, i
, blankingOption
, exposureOption
;
3005 REQUEST(xSetScreenSaverReq
);
3006 REQUEST_SIZE_MATCH(xSetScreenSaverReq
);
3008 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
3009 rc
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, screenInfo
.screens
[i
],
3015 blankingOption
= stuff
->preferBlank
;
3016 if ((blankingOption
!= DontPreferBlanking
) &&
3017 (blankingOption
!= PreferBlanking
) &&
3018 (blankingOption
!= DefaultBlanking
)) {
3019 client
->errorValue
= blankingOption
;
3022 exposureOption
= stuff
->allowExpose
;
3023 if ((exposureOption
!= DontAllowExposures
) &&
3024 (exposureOption
!= AllowExposures
) &&
3025 (exposureOption
!= DefaultExposures
)) {
3026 client
->errorValue
= exposureOption
;
3029 if (stuff
->timeout
< -1) {
3030 client
->errorValue
= stuff
->timeout
;
3033 if (stuff
->interval
< -1) {
3034 client
->errorValue
= stuff
->interval
;
3038 if (blankingOption
== DefaultBlanking
)
3039 ScreenSaverBlanking
= defaultScreenSaverBlanking
;
3041 ScreenSaverBlanking
= blankingOption
;
3042 if (exposureOption
== DefaultExposures
)
3043 ScreenSaverAllowExposures
= defaultScreenSaverAllowExposures
;
3045 ScreenSaverAllowExposures
= exposureOption
;
3047 if (stuff
->timeout
>= 0)
3048 ScreenSaverTime
= stuff
->timeout
* MILLI_PER_SECOND
;
3050 ScreenSaverTime
= defaultScreenSaverTime
;
3051 if (stuff
->interval
>= 0)
3052 ScreenSaverInterval
= stuff
->interval
* MILLI_PER_SECOND
;
3054 ScreenSaverInterval
= defaultScreenSaverInterval
;
3056 SetScreenSaverTimer();
3061 ProcGetScreenSaver(ClientPtr client
)
3063 xGetScreenSaverReply rep
;
3066 REQUEST_SIZE_MATCH(xReq
);
3068 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
3069 rc
= XaceHook(XACE_SCREENSAVER_ACCESS
, client
, screenInfo
.screens
[i
],
3075 rep
= (xGetScreenSaverReply
) {
3077 .sequenceNumber
= client
->sequence
,
3079 .timeout
= ScreenSaverTime
/ MILLI_PER_SECOND
,
3080 .interval
= ScreenSaverInterval
/ MILLI_PER_SECOND
,
3081 .preferBlanking
= ScreenSaverBlanking
,
3082 .allowExposures
= ScreenSaverAllowExposures
3084 WriteReplyToClient(client
, sizeof(xGetScreenSaverReply
), &rep
);
3089 ProcChangeHosts(ClientPtr client
)
3091 REQUEST(xChangeHostsReq
);
3093 REQUEST_FIXED_SIZE(xChangeHostsReq
, stuff
->hostLength
);
3095 if (stuff
->mode
== HostInsert
)
3096 return AddHost(client
, (int) stuff
->hostFamily
,
3097 stuff
->hostLength
, (pointer
) &stuff
[1]);
3098 if (stuff
->mode
== HostDelete
)
3099 return RemoveHost(client
, (int) stuff
->hostFamily
,
3100 stuff
->hostLength
, (pointer
) &stuff
[1]);
3101 client
->errorValue
= stuff
->mode
;
3106 ProcListHosts(ClientPtr client
)
3108 xListHostsReply reply
;
3109 int len
, nHosts
, result
;
3113 /* REQUEST(xListHostsReq); */
3115 REQUEST_SIZE_MATCH(xListHostsReq
);
3117 /* untrusted clients can't list hosts */
3118 result
= XaceHook(XACE_SERVER_ACCESS
, client
, DixReadAccess
);
3119 if (result
!= Success
)
3122 result
= GetHosts(&pdata
, &nHosts
, &len
, &enabled
);
3123 if (result
!= Success
)
3126 reply
= (xListHostsReply
) {
3129 .sequenceNumber
= client
->sequence
,
3130 .length
= bytes_to_int32(len
),
3133 WriteReplyToClient(client
, sizeof(xListHostsReply
), &reply
);
3135 client
->pSwapReplyFunc
= (ReplySwapPtr
) SLHostsExtend
;
3136 WriteSwappedDataToClient(client
, len
, pdata
);
3143 ProcChangeAccessControl(ClientPtr client
)
3145 REQUEST(xSetAccessControlReq
);
3147 REQUEST_SIZE_MATCH(xSetAccessControlReq
);
3148 if ((stuff
->mode
!= EnableAccess
) && (stuff
->mode
!= DisableAccess
)) {
3149 client
->errorValue
= stuff
->mode
;
3152 return ChangeAccessControl(client
, stuff
->mode
== EnableAccess
);
3155 /*********************
3156 * CloseDownRetainedResources
3158 * Find all clients that are gone and have terminated in RetainTemporary
3159 * and destroy their resources.
3160 *********************/
3163 CloseDownRetainedResources(void)
3168 for (i
= 1; i
< currentMaxClients
; i
++) {
3169 client
= clients
[i
];
3170 if (client
&& (client
->closeDownMode
== RetainTemporary
)
3171 && (client
->clientGone
))
3172 CloseDownClient(client
);
3177 ProcKillClient(ClientPtr client
)
3179 REQUEST(xResourceReq
);
3180 ClientPtr killclient
;
3183 REQUEST_SIZE_MATCH(xResourceReq
);
3184 if (stuff
->id
== AllTemporary
) {
3185 CloseDownRetainedResources();
3189 rc
= dixLookupClient(&killclient
, stuff
->id
, client
, DixDestroyAccess
);
3190 if (rc
== Success
) {
3191 CloseDownClient(killclient
);
3192 /* if an LBX proxy gets killed, isItTimeToYield will be set */
3193 if (isItTimeToYield
|| (client
== killclient
)) {
3194 /* force yield and return Success, so that Dispatch()
3195 * doesn't try to touch client
3197 isItTimeToYield
= TRUE
;
3207 ProcSetFontPath(ClientPtr client
)
3210 unsigned long nbytes
, total
;
3214 REQUEST(xSetFontPathReq
);
3216 REQUEST_AT_LEAST_SIZE(xSetFontPathReq
);
3218 nbytes
= (client
->req_len
<< 2) - sizeof(xSetFontPathReq
);
3220 ptr
= (unsigned char *) &stuff
[1];
3221 nfonts
= stuff
->nFonts
;
3222 while (--nfonts
>= 0) {
3223 if ((total
== 0) || (total
< (n
= (*ptr
+ 1))))
3230 return SetFontPath(client
, stuff
->nFonts
, (unsigned char *) &stuff
[1]);
3234 ProcGetFontPath(ClientPtr client
)
3236 xGetFontPathReply reply
;
3237 int rc
, stringLens
, numpaths
;
3238 unsigned char *bufferStart
;
3240 /* REQUEST (xReq); */
3242 REQUEST_SIZE_MATCH(xReq
);
3243 rc
= GetFontPath(client
, &numpaths
, &stringLens
, &bufferStart
);
3247 reply
= (xGetFontPathReply
) {
3249 .sequenceNumber
= client
->sequence
,
3250 .length
= bytes_to_int32(stringLens
+ numpaths
),
3254 WriteReplyToClient(client
, sizeof(xGetFontPathReply
), &reply
);
3255 if (stringLens
|| numpaths
)
3256 WriteToClient(client
, stringLens
+ numpaths
, bufferStart
);
3261 ProcChangeCloseDownMode(ClientPtr client
)
3265 REQUEST(xSetCloseDownModeReq
);
3266 REQUEST_SIZE_MATCH(xSetCloseDownModeReq
);
3268 rc
= XaceHook(XACE_CLIENT_ACCESS
, client
, client
, DixManageAccess
);
3272 if ((stuff
->mode
== AllTemporary
) ||
3273 (stuff
->mode
== RetainPermanent
) || (stuff
->mode
== RetainTemporary
)) {
3274 client
->closeDownMode
= stuff
->mode
;
3278 client
->errorValue
= stuff
->mode
;
3284 ProcForceScreenSaver(ClientPtr client
)
3288 REQUEST(xForceScreenSaverReq
);
3290 REQUEST_SIZE_MATCH(xForceScreenSaverReq
);
3292 if ((stuff
->mode
!= ScreenSaverReset
) && (stuff
->mode
!= ScreenSaverActive
)) {
3293 client
->errorValue
= stuff
->mode
;
3296 rc
= dixSaveScreens(client
, SCREEN_SAVER_FORCER
, (int) stuff
->mode
);
3303 ProcNoOperation(ClientPtr client
)
3305 REQUEST_AT_LEAST_SIZE(xReq
);
3307 /* noop -- don't do anything */
3311 /**********************
3314 * Client can either mark his resources destroy or retain. If retained and
3315 * then killed again, the client is really destroyed.
3316 *********************/
3318 char dispatchExceptionAtReset
= DE_RESET
;
3321 CloseDownClient(ClientPtr client
)
3323 Bool really_close_down
= client
->clientGone
||
3324 client
->closeDownMode
== DestroyAll
;
3326 if (!client
->clientGone
) {
3327 /* ungrab server if grabbing client dies */
3328 if (grabState
!= GrabNone
&& grabClient
== client
) {
3329 UngrabServer(client
);
3331 BITCLEAR(grabWaiters
, client
->index
);
3332 DeleteClientFromAnySelections(client
);
3333 ReleaseActiveGrabs(client
);
3334 DeleteClientFontStuff(client
);
3335 if (!really_close_down
) {
3336 /* This frees resources that should never be retained
3337 * no matter what the close down mode is. Actually we
3338 * could do this unconditionally, but it's probably
3339 * better not to traverse all the client's resources
3340 * twice (once here, once a few lines down in
3341 * FreeClientResources) in the common case of
3342 * really_close_down == TRUE.
3344 FreeClientNeverRetainResources(client
);
3345 client
->clientState
= ClientStateRetained
;
3346 if (ClientStateCallback
) {
3347 NewClientInfoRec clientinfo
;
3349 clientinfo
.client
= client
;
3350 clientinfo
.prefix
= (xConnSetupPrefix
*) NULL
;
3351 clientinfo
.setup
= (xConnSetup
*) NULL
;
3352 CallCallbacks((&ClientStateCallback
), (pointer
) &clientinfo
);
3355 client
->clientGone
= TRUE
; /* so events aren't sent to client */
3356 if (ClientIsAsleep(client
))
3357 ClientSignal(client
);
3358 ProcessWorkQueueZombies();
3359 CloseDownConnection(client
);
3361 /* If the client made it to the Running stage, nClients has
3362 * been incremented on its behalf, so we need to decrement it
3363 * now. If it hasn't gotten to Running, nClients has *not*
3364 * been incremented, so *don't* decrement it.
3366 if (client
->clientState
!= ClientStateInitial
) {
3371 if (really_close_down
) {
3372 if (client
->clientState
== ClientStateRunning
&& nClients
== 0)
3373 dispatchException
|= dispatchExceptionAtReset
;
3375 client
->clientState
= ClientStateGone
;
3376 if (ClientStateCallback
) {
3377 NewClientInfoRec clientinfo
;
3379 clientinfo
.client
= client
;
3380 clientinfo
.prefix
= (xConnSetupPrefix
*) NULL
;
3381 clientinfo
.setup
= (xConnSetup
*) NULL
;
3382 CallCallbacks((&ClientStateCallback
), (pointer
) &clientinfo
);
3384 TouchListenerGone(client
->clientAsMask
);
3385 FreeClientResources(client
);
3386 /* Disable client ID tracking. This must be done after
3387 * ClientStateCallback. */
3388 ReleaseClientIds(client
);
3389 #ifdef XSERVER_DTRACE
3390 XSERVER_CLIENT_DISCONNECT(client
->index
);
3392 if (client
->index
< nextFreeClientID
)
3393 nextFreeClientID
= client
->index
;
3394 clients
[client
->index
] = NullClient
;
3395 SmartLastClient
= NullClient
;
3396 dixFreeObjectWithPrivates(client
, PRIVATE_CLIENT
);
3398 while (!clients
[currentMaxClients
- 1])
3399 currentMaxClients
--;
3404 KillAllClients(void)
3408 for (i
= 1; i
< currentMaxClients
; i
++)
3410 /* Make sure Retained clients are released. */
3411 clients
[i
]->closeDownMode
= DestroyAll
;
3412 CloseDownClient(clients
[i
]);
3417 InitClient(ClientPtr client
, int i
, pointer ospriv
)
3420 client
->clientAsMask
= ((Mask
) i
) << CLIENTOFFSET
;
3421 client
->closeDownMode
= i
? DestroyAll
: RetainPermanent
;
3422 client
->requestVector
= InitialVector
;
3423 client
->osPrivate
= ospriv
;
3424 QueryMinMaxKeyCodes(&client
->minKC
, &client
->maxKC
);
3425 client
->smart_start_tick
= SmartScheduleTime
;
3426 client
->smart_stop_tick
= SmartScheduleTime
;
3427 client
->smart_check_tick
= SmartScheduleTime
;
3428 client
->clientIds
= NULL
;
3431 /************************
3432 * int NextAvailableClient(ospriv)
3434 * OS dependent portion can't assign client id's because of CloseDownModes.
3435 * Returns NULL if there are no free clients.
3436 *************************/
3439 NextAvailableClient(pointer ospriv
)
3445 i
= nextFreeClientID
;
3446 if (i
== MAXCLIENTS
)
3447 return (ClientPtr
) NULL
;
3448 clients
[i
] = client
=
3449 dixAllocateObjectWithPrivates(ClientRec
, PRIVATE_CLIENT
);
3451 return (ClientPtr
) NULL
;
3452 InitClient(client
, i
, ospriv
);
3453 if (!InitClientResources(client
)) {
3454 dixFreeObjectWithPrivates(client
, PRIVATE_CLIENT
);
3455 return (ClientPtr
) NULL
;
3458 data
.length
= bytes_to_int32(sz_xReq
+ sz_xConnClientPrefix
);
3459 if (!InsertFakeRequest(client
, (char *) &data
, sz_xReq
)) {
3460 FreeClientResources(client
);
3461 dixFreeObjectWithPrivates(client
, PRIVATE_CLIENT
);
3462 return (ClientPtr
) NULL
;
3464 if (i
== currentMaxClients
)
3465 currentMaxClients
++;
3466 while ((nextFreeClientID
< MAXCLIENTS
) && clients
[nextFreeClientID
])
3469 /* Enable client ID tracking. This must be done before
3470 * ClientStateCallback. */
3471 ReserveClientIds(client
);
3473 if (ClientStateCallback
) {
3474 NewClientInfoRec clientinfo
;
3476 clientinfo
.client
= client
;
3477 clientinfo
.prefix
= (xConnSetupPrefix
*) NULL
;
3478 clientinfo
.setup
= (xConnSetup
*) NULL
;
3479 CallCallbacks((&ClientStateCallback
), (pointer
) &clientinfo
);
3485 ProcInitialConnection(ClientPtr client
)
3488 xConnClientPrefix
*prefix
;
3492 prefix
= (xConnClientPrefix
*) ((char *)stuff
+ sz_xReq
);
3493 order
= prefix
->byteOrder
;
3494 if (order
!= 'l' && order
!= 'B' && order
!= 'r' && order
!= 'R')
3495 return client
->noClientException
= -1;
3496 if (((*(char *) &whichbyte
) && (order
== 'B' || order
== 'R')) ||
3497 (!(*(char *) &whichbyte
) && (order
== 'l' || order
== 'r'))) {
3498 client
->swapped
= TRUE
;
3499 SwapConnClientPrefix(prefix
);
3502 stuff
->length
+= bytes_to_int32(prefix
->nbytesAuthProto
) +
3503 bytes_to_int32(prefix
->nbytesAuthString
);
3504 if (client
->swapped
) {
3505 swaps(&stuff
->length
);
3507 if (order
== 'r' || order
== 'R') {
3508 client
->local
= FALSE
;
3510 ResetCurrentRequest(client
);
3515 SendConnSetup(ClientPtr client
, const char *reason
)
3520 char *lConnectionInfo
;
3521 xConnSetupPrefix
*lconnSetupPrefix
;
3524 xConnSetupPrefix csp
;
3526 csp
.success
= xFalse
;
3527 csp
.lengthReason
= strlen(reason
);
3528 csp
.length
= bytes_to_int32(csp
.lengthReason
);
3529 csp
.majorVersion
= X_PROTOCOL
;
3530 csp
.minorVersion
= X_PROTOCOL_REVISION
;
3531 if (client
->swapped
)
3532 WriteSConnSetupPrefix(client
, &csp
);
3534 WriteToClient(client
, sz_xConnSetupPrefix
, &csp
);
3535 WriteToClient(client
, (int) csp
.lengthReason
, reason
);
3536 return client
->noClientException
= -1;
3539 numScreens
= screenInfo
.numScreens
;
3540 lConnectionInfo
= ConnectionInfo
;
3541 lconnSetupPrefix
= &connSetupPrefix
;
3543 /* We're about to start speaking X protocol back to the client by
3544 * sending the connection setup info. This means the authorization
3545 * step is complete, and we can count the client as an
3550 client
->requestVector
= client
->swapped
? SwappedProcVector
: ProcVector
;
3551 client
->sequence
= 0;
3552 ((xConnSetup
*) lConnectionInfo
)->ridBase
= client
->clientAsMask
;
3553 ((xConnSetup
*) lConnectionInfo
)->ridMask
= RESOURCE_ID_MASK
;
3554 #ifdef MATCH_CLIENT_ENDIAN
3555 ((xConnSetup
*) lConnectionInfo
)->imageByteOrder
= ClientOrder(client
);
3556 ((xConnSetup
*) lConnectionInfo
)->bitmapBitOrder
= ClientOrder(client
);
3558 /* fill in the "currentInputMask" */
3559 root
= (xWindowRoot
*) (lConnectionInfo
+ connBlockScreenStart
);
3561 if (noPanoramiXExtension
)
3562 numScreens
= screenInfo
.numScreens
;
3564 numScreens
= ((xConnSetup
*) ConnectionInfo
)->numRoots
;
3567 for (i
= 0; i
< numScreens
; i
++) {
3570 WindowPtr pRoot
= screenInfo
.screens
[i
]->root
;
3572 root
->currentInputMask
= pRoot
->eventMask
| wOtherEventMasks(pRoot
);
3573 pDepth
= (xDepth
*) (root
+ 1);
3574 for (j
= 0; j
< root
->nDepths
; j
++) {
3575 pDepth
= (xDepth
*) (((char *) (pDepth
+ 1)) +
3576 pDepth
->nVisuals
* sizeof(xVisualType
));
3578 root
= (xWindowRoot
*) pDepth
;
3581 if (client
->swapped
) {
3582 WriteSConnSetupPrefix(client
, lconnSetupPrefix
);
3583 WriteSConnectionInfo(client
,
3584 (unsigned long) (lconnSetupPrefix
->length
<< 2),
3588 WriteToClient(client
, sizeof(xConnSetupPrefix
), lconnSetupPrefix
);
3589 WriteToClient(client
, (int) (lconnSetupPrefix
->length
<< 2),
3592 client
->clientState
= ClientStateRunning
;
3593 if (ClientStateCallback
) {
3594 NewClientInfoRec clientinfo
;
3596 clientinfo
.client
= client
;
3597 clientinfo
.prefix
= lconnSetupPrefix
;
3598 clientinfo
.setup
= (xConnSetup
*) lConnectionInfo
;
3599 CallCallbacks((&ClientStateCallback
), (pointer
) &clientinfo
);
3605 ProcEstablishConnection(ClientPtr client
)
3608 char *auth_proto
, *auth_string
;
3609 xConnClientPrefix
*prefix
;
3613 prefix
= (xConnClientPrefix
*) ((char *) stuff
+ sz_xReq
);
3614 auth_proto
= (char *) prefix
+ sz_xConnClientPrefix
;
3615 auth_string
= auth_proto
+ pad_to_int32(prefix
->nbytesAuthProto
);
3616 if ((prefix
->majorVersion
!= X_PROTOCOL
) ||
3617 (prefix
->minorVersion
!= X_PROTOCOL_REVISION
))
3618 reason
= "Protocol version mismatch";
3620 reason
= ClientAuthorized(client
,
3621 (unsigned short) prefix
->nbytesAuthProto
,
3623 (unsigned short) prefix
->nbytesAuthString
,
3626 return (SendConnSetup(client
, reason
));
3630 SendErrorToClient(ClientPtr client
, unsigned majorCode
, unsigned minorCode
,
3631 XID resId
, int errorCode
)
3635 .errorCode
= errorCode
,
3636 .resourceID
= resId
,
3637 .minorCode
= minorCode
,
3638 .majorCode
= majorCode
3641 WriteEventsToClient(client
, 1, (xEvent
*) &rep
);
3645 MarkClientException(ClientPtr client
)
3647 client
->noClientException
= -1;
3651 * This array encodes the answer to the question "what is the log base 2
3652 * of the number of pixels that fit in a scanline pad unit?"
3653 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3655 static int answer
[6][4] = {
3656 /* pad pad pad pad */
3659 {3, 4, 5, 6}, /* 1 bit per pixel */
3660 {1, 2, 3, 4}, /* 4 bits per pixel */
3661 {0, 1, 2, 3}, /* 8 bits per pixel */
3662 {~0, 0, 1, 2}, /* 16 bits per pixel */
3663 {~0, ~0, 0, 1}, /* 24 bits per pixel */
3664 {~0, ~0, 0, 1} /* 32 bits per pixel */
3668 * This array gives the answer to the question "what is the first index for
3669 * the answer array above given the number of bits per pixel?"
3670 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3672 static int indexForBitsPerPixel
[33] = {
3673 ~0, 0, ~0, ~0, /* 1 bit per pixel */
3674 1, ~0, ~0, ~0, /* 4 bits per pixel */
3675 2, ~0, ~0, ~0, /* 8 bits per pixel */
3677 3, ~0, ~0, ~0, /* 16 bits per pixel */
3679 4, ~0, ~0, ~0, /* 24 bits per pixel */
3681 5 /* 32 bits per pixel */
3685 * This array gives the bytesperPixel value for cases where the number
3686 * of bits per pixel is a multiple of 8 but not a power of 2.
3688 static int answerBytesPerPixel
[33] = {
3689 ~0, 0, ~0, ~0, /* 1 bit per pixel */
3690 0, ~0, ~0, ~0, /* 4 bits per pixel */
3691 0, ~0, ~0, ~0, /* 8 bits per pixel */
3693 0, ~0, ~0, ~0, /* 16 bits per pixel */
3695 3, ~0, ~0, ~0, /* 24 bits per pixel */
3697 0 /* 32 bits per pixel */
3701 * This array gives the answer to the question "what is the second index for
3702 * the answer array above given the number of bits per scanline pad unit?"
3703 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3705 static int indexForScanlinePad
[65] = {
3708 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
3710 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
3714 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
3722 3 /* 64 bits per scanline pad unit */
3726 grow the array of screenRecs if necessary.
3727 call the device-supplied initialization procedure
3728 with its screen number, a pointer to its ScreenRec, argc, and argv.
3729 return the number of successfully installed screens.
3733 static int init_screen(ScreenPtr pScreen
, int i
, Bool gpu
)
3735 int scanlinepad
, format
, depth
, bitsPerPixel
, j
, k
;
3737 dixInitScreenSpecificPrivates(pScreen
);
3739 if (!dixAllocatePrivates(&pScreen
->devPrivates
, PRIVATE_SCREEN
)) {
3744 pScreen
->myNum
+= GPU_SCREEN_OFFSET
;
3745 pScreen
->isGPU
= TRUE
;
3747 pScreen
->totalPixmapSize
= 0; /* computed in CreateScratchPixmapForScreen */
3748 pScreen
->ClipNotify
= 0; /* for R4 ddx compatibility */
3749 pScreen
->CreateScreenResources
= 0;
3751 xorg_list_init(&pScreen
->pixmap_dirty_list
);
3752 xorg_list_init(&pScreen
->unattached_list
);
3753 xorg_list_init(&pScreen
->output_slave_list
);
3754 xorg_list_init(&pScreen
->offload_slave_list
);
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;
3790 AddScreen(Bool (*pfnInit
) (ScreenPtr
/*pScreen */ ,
3793 ), int argc
, char **argv
)
3800 i
= screenInfo
.numScreens
;
3801 if (i
== MAXSCREENS
)
3804 pScreen
= (ScreenPtr
) calloc(1, sizeof(ScreenRec
));
3808 ret
= init_screen(pScreen
, i
, FALSE
);
3813 /* This is where screen specific stuff gets initialized. Load the
3814 screen structure, call the hardware, whatever.
3815 This is also where the default colormap should be allocated and
3816 also pixel values for blackPixel, whitePixel, and the cursor
3817 Note that InitScreen is NOT allowed to modify argc, argv, or
3818 any of the strings pointed to by argv. They may be passed to
3821 screenInfo
.screens
[i
] = pScreen
;
3822 screenInfo
.numScreens
++;
3823 if (!(*pfnInit
) (pScreen
, argc
, argv
)) {
3824 dixFreeScreenSpecificPrivates(pScreen
);
3825 dixFreePrivates(pScreen
->devPrivates
, PRIVATE_SCREEN
);
3827 screenInfo
.numScreens
--;
3831 update_desktop_dimensions();
3833 dixRegisterScreenPrivateKey(&cursorScreenDevPriv
, pScreen
, PRIVATE_CURSOR
,
3840 AddGPUScreen(Bool (*pfnInit
) (ScreenPtr
/*pScreen */ ,
3844 int argc
, char **argv
)
3850 i
= screenInfo
.numGPUScreens
;
3851 if (i
== MAXGPUSCREENS
)
3854 pScreen
= (ScreenPtr
) calloc(1, sizeof(ScreenRec
));
3858 ret
= init_screen(pScreen
, i
, TRUE
);
3864 /* This is where screen specific stuff gets initialized. Load the
3865 screen structure, call the hardware, whatever.
3866 This is also where the default colormap should be allocated and
3867 also pixel values for blackPixel, whitePixel, and the cursor
3868 Note that InitScreen is NOT allowed to modify argc, argv, or
3869 any of the strings pointed to by argv. They may be passed to
3872 screenInfo
.gpuscreens
[i
] = pScreen
;
3873 screenInfo
.numGPUScreens
++;
3874 if (!(*pfnInit
) (pScreen
, argc
, argv
)) {
3875 dixFreePrivates(pScreen
->devPrivates
, PRIVATE_SCREEN
);
3877 screenInfo
.numGPUScreens
--;
3881 update_desktop_dimensions();
3887 RemoveGPUScreen(ScreenPtr pScreen
)
3890 if (!pScreen
->isGPU
)
3893 idx
= pScreen
->myNum
- GPU_SCREEN_OFFSET
;
3894 for (j
= idx
; j
< screenInfo
.numGPUScreens
- 1; j
++) {
3895 screenInfo
.gpuscreens
[j
] = screenInfo
.gpuscreens
[j
+ 1];
3896 screenInfo
.gpuscreens
[j
]->myNum
= j
+ GPU_SCREEN_OFFSET
;
3898 screenInfo
.numGPUScreens
--;
3900 /* this gets freed later in the resource list, but without
3901 * the screen existing it causes crashes - so remove it here */
3902 if (pScreen
->defColormap
)
3903 FreeResource(pScreen
->defColormap
, RT_COLORMAP
);
3909 AttachUnboundGPU(ScreenPtr pScreen
, ScreenPtr
new)
3912 assert(!new->current_master
);
3913 xorg_list_add(&new->unattached_head
, &pScreen
->unattached_list
);
3914 new->current_master
= pScreen
;
3918 DetachUnboundGPU(ScreenPtr slave
)
3920 assert(slave
->isGPU
);
3921 xorg_list_del(&slave
->unattached_head
);
3922 slave
->current_master
= NULL
;
3926 AttachOutputGPU(ScreenPtr pScreen
, ScreenPtr
new)
3929 xorg_list_add(&new->output_head
, &pScreen
->output_slave_list
);
3930 new->current_master
= pScreen
;
3934 DetachOutputGPU(ScreenPtr slave
)
3936 assert(slave
->isGPU
);
3937 xorg_list_del(&slave
->output_head
);
3938 slave
->current_master
= NULL
;
3942 AttachOffloadGPU(ScreenPtr pScreen
, ScreenPtr
new)
3945 xorg_list_add(&new->offload_head
, &pScreen
->offload_slave_list
);
3946 new->current_master
= pScreen
;
3950 DetachOffloadGPU(ScreenPtr slave
)
3952 assert(slave
->isGPU
);
3953 xorg_list_del(&slave
->offload_head
);
3954 slave
->current_master
= NULL
;