First import
[xorg_rtime.git] / xorg-server-1.4 / dix / dispatch.c
blobc313796ab1519262412afa6d4c5f1c9c185fc342
1 /************************************************************
3 Copyright 1987, 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
26 Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
28 All Rights Reserved
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
44 SOFTWARE.
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>
110 #endif
112 #ifdef PANORAMIX_DEBUG
113 #include <stdio.h>
114 int ProcInitialConnection();
115 #endif
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"
125 #include "opaque.h"
126 #include "input.h"
127 #include "servermd.h"
128 #include "extnsionst.h"
129 #include "dixfont.h"
130 #include "dispatch.h"
131 #include "swaprep.h"
132 #include "swapreq.h"
133 #ifdef PANORAMIX
134 #include "panoramiX.h"
135 #include "panoramiXsrv.h"
136 #endif
137 #include "xace.h"
138 #ifdef XAPPGROUP
139 #include "appgroup.h"
140 #endif
141 #ifdef XKB
142 #ifndef XKB_IN_SERVER
143 #define XKB_IN_SERVER
144 #endif
145 #include "inputstr.h"
146 #include <xkbsrv.h>
147 #endif
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])
158 #endif
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;
176 #define GrabNone 0
177 #define GrabActive 1
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
198 * signal handlers.
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))
213 _X_EXPORT void
214 SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
216 checkForInput[0] = c0;
217 checkForInput[1] = c1;
220 _X_EXPORT void
221 UpdateCurrentTime(void)
223 TimeStamp systime;
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)
231 systime.months++;
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 */
239 _X_EXPORT void
240 UpdateCurrentTimeIf(void)
242 TimeStamp systime;
244 systime.months = currentTime.months;
245 systime.milliseconds = GetTimeInMillis();
246 if (systime.milliseconds < currentTime.milliseconds)
247 systime.months++;
248 if (*checkForInput[0] == *checkForInput[1])
249 currentTime = systime;
252 void
253 InitSelections(void)
255 if (CurrentSelections)
256 xfree(CurrentSelections);
257 CurrentSelections = (Selection *)NULL;
258 NumCurrentSelections = 0;
261 void
262 FlushClientCaches(XID id)
264 int i;
265 ClientPtr client;
267 client = clients[CLIENT_ID(id)];
268 if (client == NullClient)
269 return ;
270 for (i=0; i<currentMaxClients; i++)
272 client = clients[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
290 #undef SMART_DEBUG
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];
303 #ifdef SMART_DEBUG
304 long SmartLastPrint;
305 #endif
307 void Dispatch(void);
308 void InitProcVectors(void);
310 static int
311 SmartScheduleClient (int *clientReady, int nready)
313 ClientPtr pClient;
314 int i;
315 int client;
316 int bestPrio, best = 0;
317 int bestRobin, robin;
318 long now = SmartScheduleTime;
319 long idle;
321 bestPrio = -0x7fffffff;
322 bestRobin = 0;
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;
342 bestRobin = robin;
343 best = client;
345 #ifdef SMART_DEBUG
346 if ((now - SmartLastPrint) >= 5000)
347 fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
348 #endif
350 #ifdef SMART_DEBUG
351 if ((now - SmartLastPrint) >= 5000)
353 fprintf (stderr, " use %2d\n", best);
354 SmartLastPrint = now;
356 #endif
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;
368 * Adjust slice
370 if (nready == 1)
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;
383 else
385 SmartScheduleSlice = SmartScheduleInterval;
387 return best;
389 #endif
391 #define MAJOROP ((xReq *)client->requestBuffer)->reqType
393 void
394 Dispatch(void)
396 int *clientReady; /* array of request ready clients */
397 int result;
398 ClientPtr client;
399 int nready;
400 HWEventQueuePtr* icheck = checkForInput;
401 #ifdef SMART_SCHEDULE
402 long start_tick;
403 #endif
405 nextFreeClientID = 1;
406 InitSelections();
407 nClients = 0;
409 clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
410 if (!clientReady)
411 return;
413 #ifdef XSERVER_DTRACE
414 LoadRequestNames();
415 #endif
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);
431 nready = 1;
433 #endif
434 /*****************
435 * Handle events in round robin fashion, doing input between
436 * each round
437 *****************/
439 while (!dispatchException && (--nready >= 0))
441 client = clients[clientReady[nready]];
442 if (! client)
444 /* KillClient can cause this to happen */
445 continue;
447 /* GrabServer activation can cause this to be true */
448 if (grabState == GrabKickout)
450 grabState = GrabActive;
451 break;
453 isItTimeToYield = FALSE;
455 requestingClient = client;
456 #ifdef SMART_SCHEDULE
457 start_tick = SmartScheduleTime;
458 #endif
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--;
473 break;
475 #endif
476 /* now, finally, deal with client requests */
478 result = ReadRequestFromClient(client);
479 if (result <= 0)
481 if (result < 0)
482 CloseDownClient(client);
483 break;
486 client->sequence++;
487 #ifdef DEBUG
488 if (client->requestLogIndex == MAX_REQUEST_LOG)
489 client->requestLogIndex = 0;
490 client->requestLog[client->requestLogIndex] = MAJOROP;
491 client->requestLogIndex++;
492 #endif
493 #ifdef XSERVER_DTRACE
494 XSERVER_REQUEST_START(GetRequestName(MAJOROP), MAJOROP,
495 ((xReq *)client->requestBuffer)->length,
496 client->index, client->requestBuffer);
497 #endif
498 if (result > (maxBigRequestSize << 2))
499 result = BadLength;
500 else {
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);
508 #endif
510 if (result != Success)
512 if (client->noClientException != Success)
513 CloseDownClient(client);
514 else
515 SendErrorToClient(client, MAJOROP,
516 MinorOpcodeOfRequest(client),
517 client->errorValue, result);
518 break;
520 #ifdef DAMAGEEXT
521 FlushIfCriticalOutputPending ();
522 #endif
524 FlushAllOutput();
525 #ifdef SMART_SCHEDULE
526 client = clients[clientReady[nready]];
527 if (client)
528 client->smart_stop_tick = SmartScheduleTime;
529 #endif
530 requestingClient = NULL;
532 dispatchException &= ~DE_PRIORITYCHANGE;
534 #if defined(DDXBEFORERESET)
535 ddxBeforeReset ();
536 #endif
537 KillAllClients();
538 DEALLOCATE_LOCAL(clientReady);
539 dispatchException &= ~DE_RESET;
540 #ifdef XSERVER_DTRACE
541 FreeRequestNames();
542 #endif
545 #undef MAJOROP
547 _X_EXPORT int
548 ProcBadRequest(ClientPtr client)
550 return (BadRequest);
554 ProcCreateWindow(ClientPtr client)
556 WindowPtr pParent, pWin;
557 REQUEST(xCreateWindowReq);
558 int result, len, rc;
560 REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
562 LEGAL_NEW_RESOURCE(stuff->wid, client);
563 rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess);
564 if (rc != Success)
565 return rc;
566 len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
567 if (Ones(stuff->mask) != len)
568 return BadLength;
569 if (!stuff->width || !stuff->height)
571 client->errorValue = 0;
572 return BadValue;
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],
578 (int)stuff->depth,
579 client, stuff->visual, &result);
580 if (pWin)
582 Mask mask = pWin->eventMask;
584 pWin->eventMask = 0; /* subterfuge in case AddResource fails */
585 if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
586 return BadAlloc;
587 pWin->eventMask = mask;
589 if (client->noClientException != Success)
590 return(client->noClientException);
591 else
592 return(result);
596 ProcChangeWindowAttributes(ClientPtr client)
598 WindowPtr pWin;
599 REQUEST(xChangeWindowAttributesReq);
600 int result;
601 int len, rc;
603 REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
604 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
605 if (rc != Success)
606 return rc;
607 len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
608 if (len != Ones(stuff->valueMask))
609 return BadLength;
610 result = ChangeWindowAttributes(pWin,
611 stuff->valueMask,
612 (XID *) &stuff[1],
613 client);
614 if (client->noClientException != Success)
615 return(client->noClientException);
616 else
617 return(result);
621 ProcGetWindowAttributes(ClientPtr client)
623 WindowPtr pWin;
624 REQUEST(xResourceReq);
625 xGetWindowAttributesReply wa;
626 int rc;
628 REQUEST_SIZE_MATCH(xResourceReq);
629 rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
630 if (rc != Success)
631 return rc;
632 GetWindowAttributes(pWin, client, &wa);
633 WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
634 return(client->noClientException);
638 ProcDestroyWindow(ClientPtr client)
640 WindowPtr pWin;
641 REQUEST(xResourceReq);
642 int rc;
644 REQUEST_SIZE_MATCH(xResourceReq);
645 rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
646 if (rc != Success)
647 return rc;
648 if (pWin->parent)
649 FreeResource(stuff->id, RT_NONE);
650 return(client->noClientException);
654 ProcDestroySubwindows(ClientPtr client)
656 WindowPtr pWin;
657 REQUEST(xResourceReq);
658 int rc;
660 REQUEST_SIZE_MATCH(xResourceReq);
661 rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
662 if (rc != Success)
663 return rc;
664 DestroySubwindows(pWin, client);
665 return(client->noClientException);
669 ProcChangeSaveSet(ClientPtr client)
671 WindowPtr pWin;
672 REQUEST(xChangeSaveSetReq);
673 int result, rc;
675 REQUEST_SIZE_MATCH(xChangeSaveSetReq);
676 rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
677 if (rc != Success)
678 return rc;
679 if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
680 return BadMatch;
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);
686 else
687 return(result);
689 else
691 client->errorValue = stuff->mode;
692 return( BadValue );
697 ProcReparentWindow(ClientPtr client)
699 WindowPtr pWin, pParent;
700 REQUEST(xReparentWindowReq);
701 int result, rc;
703 REQUEST_SIZE_MATCH(xReparentWindowReq);
704 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
705 if (rc != Success)
706 return rc;
707 rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess);
708 if (rc != Success)
709 return rc;
710 if (SAME_SCREENS(pWin->drawable, pParent->drawable))
712 if ((pWin->backgroundState == ParentRelative) &&
713 (pParent->drawable.depth != pWin->drawable.depth))
714 return BadMatch;
715 if ((pWin->drawable.class != InputOnly) &&
716 (pParent->drawable.class == InputOnly))
717 return BadMatch;
718 result = ReparentWindow(pWin, pParent,
719 (short)stuff->x, (short)stuff->y, client);
720 if (client->noClientException != Success)
721 return(client->noClientException);
722 else
723 return(result);
725 else
726 return (BadMatch);
730 ProcMapWindow(ClientPtr client)
732 WindowPtr pWin;
733 REQUEST(xResourceReq);
734 int rc;
736 REQUEST_SIZE_MATCH(xResourceReq);
737 rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
738 if (rc != Success)
739 return rc;
740 MapWindow(pWin, client);
741 /* update cache to say it is mapped */
742 return(client->noClientException);
746 ProcMapSubwindows(ClientPtr client)
748 WindowPtr pWin;
749 REQUEST(xResourceReq);
750 int rc;
752 REQUEST_SIZE_MATCH(xResourceReq);
753 rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
754 if (rc != Success)
755 return rc;
756 MapSubwindows(pWin, client);
757 /* update cache to say it is mapped */
758 return(client->noClientException);
762 ProcUnmapWindow(ClientPtr client)
764 WindowPtr pWin;
765 REQUEST(xResourceReq);
766 int rc;
768 REQUEST_SIZE_MATCH(xResourceReq);
769 rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
770 if (rc != Success)
771 return rc;
772 UnmapWindow(pWin, FALSE);
773 /* update cache to say it is mapped */
774 return(client->noClientException);
778 ProcUnmapSubwindows(ClientPtr client)
780 WindowPtr pWin;
781 REQUEST(xResourceReq);
782 int rc;
784 REQUEST_SIZE_MATCH(xResourceReq);
785 rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
786 if (rc != Success)
787 return rc;
788 UnmapSubwindows(pWin);
789 return(client->noClientException);
793 ProcConfigureWindow(ClientPtr client)
795 WindowPtr pWin;
796 REQUEST(xConfigureWindowReq);
797 int result;
798 int len, rc;
800 REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
801 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
802 if (rc != Success)
803 return rc;
804 len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
805 if (Ones((Mask)stuff->mask) != len)
806 return BadLength;
807 result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
808 client);
809 if (client->noClientException != Success)
810 return(client->noClientException);
811 else
812 return(result);
816 ProcCirculateWindow(ClientPtr client)
818 WindowPtr pWin;
819 REQUEST(xCirculateWindowReq);
820 int rc;
822 REQUEST_SIZE_MATCH(xCirculateWindowReq);
823 if ((stuff->direction != RaiseLowest) &&
824 (stuff->direction != LowerHighest))
826 client->errorValue = stuff->direction;
827 return BadValue;
829 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
830 if (rc != Success)
831 return rc;
832 CirculateWindow(pWin, (int)stuff->direction, client);
833 return(client->noClientException);
836 static int
837 GetGeometry(ClientPtr client, xGetGeometryReply *rep)
839 DrawablePtr pDraw;
840 int rc;
841 REQUEST(xResourceReq);
842 REQUEST_SIZE_MATCH(xResourceReq);
844 rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixReadAccess);
845 if (rc != Success)
846 return rc;
848 rep->type = X_Reply;
849 rep->length = 0;
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;
877 return Success;
882 ProcGetGeometry(ClientPtr client)
884 xGetGeometryReply rep;
885 int status;
887 if ((status = GetGeometry(client, &rep)) != Success)
888 return status;
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);
906 if (rc != Success)
907 return rc;
908 reply.type = X_Reply;
909 reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
910 reply.sequenceNumber = client->sequence;
911 if (pWin->parent)
912 reply.parent = pWin->parent->drawable.id;
913 else
914 reply.parent = (Window)None;
915 pHead = RealChildHead(pWin);
916 for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
917 numChildren++;
918 if (numChildren)
920 int curChild = 0;
922 childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
923 if (!childIDs)
924 return BadAlloc;
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);
933 if (numChildren)
935 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
936 WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
937 DEALLOCATE_LOCAL(childIDs);
940 return(client->noClientException);
944 ProcInternAtom(ClientPtr client)
946 Atom atom;
947 char *tchar;
948 REQUEST(xInternAtomReq);
950 REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
951 if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
953 client->errorValue = stuff->onlyIfExists;
954 return(BadValue);
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;
962 reply.length = 0;
963 reply.sequenceNumber = client->sequence;
964 reply.atom = atom;
965 WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
966 return(client->noClientException);
968 else
969 return (BadAlloc);
973 ProcGetAtomName(ClientPtr client)
975 char *str;
976 xGetAtomNameReply reply;
977 int len;
978 REQUEST(xResourceReq);
980 REQUEST_SIZE_MATCH(xResourceReq);
981 if ( (str = NameForAtom(stuff->id)) )
983 len = strlen(str);
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);
992 else
994 client->errorValue = stuff->id;
995 return (BadAtom);
1000 ProcSetSelectionOwner(ClientPtr client)
1002 WindowPtr pWin;
1003 TimeStamp time;
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)
1013 return Success;
1014 if (stuff->window != None)
1016 int rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
1017 if (rc != Success)
1018 return rc;
1020 else
1021 pWin = (WindowPtr)None;
1022 if (ValidAtom(stuff->selection))
1024 int i = 0;
1027 * First, see if the selection is already set...
1029 while ((i < NumCurrentSelections) &&
1030 CurrentSelections[i].selection != stuff->selection)
1031 i++;
1032 if (i < NumCurrentSelections)
1034 xEvent event;
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
1039 success. */
1040 if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
1041 == EARLIER)
1042 return Success;
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 */,
1052 NullGrab);
1055 else
1058 * It doesn't exist, so add it...
1060 Selection *newsels;
1062 if (i == 0)
1063 newsels = (Selection *)xalloc(sizeof(Selection));
1064 else
1065 newsels = (Selection *)xrealloc(CurrentSelections,
1066 (NumCurrentSelections + 1) * sizeof(Selection));
1067 if (!newsels)
1068 return BadAlloc;
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);
1087 else
1089 client->errorValue = stuff->selection;
1090 return (BadAtom);
1095 ProcGetSelectionOwner(ClientPtr client)
1097 REQUEST(xResourceReq);
1099 REQUEST_SIZE_MATCH(xResourceReq);
1100 if (ValidAtom(stuff->id))
1102 int i;
1103 xGetSelectionOwnerReply reply;
1105 i = 0;
1106 while ((i < NumCurrentSelections) &&
1107 CurrentSelections[i].selection != stuff->id) i++;
1108 reply.type = X_Reply;
1109 reply.length = 0;
1110 reply.sequenceNumber = client->sequence;
1111 if (i < NumCurrentSelections)
1112 reply.owner = CurrentSelections[i].window;
1113 else
1114 reply.owner = None;
1115 WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
1116 return(client->noClientException);
1118 else
1120 client->errorValue = stuff->id;
1121 return (BadAtom);
1126 ProcConvertSelection(ClientPtr client)
1128 Bool paramsOkay;
1129 xEvent event;
1130 WindowPtr pWin;
1131 REQUEST(xConvertSelectionReq);
1132 int rc;
1134 REQUEST_SIZE_MATCH(xConvertSelectionReq);
1135 rc = dixLookupWindow(&pWin, stuff->requestor, client, DixReadAccess);
1136 if (rc != Success)
1137 return rc;
1139 paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
1140 if (stuff->property != None)
1141 paramsOkay &= ValidAtom(stuff->property);
1142 if (paramsOkay)
1144 int i;
1146 i = 0;
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);
1178 else
1180 client->errorValue = stuff->property;
1181 return (BadAtom);
1186 ProcGrabServer(ClientPtr client)
1188 REQUEST_SIZE_MATCH(xReq);
1189 if (grabState != GrabNone && client != grabClient)
1191 ResetCurrentRequest(client);
1192 client->sequence--;
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);
1212 static void
1213 UngrabServer(ClientPtr client)
1215 int i;
1217 grabState = GrabNone;
1218 ListenToAllClients();
1219 for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
1221 if (i >= 0)
1223 i <<= 5;
1224 while (!GETBIT(grabWaiters, i))
1225 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;
1254 int rc;
1256 REQUEST_SIZE_MATCH(xTranslateCoordsReq);
1257 rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess);
1258 if (rc != Success)
1259 return rc;
1260 rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess);
1261 if (rc != Success)
1262 return rc;
1263 rep.type = X_Reply;
1264 rep.length = 0;
1265 rep.sequenceNumber = client->sequence;
1266 if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
1268 rep.sameScreen = xFalse;
1269 rep.child = None;
1270 rep.dstX = rep.dstY = 0;
1272 else
1274 INT16 x, y;
1275 rep.sameScreen = xTrue;
1276 rep.child = None;
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;
1281 while (pWin)
1283 #ifdef SHAPE
1284 BoxRec box;
1285 #endif
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))
1293 #ifdef SHAPE
1294 /* When a window is shaped, a further check
1295 * is made to see if the point is inside
1296 * borderSize
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,
1304 wInputShape(pWin),
1305 x - pWin->drawable.x,
1306 y - pWin->drawable.y, &box))
1307 #endif
1310 rep.child = pWin->drawable.id;
1311 pWin = (WindowPtr) NULL;
1313 else
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)
1327 int err;
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]);
1335 if (err == Success)
1337 return(client->noClientException);
1339 else
1340 return err;
1344 ProcCloseFont(ClientPtr client)
1346 FontPtr pFont;
1347 REQUEST(xResourceReq);
1349 REQUEST_SIZE_MATCH(xResourceReq);
1350 pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
1351 DixDestroyAccess);
1352 if ( pFont != (FontPtr)NULL) /* id was valid */
1354 FreeResource(stuff->id, RT_NONE);
1355 return(client->noClientException);
1357 else
1359 client->errorValue = stuff->id;
1360 return (BadFont);
1365 ProcQueryFont(ClientPtr client)
1367 xQueryFontReply *reply;
1368 FontPtr pFont;
1369 GC *pGC;
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,
1375 DixReadAccess);
1376 if (!pFont)
1378 pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
1379 DixReadAccess);
1380 if (!pGC)
1382 client->errorValue = stuff->id;
1383 return(BadFont); /* procotol spec says only error is BadFont */
1385 pFont = pGC->font;
1389 xCharInfo *pmax = FONTINKMAX(pFont);
1390 xCharInfo *pmin = FONTINKMIN(pFont);
1391 int nprotoxcistructs;
1392 int rlength;
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);
1406 if(!reply)
1408 return(BadAlloc);
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;
1427 FontPtr pFont;
1428 GC *pGC;
1429 ExtentInfoRec info;
1430 unsigned long length;
1432 REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
1434 pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
1435 DixReadAccess);
1436 if (!pFont)
1438 pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
1439 DixReadAccess);
1440 if (!pGC)
1442 client->errorValue = stuff->fid;
1443 return(BadFont);
1445 pFont = pGC->font;
1447 length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
1448 length = length << 1;
1449 if (stuff->oddLength)
1451 if (length == 0)
1452 return(BadLength);
1453 length--;
1455 if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
1456 return(BadAlloc);
1457 reply.type = X_Reply;
1458 reply.length = 0;
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,
1480 stuff->maxNames);
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)
1508 PixmapPtr pMap;
1509 DrawablePtr pDraw;
1510 REQUEST(xCreatePixmapReq);
1511 DepthPtr pDepth;
1512 int i, rc;
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,
1519 DixReadAccess);
1520 if (rc != Success)
1521 return rc;
1523 if (!stuff->width || !stuff->height)
1525 client->errorValue = 0;
1526 return BadValue;
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
1543 return 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)
1550 goto CreatePmap;
1551 client->errorValue = stuff->depth;
1552 return BadValue;
1554 CreatePmap:
1555 pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
1556 (pDraw->pScreen, stuff->width,
1557 stuff->height, stuff->depth);
1558 if (pMap)
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);
1565 return (BadAlloc);
1569 ProcFreePixmap(ClientPtr client)
1571 PixmapPtr pMap;
1573 REQUEST(xResourceReq);
1575 REQUEST_SIZE_MATCH(xResourceReq);
1576 pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
1577 DixDestroyAccess);
1578 if (pMap)
1580 FreeResource(stuff->id, RT_NONE);
1581 return(client->noClientException);
1583 else
1585 client->errorValue = stuff->id;
1586 return (BadPixmap);
1591 ProcCreateGC(ClientPtr client)
1593 int error, rc;
1594 GC *pGC;
1595 DrawablePtr pDraw;
1596 unsigned len;
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);
1603 if (rc != Success)
1604 return rc;
1606 len = client->req_len - (sizeof(xCreateGCReq) >> 2);
1607 if (len != Ones(stuff->mask))
1608 return BadLength;
1609 pGC = (GC *)CreateGC(pDraw, stuff->mask,
1610 (XID *) &stuff[1], &error);
1611 if (error != Success)
1612 return error;
1613 if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
1614 return (BadAlloc);
1615 return(client->noClientException);
1619 ProcChangeGC(ClientPtr client)
1621 GC *pGC;
1622 int result;
1623 unsigned len;
1624 REQUEST(xChangeGCReq);
1625 REQUEST_AT_LEAST_SIZE(xChangeGCReq);
1627 result = dixLookupGC(&pGC, stuff->gc, client, DixWriteAccess);
1628 if (result != Success)
1629 return result;
1631 len = client->req_len - (sizeof(xChangeGCReq) >> 2);
1632 if (len != Ones(stuff->mask))
1633 return BadLength;
1635 result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
1636 if (client->noClientException != Success)
1637 return(client->noClientException);
1638 else
1640 client->errorValue = clientErrorValue;
1641 return(result);
1646 ProcCopyGC(ClientPtr client)
1648 GC *dstGC;
1649 GC *pGC;
1650 int result;
1651 REQUEST(xCopyGCReq);
1652 REQUEST_SIZE_MATCH(xCopyGCReq);
1654 result = dixLookupGC(&pGC, stuff->srcGC, client, DixReadAccess);
1655 if (result != Success)
1656 return result;
1657 result = dixLookupGC(&dstGC, stuff->dstGC, client, DixWriteAccess);
1658 if (result != Success)
1659 return result;
1660 if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
1661 return (BadMatch);
1662 result = CopyGC(pGC, dstGC, stuff->mask);
1663 if (client->noClientException != Success)
1664 return(client->noClientException);
1665 else
1667 client->errorValue = clientErrorValue;
1668 return(result);
1673 ProcSetDashes(ClientPtr client)
1675 GC *pGC;
1676 int result;
1677 REQUEST(xSetDashesReq);
1679 REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
1680 if (stuff->nDashes == 0)
1682 client->errorValue = 0;
1683 return BadValue;
1686 result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess);
1687 if (result != Success)
1688 return result;
1690 result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
1691 (unsigned char *)&stuff[1]);
1692 if (client->noClientException != Success)
1693 return(client->noClientException);
1694 else
1696 client->errorValue = clientErrorValue;
1697 return(result);
1702 ProcSetClipRectangles(ClientPtr client)
1704 int nr, result;
1705 GC *pGC;
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;
1713 return BadValue;
1715 result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess);
1716 if (result != Success)
1717 return result;
1719 nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
1720 if (nr & 4)
1721 return(BadLength);
1722 nr >>= 3;
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);
1727 else
1728 return(result);
1732 ProcFreeGC(ClientPtr client)
1734 GC *pGC;
1735 int rc;
1736 REQUEST(xResourceReq);
1737 REQUEST_SIZE_MATCH(xResourceReq);
1739 rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
1740 if (rc != Success)
1741 return rc;
1743 FreeResource(stuff->id, RT_NONE);
1744 return(client->noClientException);
1748 ProcClearToBackground(ClientPtr client)
1750 REQUEST(xClearAreaReq);
1751 WindowPtr pWin;
1752 int rc;
1754 REQUEST_SIZE_MATCH(xClearAreaReq);
1755 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
1756 if (rc != Success)
1757 return rc;
1758 if (pWin->drawable.class == InputOnly)
1760 client->errorValue = stuff->window;
1761 return (BadMatch);
1763 if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
1765 client->errorValue = stuff->exposures;
1766 return(BadValue);
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)
1777 DrawablePtr pDst;
1778 DrawablePtr pSrc;
1779 GC *pGC;
1780 REQUEST(xCopyAreaReq);
1781 RegionPtr pRgn;
1782 int rc;
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,
1790 DixReadAccess);
1791 if (rc != Success)
1792 return rc;
1793 if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
1795 client->errorValue = stuff->dstDrawable;
1796 return (BadMatch);
1799 else
1800 pSrc = pDst;
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);
1809 if (pRgn)
1810 REGION_DESTROY(pDst->pScreen, pRgn);
1813 return(client->noClientException);
1817 ProcCopyPlane(ClientPtr client)
1819 DrawablePtr psrcDraw, pdstDraw;
1820 GC *pGC;
1821 REQUEST(xCopyPlaneReq);
1822 RegionPtr pRgn;
1823 int rc;
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,
1831 DixReadAccess);
1832 if (rc != Success)
1833 return rc;
1835 if (pdstDraw->pScreen != psrcDraw->pScreen)
1837 client->errorValue = stuff->dstDrawable;
1838 return (BadMatch);
1841 else
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;
1849 return(BadValue);
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);
1859 if (pRgn)
1860 REGION_DESTROY(pdstDraw->pScreen, pRgn);
1862 return(client->noClientException);
1866 ProcPolyPoint(ClientPtr client)
1868 int npoint;
1869 GC *pGC;
1870 DrawablePtr pDraw;
1871 REQUEST(xPolyPointReq);
1873 REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1874 if ((stuff->coordMode != CoordModeOrigin) &&
1875 (stuff->coordMode != CoordModePrevious))
1877 client->errorValue = stuff->coordMode;
1878 return BadValue;
1880 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
1881 npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
1882 if (npoint)
1883 (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
1884 (xPoint *) &stuff[1]);
1885 return (client->noClientException);
1889 ProcPolyLine(ClientPtr client)
1891 int npoint;
1892 GC *pGC;
1893 DrawablePtr pDraw;
1894 REQUEST(xPolyLineReq);
1896 REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1897 if ((stuff->coordMode != CoordModeOrigin) &&
1898 (stuff->coordMode != CoordModePrevious))
1900 client->errorValue = stuff->coordMode;
1901 return BadValue;
1903 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
1904 npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
1905 if (npoint > 1)
1906 (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
1907 (DDXPointPtr) &stuff[1]);
1908 return(client->noClientException);
1912 ProcPolySegment(ClientPtr client)
1914 int nsegs;
1915 GC *pGC;
1916 DrawablePtr pDraw;
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);
1922 if (nsegs & 4)
1923 return(BadLength);
1924 nsegs >>= 3;
1925 if (nsegs)
1926 (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
1927 return (client->noClientException);
1931 ProcPolyRectangle (ClientPtr client)
1933 int nrects;
1934 GC *pGC;
1935 DrawablePtr pDraw;
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);
1941 if (nrects & 4)
1942 return(BadLength);
1943 nrects >>= 3;
1944 if (nrects)
1945 (*pGC->ops->PolyRectangle)(pDraw, pGC,
1946 nrects, (xRectangle *) &stuff[1]);
1947 return(client->noClientException);
1951 ProcPolyArc(ClientPtr client)
1953 int narcs;
1954 GC *pGC;
1955 DrawablePtr pDraw;
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))
1962 return(BadLength);
1963 narcs /= sizeof(xArc);
1964 if (narcs)
1965 (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
1966 return (client->noClientException);
1970 ProcFillPoly(ClientPtr client)
1972 int things;
1973 GC *pGC;
1974 DrawablePtr pDraw;
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;
1982 return BadValue;
1984 if ((stuff->coordMode != CoordModeOrigin) &&
1985 (stuff->coordMode != CoordModePrevious))
1987 client->errorValue = stuff->coordMode;
1988 return BadValue;
1991 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
1992 things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
1993 if (things)
1994 (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
1995 stuff->coordMode, things,
1996 (DDXPointPtr) &stuff[1]);
1997 return(client->noClientException);
2001 ProcPolyFillRectangle(ClientPtr client)
2003 int things;
2004 GC *pGC;
2005 DrawablePtr pDraw;
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);
2011 if (things & 4)
2012 return(BadLength);
2013 things >>= 3;
2015 if (things)
2016 (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
2017 (xRectangle *) &stuff[1]);
2018 return (client->noClientException);
2022 ProcPolyFillArc(ClientPtr client)
2024 int narcs;
2025 GC *pGC;
2026 DrawablePtr pDraw;
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))
2033 return(BadLength);
2034 narcs /= sizeof(xArc);
2035 if (narcs)
2036 (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
2037 return (client->noClientException);
2040 #ifdef MATCH_CLIENT_ENDIAN
2043 ServerOrder (void)
2045 int whichbyte = 1;
2047 if (*((char *) &whichbyte))
2048 return LSBFirst;
2049 return MSBFirst;
2052 #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
2054 void
2055 ReformatImage (char *base, int nbytes, int bpp, int order)
2057 switch (bpp) {
2058 case 1: /* yuck */
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);
2063 #endif
2064 break;
2065 case 4:
2066 break; /* yuck */
2067 case 8:
2068 break;
2069 case 16:
2070 if (IMAGE_BYTE_ORDER != order)
2071 TwoByteSwap ((unsigned char *) base, nbytes);
2072 break;
2073 case 32:
2074 if (IMAGE_BYTE_ORDER != order)
2075 FourByteSwap ((unsigned char *) base, nbytes);
2076 break;
2079 #else
2080 #define ReformatImage(b,n,bpp,o)
2081 #endif
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)
2097 GC *pGC;
2098 DrawablePtr pDraw;
2099 long length; /* length of scanline server padded */
2100 long lengthProto; /* length of scanline protocol padded */
2101 char *tmpImage;
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))
2110 return BadMatch;
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))
2117 return BadMatch;
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))
2124 return BadMatch;
2125 length = PixmapBytePad(stuff->width, stuff->depth);
2127 else
2129 client->errorValue = stuff->format;
2130 return BadValue;
2133 tmpImage = (char *)&stuff[1];
2134 lengthProto = length;
2136 if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
2137 (sizeof(xPutImageReq) >> 2)) != client->req_len)
2138 return BadLength;
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);
2151 static int
2152 DoGetImage(ClientPtr client, int format, Drawable drawable,
2153 int x, int y, int width, int height,
2154 Mask planemask, xGetImageReply **im_return)
2156 DrawablePtr pDraw;
2157 int nlines, linesPerBuf, rc;
2158 int linesDone;
2159 long widthBytesLine, length;
2160 Mask plane = 0;
2161 char *pBuf;
2162 xGetImageReply xgi;
2163 RegionPtr pVisibleRegion = NULL;
2165 if ((format != XYPixmap) && (format != ZPixmap))
2167 client->errorValue = format;
2168 return(BadValue);
2170 rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
2171 if (rc != Success)
2172 return rc;
2174 if(pDraw->type == DRAWABLE_WINDOW)
2176 if( /* check for being viewable */
2177 !((WindowPtr) pDraw)->realized ||
2178 /* check for being on screen */
2179 pDraw->x + x < 0 ||
2180 pDraw->x + x + width > pDraw->pScreen->width ||
2181 pDraw->y + y < 0 ||
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
2189 return(BadMatch);
2190 xgi.visual = wVisual (((WindowPtr) pDraw));
2192 else
2194 if(x < 0 ||
2195 x+width > (int)pDraw->width ||
2196 y < 0 ||
2197 y+height > (int)pDraw->height
2199 return(BadMatch);
2200 xgi.visual = None;
2203 xgi.type = X_Reply;
2204 xgi.sequenceNumber = client->sequence;
2205 xgi.depth = pDraw->depth;
2206 if(format == ZPixmap)
2208 widthBytesLine = PixmapBytePad(width, pDraw->depth);
2209 length = widthBytesLine * height;
2212 else
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;
2224 if (im_return) {
2225 pBuf = (char *)xalloc(sz_xGetImageReply + length);
2226 if (!pBuf)
2227 return (BadAlloc);
2228 if (widthBytesLine == 0)
2229 linesPerBuf = 0;
2230 else
2231 linesPerBuf = height;
2232 *im_return = (xGetImageReply *)pBuf;
2233 *(xGetImageReply *)pBuf = xgi;
2234 pBuf += sz_xGetImageReply;
2235 } else {
2236 xgi.length = (xgi.length + 3) >> 2;
2237 if (widthBytesLine == 0 || height == 0)
2238 linesPerBuf = 0;
2239 else if (widthBytesLine >= IMAGE_BUFSIZE)
2240 linesPerBuf = 1;
2241 else
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)))
2254 linesPerBuf--;
2255 length -= widthBytesLine;
2257 while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
2259 linesPerBuf++;
2260 length += widthBytesLine;
2263 if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
2264 return (BadAlloc);
2265 WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
2268 if (pDraw->type == DRAWABLE_WINDOW &&
2269 !XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw))
2271 pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
2272 if (pVisibleRegion)
2274 REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion,
2275 -pDraw->x, -pDraw->y);
2279 if (linesPerBuf == 0)
2281 /* nothing to do */
2283 else if (format == ZPixmap)
2285 linesDone = 0;
2286 while (height - linesDone > 0)
2288 nlines = min(linesPerBuf, height - linesDone);
2289 (*pDraw->pScreen->GetImage) (pDraw,
2291 y + linesDone,
2292 width,
2293 nlines,
2294 format,
2295 planemask,
2296 (pointer) pBuf);
2297 if (pVisibleRegion)
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 */
2304 if (!im_return)
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),
2313 pBuf);
2315 linesDone += nlines;
2318 else /* XYPixmap */
2320 for (; plane; plane >>= 1)
2322 if (planemask & plane)
2324 linesDone = 0;
2325 while (height - linesDone > 0)
2327 nlines = min(linesPerBuf, height - linesDone);
2328 (*pDraw->pScreen->GetImage) (pDraw,
2330 y + linesDone,
2331 width,
2332 nlines,
2333 format,
2334 plane,
2335 (pointer)pBuf);
2336 if (pVisibleRegion)
2337 XaceCensorImage(client, pVisibleRegion,
2338 widthBytesLine,
2339 pDraw, x, y + linesDone, width,
2340 nlines, format, pBuf);
2342 /* Note: NOT a call to WriteSwappedDataToClient,
2343 as we do NOT byte swap */
2344 if (im_return) {
2345 pBuf += nlines * widthBytesLine;
2346 } else {
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),
2355 pBuf);
2357 linesDone += nlines;
2362 if (pVisibleRegion)
2363 REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
2364 if (!im_return)
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,
2377 stuff->x, stuff->y,
2378 (int)stuff->width, (int)stuff->height,
2379 stuff->planeMask, (xGetImageReply **)NULL);
2383 ProcPolyText(ClientPtr client)
2385 int err;
2386 REQUEST(xPolyTextReq);
2387 DrawablePtr pDraw;
2388 GC *pGC;
2390 REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2391 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
2393 err = PolyText(client,
2394 pDraw,
2395 pGC,
2396 (unsigned char *)&stuff[1],
2397 ((unsigned char *) stuff) + (client->req_len << 2),
2398 stuff->x,
2399 stuff->y,
2400 stuff->reqType,
2401 stuff->drawable);
2403 if (err == Success)
2405 return(client->noClientException);
2407 else
2408 return err;
2412 ProcImageText8(ClientPtr client)
2414 int err;
2415 DrawablePtr pDraw;
2416 GC *pGC;
2418 REQUEST(xImageTextReq);
2420 REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2421 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
2423 err = ImageText(client,
2424 pDraw,
2425 pGC,
2426 stuff->nChars,
2427 (unsigned char *)&stuff[1],
2428 stuff->x,
2429 stuff->y,
2430 stuff->reqType,
2431 stuff->drawable);
2433 if (err == Success)
2435 return(client->noClientException);
2437 else
2438 return err;
2442 ProcImageText16(ClientPtr client)
2444 int err;
2445 DrawablePtr pDraw;
2446 GC *pGC;
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,
2454 pDraw,
2455 pGC,
2456 stuff->nChars,
2457 (unsigned char *)&stuff[1],
2458 stuff->x,
2459 stuff->y,
2460 stuff->reqType,
2461 stuff->drawable);
2463 if (err == Success)
2465 return(client->noClientException);
2467 else
2468 return err;
2473 ProcCreateColormap(ClientPtr client)
2475 VisualPtr pVisual;
2476 ColormapPtr pmap;
2477 Colormap mid;
2478 WindowPtr pWin;
2479 ScreenPtr pScreen;
2480 REQUEST(xCreateColormapReq);
2481 int i, result;
2483 REQUEST_SIZE_MATCH(xCreateColormapReq);
2485 if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
2487 client->errorValue = stuff->alloc;
2488 return(BadValue);
2490 mid = stuff->mid;
2491 LEGAL_NEW_RESOURCE(mid, client);
2492 result = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
2493 if (result != Success)
2494 return result;
2496 pScreen = pWin->drawable.pScreen;
2497 for (i = 0, pVisual = pScreen->visuals;
2498 i < pScreen->numVisuals;
2499 i++, pVisual++)
2501 if (pVisual->vid != stuff->visual)
2502 continue;
2503 result = CreateColormap(mid, pScreen, pVisual, &pmap,
2504 (int)stuff->alloc, client->index);
2505 if (client->noClientException != Success)
2506 return(client->noClientException);
2507 else
2508 return(result);
2510 client->errorValue = stuff->visual;
2511 return(BadMatch);
2515 ProcFreeColormap(ClientPtr client)
2517 ColormapPtr pmap;
2518 REQUEST(xResourceReq);
2520 REQUEST_SIZE_MATCH(xResourceReq);
2521 pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
2522 DixDestroyAccess);
2523 if (pmap)
2525 /* Freeing a default colormap is a no-op */
2526 if (!(pmap->flags & IsDefault))
2527 FreeResource(stuff->id, RT_NONE);
2528 return (client->noClientException);
2530 else
2532 client->errorValue = stuff->id;
2533 return (BadColor);
2539 ProcCopyColormapAndFree(ClientPtr client)
2541 Colormap mid;
2542 ColormapPtr pSrcMap;
2543 REQUEST(xCopyColormapAndFreeReq);
2544 int result;
2546 REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2547 mid = stuff->mid;
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);
2555 else
2556 return(result);
2558 else
2560 client->errorValue = stuff->srcCmap;
2561 return(BadColor);
2566 ProcInstallColormap(ClientPtr client)
2568 ColormapPtr pcmp;
2569 REQUEST(xResourceReq);
2571 REQUEST_SIZE_MATCH(xResourceReq);
2572 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
2573 RT_COLORMAP, DixReadAccess);
2574 if (pcmp)
2576 (*(pcmp->pScreen->InstallColormap)) (pcmp);
2577 return (client->noClientException);
2579 else
2581 client->errorValue = stuff->id;
2582 return (BadColor);
2587 ProcUninstallColormap(ClientPtr client)
2589 ColormapPtr pcmp;
2590 REQUEST(xResourceReq);
2592 REQUEST_SIZE_MATCH(xResourceReq);
2593 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
2594 RT_COLORMAP, DixReadAccess);
2595 if (pcmp)
2597 if(pcmp->mid != pcmp->pScreen->defColormap)
2598 (*(pcmp->pScreen->UninstallColormap)) (pcmp);
2599 return (client->noClientException);
2601 else
2603 client->errorValue = stuff->id;
2604 return (BadColor);
2609 ProcListInstalledColormaps(ClientPtr client)
2611 xListInstalledColormapsReply *preply;
2612 int nummaps, rc;
2613 WindowPtr pWin;
2614 REQUEST(xResourceReq);
2616 REQUEST_SIZE_MATCH(xResourceReq);
2617 rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
2618 if (rc != Success)
2619 return rc;
2621 preply = (xListInstalledColormapsReply *)
2622 ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
2623 pWin->drawable.pScreen->maxInstalledCmaps *
2624 sizeof(Colormap));
2625 if(!preply)
2626 return(BadAlloc);
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)
2644 ColormapPtr pmap;
2645 int retval;
2646 xAllocColorReply acr;
2647 REQUEST(xAllocColorReq);
2649 REQUEST_SIZE_MATCH(xAllocColorReq);
2650 pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2651 RT_COLORMAP, DixWriteAccess);
2652 if (pmap)
2654 acr.type = X_Reply;
2655 acr.length = 0;
2656 acr.sequenceNumber = client->sequence;
2657 acr.red = stuff->red;
2658 acr.green = stuff->green;
2659 acr.blue = stuff->blue;
2660 acr.pixel = 0;
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);
2666 else
2667 return (retval);
2669 #ifdef PANORAMIX
2670 if (noPanoramiXExtension || !pmap->pScreen->myNum)
2671 #endif
2672 WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
2673 return (client->noClientException);
2676 else
2678 client->errorValue = stuff->cmap;
2679 return (BadColor);
2684 ProcAllocNamedColor (ClientPtr client)
2686 ColormapPtr pcmp;
2687 REQUEST(xAllocNamedColorReq);
2689 REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2690 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2691 RT_COLORMAP, DixWriteAccess);
2692 if (pcmp)
2694 int retval;
2696 xAllocNamedColorReply ancr;
2698 ancr.type = X_Reply;
2699 ancr.length = 0;
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;
2708 ancr.pixel = 0;
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);
2715 else
2716 return(retval);
2718 #ifdef PANORAMIX
2719 if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2720 #endif
2721 WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
2722 return (client->noClientException);
2724 else
2725 return(BadName);
2728 else
2730 client->errorValue = stuff->cmap;
2731 return (BadColor);
2736 ProcAllocColorCells (ClientPtr client)
2738 ColormapPtr pcmp;
2739 REQUEST(xAllocColorCellsReq);
2741 REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2742 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2743 RT_COLORMAP, DixWriteAccess);
2744 if (pcmp)
2746 xAllocColorCellsReply accr;
2747 int npixels, nmasks, retval;
2748 long length;
2749 Pixel *ppixels, *pmasks;
2751 npixels = stuff->colors;
2752 if (!npixels)
2754 client->errorValue = npixels;
2755 return (BadValue);
2757 if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
2759 client->errorValue = stuff->contiguous;
2760 return (BadValue);
2762 nmasks = stuff->planes;
2763 length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
2764 ppixels = (Pixel *)ALLOCATE_LOCAL(length);
2765 if(!ppixels)
2766 return(BadAlloc);
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);
2775 else
2776 return(retval);
2778 #ifdef PANORAMIX
2779 if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2780 #endif
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);
2794 else
2796 client->errorValue = stuff->cmap;
2797 return (BadColor);
2802 ProcAllocColorPlanes(ClientPtr client)
2804 ColormapPtr pcmp;
2805 REQUEST(xAllocColorPlanesReq);
2807 REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2808 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2809 RT_COLORMAP, DixWriteAccess);
2810 if (pcmp)
2812 xAllocColorPlanesReply acpr;
2813 int npixels, retval;
2814 long length;
2815 Pixel *ppixels;
2817 npixels = stuff->colors;
2818 if (!npixels)
2820 client->errorValue = npixels;
2821 return (BadValue);
2823 if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
2825 client->errorValue = stuff->contiguous;
2826 return (BadValue);
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);
2833 if(!ppixels)
2834 return(BadAlloc);
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);
2843 else
2844 return(retval);
2846 acpr.length = length >> 2;
2847 #ifdef PANORAMIX
2848 if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2849 #endif
2851 WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
2852 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2853 WriteSwappedDataToClient(client, length, ppixels);
2855 DEALLOCATE_LOCAL(ppixels);
2856 return (client->noClientException);
2858 else
2860 client->errorValue = stuff->cmap;
2861 return (BadColor);
2866 ProcFreeColors(ClientPtr client)
2868 ColormapPtr pcmp;
2869 REQUEST(xFreeColorsReq);
2871 REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2872 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2873 RT_COLORMAP, DixWriteAccess);
2874 if (pcmp)
2876 int count;
2877 int retval;
2879 if(pcmp->flags & AllAllocated)
2880 return(BadAccess);
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);
2886 else
2888 client->errorValue = clientErrorValue;
2889 return(retval);
2893 else
2895 client->errorValue = stuff->cmap;
2896 return (BadColor);
2901 ProcStoreColors (ClientPtr client)
2903 ColormapPtr pcmp;
2904 REQUEST(xStoreColorsReq);
2906 REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2907 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2908 RT_COLORMAP, DixWriteAccess);
2909 if (pcmp)
2911 int count;
2912 int retval;
2914 count = (client->req_len << 2) - sizeof(xStoreColorsReq);
2915 if (count % sizeof(xColorItem))
2916 return(BadLength);
2917 count /= sizeof(xColorItem);
2918 retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
2919 if (client->noClientException != Success)
2920 return(client->noClientException);
2921 else
2923 client->errorValue = clientErrorValue;
2924 return(retval);
2927 else
2929 client->errorValue = stuff->cmap;
2930 return (BadColor);
2935 ProcStoreNamedColor (ClientPtr client)
2937 ColormapPtr pcmp;
2938 REQUEST(xStoreNamedColorReq);
2940 REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2941 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2942 RT_COLORMAP, DixWriteAccess);
2943 if (pcmp)
2945 xColorItem def;
2946 int retval;
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);
2956 else
2957 return(retval);
2959 return (BadName);
2961 else
2963 client->errorValue = stuff->cmap;
2964 return (BadColor);
2969 ProcQueryColors(ClientPtr client)
2971 ColormapPtr pcmp;
2972 REQUEST(xQueryColorsReq);
2974 REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2975 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
2976 RT_COLORMAP, DixReadAccess);
2977 if (pcmp)
2979 int count, retval;
2980 xrgb *prgbs;
2981 xQueryColorsReply qcr;
2983 count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
2984 prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
2985 if(!prgbs && count)
2986 return(BadAlloc);
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);
2992 else
2994 client->errorValue = clientErrorValue;
2995 return (retval);
2998 qcr.type = X_Reply;
2999 qcr.length = (count * sizeof(xrgb)) >> 2;
3000 qcr.sequenceNumber = client->sequence;
3001 qcr.nColors = count;
3002 WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
3003 if (count)
3005 client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
3006 WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
3008 if (prgbs) DEALLOCATE_LOCAL(prgbs);
3009 return(client->noClientException);
3012 else
3014 client->errorValue = stuff->cmap;
3015 return (BadColor);
3020 ProcLookupColor(ClientPtr client)
3022 ColormapPtr pcmp;
3023 REQUEST(xLookupColorReq);
3025 REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
3026 pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
3027 RT_COLORMAP, DixReadAccess);
3028 if (pcmp)
3030 xLookupColorReply lcr;
3032 if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
3033 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
3035 lcr.type = X_Reply;
3036 lcr.length = 0;
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,
3042 &lcr.screenGreen,
3043 &lcr.screenBlue,
3044 pcmp->pVisual);
3045 WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
3046 return(client->noClientException);
3048 return (BadName);
3050 else
3052 client->errorValue = stuff->cmap;
3053 return (BadColor);
3058 ProcCreateCursor (ClientPtr client)
3060 CursorPtr pCursor;
3061 PixmapPtr src;
3062 PixmapPtr msk;
3063 unsigned char * srcbits;
3064 unsigned char * mskbits;
3065 unsigned short width, height;
3066 long n;
3067 CursorMetricRec cm;
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;
3082 return (BadPixmap);
3084 if ( msk == (PixmapPtr)NULL)
3086 if (stuff->mask != None)
3088 client->errorValue = stuff->mask;
3089 return (BadPixmap);
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)
3096 return (BadMatch);
3098 width = src->drawable.width;
3099 height = src->drawable.height;
3101 if ( stuff->x > width
3102 || stuff->y > height )
3103 return (BadMatch);
3105 n = BitmapBytePad(width)*height;
3106 srcbits = (unsigned char *)xalloc(n);
3107 if (!srcbits)
3108 return (BadAlloc);
3109 mskbits = (unsigned char *)xalloc(n);
3110 if (!mskbits)
3112 xfree(srcbits);
3113 return (BadAlloc);
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;
3123 while (--n >= 0)
3124 *bits++ = ~0;
3126 else
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);
3133 cm.width = width;
3134 cm.height = height;
3135 cm.xhot = stuff->x;
3136 cm.yhot = stuff->y;
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);
3143 return BadAlloc;
3147 ProcCreateGlyphCursor (ClientPtr client)
3149 CursorPtr pCursor;
3150 int res;
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,
3161 &pCursor, client);
3162 if (res != Success)
3163 return res;
3164 if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
3165 return client->noClientException;
3166 return BadAlloc;
3171 ProcFreeCursor (ClientPtr client)
3173 CursorPtr pCursor;
3174 REQUEST(xResourceReq);
3176 REQUEST_SIZE_MATCH(xResourceReq);
3177 pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
3178 RT_CURSOR, DixDestroyAccess);
3179 if (pCursor)
3181 FreeResource(stuff->id, RT_NONE);
3182 return (client->noClientException);
3184 else
3186 client->errorValue = stuff->id;
3187 return (BadCursor);
3192 ProcQueryBestSize (ClientPtr client)
3194 xQueryBestSizeReply reply;
3195 DrawablePtr pDraw;
3196 ScreenPtr pScreen;
3197 int rc;
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;
3206 return(BadValue);
3209 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
3210 DixReadAccess);
3211 if (rc != Success)
3212 return rc;
3213 if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
3214 return (BadMatch);
3215 pScreen = pDraw->pScreen;
3216 (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
3217 &stuff->height, pScreen);
3218 reply.type = X_Reply;
3219 reply.length = 0;
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;
3241 return BadValue;
3243 exposureOption = stuff->allowExpose;
3244 if ((exposureOption != DontAllowExposures) &&
3245 (exposureOption != AllowExposures) &&
3246 (exposureOption != DefaultExposures))
3248 client->errorValue = exposureOption;
3249 return BadValue;
3251 if (stuff->timeout < -1)
3253 client->errorValue = stuff->timeout;
3254 return BadValue;
3256 if (stuff->interval < -1)
3258 client->errorValue = stuff->interval;
3259 return BadValue;
3262 if (blankingOption == DefaultBlanking)
3263 ScreenSaverBlanking = defaultScreenSaverBlanking;
3264 else
3265 ScreenSaverBlanking = blankingOption;
3266 if (exposureOption == DefaultExposures)
3267 ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
3268 else
3269 ScreenSaverAllowExposures = exposureOption;
3271 if (stuff->timeout >= 0)
3272 ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
3273 else
3274 ScreenSaverTime = defaultScreenSaverTime;
3275 if (stuff->interval >= 0)
3276 ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
3277 else
3278 ScreenSaverInterval = defaultScreenSaverInterval;
3280 SetScreenSaverTimer();
3281 return (client->noClientException);
3285 ProcGetScreenSaver(ClientPtr client)
3287 xGetScreenSaverReply rep;
3289 REQUEST_SIZE_MATCH(xReq);
3290 rep.type = X_Reply;
3291 rep.length = 0;
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);
3305 int result;
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]);
3315 else
3317 client->errorValue = stuff->mode;
3318 return BadValue;
3320 if (!result)
3321 result = client->noClientException;
3322 return (result);
3326 ProcListHosts(ClientPtr client)
3328 xListHostsReply reply;
3329 int len, nHosts, result;
3330 pointer pdata;
3331 /* REQUEST(xListHostsReq); */
3333 REQUEST_SIZE_MATCH(xListHostsReq);
3335 /* untrusted clients can't list hosts */
3336 if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixReadAccess))
3337 return BadAccess;
3339 result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
3340 if (result != Success)
3341 return(result);
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);
3347 if (nHosts)
3349 client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
3350 WriteSwappedDataToClient(client, len, pdata);
3352 xfree(pdata);
3353 return (client->noClientException);
3357 ProcChangeAccessControl(ClientPtr client)
3359 int result;
3360 REQUEST(xSetAccessControlReq);
3362 REQUEST_SIZE_MATCH(xSetAccessControlReq);
3363 if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
3365 client->errorValue = stuff->mode;
3366 return BadValue;
3368 result = ChangeAccessControl(client, stuff->mode == EnableAccess);
3369 if (!result)
3370 result = client->noClientException;
3371 return (result);
3374 /*********************
3375 * CloseDownRetainedResources
3377 * Find all clients that are gone and have terminated in RetainTemporary
3378 * and destroy their resources.
3379 *********************/
3381 static void
3382 CloseDownRetainedResources(void)
3384 int i;
3385 ClientPtr client;
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;
3401 int rc;
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;
3420 return (Success);
3422 return (client->noClientException);
3424 else
3425 return rc;
3429 ProcSetFontPath(ClientPtr client)
3431 unsigned char *ptr;
3432 unsigned long nbytes, total;
3433 long nfonts;
3434 int n, result;
3435 int error;
3436 REQUEST(xSetFontPathReq);
3438 REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
3440 nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
3441 total = nbytes;
3442 ptr = (unsigned char *)&stuff[1];
3443 nfonts = stuff->nFonts;
3444 while (--nfonts >= 0)
3446 if ((total == 0) || (total < (n = (*ptr + 1))))
3447 return(BadLength);
3448 total -= n;
3449 ptr += n;
3451 if (total >= 4)
3452 return(BadLength);
3453 result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
3454 &error);
3455 if (!result)
3457 result = client->noClientException;
3458 client->errorValue = error;
3460 return (result);
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);
3498 else
3500 client->errorValue = stuff->mode;
3501 return (BadValue);
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;
3515 return BadValue;
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);
3529 void
3530 InitProcVectors(void)
3532 int i;
3533 for (i = 0; i<256; i++)
3535 if(!ProcVector[i])
3537 ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
3538 ReplySwapVector[i] = ReplyNotSwappd;
3541 for(i = LASTEvent; i < 128; i++)
3543 EventSwapVector[i] = NotImplemented;
3548 /**********************
3549 * CloseDownClient
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;
3557 void
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 )
3610 --nClients;
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);
3632 #endif
3633 if (client->index < nextFreeClientID)
3634 nextFreeClientID = client->index;
3635 clients[client->index] = NullClient;
3636 #ifdef SMART_SCHEDULE
3637 SmartLastClient = NullClient;
3638 #endif
3639 xfree(client);
3641 while (!clients[currentMaxClients-1])
3642 currentMaxClients--;
3646 static void
3647 KillAllClients(void)
3649 int i;
3650 for (i=1; i<currentMaxClients; i++)
3651 if (clients[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)
3664 client->index = i;
3665 client->sequence = 0;
3666 client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
3667 client->clientGone = FALSE;
3668 if (i)
3670 client->closeDownMode = DestroyAll;
3671 client->lastDrawable = (DrawablePtr)WindowTable[0];
3672 client->lastDrawableID = WindowTable[0]->drawable.id;
3674 else
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;
3685 #ifdef DEBUG
3686 client->requestLogIndex = 0;
3687 #endif
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;
3694 #ifdef XKB
3695 if (!noXkbExtension) {
3696 client->xkbClientFlags = 0;
3697 client->mapNotifyMask = 0;
3698 QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
3700 #endif
3701 client->replyBytesRemaining = 0;
3702 #ifdef XAPPGROUP
3703 client->appgroup = NULL;
3704 #endif
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;
3711 #endif
3715 InitClientPrivates(ClientPtr client)
3717 char *ptr;
3718 DevUnion *ppriv;
3719 unsigned *sizes;
3720 unsigned size;
3721 int i;
3723 if (totalClientSize == sizeof(ClientRec))
3724 ppriv = (DevUnion *)NULL;
3725 else if (client->index)
3726 ppriv = (DevUnion *)(client + 1);
3727 else
3729 ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
3730 if (!ppriv)
3731 return 0;
3733 client->devPrivates = ppriv;
3734 sizes = clientPrivateSizes;
3735 ptr = (char *)(ppriv + clientPrivateLen);
3736 if (ppriv)
3737 bzero(ppriv, totalClientSize - sizeof(ClientRec));
3738 for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
3740 if ( (size = *sizes) )
3742 ppriv->ptr = (pointer)ptr;
3743 ptr += size;
3745 else
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);
3759 return 1;
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)
3771 int i;
3772 ClientPtr client;
3773 xReq data;
3775 i = nextFreeClientID;
3776 if (i == MAXCLIENTS)
3777 return (ClientPtr)NULL;
3778 clients[i] = client = (ClientPtr)xalloc(totalClientSize);
3779 if (!client)
3780 return (ClientPtr)NULL;
3781 InitClient(client, i, ospriv);
3782 InitClientPrivates(client);
3783 if (!InitClientResources(client))
3785 xfree(client);
3786 return (ClientPtr)NULL;
3788 data.reqType = 1;
3789 data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
3790 if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
3792 FreeClientResources(client);
3793 xfree(client);
3794 return (ClientPtr)NULL;
3796 if (i == currentMaxClients)
3797 currentMaxClients++;
3798 while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
3799 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);
3809 return(client);
3813 ProcInitialConnection(ClientPtr client)
3815 REQUEST(xReq);
3816 xConnClientPrefix *prefix;
3817 int whichbyte = 1;
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);
3828 stuff->reqType = 2;
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)
3842 xWindowRoot *root;
3843 int i;
3844 int numScreens;
3845 char* lConnectionInfo;
3846 xConnSetupPrefix* lconnSetupPrefix;
3848 if (reason)
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);
3859 else
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
3872 * authorized one.
3874 nClients++;
3876 client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
3877 client->sequence = 0;
3878 #ifdef XAPPGROUP
3879 XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
3880 #endif
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);
3886 #endif
3887 /* fill in the "currentInputMask" */
3888 root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
3889 #ifdef PANORAMIX
3890 if (noPanoramiXExtension)
3891 numScreens = screenInfo.numScreens;
3892 else
3893 numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
3894 #endif
3896 for (i=0; i<numScreens; i++)
3898 unsigned int j;
3899 xDepth *pDepth;
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),
3917 lConnectionInfo);
3919 else
3921 (void)WriteToClient(client, sizeof(xConnSetupPrefix),
3922 (char *) lconnSetupPrefix);
3923 (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
3924 lConnectionInfo);
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;
3944 REQUEST(xReq);
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";
3952 else
3953 reason = ClientAuthorized(client,
3954 (unsigned short)prefix->nbytesAuthProto,
3955 auth_proto,
3956 (unsigned short)prefix->nbytesAuthString,
3957 auth_string);
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);
3973 _X_EXPORT void
3974 SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
3975 XID resId, int errorCode)
3977 xError rep;
3979 rep.type = X_Error;
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);
3989 void
3990 DeleteWindowFromAnySelections(WindowPtr pWin)
3992 int i;
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;
4011 static void
4012 DeleteClientFromAnySelections(ClientPtr client)
4014 int i;
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;
4033 void
4034 MarkClientException(ClientPtr client)
4036 client->noClientException = -1;
4039 #ifdef XSERVER_DTRACE
4040 #include <ctype.h>
4042 /* Load table of request names for dtrace probes */
4043 static void LoadRequestNames(void)
4045 int i;
4046 FILE *xedb;
4047 extern void LoadExtensionNames(char **RequestNames);
4049 bzero(RequestNames, 256 * sizeof(char *));
4051 xedb = fopen(XERRORDB_PATH, "r");
4052 if (xedb != NULL) {
4053 char buf[256];
4054 while (fgets(buf, sizeof(buf), xedb)) {
4055 if ((strncmp("XRequest.", buf, 9) == 0) && (isdigit(buf[9]))) {
4056 char *name;
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);
4065 fclose(xedb);
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)
4084 int i;
4086 for (i = 0; i < 256; i++) {
4087 if (RequestNames[i] != 0) {
4088 free(RequestNames[i]);
4089 RequestNames[i] = 0;
4094 #endif