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.
26 Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46 ********************************************************/
48 /* The panoramix components contained the following notice */
49 /*****************************************************************
51 Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
53 Permission is hereby granted, free of charge, to any person obtaining a copy
54 of this software and associated documentation files (the "Software"), to deal
55 in the Software without restriction, including without limitation the rights
56 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57 copies of the Software.
59 The above copyright notice and this permission notice shall be included in
60 all copies or substantial portions of the Software.
62 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
65 DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
66 BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
67 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
68 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
70 Except as contained in this notice, the name of Digital Equipment Corporation
71 shall not be used in advertising or otherwise to promote the sale, use or other
72 dealings in this Software without prior written authorization from Digital
73 Equipment Corporation.
75 ******************************************************************/
77 /* XSERVER_DTRACE additions:
78 * Copyright 2005-2006 Sun Microsystems, Inc. All rights reserved.
80 * Permission is hereby granted, free of charge, to any person obtaining a
81 * copy of this software and associated documentation files (the
82 * "Software"), to deal in the Software without restriction, including
83 * without limitation the rights to use, copy, modify, merge, publish,
84 * distribute, and/or sell copies of the Software, and to permit persons
85 * to whom the Software is furnished to do so, provided that the above
86 * copyright notice(s) and this permission notice appear in all copies of
87 * the Software and that both the above copyright notice(s) and this
88 * permission notice appear in supporting documentation.
90 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
91 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
92 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
93 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
94 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
95 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
96 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
97 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
98 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
100 * Except as contained in this notice, the name of a copyright holder
101 * shall not be used in advertising or otherwise to promote the sale, use
102 * or other dealings in this Software without prior written authorization
103 * of the copyright holder.
108 #ifdef HAVE_DIX_CONFIG_H
109 #include <dix-config.h>
112 #ifdef PANORAMIX_DEBUG
114 int ProcInitialConnection();
117 #include "windowstr.h"
118 #include <X11/fonts/fontstruct.h>
119 #include "dixfontstr.h"
120 #include "gcstruct.h"
121 #include "selection.h"
122 #include "colormapst.h"
123 #include "cursorstr.h"
124 #include "scrnintstr.h"
127 #include "servermd.h"
128 #include "extnsionst.h"
130 #include "dispatch.h"
134 #include "panoramiX.h"
135 #include "panoramiXsrv.h"
139 #include "appgroup.h"
142 #ifndef XKB_IN_SERVER
143 #define XKB_IN_SERVER
145 #include "inputstr.h"
149 #ifdef XSERVER_DTRACE
150 #include <sys/types.h>
151 typedef const char *string
;
152 #include "Xserver-dtrace.h"
154 char *RequestNames
[256];
155 static void LoadRequestNames(void);
156 static void FreeRequestNames(void);
157 #define GetRequestName(i) (RequestNames[i])
160 #define mskcnt ((MAXCLIENTS + 31) / 32)
161 #define BITMASK(i) (1U << ((i) & 31))
162 #define MASKIDX(i) ((i) >> 5)
163 #define MASKWORD(buf, i) buf[MASKIDX(i)]
164 #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
165 #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
166 #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
168 extern xConnSetupPrefix connSetupPrefix
;
169 extern char *ConnectionInfo
;
171 _X_EXPORT Selection
*CurrentSelections
;
172 _X_EXPORT
int NumCurrentSelections
;
173 CallbackListPtr SelectionCallback
= NULL
;
175 static ClientPtr grabClient
;
178 #define GrabKickout 2
179 static int grabState
= GrabNone
;
180 static long grabWaiters
[mskcnt
];
181 _X_EXPORT CallbackListPtr ServerGrabCallback
= NULL
;
182 HWEventQueuePtr checkForInput
[2];
183 extern int connBlockScreenStart
;
185 static void KillAllClients(void);
187 static void DeleteClientFromAnySelections(ClientPtr client
);
189 static int nextFreeClientID
; /* always MIN free client ID */
191 static int nClients
; /* number of authorized clients */
193 _X_EXPORT CallbackListPtr ClientStateCallback
;
195 /* dispatchException & isItTimeToYield must be declared volatile since they
196 * are modified by signal handlers - otherwise optimizer may assume it doesn't
197 * need to actually check value in memory when used and may miss changes from
200 _X_EXPORT
volatile char dispatchException
= 0;
201 _X_EXPORT
volatile char isItTimeToYield
;
203 /* Various of the DIX function interfaces were not designed to allow
204 * the client->errorValue to be set on BadValue and other errors.
205 * Rather than changing interfaces and breaking untold code we introduce
206 * a new global that dispatch can use.
208 XID clientErrorValue
; /* XXX this is a kludge */
210 #define SAME_SCREENS(a, b) (\
211 (a.pScreen == b.pScreen))
214 SetInputCheck(HWEventQueuePtr c0
, HWEventQueuePtr c1
)
216 checkForInput
[0] = c0
;
217 checkForInput
[1] = c1
;
221 UpdateCurrentTime(void)
225 /* To avoid time running backwards, we must call GetTimeInMillis before
226 * calling ProcessInputEvents.
228 systime
.months
= currentTime
.months
;
229 systime
.milliseconds
= GetTimeInMillis();
230 if (systime
.milliseconds
< currentTime
.milliseconds
)
232 if (*checkForInput
[0] != *checkForInput
[1])
233 ProcessInputEvents();
234 if (CompareTimeStamps(systime
, currentTime
) == LATER
)
235 currentTime
= systime
;
238 /* Like UpdateCurrentTime, but can't call ProcessInputEvents */
240 UpdateCurrentTimeIf(void)
244 systime
.months
= currentTime
.months
;
245 systime
.milliseconds
= GetTimeInMillis();
246 if (systime
.milliseconds
< currentTime
.milliseconds
)
248 if (*checkForInput
[0] == *checkForInput
[1])
249 currentTime
= systime
;
255 if (CurrentSelections
)
256 xfree(CurrentSelections
);
257 CurrentSelections
= (Selection
*)NULL
;
258 NumCurrentSelections
= 0;
262 FlushClientCaches(XID id
)
267 client
= clients
[CLIENT_ID(id
)];
268 if (client
== NullClient
)
270 for (i
=0; i
<currentMaxClients
; i
++)
273 if (client
!= NullClient
)
275 if (client
->lastDrawableID
== id
)
277 client
->lastDrawableID
= WindowTable
[0]->drawable
.id
;
278 client
->lastDrawable
= (DrawablePtr
)WindowTable
[0];
280 else if (client
->lastGCID
== id
)
282 client
->lastGCID
= INVALID
;
283 client
->lastGC
= (GCPtr
)NULL
;
288 #ifdef SMART_SCHEDULE
292 #define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
293 #define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
295 Bool SmartScheduleDisable
= FALSE
;
296 long SmartScheduleSlice
= SMART_SCHEDULE_DEFAULT_INTERVAL
;
297 long SmartScheduleInterval
= SMART_SCHEDULE_DEFAULT_INTERVAL
;
298 long SmartScheduleMaxSlice
= SMART_SCHEDULE_MAX_SLICE
;
299 long SmartScheduleTime
;
300 static ClientPtr SmartLastClient
;
301 static int SmartLastIndex
[SMART_MAX_PRIORITY
-SMART_MIN_PRIORITY
+1];
308 void InitProcVectors(void);
311 SmartScheduleClient (int *clientReady
, int nready
)
316 int bestPrio
, best
= 0;
317 int bestRobin
, robin
;
318 long now
= SmartScheduleTime
;
321 bestPrio
= -0x7fffffff;
323 idle
= 2 * SmartScheduleSlice
;
324 for (i
= 0; i
< nready
; i
++)
326 client
= clientReady
[i
];
327 pClient
= clients
[client
];
328 /* Praise clients which are idle */
329 if ((now
- pClient
->smart_check_tick
) >= idle
)
331 if (pClient
->smart_priority
< 0)
332 pClient
->smart_priority
++;
334 pClient
->smart_check_tick
= now
;
336 /* check priority to select best client */
337 robin
= (pClient
->index
- SmartLastIndex
[pClient
->smart_priority
-SMART_MIN_PRIORITY
]) & 0xff;
338 if (pClient
->smart_priority
> bestPrio
||
339 (pClient
->smart_priority
== bestPrio
&& robin
> bestRobin
))
341 bestPrio
= pClient
->smart_priority
;
346 if ((now
- SmartLastPrint
) >= 5000)
347 fprintf (stderr
, " %2d: %3d", client
, pClient
->smart_priority
);
351 if ((now
- SmartLastPrint
) >= 5000)
353 fprintf (stderr
, " use %2d\n", best
);
354 SmartLastPrint
= now
;
357 pClient
= clients
[best
];
358 SmartLastIndex
[bestPrio
-SMART_MIN_PRIORITY
] = pClient
->index
;
360 * Set current client pointer
362 if (SmartLastClient
!= pClient
)
364 pClient
->smart_start_tick
= now
;
365 SmartLastClient
= pClient
;
373 * If it's been a long time since another client
374 * has run, bump the slice up to get maximal
375 * performance from a single client
377 if ((now
- pClient
->smart_start_tick
) > 1000 &&
378 SmartScheduleSlice
< SmartScheduleMaxSlice
)
380 SmartScheduleSlice
+= SmartScheduleInterval
;
385 SmartScheduleSlice
= SmartScheduleInterval
;
391 #define MAJOROP ((xReq *)client->requestBuffer)->reqType
396 int *clientReady
; /* array of request ready clients */
400 HWEventQueuePtr
* icheck
= checkForInput
;
401 #ifdef SMART_SCHEDULE
405 nextFreeClientID
= 1;
409 clientReady
= (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients
);
413 #ifdef XSERVER_DTRACE
417 while (!dispatchException
)
419 if (*icheck
[0] != *icheck
[1])
421 ProcessInputEvents();
422 FlushIfCriticalOutputPending();
425 nready
= WaitForSomething(clientReady
);
427 #ifdef SMART_SCHEDULE
428 if (nready
&& !SmartScheduleDisable
)
430 clientReady
[0] = SmartScheduleClient (clientReady
, nready
);
435 * Handle events in round robin fashion, doing input between
439 while (!dispatchException
&& (--nready
>= 0))
441 client
= clients
[clientReady
[nready
]];
444 /* KillClient can cause this to happen */
447 /* GrabServer activation can cause this to be true */
448 if (grabState
== GrabKickout
)
450 grabState
= GrabActive
;
453 isItTimeToYield
= FALSE
;
455 requestingClient
= client
;
456 #ifdef SMART_SCHEDULE
457 start_tick
= SmartScheduleTime
;
459 while (!isItTimeToYield
)
461 if (*icheck
[0] != *icheck
[1])
463 ProcessInputEvents();
464 FlushIfCriticalOutputPending();
466 #ifdef SMART_SCHEDULE
467 if (!SmartScheduleDisable
&&
468 (SmartScheduleTime
- start_tick
) >= SmartScheduleSlice
)
470 /* Penalize clients which consume ticks */
471 if (client
->smart_priority
> SMART_MIN_PRIORITY
)
472 client
->smart_priority
--;
476 /* now, finally, deal with client requests */
478 result
= ReadRequestFromClient(client
);
482 CloseDownClient(client
);
488 if (client
->requestLogIndex
== MAX_REQUEST_LOG
)
489 client
->requestLogIndex
= 0;
490 client
->requestLog
[client
->requestLogIndex
] = MAJOROP
;
491 client
->requestLogIndex
++;
493 #ifdef XSERVER_DTRACE
494 XSERVER_REQUEST_START(GetRequestName(MAJOROP
), MAJOROP
,
495 ((xReq
*)client
->requestBuffer
)->length
,
496 client
->index
, client
->requestBuffer
);
498 if (result
> (maxBigRequestSize
<< 2))
501 XaceHook(XACE_AUDIT_BEGIN
, client
);
502 result
= (* client
->requestVector
[MAJOROP
])(client
);
503 XaceHook(XACE_AUDIT_END
, client
, result
);
505 #ifdef XSERVER_DTRACE
506 XSERVER_REQUEST_DONE(GetRequestName(MAJOROP
), MAJOROP
,
507 client
->sequence
, client
->index
, result
);
510 if (result
!= Success
)
512 if (client
->noClientException
!= Success
)
513 CloseDownClient(client
);
515 SendErrorToClient(client
, MAJOROP
,
516 MinorOpcodeOfRequest(client
),
517 client
->errorValue
, result
);
521 FlushIfCriticalOutputPending ();
525 #ifdef SMART_SCHEDULE
526 client
= clients
[clientReady
[nready
]];
528 client
->smart_stop_tick
= SmartScheduleTime
;
530 requestingClient
= NULL
;
532 dispatchException
&= ~DE_PRIORITYCHANGE
;
534 #if defined(DDXBEFORERESET)
538 DEALLOCATE_LOCAL(clientReady
);
539 dispatchException
&= ~DE_RESET
;
540 #ifdef XSERVER_DTRACE
548 ProcBadRequest(ClientPtr client
)
554 ProcCreateWindow(ClientPtr client
)
556 WindowPtr pParent
, pWin
;
557 REQUEST(xCreateWindowReq
);
560 REQUEST_AT_LEAST_SIZE(xCreateWindowReq
);
562 LEGAL_NEW_RESOURCE(stuff
->wid
, client
);
563 rc
= dixLookupWindow(&pParent
, stuff
->parent
, client
, DixWriteAccess
);
566 len
= client
->req_len
- (sizeof(xCreateWindowReq
) >> 2);
567 if (Ones(stuff
->mask
) != len
)
569 if (!stuff
->width
|| !stuff
->height
)
571 client
->errorValue
= 0;
574 pWin
= CreateWindow(stuff
->wid
, pParent
, stuff
->x
,
575 stuff
->y
, stuff
->width
, stuff
->height
,
576 stuff
->borderWidth
, stuff
->class,
577 stuff
->mask
, (XID
*) &stuff
[1],
579 client
, stuff
->visual
, &result
);
582 Mask mask
= pWin
->eventMask
;
584 pWin
->eventMask
= 0; /* subterfuge in case AddResource fails */
585 if (!AddResource(stuff
->wid
, RT_WINDOW
, (pointer
)pWin
))
587 pWin
->eventMask
= mask
;
589 if (client
->noClientException
!= Success
)
590 return(client
->noClientException
);
596 ProcChangeWindowAttributes(ClientPtr client
)
599 REQUEST(xChangeWindowAttributesReq
);
603 REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq
);
604 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
607 len
= client
->req_len
- (sizeof(xChangeWindowAttributesReq
) >> 2);
608 if (len
!= Ones(stuff
->valueMask
))
610 result
= ChangeWindowAttributes(pWin
,
614 if (client
->noClientException
!= Success
)
615 return(client
->noClientException
);
621 ProcGetWindowAttributes(ClientPtr client
)
624 REQUEST(xResourceReq
);
625 xGetWindowAttributesReply wa
;
628 REQUEST_SIZE_MATCH(xResourceReq
);
629 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
632 GetWindowAttributes(pWin
, client
, &wa
);
633 WriteReplyToClient(client
, sizeof(xGetWindowAttributesReply
), &wa
);
634 return(client
->noClientException
);
638 ProcDestroyWindow(ClientPtr client
)
641 REQUEST(xResourceReq
);
644 REQUEST_SIZE_MATCH(xResourceReq
);
645 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixDestroyAccess
);
649 FreeResource(stuff
->id
, RT_NONE
);
650 return(client
->noClientException
);
654 ProcDestroySubwindows(ClientPtr client
)
657 REQUEST(xResourceReq
);
660 REQUEST_SIZE_MATCH(xResourceReq
);
661 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixDestroyAccess
);
664 DestroySubwindows(pWin
, client
);
665 return(client
->noClientException
);
669 ProcChangeSaveSet(ClientPtr client
)
672 REQUEST(xChangeSaveSetReq
);
675 REQUEST_SIZE_MATCH(xChangeSaveSetReq
);
676 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReadAccess
);
679 if (client
->clientAsMask
== (CLIENT_BITS(pWin
->drawable
.id
)))
681 if ((stuff
->mode
== SetModeInsert
) || (stuff
->mode
== SetModeDelete
))
683 result
= AlterSaveSetForClient(client
, pWin
, stuff
->mode
, FALSE
, TRUE
);
684 if (client
->noClientException
!= Success
)
685 return(client
->noClientException
);
691 client
->errorValue
= stuff
->mode
;
697 ProcReparentWindow(ClientPtr client
)
699 WindowPtr pWin
, pParent
;
700 REQUEST(xReparentWindowReq
);
703 REQUEST_SIZE_MATCH(xReparentWindowReq
);
704 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
707 rc
= dixLookupWindow(&pParent
, stuff
->parent
, client
, DixWriteAccess
);
710 if (SAME_SCREENS(pWin
->drawable
, pParent
->drawable
))
712 if ((pWin
->backgroundState
== ParentRelative
) &&
713 (pParent
->drawable
.depth
!= pWin
->drawable
.depth
))
715 if ((pWin
->drawable
.class != InputOnly
) &&
716 (pParent
->drawable
.class == InputOnly
))
718 result
= ReparentWindow(pWin
, pParent
,
719 (short)stuff
->x
, (short)stuff
->y
, client
);
720 if (client
->noClientException
!= Success
)
721 return(client
->noClientException
);
730 ProcMapWindow(ClientPtr client
)
733 REQUEST(xResourceReq
);
736 REQUEST_SIZE_MATCH(xResourceReq
);
737 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
740 MapWindow(pWin
, client
);
741 /* update cache to say it is mapped */
742 return(client
->noClientException
);
746 ProcMapSubwindows(ClientPtr client
)
749 REQUEST(xResourceReq
);
752 REQUEST_SIZE_MATCH(xResourceReq
);
753 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
756 MapSubwindows(pWin
, client
);
757 /* update cache to say it is mapped */
758 return(client
->noClientException
);
762 ProcUnmapWindow(ClientPtr client
)
765 REQUEST(xResourceReq
);
768 REQUEST_SIZE_MATCH(xResourceReq
);
769 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
772 UnmapWindow(pWin
, FALSE
);
773 /* update cache to say it is mapped */
774 return(client
->noClientException
);
778 ProcUnmapSubwindows(ClientPtr client
)
781 REQUEST(xResourceReq
);
784 REQUEST_SIZE_MATCH(xResourceReq
);
785 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
788 UnmapSubwindows(pWin
);
789 return(client
->noClientException
);
793 ProcConfigureWindow(ClientPtr client
)
796 REQUEST(xConfigureWindowReq
);
800 REQUEST_AT_LEAST_SIZE(xConfigureWindowReq
);
801 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
804 len
= client
->req_len
- (sizeof(xConfigureWindowReq
) >> 2);
805 if (Ones((Mask
)stuff
->mask
) != len
)
807 result
= ConfigureWindow(pWin
, (Mask
)stuff
->mask
, (XID
*) &stuff
[1],
809 if (client
->noClientException
!= Success
)
810 return(client
->noClientException
);
816 ProcCirculateWindow(ClientPtr client
)
819 REQUEST(xCirculateWindowReq
);
822 REQUEST_SIZE_MATCH(xCirculateWindowReq
);
823 if ((stuff
->direction
!= RaiseLowest
) &&
824 (stuff
->direction
!= LowerHighest
))
826 client
->errorValue
= stuff
->direction
;
829 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
832 CirculateWindow(pWin
, (int)stuff
->direction
, client
);
833 return(client
->noClientException
);
837 GetGeometry(ClientPtr client
, xGetGeometryReply
*rep
)
841 REQUEST(xResourceReq
);
842 REQUEST_SIZE_MATCH(xResourceReq
);
844 rc
= dixLookupDrawable(&pDraw
, stuff
->id
, client
, M_ANY
, DixReadAccess
);
850 rep
->sequenceNumber
= client
->sequence
;
851 rep
->root
= WindowTable
[pDraw
->pScreen
->myNum
]->drawable
.id
;
852 rep
->depth
= pDraw
->depth
;
853 rep
->width
= pDraw
->width
;
854 rep
->height
= pDraw
->height
;
856 /* XXX - Because the pixmap-implementation of the multibuffer extension
857 * may have the buffer-id's drawable resource value be a pointer
858 * to the buffer's window instead of the buffer itself
859 * (this happens if the buffer is the displayed buffer),
860 * we also have to check that the id matches before we can
861 * truly say that it is a DRAWABLE_WINDOW.
864 if ((pDraw
->type
== UNDRAWABLE_WINDOW
) ||
865 ((pDraw
->type
== DRAWABLE_WINDOW
) && (stuff
->id
== pDraw
->id
)))
867 WindowPtr pWin
= (WindowPtr
)pDraw
;
868 rep
->x
= pWin
->origin
.x
- wBorderWidth (pWin
);
869 rep
->y
= pWin
->origin
.y
- wBorderWidth (pWin
);
870 rep
->borderWidth
= pWin
->borderWidth
;
872 else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
874 rep
->x
= rep
->y
= rep
->borderWidth
= 0;
882 ProcGetGeometry(ClientPtr client
)
884 xGetGeometryReply rep
;
887 if ((status
= GetGeometry(client
, &rep
)) != Success
)
890 WriteReplyToClient(client
, sizeof(xGetGeometryReply
), &rep
);
891 return(client
->noClientException
);
896 ProcQueryTree(ClientPtr client
)
898 xQueryTreeReply reply
;
899 int rc
, numChildren
= 0;
900 WindowPtr pChild
, pWin
, pHead
;
901 Window
*childIDs
= (Window
*)NULL
;
902 REQUEST(xResourceReq
);
904 REQUEST_SIZE_MATCH(xResourceReq
);
905 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
908 reply
.type
= X_Reply
;
909 reply
.root
= WindowTable
[pWin
->drawable
.pScreen
->myNum
]->drawable
.id
;
910 reply
.sequenceNumber
= client
->sequence
;
912 reply
.parent
= pWin
->parent
->drawable
.id
;
914 reply
.parent
= (Window
)None
;
915 pHead
= RealChildHead(pWin
);
916 for (pChild
= pWin
->lastChild
; pChild
!= pHead
; pChild
= pChild
->prevSib
)
922 childIDs
= (Window
*) ALLOCATE_LOCAL(numChildren
* sizeof(Window
));
925 for (pChild
= pWin
->lastChild
; pChild
!= pHead
; pChild
= pChild
->prevSib
)
926 childIDs
[curChild
++] = pChild
->drawable
.id
;
929 reply
.nChildren
= numChildren
;
930 reply
.length
= (numChildren
* sizeof(Window
)) >> 2;
932 WriteReplyToClient(client
, sizeof(xQueryTreeReply
), &reply
);
935 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
936 WriteSwappedDataToClient(client
, numChildren
* sizeof(Window
), childIDs
);
937 DEALLOCATE_LOCAL(childIDs
);
940 return(client
->noClientException
);
944 ProcInternAtom(ClientPtr client
)
948 REQUEST(xInternAtomReq
);
950 REQUEST_FIXED_SIZE(xInternAtomReq
, stuff
->nbytes
);
951 if ((stuff
->onlyIfExists
!= xTrue
) && (stuff
->onlyIfExists
!= xFalse
))
953 client
->errorValue
= stuff
->onlyIfExists
;
956 tchar
= (char *) &stuff
[1];
957 atom
= MakeAtom(tchar
, stuff
->nbytes
, !stuff
->onlyIfExists
);
958 if (atom
!= BAD_RESOURCE
)
960 xInternAtomReply reply
;
961 reply
.type
= X_Reply
;
963 reply
.sequenceNumber
= client
->sequence
;
965 WriteReplyToClient(client
, sizeof(xInternAtomReply
), &reply
);
966 return(client
->noClientException
);
973 ProcGetAtomName(ClientPtr client
)
976 xGetAtomNameReply reply
;
978 REQUEST(xResourceReq
);
980 REQUEST_SIZE_MATCH(xResourceReq
);
981 if ( (str
= NameForAtom(stuff
->id
)) )
984 reply
.type
= X_Reply
;
985 reply
.length
= (len
+ 3) >> 2;
986 reply
.sequenceNumber
= client
->sequence
;
987 reply
.nameLength
= len
;
988 WriteReplyToClient(client
, sizeof(xGetAtomNameReply
), &reply
);
989 (void)WriteToClient(client
, len
, str
);
990 return(client
->noClientException
);
994 client
->errorValue
= stuff
->id
;
1000 ProcSetSelectionOwner(ClientPtr client
)
1004 REQUEST(xSetSelectionOwnerReq
);
1006 REQUEST_SIZE_MATCH(xSetSelectionOwnerReq
);
1007 UpdateCurrentTime();
1008 time
= ClientTimeToServerTime(stuff
->time
);
1010 /* If the client's time stamp is in the future relative to the server's
1011 time stamp, do not set the selection, just return success. */
1012 if (CompareTimeStamps(time
, currentTime
) == LATER
)
1014 if (stuff
->window
!= None
)
1016 int rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReadAccess
);
1021 pWin
= (WindowPtr
)None
;
1022 if (ValidAtom(stuff
->selection
))
1027 * First, see if the selection is already set...
1029 while ((i
< NumCurrentSelections
) &&
1030 CurrentSelections
[i
].selection
!= stuff
->selection
)
1032 if (i
< NumCurrentSelections
)
1036 /* If the timestamp in client's request is in the past relative
1037 to the time stamp indicating the last time the owner of the
1038 selection was set, do not set the selection, just return
1040 if (CompareTimeStamps(time
, CurrentSelections
[i
].lastTimeChanged
)
1043 if (CurrentSelections
[i
].client
&&
1044 (!pWin
|| (CurrentSelections
[i
].client
!= client
)))
1046 event
.u
.u
.type
= SelectionClear
;
1047 event
.u
.selectionClear
.time
= time
.milliseconds
;
1048 event
.u
.selectionClear
.window
= CurrentSelections
[i
].window
;
1049 event
.u
.selectionClear
.atom
= CurrentSelections
[i
].selection
;
1050 (void) TryClientEvents (CurrentSelections
[i
].client
, &event
, 1,
1051 NoEventMask
, NoEventMask
/* CantBeFiltered */,
1058 * It doesn't exist, so add it...
1063 newsels
= (Selection
*)xalloc(sizeof(Selection
));
1065 newsels
= (Selection
*)xrealloc(CurrentSelections
,
1066 (NumCurrentSelections
+ 1) * sizeof(Selection
));
1069 NumCurrentSelections
++;
1070 CurrentSelections
= newsels
;
1071 CurrentSelections
[i
].selection
= stuff
->selection
;
1073 CurrentSelections
[i
].lastTimeChanged
= time
;
1074 CurrentSelections
[i
].window
= stuff
->window
;
1075 CurrentSelections
[i
].pWin
= pWin
;
1076 CurrentSelections
[i
].client
= (pWin
? client
: NullClient
);
1077 if (SelectionCallback
)
1079 SelectionInfoRec info
;
1081 info
.selection
= &CurrentSelections
[i
];
1082 info
.kind
= SelectionSetOwner
;
1083 CallCallbacks(&SelectionCallback
, &info
);
1085 return (client
->noClientException
);
1089 client
->errorValue
= stuff
->selection
;
1095 ProcGetSelectionOwner(ClientPtr client
)
1097 REQUEST(xResourceReq
);
1099 REQUEST_SIZE_MATCH(xResourceReq
);
1100 if (ValidAtom(stuff
->id
))
1103 xGetSelectionOwnerReply reply
;
1106 while ((i
< NumCurrentSelections
) &&
1107 CurrentSelections
[i
].selection
!= stuff
->id
) i
++;
1108 reply
.type
= X_Reply
;
1110 reply
.sequenceNumber
= client
->sequence
;
1111 if (i
< NumCurrentSelections
)
1112 reply
.owner
= CurrentSelections
[i
].window
;
1115 WriteReplyToClient(client
, sizeof(xGetSelectionOwnerReply
), &reply
);
1116 return(client
->noClientException
);
1120 client
->errorValue
= stuff
->id
;
1126 ProcConvertSelection(ClientPtr client
)
1131 REQUEST(xConvertSelectionReq
);
1134 REQUEST_SIZE_MATCH(xConvertSelectionReq
);
1135 rc
= dixLookupWindow(&pWin
, stuff
->requestor
, client
, DixReadAccess
);
1139 paramsOkay
= (ValidAtom(stuff
->selection
) && ValidAtom(stuff
->target
));
1140 if (stuff
->property
!= None
)
1141 paramsOkay
&= ValidAtom(stuff
->property
);
1147 while ((i
< NumCurrentSelections
) &&
1148 CurrentSelections
[i
].selection
!= stuff
->selection
) i
++;
1149 if ((i
< NumCurrentSelections
) &&
1150 (CurrentSelections
[i
].window
!= None
) &&
1151 XaceHook(XACE_RESOURCE_ACCESS
, client
,
1152 CurrentSelections
[i
].window
, RT_WINDOW
,
1153 DixReadAccess
, CurrentSelections
[i
].pWin
))
1155 event
.u
.u
.type
= SelectionRequest
;
1156 event
.u
.selectionRequest
.time
= stuff
->time
;
1157 event
.u
.selectionRequest
.owner
=
1158 CurrentSelections
[i
].window
;
1159 event
.u
.selectionRequest
.requestor
= stuff
->requestor
;
1160 event
.u
.selectionRequest
.selection
= stuff
->selection
;
1161 event
.u
.selectionRequest
.target
= stuff
->target
;
1162 event
.u
.selectionRequest
.property
= stuff
->property
;
1163 if (TryClientEvents(
1164 CurrentSelections
[i
].client
, &event
, 1, NoEventMask
,
1165 NoEventMask
/* CantBeFiltered */, NullGrab
))
1166 return (client
->noClientException
);
1168 event
.u
.u
.type
= SelectionNotify
;
1169 event
.u
.selectionNotify
.time
= stuff
->time
;
1170 event
.u
.selectionNotify
.requestor
= stuff
->requestor
;
1171 event
.u
.selectionNotify
.selection
= stuff
->selection
;
1172 event
.u
.selectionNotify
.target
= stuff
->target
;
1173 event
.u
.selectionNotify
.property
= None
;
1174 (void) TryClientEvents(client
, &event
, 1, NoEventMask
,
1175 NoEventMask
/* CantBeFiltered */, NullGrab
);
1176 return (client
->noClientException
);
1180 client
->errorValue
= stuff
->property
;
1186 ProcGrabServer(ClientPtr client
)
1188 REQUEST_SIZE_MATCH(xReq
);
1189 if (grabState
!= GrabNone
&& client
!= grabClient
)
1191 ResetCurrentRequest(client
);
1193 BITSET(grabWaiters
, client
->index
);
1194 IgnoreClient(client
);
1195 return(client
->noClientException
);
1197 OnlyListenToOneClient(client
);
1198 grabState
= GrabKickout
;
1199 grabClient
= client
;
1201 if (ServerGrabCallback
)
1203 ServerGrabInfoRec grabinfo
;
1204 grabinfo
.client
= client
;
1205 grabinfo
.grabstate
= SERVER_GRABBED
;
1206 CallCallbacks(&ServerGrabCallback
, (pointer
)&grabinfo
);
1209 return(client
->noClientException
);
1213 UngrabServer(ClientPtr client
)
1217 grabState
= GrabNone
;
1218 ListenToAllClients();
1219 for (i
= mskcnt
; --i
>= 0 && !grabWaiters
[i
]; )
1224 while (!GETBIT(grabWaiters
, i
))
1226 BITCLEAR(grabWaiters
, i
);
1227 AttendClient(clients
[i
]);
1230 if (ServerGrabCallback
)
1232 ServerGrabInfoRec grabinfo
;
1233 grabinfo
.client
= client
;
1234 grabinfo
.grabstate
= SERVER_UNGRABBED
;
1235 CallCallbacks(&ServerGrabCallback
, (pointer
)&grabinfo
);
1240 ProcUngrabServer(ClientPtr client
)
1242 REQUEST_SIZE_MATCH(xReq
);
1243 UngrabServer(client
);
1244 return(client
->noClientException
);
1248 ProcTranslateCoords(ClientPtr client
)
1250 REQUEST(xTranslateCoordsReq
);
1252 WindowPtr pWin
, pDst
;
1253 xTranslateCoordsReply rep
;
1256 REQUEST_SIZE_MATCH(xTranslateCoordsReq
);
1257 rc
= dixLookupWindow(&pWin
, stuff
->srcWid
, client
, DixReadAccess
);
1260 rc
= dixLookupWindow(&pDst
, stuff
->dstWid
, client
, DixReadAccess
);
1265 rep
.sequenceNumber
= client
->sequence
;
1266 if (!SAME_SCREENS(pWin
->drawable
, pDst
->drawable
))
1268 rep
.sameScreen
= xFalse
;
1270 rep
.dstX
= rep
.dstY
= 0;
1275 rep
.sameScreen
= xTrue
;
1277 /* computing absolute coordinates -- adjust to destination later */
1278 x
= pWin
->drawable
.x
+ stuff
->srcX
;
1279 y
= pWin
->drawable
.y
+ stuff
->srcY
;
1280 pWin
= pDst
->firstChild
;
1286 if ((pWin
->mapped
) &&
1287 (x
>= pWin
->drawable
.x
- wBorderWidth (pWin
)) &&
1288 (x
< pWin
->drawable
.x
+ (int)pWin
->drawable
.width
+
1289 wBorderWidth (pWin
)) &&
1290 (y
>= pWin
->drawable
.y
- wBorderWidth (pWin
)) &&
1291 (y
< pWin
->drawable
.y
+ (int)pWin
->drawable
.height
+
1292 wBorderWidth (pWin
))
1294 /* When a window is shaped, a further check
1295 * is made to see if the point is inside
1298 && (!wBoundingShape(pWin
) ||
1299 POINT_IN_REGION(pWin
->drawable
.pScreen
,
1300 &pWin
->borderSize
, x
, y
, &box
))
1302 && (!wInputShape(pWin
) ||
1303 POINT_IN_REGION(pWin
->drawable
.pScreen
,
1305 x
- pWin
->drawable
.x
,
1306 y
- pWin
->drawable
.y
, &box
))
1310 rep
.child
= pWin
->drawable
.id
;
1311 pWin
= (WindowPtr
) NULL
;
1314 pWin
= pWin
->nextSib
;
1316 /* adjust to destination coordinates */
1317 rep
.dstX
= x
- pDst
->drawable
.x
;
1318 rep
.dstY
= y
- pDst
->drawable
.y
;
1320 WriteReplyToClient(client
, sizeof(xTranslateCoordsReply
), &rep
);
1321 return(client
->noClientException
);
1325 ProcOpenFont(ClientPtr client
)
1328 REQUEST(xOpenFontReq
);
1330 REQUEST_FIXED_SIZE(xOpenFontReq
, stuff
->nbytes
);
1331 client
->errorValue
= stuff
->fid
;
1332 LEGAL_NEW_RESOURCE(stuff
->fid
, client
);
1333 err
= OpenFont(client
, stuff
->fid
, (Mask
) 0,
1334 stuff
->nbytes
, (char *)&stuff
[1]);
1337 return(client
->noClientException
);
1344 ProcCloseFont(ClientPtr client
)
1347 REQUEST(xResourceReq
);
1349 REQUEST_SIZE_MATCH(xResourceReq
);
1350 pFont
= (FontPtr
)SecurityLookupIDByType(client
, stuff
->id
, RT_FONT
,
1352 if ( pFont
!= (FontPtr
)NULL
) /* id was valid */
1354 FreeResource(stuff
->id
, RT_NONE
);
1355 return(client
->noClientException
);
1359 client
->errorValue
= stuff
->id
;
1365 ProcQueryFont(ClientPtr client
)
1367 xQueryFontReply
*reply
;
1370 REQUEST(xResourceReq
);
1372 REQUEST_SIZE_MATCH(xResourceReq
);
1373 client
->errorValue
= stuff
->id
; /* EITHER font or gc */
1374 pFont
= (FontPtr
)SecurityLookupIDByType(client
, stuff
->id
, RT_FONT
,
1378 pGC
= (GC
*) SecurityLookupIDByType(client
, stuff
->id
, RT_GC
,
1382 client
->errorValue
= stuff
->id
;
1383 return(BadFont
); /* procotol spec says only error is BadFont */
1389 xCharInfo
*pmax
= FONTINKMAX(pFont
);
1390 xCharInfo
*pmin
= FONTINKMIN(pFont
);
1391 int nprotoxcistructs
;
1394 nprotoxcistructs
= (
1395 pmax
->rightSideBearing
== pmin
->rightSideBearing
&&
1396 pmax
->leftSideBearing
== pmin
->leftSideBearing
&&
1397 pmax
->descent
== pmin
->descent
&&
1398 pmax
->ascent
== pmin
->ascent
&&
1399 pmax
->characterWidth
== pmin
->characterWidth
) ?
1400 0 : N2dChars(pFont
);
1402 rlength
= sizeof(xQueryFontReply
) +
1403 FONTINFONPROPS(FONTCHARSET(pFont
)) * sizeof(xFontProp
) +
1404 nprotoxcistructs
* sizeof(xCharInfo
);
1405 reply
= (xQueryFontReply
*)ALLOCATE_LOCAL(rlength
);
1411 reply
->type
= X_Reply
;
1412 reply
->length
= (rlength
- sizeof(xGenericReply
)) >> 2;
1413 reply
->sequenceNumber
= client
->sequence
;
1414 QueryFont( pFont
, reply
, nprotoxcistructs
);
1416 WriteReplyToClient(client
, rlength
, reply
);
1417 DEALLOCATE_LOCAL(reply
);
1418 return(client
->noClientException
);
1423 ProcQueryTextExtents(ClientPtr client
)
1425 REQUEST(xQueryTextExtentsReq
);
1426 xQueryTextExtentsReply reply
;
1430 unsigned long length
;
1432 REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq
);
1434 pFont
= (FontPtr
)SecurityLookupIDByType(client
, stuff
->fid
, RT_FONT
,
1438 pGC
= (GC
*)SecurityLookupIDByType(client
, stuff
->fid
, RT_GC
,
1442 client
->errorValue
= stuff
->fid
;
1447 length
= client
->req_len
- (sizeof(xQueryTextExtentsReq
) >> 2);
1448 length
= length
<< 1;
1449 if (stuff
->oddLength
)
1455 if (!QueryTextExtents(pFont
, length
, (unsigned char *)&stuff
[1], &info
))
1457 reply
.type
= X_Reply
;
1459 reply
.sequenceNumber
= client
->sequence
;
1460 reply
.drawDirection
= info
.drawDirection
;
1461 reply
.fontAscent
= info
.fontAscent
;
1462 reply
.fontDescent
= info
.fontDescent
;
1463 reply
.overallAscent
= info
.overallAscent
;
1464 reply
.overallDescent
= info
.overallDescent
;
1465 reply
.overallWidth
= info
.overallWidth
;
1466 reply
.overallLeft
= info
.overallLeft
;
1467 reply
.overallRight
= info
.overallRight
;
1468 WriteReplyToClient(client
, sizeof(xQueryTextExtentsReply
), &reply
);
1469 return(client
->noClientException
);
1473 ProcListFonts(ClientPtr client
)
1475 REQUEST(xListFontsReq
);
1477 REQUEST_FIXED_SIZE(xListFontsReq
, stuff
->nbytes
);
1479 return ListFonts(client
, (unsigned char *) &stuff
[1], stuff
->nbytes
,
1484 ProcListFontsWithInfo(ClientPtr client
)
1486 REQUEST(xListFontsWithInfoReq
);
1488 REQUEST_FIXED_SIZE(xListFontsWithInfoReq
, stuff
->nbytes
);
1490 return StartListFontsWithInfo(client
, stuff
->nbytes
,
1491 (unsigned char *) &stuff
[1], stuff
->maxNames
);
1496 * \param value must conform to DeleteType
1499 dixDestroyPixmap(pointer value
, XID pid
)
1501 PixmapPtr pPixmap
= (PixmapPtr
)value
;
1502 return (*pPixmap
->drawable
.pScreen
->DestroyPixmap
)(pPixmap
);
1506 ProcCreatePixmap(ClientPtr client
)
1510 REQUEST(xCreatePixmapReq
);
1514 REQUEST_SIZE_MATCH(xCreatePixmapReq
);
1515 client
->errorValue
= stuff
->pid
;
1516 LEGAL_NEW_RESOURCE(stuff
->pid
, client
);
1518 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
1523 if (!stuff
->width
|| !stuff
->height
)
1525 client
->errorValue
= 0;
1528 if (stuff
->width
> 32767 || stuff
->height
> 32767)
1530 /* It is allowed to try and allocate a pixmap which is larger than
1531 * 32767 in either dimension. However, all of the framebuffer code
1532 * is buggy and does not reliably draw to such big pixmaps, basically
1533 * because the Region data structure operates with signed shorts
1534 * for the rectangles in it.
1536 * Furthermore, several places in the X server computes the
1537 * size in bytes of the pixmap and tries to store it in an
1538 * integer. This integer can overflow and cause the allocated size
1539 * to be much smaller.
1541 * So, such big pixmaps are rejected here with a BadAlloc
1545 if (stuff
->depth
!= 1)
1547 pDepth
= pDraw
->pScreen
->allowedDepths
;
1548 for (i
=0; i
<pDraw
->pScreen
->numDepths
; i
++, pDepth
++)
1549 if (pDepth
->depth
== stuff
->depth
)
1551 client
->errorValue
= stuff
->depth
;
1555 pMap
= (PixmapPtr
)(*pDraw
->pScreen
->CreatePixmap
)
1556 (pDraw
->pScreen
, stuff
->width
,
1557 stuff
->height
, stuff
->depth
);
1560 pMap
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
1561 pMap
->drawable
.id
= stuff
->pid
;
1562 if (AddResource(stuff
->pid
, RT_PIXMAP
, (pointer
)pMap
))
1563 return(client
->noClientException
);
1569 ProcFreePixmap(ClientPtr client
)
1573 REQUEST(xResourceReq
);
1575 REQUEST_SIZE_MATCH(xResourceReq
);
1576 pMap
= (PixmapPtr
)SecurityLookupIDByType(client
, stuff
->id
, RT_PIXMAP
,
1580 FreeResource(stuff
->id
, RT_NONE
);
1581 return(client
->noClientException
);
1585 client
->errorValue
= stuff
->id
;
1591 ProcCreateGC(ClientPtr client
)
1597 REQUEST(xCreateGCReq
);
1599 REQUEST_AT_LEAST_SIZE(xCreateGCReq
);
1600 client
->errorValue
= stuff
->gc
;
1601 LEGAL_NEW_RESOURCE(stuff
->gc
, client
);
1602 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0, DixReadAccess
);
1606 len
= client
->req_len
- (sizeof(xCreateGCReq
) >> 2);
1607 if (len
!= Ones(stuff
->mask
))
1609 pGC
= (GC
*)CreateGC(pDraw
, stuff
->mask
,
1610 (XID
*) &stuff
[1], &error
);
1611 if (error
!= Success
)
1613 if (!AddResource(stuff
->gc
, RT_GC
, (pointer
)pGC
))
1615 return(client
->noClientException
);
1619 ProcChangeGC(ClientPtr client
)
1624 REQUEST(xChangeGCReq
);
1625 REQUEST_AT_LEAST_SIZE(xChangeGCReq
);
1627 result
= dixLookupGC(&pGC
, stuff
->gc
, client
, DixWriteAccess
);
1628 if (result
!= Success
)
1631 len
= client
->req_len
- (sizeof(xChangeGCReq
) >> 2);
1632 if (len
!= Ones(stuff
->mask
))
1635 result
= dixChangeGC(client
, pGC
, stuff
->mask
, (CARD32
*) &stuff
[1], 0);
1636 if (client
->noClientException
!= Success
)
1637 return(client
->noClientException
);
1640 client
->errorValue
= clientErrorValue
;
1646 ProcCopyGC(ClientPtr client
)
1651 REQUEST(xCopyGCReq
);
1652 REQUEST_SIZE_MATCH(xCopyGCReq
);
1654 result
= dixLookupGC(&pGC
, stuff
->srcGC
, client
, DixReadAccess
);
1655 if (result
!= Success
)
1657 result
= dixLookupGC(&dstGC
, stuff
->dstGC
, client
, DixWriteAccess
);
1658 if (result
!= Success
)
1660 if ((dstGC
->pScreen
!= pGC
->pScreen
) || (dstGC
->depth
!= pGC
->depth
))
1662 result
= CopyGC(pGC
, dstGC
, stuff
->mask
);
1663 if (client
->noClientException
!= Success
)
1664 return(client
->noClientException
);
1667 client
->errorValue
= clientErrorValue
;
1673 ProcSetDashes(ClientPtr client
)
1677 REQUEST(xSetDashesReq
);
1679 REQUEST_FIXED_SIZE(xSetDashesReq
, stuff
->nDashes
);
1680 if (stuff
->nDashes
== 0)
1682 client
->errorValue
= 0;
1686 result
= dixLookupGC(&pGC
,stuff
->gc
, client
, DixWriteAccess
);
1687 if (result
!= Success
)
1690 result
= SetDashes(pGC
, stuff
->dashOffset
, stuff
->nDashes
,
1691 (unsigned char *)&stuff
[1]);
1692 if (client
->noClientException
!= Success
)
1693 return(client
->noClientException
);
1696 client
->errorValue
= clientErrorValue
;
1702 ProcSetClipRectangles(ClientPtr client
)
1706 REQUEST(xSetClipRectanglesReq
);
1708 REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq
);
1709 if ((stuff
->ordering
!= Unsorted
) && (stuff
->ordering
!= YSorted
) &&
1710 (stuff
->ordering
!= YXSorted
) && (stuff
->ordering
!= YXBanded
))
1712 client
->errorValue
= stuff
->ordering
;
1715 result
= dixLookupGC(&pGC
,stuff
->gc
, client
, DixWriteAccess
);
1716 if (result
!= Success
)
1719 nr
= (client
->req_len
<< 2) - sizeof(xSetClipRectanglesReq
);
1723 result
= SetClipRects(pGC
, stuff
->xOrigin
, stuff
->yOrigin
,
1724 nr
, (xRectangle
*)&stuff
[1], (int)stuff
->ordering
);
1725 if (client
->noClientException
!= Success
)
1726 return(client
->noClientException
);
1732 ProcFreeGC(ClientPtr client
)
1736 REQUEST(xResourceReq
);
1737 REQUEST_SIZE_MATCH(xResourceReq
);
1739 rc
= dixLookupGC(&pGC
, stuff
->id
, client
, DixDestroyAccess
);
1743 FreeResource(stuff
->id
, RT_NONE
);
1744 return(client
->noClientException
);
1748 ProcClearToBackground(ClientPtr client
)
1750 REQUEST(xClearAreaReq
);
1754 REQUEST_SIZE_MATCH(xClearAreaReq
);
1755 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
1758 if (pWin
->drawable
.class == InputOnly
)
1760 client
->errorValue
= stuff
->window
;
1763 if ((stuff
->exposures
!= xTrue
) && (stuff
->exposures
!= xFalse
))
1765 client
->errorValue
= stuff
->exposures
;
1768 (*pWin
->drawable
.pScreen
->ClearToBackground
)(pWin
, stuff
->x
, stuff
->y
,
1769 stuff
->width
, stuff
->height
,
1770 (Bool
)stuff
->exposures
);
1771 return(client
->noClientException
);
1775 ProcCopyArea(ClientPtr client
)
1780 REQUEST(xCopyAreaReq
);
1784 REQUEST_SIZE_MATCH(xCopyAreaReq
);
1786 VALIDATE_DRAWABLE_AND_GC(stuff
->dstDrawable
, pDst
, pGC
, client
);
1787 if (stuff
->dstDrawable
!= stuff
->srcDrawable
)
1789 rc
= dixLookupDrawable(&pSrc
, stuff
->srcDrawable
, client
, 0,
1793 if ((pDst
->pScreen
!= pSrc
->pScreen
) || (pDst
->depth
!= pSrc
->depth
))
1795 client
->errorValue
= stuff
->dstDrawable
;
1802 pRgn
= (*pGC
->ops
->CopyArea
)(pSrc
, pDst
, pGC
, stuff
->srcX
, stuff
->srcY
,
1803 stuff
->width
, stuff
->height
,
1804 stuff
->dstX
, stuff
->dstY
);
1805 if (pGC
->graphicsExposures
)
1807 (*pDst
->pScreen
->SendGraphicsExpose
)
1808 (client
, pRgn
, stuff
->dstDrawable
, X_CopyArea
, 0);
1810 REGION_DESTROY(pDst
->pScreen
, pRgn
);
1813 return(client
->noClientException
);
1817 ProcCopyPlane(ClientPtr client
)
1819 DrawablePtr psrcDraw
, pdstDraw
;
1821 REQUEST(xCopyPlaneReq
);
1825 REQUEST_SIZE_MATCH(xCopyPlaneReq
);
1827 VALIDATE_DRAWABLE_AND_GC(stuff
->dstDrawable
, pdstDraw
, pGC
, client
);
1828 if (stuff
->dstDrawable
!= stuff
->srcDrawable
)
1830 rc
= dixLookupDrawable(&psrcDraw
, stuff
->srcDrawable
, client
, 0,
1835 if (pdstDraw
->pScreen
!= psrcDraw
->pScreen
)
1837 client
->errorValue
= stuff
->dstDrawable
;
1842 psrcDraw
= pdstDraw
;
1844 /* Check to see if stuff->bitPlane has exactly ONE good bit set */
1845 if(stuff
->bitPlane
== 0 || (stuff
->bitPlane
& (stuff
->bitPlane
- 1)) ||
1846 (stuff
->bitPlane
> (1L << (psrcDraw
->depth
- 1))))
1848 client
->errorValue
= stuff
->bitPlane
;
1852 pRgn
= (*pGC
->ops
->CopyPlane
)(psrcDraw
, pdstDraw
, pGC
, stuff
->srcX
, stuff
->srcY
,
1853 stuff
->width
, stuff
->height
,
1854 stuff
->dstX
, stuff
->dstY
, stuff
->bitPlane
);
1855 if (pGC
->graphicsExposures
)
1857 (*pdstDraw
->pScreen
->SendGraphicsExpose
)
1858 (client
, pRgn
, stuff
->dstDrawable
, X_CopyPlane
, 0);
1860 REGION_DESTROY(pdstDraw
->pScreen
, pRgn
);
1862 return(client
->noClientException
);
1866 ProcPolyPoint(ClientPtr client
)
1871 REQUEST(xPolyPointReq
);
1873 REQUEST_AT_LEAST_SIZE(xPolyPointReq
);
1874 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1875 (stuff
->coordMode
!= CoordModePrevious
))
1877 client
->errorValue
= stuff
->coordMode
;
1880 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
1881 npoint
= ((client
->req_len
<< 2) - sizeof(xPolyPointReq
)) >> 2;
1883 (*pGC
->ops
->PolyPoint
)(pDraw
, pGC
, stuff
->coordMode
, npoint
,
1884 (xPoint
*) &stuff
[1]);
1885 return (client
->noClientException
);
1889 ProcPolyLine(ClientPtr client
)
1894 REQUEST(xPolyLineReq
);
1896 REQUEST_AT_LEAST_SIZE(xPolyLineReq
);
1897 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1898 (stuff
->coordMode
!= CoordModePrevious
))
1900 client
->errorValue
= stuff
->coordMode
;
1903 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
1904 npoint
= ((client
->req_len
<< 2) - sizeof(xPolyLineReq
)) >> 2;
1906 (*pGC
->ops
->Polylines
)(pDraw
, pGC
, stuff
->coordMode
, npoint
,
1907 (DDXPointPtr
) &stuff
[1]);
1908 return(client
->noClientException
);
1912 ProcPolySegment(ClientPtr client
)
1917 REQUEST(xPolySegmentReq
);
1919 REQUEST_AT_LEAST_SIZE(xPolySegmentReq
);
1920 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
1921 nsegs
= (client
->req_len
<< 2) - sizeof(xPolySegmentReq
);
1926 (*pGC
->ops
->PolySegment
)(pDraw
, pGC
, nsegs
, (xSegment
*) &stuff
[1]);
1927 return (client
->noClientException
);
1931 ProcPolyRectangle (ClientPtr client
)
1936 REQUEST(xPolyRectangleReq
);
1938 REQUEST_AT_LEAST_SIZE(xPolyRectangleReq
);
1939 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
1940 nrects
= (client
->req_len
<< 2) - sizeof(xPolyRectangleReq
);
1945 (*pGC
->ops
->PolyRectangle
)(pDraw
, pGC
,
1946 nrects
, (xRectangle
*) &stuff
[1]);
1947 return(client
->noClientException
);
1951 ProcPolyArc(ClientPtr client
)
1956 REQUEST(xPolyArcReq
);
1958 REQUEST_AT_LEAST_SIZE(xPolyArcReq
);
1959 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
1960 narcs
= (client
->req_len
<< 2) - sizeof(xPolyArcReq
);
1961 if (narcs
% sizeof(xArc
))
1963 narcs
/= sizeof(xArc
);
1965 (*pGC
->ops
->PolyArc
)(pDraw
, pGC
, narcs
, (xArc
*) &stuff
[1]);
1966 return (client
->noClientException
);
1970 ProcFillPoly(ClientPtr client
)
1975 REQUEST(xFillPolyReq
);
1977 REQUEST_AT_LEAST_SIZE(xFillPolyReq
);
1978 if ((stuff
->shape
!= Complex
) && (stuff
->shape
!= Nonconvex
) &&
1979 (stuff
->shape
!= Convex
))
1981 client
->errorValue
= stuff
->shape
;
1984 if ((stuff
->coordMode
!= CoordModeOrigin
) &&
1985 (stuff
->coordMode
!= CoordModePrevious
))
1987 client
->errorValue
= stuff
->coordMode
;
1991 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
1992 things
= ((client
->req_len
<< 2) - sizeof(xFillPolyReq
)) >> 2;
1994 (*pGC
->ops
->FillPolygon
) (pDraw
, pGC
, stuff
->shape
,
1995 stuff
->coordMode
, things
,
1996 (DDXPointPtr
) &stuff
[1]);
1997 return(client
->noClientException
);
2001 ProcPolyFillRectangle(ClientPtr client
)
2006 REQUEST(xPolyFillRectangleReq
);
2008 REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq
);
2009 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
2010 things
= (client
->req_len
<< 2) - sizeof(xPolyFillRectangleReq
);
2016 (*pGC
->ops
->PolyFillRect
) (pDraw
, pGC
, things
,
2017 (xRectangle
*) &stuff
[1]);
2018 return (client
->noClientException
);
2022 ProcPolyFillArc(ClientPtr client
)
2027 REQUEST(xPolyFillArcReq
);
2029 REQUEST_AT_LEAST_SIZE(xPolyFillArcReq
);
2030 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
2031 narcs
= (client
->req_len
<< 2) - sizeof(xPolyFillArcReq
);
2032 if (narcs
% sizeof(xArc
))
2034 narcs
/= sizeof(xArc
);
2036 (*pGC
->ops
->PolyFillArc
) (pDraw
, pGC
, narcs
, (xArc
*) &stuff
[1]);
2037 return (client
->noClientException
);
2040 #ifdef MATCH_CLIENT_ENDIAN
2047 if (*((char *) &whichbyte
))
2052 #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
2055 ReformatImage (char *base
, int nbytes
, int bpp
, int order
)
2059 if (BITMAP_BIT_ORDER
!= order
)
2060 BitOrderInvert ((unsigned char *) base
, nbytes
);
2061 #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
2062 ReformatImage (base
, nbytes
, BITMAP_SCANLINE_UNIT
, order
);
2070 if (IMAGE_BYTE_ORDER
!= order
)
2071 TwoByteSwap ((unsigned char *) base
, nbytes
);
2074 if (IMAGE_BYTE_ORDER
!= order
)
2075 FourByteSwap ((unsigned char *) base
, nbytes
);
2080 #define ReformatImage(b,n,bpp,o)
2083 /* 64-bit server notes: the protocol restricts padding of images to
2084 * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
2085 * to use internally. Removes need for internal alignment checking.
2086 * All of the PutImage functions could be changed individually, but
2087 * as currently written, they call other routines which require things
2088 * to be 64-bit padded on scanlines, so we changed things here.
2089 * If an image would be padded differently for 64- versus 32-, then
2090 * copy each scanline to a 64-bit padded scanline.
2091 * Also, we need to make sure that the image is aligned on a 64-bit
2092 * boundary, even if the scanlines are padded to our satisfaction.
2095 ProcPutImage(ClientPtr client
)
2099 long length
; /* length of scanline server padded */
2100 long lengthProto
; /* length of scanline protocol padded */
2102 REQUEST(xPutImageReq
);
2104 REQUEST_AT_LEAST_SIZE(xPutImageReq
);
2105 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
2106 if (stuff
->format
== XYBitmap
)
2108 if ((stuff
->depth
!= 1) ||
2109 (stuff
->leftPad
>= (unsigned int)screenInfo
.bitmapScanlinePad
))
2111 length
= BitmapBytePad(stuff
->width
+ stuff
->leftPad
);
2113 else if (stuff
->format
== XYPixmap
)
2115 if ((pDraw
->depth
!= stuff
->depth
) ||
2116 (stuff
->leftPad
>= (unsigned int)screenInfo
.bitmapScanlinePad
))
2118 length
= BitmapBytePad(stuff
->width
+ stuff
->leftPad
);
2119 length
*= stuff
->depth
;
2121 else if (stuff
->format
== ZPixmap
)
2123 if ((pDraw
->depth
!= stuff
->depth
) || (stuff
->leftPad
!= 0))
2125 length
= PixmapBytePad(stuff
->width
, stuff
->depth
);
2129 client
->errorValue
= stuff
->format
;
2133 tmpImage
= (char *)&stuff
[1];
2134 lengthProto
= length
;
2136 if (((((lengthProto
* stuff
->height
) + (unsigned)3) >> 2) +
2137 (sizeof(xPutImageReq
) >> 2)) != client
->req_len
)
2140 ReformatImage (tmpImage
, lengthProto
* stuff
->height
,
2141 stuff
->format
== ZPixmap
? BitsPerPixel (stuff
->depth
) : 1,
2142 ClientOrder(client
));
2144 (*pGC
->ops
->PutImage
) (pDraw
, pGC
, stuff
->depth
, stuff
->dstX
, stuff
->dstY
,
2145 stuff
->width
, stuff
->height
,
2146 stuff
->leftPad
, stuff
->format
, tmpImage
);
2148 return (client
->noClientException
);
2152 DoGetImage(ClientPtr client
, int format
, Drawable drawable
,
2153 int x
, int y
, int width
, int height
,
2154 Mask planemask
, xGetImageReply
**im_return
)
2157 int nlines
, linesPerBuf
, rc
;
2159 long widthBytesLine
, length
;
2163 RegionPtr pVisibleRegion
= NULL
;
2165 if ((format
!= XYPixmap
) && (format
!= ZPixmap
))
2167 client
->errorValue
= format
;
2170 rc
= dixLookupDrawable(&pDraw
, drawable
, client
, 0, DixReadAccess
);
2174 if(pDraw
->type
== DRAWABLE_WINDOW
)
2176 if( /* check for being viewable */
2177 !((WindowPtr
) pDraw
)->realized
||
2178 /* check for being on screen */
2180 pDraw
->x
+ x
+ width
> pDraw
->pScreen
->width
||
2182 pDraw
->y
+ y
+ height
> pDraw
->pScreen
->height
||
2183 /* check for being inside of border */
2184 x
< - wBorderWidth((WindowPtr
)pDraw
) ||
2185 x
+ width
> wBorderWidth((WindowPtr
)pDraw
) + (int)pDraw
->width
||
2186 y
< -wBorderWidth((WindowPtr
)pDraw
) ||
2187 y
+ height
> wBorderWidth ((WindowPtr
)pDraw
) + (int)pDraw
->height
2190 xgi
.visual
= wVisual (((WindowPtr
) pDraw
));
2195 x
+width
> (int)pDraw
->width
||
2197 y
+height
> (int)pDraw
->height
2204 xgi
.sequenceNumber
= client
->sequence
;
2205 xgi
.depth
= pDraw
->depth
;
2206 if(format
== ZPixmap
)
2208 widthBytesLine
= PixmapBytePad(width
, pDraw
->depth
);
2209 length
= widthBytesLine
* height
;
2214 widthBytesLine
= BitmapBytePad(width
);
2215 plane
= ((Mask
)1) << (pDraw
->depth
- 1);
2216 /* only planes asked for */
2217 length
= widthBytesLine
* height
*
2218 Ones(planemask
& (plane
| (plane
- 1)));
2222 xgi
.length
= length
;
2225 pBuf
= (char *)xalloc(sz_xGetImageReply
+ length
);
2228 if (widthBytesLine
== 0)
2231 linesPerBuf
= height
;
2232 *im_return
= (xGetImageReply
*)pBuf
;
2233 *(xGetImageReply
*)pBuf
= xgi
;
2234 pBuf
+= sz_xGetImageReply
;
2236 xgi
.length
= (xgi
.length
+ 3) >> 2;
2237 if (widthBytesLine
== 0 || height
== 0)
2239 else if (widthBytesLine
>= IMAGE_BUFSIZE
)
2243 linesPerBuf
= IMAGE_BUFSIZE
/ widthBytesLine
;
2244 if (linesPerBuf
> height
)
2245 linesPerBuf
= height
;
2247 length
= linesPerBuf
* widthBytesLine
;
2248 if (linesPerBuf
< height
)
2250 /* we have to make sure intermediate buffers don't need padding */
2251 while ((linesPerBuf
> 1) &&
2252 (length
& ((1L << LOG2_BYTES_PER_SCANLINE_PAD
)-1)))
2255 length
-= widthBytesLine
;
2257 while (length
& ((1L << LOG2_BYTES_PER_SCANLINE_PAD
)-1))
2260 length
+= widthBytesLine
;
2263 if(!(pBuf
= (char *) ALLOCATE_LOCAL(length
)))
2265 WriteReplyToClient(client
, sizeof (xGetImageReply
), &xgi
);
2268 if (pDraw
->type
== DRAWABLE_WINDOW
&&
2269 !XaceHook(XACE_DRAWABLE_ACCESS
, client
, pDraw
))
2271 pVisibleRegion
= NotClippedByChildren((WindowPtr
)pDraw
);
2274 REGION_TRANSLATE(pDraw
->pScreen
, pVisibleRegion
,
2275 -pDraw
->x
, -pDraw
->y
);
2279 if (linesPerBuf
== 0)
2283 else if (format
== ZPixmap
)
2286 while (height
- linesDone
> 0)
2288 nlines
= min(linesPerBuf
, height
- linesDone
);
2289 (*pDraw
->pScreen
->GetImage
) (pDraw
,
2298 XaceCensorImage(client
, pVisibleRegion
, widthBytesLine
,
2299 pDraw
, x
, y
+ linesDone
, width
,
2300 nlines
, format
, pBuf
);
2302 /* Note that this is NOT a call to WriteSwappedDataToClient,
2303 as we do NOT byte swap */
2306 ReformatImage (pBuf
, (int)(nlines
* widthBytesLine
),
2307 BitsPerPixel (pDraw
->depth
),
2308 ClientOrder(client
));
2310 /* Don't split me, gcc pukes when you do */
2311 (void)WriteToClient(client
,
2312 (int)(nlines
* widthBytesLine
),
2315 linesDone
+= nlines
;
2320 for (; plane
; plane
>>= 1)
2322 if (planemask
& plane
)
2325 while (height
- linesDone
> 0)
2327 nlines
= min(linesPerBuf
, height
- linesDone
);
2328 (*pDraw
->pScreen
->GetImage
) (pDraw
,
2337 XaceCensorImage(client
, pVisibleRegion
,
2339 pDraw
, x
, y
+ linesDone
, width
,
2340 nlines
, format
, pBuf
);
2342 /* Note: NOT a call to WriteSwappedDataToClient,
2343 as we do NOT byte swap */
2345 pBuf
+= nlines
* widthBytesLine
;
2347 ReformatImage (pBuf
,
2348 (int)(nlines
* widthBytesLine
),
2350 ClientOrder (client
));
2352 /* Don't split me, gcc pukes when you do */
2353 (void)WriteToClient(client
,
2354 (int)(nlines
* widthBytesLine
),
2357 linesDone
+= nlines
;
2363 REGION_DESTROY(pDraw
->pScreen
, pVisibleRegion
);
2365 DEALLOCATE_LOCAL(pBuf
);
2366 return (client
->noClientException
);
2370 ProcGetImage(ClientPtr client
)
2372 REQUEST(xGetImageReq
);
2374 REQUEST_SIZE_MATCH(xGetImageReq
);
2376 return DoGetImage(client
, stuff
->format
, stuff
->drawable
,
2378 (int)stuff
->width
, (int)stuff
->height
,
2379 stuff
->planeMask
, (xGetImageReply
**)NULL
);
2383 ProcPolyText(ClientPtr client
)
2386 REQUEST(xPolyTextReq
);
2390 REQUEST_AT_LEAST_SIZE(xPolyTextReq
);
2391 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
2393 err
= PolyText(client
,
2396 (unsigned char *)&stuff
[1],
2397 ((unsigned char *) stuff
) + (client
->req_len
<< 2),
2405 return(client
->noClientException
);
2412 ProcImageText8(ClientPtr client
)
2418 REQUEST(xImageTextReq
);
2420 REQUEST_FIXED_SIZE(xImageTextReq
, stuff
->nChars
);
2421 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
2423 err
= ImageText(client
,
2427 (unsigned char *)&stuff
[1],
2435 return(client
->noClientException
);
2442 ProcImageText16(ClientPtr client
)
2448 REQUEST(xImageTextReq
);
2450 REQUEST_FIXED_SIZE(xImageTextReq
, stuff
->nChars
<< 1);
2451 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, pGC
, client
);
2453 err
= ImageText(client
,
2457 (unsigned char *)&stuff
[1],
2465 return(client
->noClientException
);
2473 ProcCreateColormap(ClientPtr client
)
2480 REQUEST(xCreateColormapReq
);
2483 REQUEST_SIZE_MATCH(xCreateColormapReq
);
2485 if ((stuff
->alloc
!= AllocNone
) && (stuff
->alloc
!= AllocAll
))
2487 client
->errorValue
= stuff
->alloc
;
2491 LEGAL_NEW_RESOURCE(mid
, client
);
2492 result
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReadAccess
);
2493 if (result
!= Success
)
2496 pScreen
= pWin
->drawable
.pScreen
;
2497 for (i
= 0, pVisual
= pScreen
->visuals
;
2498 i
< pScreen
->numVisuals
;
2501 if (pVisual
->vid
!= stuff
->visual
)
2503 result
= CreateColormap(mid
, pScreen
, pVisual
, &pmap
,
2504 (int)stuff
->alloc
, client
->index
);
2505 if (client
->noClientException
!= Success
)
2506 return(client
->noClientException
);
2510 client
->errorValue
= stuff
->visual
;
2515 ProcFreeColormap(ClientPtr client
)
2518 REQUEST(xResourceReq
);
2520 REQUEST_SIZE_MATCH(xResourceReq
);
2521 pmap
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->id
, RT_COLORMAP
,
2525 /* Freeing a default colormap is a no-op */
2526 if (!(pmap
->flags
& IsDefault
))
2527 FreeResource(stuff
->id
, RT_NONE
);
2528 return (client
->noClientException
);
2532 client
->errorValue
= stuff
->id
;
2539 ProcCopyColormapAndFree(ClientPtr client
)
2542 ColormapPtr pSrcMap
;
2543 REQUEST(xCopyColormapAndFreeReq
);
2546 REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq
);
2548 LEGAL_NEW_RESOURCE(mid
, client
);
2549 if( (pSrcMap
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->srcCmap
,
2550 RT_COLORMAP
, DixReadAccess
|DixWriteAccess
)) )
2552 result
= CopyColormapAndFree(mid
, pSrcMap
, client
->index
);
2553 if (client
->noClientException
!= Success
)
2554 return(client
->noClientException
);
2560 client
->errorValue
= stuff
->srcCmap
;
2566 ProcInstallColormap(ClientPtr client
)
2569 REQUEST(xResourceReq
);
2571 REQUEST_SIZE_MATCH(xResourceReq
);
2572 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->id
,
2573 RT_COLORMAP
, DixReadAccess
);
2576 (*(pcmp
->pScreen
->InstallColormap
)) (pcmp
);
2577 return (client
->noClientException
);
2581 client
->errorValue
= stuff
->id
;
2587 ProcUninstallColormap(ClientPtr client
)
2590 REQUEST(xResourceReq
);
2592 REQUEST_SIZE_MATCH(xResourceReq
);
2593 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->id
,
2594 RT_COLORMAP
, DixReadAccess
);
2597 if(pcmp
->mid
!= pcmp
->pScreen
->defColormap
)
2598 (*(pcmp
->pScreen
->UninstallColormap
)) (pcmp
);
2599 return (client
->noClientException
);
2603 client
->errorValue
= stuff
->id
;
2609 ProcListInstalledColormaps(ClientPtr client
)
2611 xListInstalledColormapsReply
*preply
;
2614 REQUEST(xResourceReq
);
2616 REQUEST_SIZE_MATCH(xResourceReq
);
2617 rc
= dixLookupWindow(&pWin
, stuff
->id
, client
, DixReadAccess
);
2621 preply
= (xListInstalledColormapsReply
*)
2622 ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply
) +
2623 pWin
->drawable
.pScreen
->maxInstalledCmaps
*
2628 preply
->type
= X_Reply
;
2629 preply
->sequenceNumber
= client
->sequence
;
2630 nummaps
= (*pWin
->drawable
.pScreen
->ListInstalledColormaps
)
2631 (pWin
->drawable
.pScreen
, (Colormap
*)&preply
[1]);
2632 preply
->nColormaps
= nummaps
;
2633 preply
->length
= nummaps
;
2634 WriteReplyToClient(client
, sizeof (xListInstalledColormapsReply
), preply
);
2635 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2636 WriteSwappedDataToClient(client
, nummaps
* sizeof(Colormap
), &preply
[1]);
2637 DEALLOCATE_LOCAL(preply
);
2638 return(client
->noClientException
);
2642 ProcAllocColor (ClientPtr client
)
2646 xAllocColorReply acr
;
2647 REQUEST(xAllocColorReq
);
2649 REQUEST_SIZE_MATCH(xAllocColorReq
);
2650 pmap
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2651 RT_COLORMAP
, DixWriteAccess
);
2656 acr
.sequenceNumber
= client
->sequence
;
2657 acr
.red
= stuff
->red
;
2658 acr
.green
= stuff
->green
;
2659 acr
.blue
= stuff
->blue
;
2661 if( (retval
= AllocColor(pmap
, &acr
.red
, &acr
.green
, &acr
.blue
,
2662 &acr
.pixel
, client
->index
)) )
2664 if (client
->noClientException
!= Success
)
2665 return(client
->noClientException
);
2670 if (noPanoramiXExtension
|| !pmap
->pScreen
->myNum
)
2672 WriteReplyToClient(client
, sizeof(xAllocColorReply
), &acr
);
2673 return (client
->noClientException
);
2678 client
->errorValue
= stuff
->cmap
;
2684 ProcAllocNamedColor (ClientPtr client
)
2687 REQUEST(xAllocNamedColorReq
);
2689 REQUEST_FIXED_SIZE(xAllocNamedColorReq
, stuff
->nbytes
);
2690 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2691 RT_COLORMAP
, DixWriteAccess
);
2696 xAllocNamedColorReply ancr
;
2698 ancr
.type
= X_Reply
;
2700 ancr
.sequenceNumber
= client
->sequence
;
2702 if(OsLookupColor(pcmp
->pScreen
->myNum
, (char *)&stuff
[1], stuff
->nbytes
,
2703 &ancr
.exactRed
, &ancr
.exactGreen
, &ancr
.exactBlue
))
2705 ancr
.screenRed
= ancr
.exactRed
;
2706 ancr
.screenGreen
= ancr
.exactGreen
;
2707 ancr
.screenBlue
= ancr
.exactBlue
;
2709 if( (retval
= AllocColor(pcmp
,
2710 &ancr
.screenRed
, &ancr
.screenGreen
, &ancr
.screenBlue
,
2711 &ancr
.pixel
, client
->index
)) )
2713 if (client
->noClientException
!= Success
)
2714 return(client
->noClientException
);
2719 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2721 WriteReplyToClient(client
, sizeof (xAllocNamedColorReply
), &ancr
);
2722 return (client
->noClientException
);
2730 client
->errorValue
= stuff
->cmap
;
2736 ProcAllocColorCells (ClientPtr client
)
2739 REQUEST(xAllocColorCellsReq
);
2741 REQUEST_SIZE_MATCH(xAllocColorCellsReq
);
2742 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2743 RT_COLORMAP
, DixWriteAccess
);
2746 xAllocColorCellsReply accr
;
2747 int npixels
, nmasks
, retval
;
2749 Pixel
*ppixels
, *pmasks
;
2751 npixels
= stuff
->colors
;
2754 client
->errorValue
= npixels
;
2757 if (stuff
->contiguous
!= xTrue
&& stuff
->contiguous
!= xFalse
)
2759 client
->errorValue
= stuff
->contiguous
;
2762 nmasks
= stuff
->planes
;
2763 length
= ((long)npixels
+ (long)nmasks
) * sizeof(Pixel
);
2764 ppixels
= (Pixel
*)ALLOCATE_LOCAL(length
);
2767 pmasks
= ppixels
+ npixels
;
2769 if( (retval
= AllocColorCells(client
->index
, pcmp
, npixels
, nmasks
,
2770 (Bool
)stuff
->contiguous
, ppixels
, pmasks
)) )
2772 DEALLOCATE_LOCAL(ppixels
);
2773 if (client
->noClientException
!= Success
)
2774 return(client
->noClientException
);
2779 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2782 accr
.type
= X_Reply
;
2783 accr
.length
= length
>> 2;
2784 accr
.sequenceNumber
= client
->sequence
;
2785 accr
.nPixels
= npixels
;
2786 accr
.nMasks
= nmasks
;
2787 WriteReplyToClient(client
, sizeof (xAllocColorCellsReply
), &accr
);
2788 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2789 WriteSwappedDataToClient(client
, length
, ppixels
);
2791 DEALLOCATE_LOCAL(ppixels
);
2792 return (client
->noClientException
);
2796 client
->errorValue
= stuff
->cmap
;
2802 ProcAllocColorPlanes(ClientPtr client
)
2805 REQUEST(xAllocColorPlanesReq
);
2807 REQUEST_SIZE_MATCH(xAllocColorPlanesReq
);
2808 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2809 RT_COLORMAP
, DixWriteAccess
);
2812 xAllocColorPlanesReply acpr
;
2813 int npixels
, retval
;
2817 npixels
= stuff
->colors
;
2820 client
->errorValue
= npixels
;
2823 if (stuff
->contiguous
!= xTrue
&& stuff
->contiguous
!= xFalse
)
2825 client
->errorValue
= stuff
->contiguous
;
2828 acpr
.type
= X_Reply
;
2829 acpr
.sequenceNumber
= client
->sequence
;
2830 acpr
.nPixels
= npixels
;
2831 length
= (long)npixels
* sizeof(Pixel
);
2832 ppixels
= (Pixel
*)ALLOCATE_LOCAL(length
);
2835 if( (retval
= AllocColorPlanes(client
->index
, pcmp
, npixels
,
2836 (int)stuff
->red
, (int)stuff
->green
, (int)stuff
->blue
,
2837 (Bool
)stuff
->contiguous
, ppixels
,
2838 &acpr
.redMask
, &acpr
.greenMask
, &acpr
.blueMask
)) )
2840 DEALLOCATE_LOCAL(ppixels
);
2841 if (client
->noClientException
!= Success
)
2842 return(client
->noClientException
);
2846 acpr
.length
= length
>> 2;
2848 if (noPanoramiXExtension
|| !pcmp
->pScreen
->myNum
)
2851 WriteReplyToClient(client
, sizeof(xAllocColorPlanesReply
), &acpr
);
2852 client
->pSwapReplyFunc
= (ReplySwapPtr
) Swap32Write
;
2853 WriteSwappedDataToClient(client
, length
, ppixels
);
2855 DEALLOCATE_LOCAL(ppixels
);
2856 return (client
->noClientException
);
2860 client
->errorValue
= stuff
->cmap
;
2866 ProcFreeColors(ClientPtr client
)
2869 REQUEST(xFreeColorsReq
);
2871 REQUEST_AT_LEAST_SIZE(xFreeColorsReq
);
2872 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2873 RT_COLORMAP
, DixWriteAccess
);
2879 if(pcmp
->flags
& AllAllocated
)
2881 count
= ((client
->req_len
<< 2)- sizeof(xFreeColorsReq
)) >> 2;
2882 retval
= FreeColors(pcmp
, client
->index
, count
,
2883 (Pixel
*)&stuff
[1], (Pixel
)stuff
->planeMask
);
2884 if (client
->noClientException
!= Success
)
2885 return(client
->noClientException
);
2888 client
->errorValue
= clientErrorValue
;
2895 client
->errorValue
= stuff
->cmap
;
2901 ProcStoreColors (ClientPtr client
)
2904 REQUEST(xStoreColorsReq
);
2906 REQUEST_AT_LEAST_SIZE(xStoreColorsReq
);
2907 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2908 RT_COLORMAP
, DixWriteAccess
);
2914 count
= (client
->req_len
<< 2) - sizeof(xStoreColorsReq
);
2915 if (count
% sizeof(xColorItem
))
2917 count
/= sizeof(xColorItem
);
2918 retval
= StoreColors(pcmp
, count
, (xColorItem
*)&stuff
[1]);
2919 if (client
->noClientException
!= Success
)
2920 return(client
->noClientException
);
2923 client
->errorValue
= clientErrorValue
;
2929 client
->errorValue
= stuff
->cmap
;
2935 ProcStoreNamedColor (ClientPtr client
)
2938 REQUEST(xStoreNamedColorReq
);
2940 REQUEST_FIXED_SIZE(xStoreNamedColorReq
, stuff
->nbytes
);
2941 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2942 RT_COLORMAP
, DixWriteAccess
);
2948 if(OsLookupColor(pcmp
->pScreen
->myNum
, (char *)&stuff
[1],
2949 stuff
->nbytes
, &def
.red
, &def
.green
, &def
.blue
))
2951 def
.flags
= stuff
->flags
;
2952 def
.pixel
= stuff
->pixel
;
2953 retval
= StoreColors(pcmp
, 1, &def
);
2954 if (client
->noClientException
!= Success
)
2955 return(client
->noClientException
);
2963 client
->errorValue
= stuff
->cmap
;
2969 ProcQueryColors(ClientPtr client
)
2972 REQUEST(xQueryColorsReq
);
2974 REQUEST_AT_LEAST_SIZE(xQueryColorsReq
);
2975 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
2976 RT_COLORMAP
, DixReadAccess
);
2981 xQueryColorsReply qcr
;
2983 count
= ((client
->req_len
<< 2) - sizeof(xQueryColorsReq
)) >> 2;
2984 prgbs
= (xrgb
*)ALLOCATE_LOCAL(count
* sizeof(xrgb
));
2987 if( (retval
= QueryColors(pcmp
, count
, (Pixel
*)&stuff
[1], prgbs
)) )
2989 if (prgbs
) DEALLOCATE_LOCAL(prgbs
);
2990 if (client
->noClientException
!= Success
)
2991 return(client
->noClientException
);
2994 client
->errorValue
= clientErrorValue
;
2999 qcr
.length
= (count
* sizeof(xrgb
)) >> 2;
3000 qcr
.sequenceNumber
= client
->sequence
;
3001 qcr
.nColors
= count
;
3002 WriteReplyToClient(client
, sizeof(xQueryColorsReply
), &qcr
);
3005 client
->pSwapReplyFunc
= (ReplySwapPtr
) SQColorsExtend
;
3006 WriteSwappedDataToClient(client
, count
* sizeof(xrgb
), prgbs
);
3008 if (prgbs
) DEALLOCATE_LOCAL(prgbs
);
3009 return(client
->noClientException
);
3014 client
->errorValue
= stuff
->cmap
;
3020 ProcLookupColor(ClientPtr client
)
3023 REQUEST(xLookupColorReq
);
3025 REQUEST_FIXED_SIZE(xLookupColorReq
, stuff
->nbytes
);
3026 pcmp
= (ColormapPtr
)SecurityLookupIDByType(client
, stuff
->cmap
,
3027 RT_COLORMAP
, DixReadAccess
);
3030 xLookupColorReply lcr
;
3032 if(OsLookupColor(pcmp
->pScreen
->myNum
, (char *)&stuff
[1], stuff
->nbytes
,
3033 &lcr
.exactRed
, &lcr
.exactGreen
, &lcr
.exactBlue
))
3037 lcr
.sequenceNumber
= client
->sequence
;
3038 lcr
.screenRed
= lcr
.exactRed
;
3039 lcr
.screenGreen
= lcr
.exactGreen
;
3040 lcr
.screenBlue
= lcr
.exactBlue
;
3041 (*pcmp
->pScreen
->ResolveColor
)(&lcr
.screenRed
,
3045 WriteReplyToClient(client
, sizeof(xLookupColorReply
), &lcr
);
3046 return(client
->noClientException
);
3052 client
->errorValue
= stuff
->cmap
;
3058 ProcCreateCursor (ClientPtr client
)
3063 unsigned char * srcbits
;
3064 unsigned char * mskbits
;
3065 unsigned short width
, height
;
3070 REQUEST(xCreateCursorReq
);
3072 REQUEST_SIZE_MATCH(xCreateCursorReq
);
3073 LEGAL_NEW_RESOURCE(stuff
->cid
, client
);
3075 src
= (PixmapPtr
)SecurityLookupIDByType(client
, stuff
->source
,
3076 RT_PIXMAP
, DixReadAccess
);
3077 msk
= (PixmapPtr
)SecurityLookupIDByType(client
, stuff
->mask
,
3078 RT_PIXMAP
, DixReadAccess
);
3079 if ( src
== (PixmapPtr
)NULL
)
3081 client
->errorValue
= stuff
->source
;
3084 if ( msk
== (PixmapPtr
)NULL
)
3086 if (stuff
->mask
!= None
)
3088 client
->errorValue
= stuff
->mask
;
3092 else if ( src
->drawable
.width
!= msk
->drawable
.width
3093 || src
->drawable
.height
!= msk
->drawable
.height
3094 || src
->drawable
.depth
!= 1
3095 || msk
->drawable
.depth
!= 1)
3098 width
= src
->drawable
.width
;
3099 height
= src
->drawable
.height
;
3101 if ( stuff
->x
> width
3102 || stuff
->y
> height
)
3105 n
= BitmapBytePad(width
)*height
;
3106 srcbits
= (unsigned char *)xalloc(n
);
3109 mskbits
= (unsigned char *)xalloc(n
);
3116 /* zeroing the (pad) bits helps some ddx cursor handling */
3117 bzero((char *)srcbits
, n
);
3118 (* src
->drawable
.pScreen
->GetImage
)( (DrawablePtr
)src
, 0, 0, width
, height
,
3119 XYPixmap
, 1, (pointer
)srcbits
);
3120 if ( msk
== (PixmapPtr
)NULL
)
3122 unsigned char *bits
= mskbits
;
3128 /* zeroing the (pad) bits helps some ddx cursor handling */
3129 bzero((char *)mskbits
, n
);
3130 (* msk
->drawable
.pScreen
->GetImage
)( (DrawablePtr
)msk
, 0, 0, width
,
3131 height
, XYPixmap
, 1, (pointer
)mskbits
);
3137 pCursor
= AllocCursor( srcbits
, mskbits
, &cm
,
3138 stuff
->foreRed
, stuff
->foreGreen
, stuff
->foreBlue
,
3139 stuff
->backRed
, stuff
->backGreen
, stuff
->backBlue
);
3141 if (pCursor
&& AddResource(stuff
->cid
, RT_CURSOR
, (pointer
)pCursor
))
3142 return (client
->noClientException
);
3147 ProcCreateGlyphCursor (ClientPtr client
)
3152 REQUEST(xCreateGlyphCursorReq
);
3154 REQUEST_SIZE_MATCH(xCreateGlyphCursorReq
);
3155 LEGAL_NEW_RESOURCE(stuff
->cid
, client
);
3157 res
= AllocGlyphCursor(stuff
->source
, stuff
->sourceChar
,
3158 stuff
->mask
, stuff
->maskChar
,
3159 stuff
->foreRed
, stuff
->foreGreen
, stuff
->foreBlue
,
3160 stuff
->backRed
, stuff
->backGreen
, stuff
->backBlue
,
3164 if (AddResource(stuff
->cid
, RT_CURSOR
, (pointer
)pCursor
))
3165 return client
->noClientException
;
3171 ProcFreeCursor (ClientPtr client
)
3174 REQUEST(xResourceReq
);
3176 REQUEST_SIZE_MATCH(xResourceReq
);
3177 pCursor
= (CursorPtr
)SecurityLookupIDByType(client
, stuff
->id
,
3178 RT_CURSOR
, DixDestroyAccess
);
3181 FreeResource(stuff
->id
, RT_NONE
);
3182 return (client
->noClientException
);
3186 client
->errorValue
= stuff
->id
;
3192 ProcQueryBestSize (ClientPtr client
)
3194 xQueryBestSizeReply reply
;
3198 REQUEST(xQueryBestSizeReq
);
3199 REQUEST_SIZE_MATCH(xQueryBestSizeReq
);
3201 if ((stuff
->class != CursorShape
) &&
3202 (stuff
->class != TileShape
) &&
3203 (stuff
->class != StippleShape
))
3205 client
->errorValue
= stuff
->class;
3209 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
3213 if (stuff
->class != CursorShape
&& pDraw
->type
== UNDRAWABLE_WINDOW
)
3215 pScreen
= pDraw
->pScreen
;
3216 (* pScreen
->QueryBestSize
)(stuff
->class, &stuff
->width
,
3217 &stuff
->height
, pScreen
);
3218 reply
.type
= X_Reply
;
3220 reply
.sequenceNumber
= client
->sequence
;
3221 reply
.width
= stuff
->width
;
3222 reply
.height
= stuff
->height
;
3223 WriteReplyToClient(client
, sizeof(xQueryBestSizeReply
), &reply
);
3224 return (client
->noClientException
);
3229 ProcSetScreenSaver (ClientPtr client
)
3231 int blankingOption
, exposureOption
;
3232 REQUEST(xSetScreenSaverReq
);
3234 REQUEST_SIZE_MATCH(xSetScreenSaverReq
);
3235 blankingOption
= stuff
->preferBlank
;
3236 if ((blankingOption
!= DontPreferBlanking
) &&
3237 (blankingOption
!= PreferBlanking
) &&
3238 (blankingOption
!= DefaultBlanking
))
3240 client
->errorValue
= blankingOption
;
3243 exposureOption
= stuff
->allowExpose
;
3244 if ((exposureOption
!= DontAllowExposures
) &&
3245 (exposureOption
!= AllowExposures
) &&
3246 (exposureOption
!= DefaultExposures
))
3248 client
->errorValue
= exposureOption
;
3251 if (stuff
->timeout
< -1)
3253 client
->errorValue
= stuff
->timeout
;
3256 if (stuff
->interval
< -1)
3258 client
->errorValue
= stuff
->interval
;
3262 if (blankingOption
== DefaultBlanking
)
3263 ScreenSaverBlanking
= defaultScreenSaverBlanking
;
3265 ScreenSaverBlanking
= blankingOption
;
3266 if (exposureOption
== DefaultExposures
)
3267 ScreenSaverAllowExposures
= defaultScreenSaverAllowExposures
;
3269 ScreenSaverAllowExposures
= exposureOption
;
3271 if (stuff
->timeout
>= 0)
3272 ScreenSaverTime
= stuff
->timeout
* MILLI_PER_SECOND
;
3274 ScreenSaverTime
= defaultScreenSaverTime
;
3275 if (stuff
->interval
>= 0)
3276 ScreenSaverInterval
= stuff
->interval
* MILLI_PER_SECOND
;
3278 ScreenSaverInterval
= defaultScreenSaverInterval
;
3280 SetScreenSaverTimer();
3281 return (client
->noClientException
);
3285 ProcGetScreenSaver(ClientPtr client
)
3287 xGetScreenSaverReply rep
;
3289 REQUEST_SIZE_MATCH(xReq
);
3292 rep
.sequenceNumber
= client
->sequence
;
3293 rep
.timeout
= ScreenSaverTime
/ MILLI_PER_SECOND
;
3294 rep
.interval
= ScreenSaverInterval
/ MILLI_PER_SECOND
;
3295 rep
.preferBlanking
= ScreenSaverBlanking
;
3296 rep
.allowExposures
= ScreenSaverAllowExposures
;
3297 WriteReplyToClient(client
, sizeof(xGetScreenSaverReply
), &rep
);
3298 return (client
->noClientException
);
3302 ProcChangeHosts(ClientPtr client
)
3304 REQUEST(xChangeHostsReq
);
3307 REQUEST_FIXED_SIZE(xChangeHostsReq
, stuff
->hostLength
);
3309 if(stuff
->mode
== HostInsert
)
3310 result
= AddHost(client
, (int)stuff
->hostFamily
,
3311 stuff
->hostLength
, (pointer
)&stuff
[1]);
3312 else if (stuff
->mode
== HostDelete
)
3313 result
= RemoveHost(client
, (int)stuff
->hostFamily
,
3314 stuff
->hostLength
, (pointer
)&stuff
[1]);
3317 client
->errorValue
= stuff
->mode
;
3321 result
= client
->noClientException
;
3326 ProcListHosts(ClientPtr client
)
3328 xListHostsReply reply
;
3329 int len
, nHosts
, result
;
3331 /* REQUEST(xListHostsReq); */
3333 REQUEST_SIZE_MATCH(xListHostsReq
);
3335 /* untrusted clients can't list hosts */
3336 if (!XaceHook(XACE_HOSTLIST_ACCESS
, client
, DixReadAccess
))
3339 result
= GetHosts(&pdata
, &nHosts
, &len
, &reply
.enabled
);
3340 if (result
!= Success
)
3342 reply
.type
= X_Reply
;
3343 reply
.sequenceNumber
= client
->sequence
;
3344 reply
.nHosts
= nHosts
;
3345 reply
.length
= len
>> 2;
3346 WriteReplyToClient(client
, sizeof(xListHostsReply
), &reply
);
3349 client
->pSwapReplyFunc
= (ReplySwapPtr
) SLHostsExtend
;
3350 WriteSwappedDataToClient(client
, len
, pdata
);
3353 return (client
->noClientException
);
3357 ProcChangeAccessControl(ClientPtr client
)
3360 REQUEST(xSetAccessControlReq
);
3362 REQUEST_SIZE_MATCH(xSetAccessControlReq
);
3363 if ((stuff
->mode
!= EnableAccess
) && (stuff
->mode
!= DisableAccess
))
3365 client
->errorValue
= stuff
->mode
;
3368 result
= ChangeAccessControl(client
, stuff
->mode
== EnableAccess
);
3370 result
= client
->noClientException
;
3374 /*********************
3375 * CloseDownRetainedResources
3377 * Find all clients that are gone and have terminated in RetainTemporary
3378 * and destroy their resources.
3379 *********************/
3382 CloseDownRetainedResources(void)
3387 for (i
=1; i
<currentMaxClients
; i
++)
3389 client
= clients
[i
];
3390 if (client
&& (client
->closeDownMode
== RetainTemporary
)
3391 && (client
->clientGone
))
3392 CloseDownClient(client
);
3397 ProcKillClient(ClientPtr client
)
3399 REQUEST(xResourceReq
);
3400 ClientPtr killclient
;
3403 REQUEST_SIZE_MATCH(xResourceReq
);
3404 if (stuff
->id
== AllTemporary
)
3406 CloseDownRetainedResources();
3407 return (client
->noClientException
);
3410 rc
= dixLookupClient(&killclient
, stuff
->id
, client
, DixDestroyAccess
);
3411 if (rc
== Success
) {
3412 CloseDownClient(killclient
);
3413 /* if an LBX proxy gets killed, isItTimeToYield will be set */
3414 if (isItTimeToYield
|| (client
== killclient
))
3416 /* force yield and return Success, so that Dispatch()
3417 * doesn't try to touch client
3419 isItTimeToYield
= TRUE
;
3422 return (client
->noClientException
);
3429 ProcSetFontPath(ClientPtr client
)
3432 unsigned long nbytes
, total
;
3436 REQUEST(xSetFontPathReq
);
3438 REQUEST_AT_LEAST_SIZE(xSetFontPathReq
);
3440 nbytes
= (client
->req_len
<< 2) - sizeof(xSetFontPathReq
);
3442 ptr
= (unsigned char *)&stuff
[1];
3443 nfonts
= stuff
->nFonts
;
3444 while (--nfonts
>= 0)
3446 if ((total
== 0) || (total
< (n
= (*ptr
+ 1))))
3453 result
= SetFontPath(client
, stuff
->nFonts
, (unsigned char *)&stuff
[1],
3457 result
= client
->noClientException
;
3458 client
->errorValue
= error
;
3464 ProcGetFontPath(ClientPtr client
)
3466 xGetFontPathReply reply
;
3467 int stringLens
, numpaths
;
3468 unsigned char *bufferStart
;
3469 /* REQUEST (xReq); */
3471 REQUEST_SIZE_MATCH(xReq
);
3472 bufferStart
= GetFontPath(&numpaths
, &stringLens
);
3474 reply
.type
= X_Reply
;
3475 reply
.sequenceNumber
= client
->sequence
;
3476 reply
.length
= (stringLens
+ numpaths
+ 3) >> 2;
3477 reply
.nPaths
= numpaths
;
3479 WriteReplyToClient(client
, sizeof(xGetFontPathReply
), &reply
);
3480 if (stringLens
|| numpaths
)
3481 (void)WriteToClient(client
, stringLens
+ numpaths
, (char *)bufferStart
);
3482 return(client
->noClientException
);
3486 ProcChangeCloseDownMode(ClientPtr client
)
3488 REQUEST(xSetCloseDownModeReq
);
3490 REQUEST_SIZE_MATCH(xSetCloseDownModeReq
);
3491 if ((stuff
->mode
== AllTemporary
) ||
3492 (stuff
->mode
== RetainPermanent
) ||
3493 (stuff
->mode
== RetainTemporary
))
3495 client
->closeDownMode
= stuff
->mode
;
3496 return (client
->noClientException
);
3500 client
->errorValue
= stuff
->mode
;
3505 int ProcForceScreenSaver(ClientPtr client
)
3507 REQUEST(xForceScreenSaverReq
);
3509 REQUEST_SIZE_MATCH(xForceScreenSaverReq
);
3511 if ((stuff
->mode
!= ScreenSaverReset
) &&
3512 (stuff
->mode
!= ScreenSaverActive
))
3514 client
->errorValue
= stuff
->mode
;
3517 SaveScreens(SCREEN_SAVER_FORCER
, (int)stuff
->mode
);
3518 return client
->noClientException
;
3521 int ProcNoOperation(ClientPtr client
)
3523 REQUEST_AT_LEAST_SIZE(xReq
);
3525 /* noop -- don't do anything */
3526 return(client
->noClientException
);
3530 InitProcVectors(void)
3533 for (i
= 0; i
<256; i
++)
3537 ProcVector
[i
] = SwappedProcVector
[i
] = ProcBadRequest
;
3538 ReplySwapVector
[i
] = ReplyNotSwappd
;
3541 for(i
= LASTEvent
; i
< 128; i
++)
3543 EventSwapVector
[i
] = NotImplemented
;
3548 /**********************
3551 * Client can either mark his resources destroy or retain. If retained and
3552 * then killed again, the client is really destroyed.
3553 *********************/
3555 char dispatchExceptionAtReset
= DE_RESET
;
3558 CloseDownClient(ClientPtr client
)
3560 Bool really_close_down
= client
->clientGone
||
3561 client
->closeDownMode
== DestroyAll
;
3563 if (!client
->clientGone
)
3565 /* ungrab server if grabbing client dies */
3566 if (grabState
!= GrabNone
&& grabClient
== client
)
3568 UngrabServer(client
);
3570 BITCLEAR(grabWaiters
, client
->index
);
3571 DeleteClientFromAnySelections(client
);
3572 ReleaseActiveGrabs(client
);
3573 DeleteClientFontStuff(client
);
3574 if (!really_close_down
)
3576 /* This frees resources that should never be retained
3577 * no matter what the close down mode is. Actually we
3578 * could do this unconditionally, but it's probably
3579 * better not to traverse all the client's resources
3580 * twice (once here, once a few lines down in
3581 * FreeClientResources) in the common case of
3582 * really_close_down == TRUE.
3584 FreeClientNeverRetainResources(client
);
3585 client
->clientState
= ClientStateRetained
;
3586 if (ClientStateCallback
)
3588 NewClientInfoRec clientinfo
;
3590 clientinfo
.client
= client
;
3591 clientinfo
.prefix
= (xConnSetupPrefix
*)NULL
;
3592 clientinfo
.setup
= (xConnSetup
*) NULL
;
3593 CallCallbacks((&ClientStateCallback
), (pointer
)&clientinfo
);
3596 client
->clientGone
= TRUE
; /* so events aren't sent to client */
3597 if (ClientIsAsleep(client
))
3598 ClientSignal (client
);
3599 ProcessWorkQueueZombies();
3600 CloseDownConnection(client
);
3602 /* If the client made it to the Running stage, nClients has
3603 * been incremented on its behalf, so we need to decrement it
3604 * now. If it hasn't gotten to Running, nClients has *not*
3605 * been incremented, so *don't* decrement it.
3607 if (client
->clientState
!= ClientStateInitial
&&
3608 client
->clientState
!= ClientStateAuthenticating
)
3614 if (really_close_down
)
3616 if (client
->clientState
== ClientStateRunning
&& nClients
== 0)
3617 dispatchException
|= dispatchExceptionAtReset
;
3619 client
->clientState
= ClientStateGone
;
3620 if (ClientStateCallback
)
3622 NewClientInfoRec clientinfo
;
3624 clientinfo
.client
= client
;
3625 clientinfo
.prefix
= (xConnSetupPrefix
*)NULL
;
3626 clientinfo
.setup
= (xConnSetup
*) NULL
;
3627 CallCallbacks((&ClientStateCallback
), (pointer
)&clientinfo
);
3629 FreeClientResources(client
);
3630 #ifdef XSERVER_DTRACE
3631 XSERVER_CLIENT_DISCONNECT(client
->index
);
3633 if (client
->index
< nextFreeClientID
)
3634 nextFreeClientID
= client
->index
;
3635 clients
[client
->index
] = NullClient
;
3636 #ifdef SMART_SCHEDULE
3637 SmartLastClient
= NullClient
;
3641 while (!clients
[currentMaxClients
-1])
3642 currentMaxClients
--;
3647 KillAllClients(void)
3650 for (i
=1; i
<currentMaxClients
; i
++)
3652 /* Make sure Retained clients are released. */
3653 clients
[i
]->closeDownMode
= DestroyAll
;
3654 CloseDownClient(clients
[i
]);
3658 extern int clientPrivateLen
;
3659 extern unsigned *clientPrivateSizes
;
3660 extern unsigned totalClientSize
;
3662 void InitClient(ClientPtr client
, int i
, pointer ospriv
)
3665 client
->sequence
= 0;
3666 client
->clientAsMask
= ((Mask
)i
) << CLIENTOFFSET
;
3667 client
->clientGone
= FALSE
;
3670 client
->closeDownMode
= DestroyAll
;
3671 client
->lastDrawable
= (DrawablePtr
)WindowTable
[0];
3672 client
->lastDrawableID
= WindowTable
[0]->drawable
.id
;
3676 client
->closeDownMode
= RetainPermanent
;
3677 client
->lastDrawable
= (DrawablePtr
)NULL
;
3678 client
->lastDrawableID
= INVALID
;
3680 client
->lastGC
= (GCPtr
) NULL
;
3681 client
->lastGCID
= INVALID
;
3682 client
->numSaved
= 0;
3683 client
->saveSet
= (SaveSetElt
*)NULL
;
3684 client
->noClientException
= Success
;
3686 client
->requestLogIndex
= 0;
3688 client
->requestVector
= InitialVector
;
3689 client
->osPrivate
= ospriv
;
3690 client
->swapped
= FALSE
;
3691 client
->big_requests
= FALSE
;
3692 client
->priority
= 0;
3693 client
->clientState
= ClientStateInitial
;
3695 if (!noXkbExtension
) {
3696 client
->xkbClientFlags
= 0;
3697 client
->mapNotifyMask
= 0;
3698 QueryMinMaxKeyCodes(&client
->minKC
,&client
->maxKC
);
3701 client
->replyBytesRemaining
= 0;
3703 client
->appgroup
= NULL
;
3705 client
->fontResFunc
= NULL
;
3706 #ifdef SMART_SCHEDULE
3707 client
->smart_priority
= 0;
3708 client
->smart_start_tick
= SmartScheduleTime
;
3709 client
->smart_stop_tick
= SmartScheduleTime
;
3710 client
->smart_check_tick
= SmartScheduleTime
;
3715 InitClientPrivates(ClientPtr client
)
3723 if (totalClientSize
== sizeof(ClientRec
))
3724 ppriv
= (DevUnion
*)NULL
;
3725 else if (client
->index
)
3726 ppriv
= (DevUnion
*)(client
+ 1);
3729 ppriv
= (DevUnion
*)xalloc(totalClientSize
- sizeof(ClientRec
));
3733 client
->devPrivates
= ppriv
;
3734 sizes
= clientPrivateSizes
;
3735 ptr
= (char *)(ppriv
+ clientPrivateLen
);
3737 bzero(ppriv
, totalClientSize
- sizeof(ClientRec
));
3738 for (i
= clientPrivateLen
; --i
>= 0; ppriv
++, sizes
++)
3740 if ( (size
= *sizes
) )
3742 ppriv
->ptr
= (pointer
)ptr
;
3746 ppriv
->ptr
= (pointer
)NULL
;
3749 /* Allow registrants to initialize the serverClient devPrivates */
3750 if (!client
->index
&& ClientStateCallback
)
3752 NewClientInfoRec clientinfo
;
3754 clientinfo
.client
= client
;
3755 clientinfo
.prefix
= (xConnSetupPrefix
*)NULL
;
3756 clientinfo
.setup
= (xConnSetup
*) NULL
;
3757 CallCallbacks((&ClientStateCallback
), (pointer
)&clientinfo
);
3762 /************************
3763 * int NextAvailableClient(ospriv)
3765 * OS dependent portion can't assign client id's because of CloseDownModes.
3766 * Returns NULL if there are no free clients.
3767 *************************/
3769 ClientPtr
NextAvailableClient(pointer ospriv
)
3775 i
= nextFreeClientID
;
3776 if (i
== MAXCLIENTS
)
3777 return (ClientPtr
)NULL
;
3778 clients
[i
] = client
= (ClientPtr
)xalloc(totalClientSize
);
3780 return (ClientPtr
)NULL
;
3781 InitClient(client
, i
, ospriv
);
3782 InitClientPrivates(client
);
3783 if (!InitClientResources(client
))
3786 return (ClientPtr
)NULL
;
3789 data
.length
= (sz_xReq
+ sz_xConnClientPrefix
) >> 2;
3790 if (!InsertFakeRequest(client
, (char *)&data
, sz_xReq
))
3792 FreeClientResources(client
);
3794 return (ClientPtr
)NULL
;
3796 if (i
== currentMaxClients
)
3797 currentMaxClients
++;
3798 while ((nextFreeClientID
< MAXCLIENTS
) && clients
[nextFreeClientID
])
3800 if (ClientStateCallback
)
3802 NewClientInfoRec clientinfo
;
3804 clientinfo
.client
= client
;
3805 clientinfo
.prefix
= (xConnSetupPrefix
*)NULL
;
3806 clientinfo
.setup
= (xConnSetup
*) NULL
;
3807 CallCallbacks((&ClientStateCallback
), (pointer
)&clientinfo
);
3813 ProcInitialConnection(ClientPtr client
)
3816 xConnClientPrefix
*prefix
;
3819 prefix
= (xConnClientPrefix
*)((char *)stuff
+ sz_xReq
);
3820 if ((prefix
->byteOrder
!= 'l') && (prefix
->byteOrder
!= 'B'))
3821 return (client
->noClientException
= -1);
3822 if (((*(char *) &whichbyte
) && (prefix
->byteOrder
== 'B')) ||
3823 (!(*(char *) &whichbyte
) && (prefix
->byteOrder
== 'l')))
3825 client
->swapped
= TRUE
;
3826 SwapConnClientPrefix(prefix
);
3829 stuff
->length
+= ((prefix
->nbytesAuthProto
+ (unsigned)3) >> 2) +
3830 ((prefix
->nbytesAuthString
+ (unsigned)3) >> 2);
3831 if (client
->swapped
)
3833 swaps(&stuff
->length
, whichbyte
);
3835 ResetCurrentRequest(client
);
3836 return (client
->noClientException
);
3840 SendConnSetup(ClientPtr client
, char *reason
)
3845 char* lConnectionInfo
;
3846 xConnSetupPrefix
* lconnSetupPrefix
;
3850 xConnSetupPrefix csp
;
3852 csp
.success
= xFalse
;
3853 csp
.lengthReason
= strlen(reason
);
3854 csp
.length
= (csp
.lengthReason
+ (unsigned)3) >> 2;
3855 csp
.majorVersion
= X_PROTOCOL
;
3856 csp
.minorVersion
= X_PROTOCOL_REVISION
;
3857 if (client
->swapped
)
3858 WriteSConnSetupPrefix(client
, &csp
);
3860 (void)WriteToClient(client
, sz_xConnSetupPrefix
, (char *) &csp
);
3861 (void)WriteToClient(client
, (int)csp
.lengthReason
, reason
);
3862 return (client
->noClientException
= -1);
3865 numScreens
= screenInfo
.numScreens
;
3866 lConnectionInfo
= ConnectionInfo
;
3867 lconnSetupPrefix
= &connSetupPrefix
;
3869 /* We're about to start speaking X protocol back to the client by
3870 * sending the connection setup info. This means the authorization
3871 * step is complete, and we can count the client as an
3876 client
->requestVector
= client
->swapped
? SwappedProcVector
: ProcVector
;
3877 client
->sequence
= 0;
3879 XagConnectionInfo (client
, &lconnSetupPrefix
, &lConnectionInfo
, &numScreens
);
3881 ((xConnSetup
*)lConnectionInfo
)->ridBase
= client
->clientAsMask
;
3882 ((xConnSetup
*)lConnectionInfo
)->ridMask
= RESOURCE_ID_MASK
;
3883 #ifdef MATCH_CLIENT_ENDIAN
3884 ((xConnSetup
*)lConnectionInfo
)->imageByteOrder
= ClientOrder (client
);
3885 ((xConnSetup
*)lConnectionInfo
)->bitmapBitOrder
= ClientOrder (client
);
3887 /* fill in the "currentInputMask" */
3888 root
= (xWindowRoot
*)(lConnectionInfo
+ connBlockScreenStart
);
3890 if (noPanoramiXExtension
)
3891 numScreens
= screenInfo
.numScreens
;
3893 numScreens
= ((xConnSetup
*)ConnectionInfo
)->numRoots
;
3896 for (i
=0; i
<numScreens
; i
++)
3901 root
->currentInputMask
= WindowTable
[i
]->eventMask
|
3902 wOtherEventMasks (WindowTable
[i
]);
3903 pDepth
= (xDepth
*)(root
+ 1);
3904 for (j
= 0; j
< root
->nDepths
; j
++)
3906 pDepth
= (xDepth
*)(((char *)(pDepth
+ 1)) +
3907 pDepth
->nVisuals
* sizeof(xVisualType
));
3909 root
= (xWindowRoot
*)pDepth
;
3912 if (client
->swapped
)
3914 WriteSConnSetupPrefix(client
, lconnSetupPrefix
);
3915 WriteSConnectionInfo(client
,
3916 (unsigned long)(lconnSetupPrefix
->length
<< 2),
3921 (void)WriteToClient(client
, sizeof(xConnSetupPrefix
),
3922 (char *) lconnSetupPrefix
);
3923 (void)WriteToClient(client
, (int)(lconnSetupPrefix
->length
<< 2),
3926 client
->clientState
= ClientStateRunning
;
3927 if (ClientStateCallback
)
3929 NewClientInfoRec clientinfo
;
3931 clientinfo
.client
= client
;
3932 clientinfo
.prefix
= lconnSetupPrefix
;
3933 clientinfo
.setup
= (xConnSetup
*)lConnectionInfo
;
3934 CallCallbacks((&ClientStateCallback
), (pointer
)&clientinfo
);
3936 return (client
->noClientException
);
3940 ProcEstablishConnection(ClientPtr client
)
3942 char *reason
, *auth_proto
, *auth_string
;
3943 xConnClientPrefix
*prefix
;
3946 prefix
= (xConnClientPrefix
*)((char *)stuff
+ sz_xReq
);
3947 auth_proto
= (char *)prefix
+ sz_xConnClientPrefix
;
3948 auth_string
= auth_proto
+ ((prefix
->nbytesAuthProto
+ 3) & ~3);
3949 if ((prefix
->majorVersion
!= X_PROTOCOL
) ||
3950 (prefix
->minorVersion
!= X_PROTOCOL_REVISION
))
3951 reason
= "Protocol version mismatch";
3953 reason
= ClientAuthorized(client
,
3954 (unsigned short)prefix
->nbytesAuthProto
,
3956 (unsigned short)prefix
->nbytesAuthString
,
3959 * If Kerberos is being used for this client, the clientState
3960 * will be set to ClientStateAuthenticating at this point.
3961 * More messages need to be exchanged among the X server, Kerberos
3962 * server, and client to figure out if everyone is authorized.
3963 * So we don't want to send the connection setup info yet, since
3964 * the auth step isn't really done.
3966 if (client
->clientState
== ClientStateCheckingSecurity
)
3967 client
->clientState
= ClientStateCheckedSecurity
;
3968 else if (client
->clientState
!= ClientStateAuthenticating
)
3969 return(SendConnSetup(client
, reason
));
3970 return(client
->noClientException
);
3974 SendErrorToClient(ClientPtr client
, unsigned majorCode
, unsigned minorCode
,
3975 XID resId
, int errorCode
)
3980 rep
.sequenceNumber
= client
->sequence
;
3981 rep
.errorCode
= errorCode
;
3982 rep
.majorCode
= majorCode
;
3983 rep
.minorCode
= minorCode
;
3984 rep
.resourceID
= resId
;
3986 WriteEventsToClient (client
, 1, (xEvent
*)&rep
);
3990 DeleteWindowFromAnySelections(WindowPtr pWin
)
3994 for (i
= 0; i
< NumCurrentSelections
; i
++)
3995 if (CurrentSelections
[i
].pWin
== pWin
)
3997 if (SelectionCallback
)
3999 SelectionInfoRec info
;
4001 info
.selection
= &CurrentSelections
[i
];
4002 info
.kind
= SelectionWindowDestroy
;
4003 CallCallbacks(&SelectionCallback
, &info
);
4005 CurrentSelections
[i
].pWin
= (WindowPtr
)NULL
;
4006 CurrentSelections
[i
].window
= None
;
4007 CurrentSelections
[i
].client
= NullClient
;
4012 DeleteClientFromAnySelections(ClientPtr client
)
4016 for (i
= 0; i
< NumCurrentSelections
; i
++)
4017 if (CurrentSelections
[i
].client
== client
)
4019 if (SelectionCallback
)
4021 SelectionInfoRec info
;
4023 info
.selection
= &CurrentSelections
[i
];
4024 info
.kind
= SelectionWindowDestroy
;
4025 CallCallbacks(&SelectionCallback
, &info
);
4027 CurrentSelections
[i
].pWin
= (WindowPtr
)NULL
;
4028 CurrentSelections
[i
].window
= None
;
4029 CurrentSelections
[i
].client
= NullClient
;
4034 MarkClientException(ClientPtr client
)
4036 client
->noClientException
= -1;
4039 #ifdef XSERVER_DTRACE
4042 /* Load table of request names for dtrace probes */
4043 static void LoadRequestNames(void)
4047 extern void LoadExtensionNames(char **RequestNames
);
4049 bzero(RequestNames
, 256 * sizeof(char *));
4051 xedb
= fopen(XERRORDB_PATH
, "r");
4054 while (fgets(buf
, sizeof(buf
), xedb
)) {
4055 if ((strncmp("XRequest.", buf
, 9) == 0) && (isdigit(buf
[9]))) {
4057 i
= strtol(buf
+ 9, &name
, 10);
4058 if (RequestNames
[i
] == 0) {
4059 char *end
= strchr(name
, '\n');
4060 if (end
) { *end
= '\0'; }
4061 RequestNames
[i
] = strdup(name
+ 1);
4068 LoadExtensionNames(RequestNames
);
4070 for (i
= 0; i
< 256; i
++) {
4071 if (RequestNames
[i
] == 0) {
4072 #define RN_SIZE 12 /* "Request#' + up to 3 digits + \0 */
4073 RequestNames
[i
] = xalloc(RN_SIZE
);
4074 if (RequestNames
[i
]) {
4075 snprintf(RequestNames
[i
], RN_SIZE
, "Request#%d", i
);
4078 /* fprintf(stderr, "%d: %s\n", i, RequestNames[i]); */
4082 static void FreeRequestNames(void)
4086 for (i
= 0; i
< 256; i
++) {
4087 if (RequestNames
[i
] != 0) {
4088 free(RequestNames
[i
]);
4089 RequestNames
[i
] = 0;