dispatch.c revision 05b261ec
105b261ecSmrg/************************************************************
205b261ecSmrg
305b261ecSmrgCopyright 1987, 1989, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included in
1205b261ecSmrgall copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2005b261ecSmrg
2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be
2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings
2305b261ecSmrgin this Software without prior written authorization from The Open Group.
2405b261ecSmrg
2505b261ecSmrg
2605b261ecSmrgCopyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
2705b261ecSmrg
2805b261ecSmrg                        All Rights Reserved
2905b261ecSmrg
3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its
3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted,
3205b261ecSmrgprovided that the above copyright notice appear in all copies and that
3305b261ecSmrgboth that copyright notice and this permission notice appear in
3405b261ecSmrgsupporting documentation, and that the name of Digital not be
3505b261ecSmrgused in advertising or publicity pertaining to distribution of the
3605b261ecSmrgsoftware without specific, written prior permission.
3705b261ecSmrg
3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4405b261ecSmrgSOFTWARE.
4505b261ecSmrg
4605b261ecSmrg********************************************************/
4705b261ecSmrg
4805b261ecSmrg/* The panoramix components contained the following notice */
4905b261ecSmrg/*****************************************************************
5005b261ecSmrg
5105b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
5205b261ecSmrg
5305b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy
5405b261ecSmrgof this software and associated documentation files (the "Software"), to deal
5505b261ecSmrgin the Software without restriction, including without limitation the rights
5605b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5705b261ecSmrgcopies of the Software.
5805b261ecSmrg
5905b261ecSmrgThe above copyright notice and this permission notice shall be included in
6005b261ecSmrgall copies or substantial portions of the Software.
6105b261ecSmrg
6205b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6305b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6405b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
6505b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
6605b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
6705b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
6805b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6905b261ecSmrg
7005b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation
7105b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other
7205b261ecSmrgdealings in this Software without prior written authorization from Digital
7305b261ecSmrgEquipment Corporation.
7405b261ecSmrg
7505b261ecSmrg******************************************************************/
7605b261ecSmrg
7705b261ecSmrg/* XSERVER_DTRACE additions:
7805b261ecSmrg * Copyright 2005-2006 Sun Microsystems, Inc.  All rights reserved.
7905b261ecSmrg *
8005b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
8105b261ecSmrg * copy of this software and associated documentation files (the
8205b261ecSmrg * "Software"), to deal in the Software without restriction, including
8305b261ecSmrg * without limitation the rights to use, copy, modify, merge, publish,
8405b261ecSmrg * distribute, and/or sell copies of the Software, and to permit persons
8505b261ecSmrg * to whom the Software is furnished to do so, provided that the above
8605b261ecSmrg * copyright notice(s) and this permission notice appear in all copies of
8705b261ecSmrg * the Software and that both the above copyright notice(s) and this
8805b261ecSmrg * permission notice appear in supporting documentation.
8905b261ecSmrg *
9005b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9105b261ecSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9205b261ecSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
9305b261ecSmrg * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
9405b261ecSmrg * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
9505b261ecSmrg * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
9605b261ecSmrg * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
9705b261ecSmrg * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
9805b261ecSmrg * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9905b261ecSmrg *
10005b261ecSmrg * Except as contained in this notice, the name of a copyright holder
10105b261ecSmrg * shall not be used in advertising or otherwise to promote the sale, use
10205b261ecSmrg * or other dealings in this Software without prior written authorization
10305b261ecSmrg * of the copyright holder.
10405b261ecSmrg */
10505b261ecSmrg
10605b261ecSmrg
10705b261ecSmrg
10805b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
10905b261ecSmrg#include <dix-config.h>
11005b261ecSmrg#endif
11105b261ecSmrg
11205b261ecSmrg#ifdef PANORAMIX_DEBUG
11305b261ecSmrg#include <stdio.h>
11405b261ecSmrgint ProcInitialConnection();
11505b261ecSmrg#endif
11605b261ecSmrg
11705b261ecSmrg#include "windowstr.h"
11805b261ecSmrg#include <X11/fonts/fontstruct.h>
11905b261ecSmrg#include "dixfontstr.h"
12005b261ecSmrg#include "gcstruct.h"
12105b261ecSmrg#include "selection.h"
12205b261ecSmrg#include "colormapst.h"
12305b261ecSmrg#include "cursorstr.h"
12405b261ecSmrg#include "scrnintstr.h"
12505b261ecSmrg#include "opaque.h"
12605b261ecSmrg#include "input.h"
12705b261ecSmrg#include "servermd.h"
12805b261ecSmrg#include "extnsionst.h"
12905b261ecSmrg#include "dixfont.h"
13005b261ecSmrg#include "dispatch.h"
13105b261ecSmrg#include "swaprep.h"
13205b261ecSmrg#include "swapreq.h"
13305b261ecSmrg#ifdef PANORAMIX
13405b261ecSmrg#include "panoramiX.h"
13505b261ecSmrg#include "panoramiXsrv.h"
13605b261ecSmrg#endif
13705b261ecSmrg#include "xace.h"
13805b261ecSmrg#ifdef XAPPGROUP
13905b261ecSmrg#include "appgroup.h"
14005b261ecSmrg#endif
14105b261ecSmrg#ifdef XKB
14205b261ecSmrg#ifndef XKB_IN_SERVER
14305b261ecSmrg#define XKB_IN_SERVER
14405b261ecSmrg#endif
14505b261ecSmrg#include "inputstr.h"
14605b261ecSmrg#include <xkbsrv.h>
14705b261ecSmrg#endif
14805b261ecSmrg
14905b261ecSmrg#ifdef XSERVER_DTRACE
15005b261ecSmrg#include <sys/types.h>
15105b261ecSmrgtypedef const char *string;
15205b261ecSmrg#include "Xserver-dtrace.h"
15305b261ecSmrg
15405b261ecSmrgchar *RequestNames[256];
15505b261ecSmrgstatic void LoadRequestNames(void);
15605b261ecSmrgstatic void FreeRequestNames(void);
15705b261ecSmrg#define GetRequestName(i) (RequestNames[i])
15805b261ecSmrg#endif
15905b261ecSmrg
16005b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32)
16105b261ecSmrg#define BITMASK(i) (1U << ((i) & 31))
16205b261ecSmrg#define MASKIDX(i) ((i) >> 5)
16305b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)]
16405b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
16505b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
16605b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
16705b261ecSmrg
16805b261ecSmrgextern xConnSetupPrefix connSetupPrefix;
16905b261ecSmrgextern char *ConnectionInfo;
17005b261ecSmrg
17105b261ecSmrg_X_EXPORT Selection *CurrentSelections;
17205b261ecSmrg_X_EXPORT int NumCurrentSelections;
17305b261ecSmrgCallbackListPtr SelectionCallback = NULL;
17405b261ecSmrg
17505b261ecSmrgstatic ClientPtr grabClient;
17605b261ecSmrg#define GrabNone 0
17705b261ecSmrg#define GrabActive 1
17805b261ecSmrg#define GrabKickout 2
17905b261ecSmrgstatic int grabState = GrabNone;
18005b261ecSmrgstatic long grabWaiters[mskcnt];
18105b261ecSmrg_X_EXPORT CallbackListPtr ServerGrabCallback = NULL;
18205b261ecSmrgHWEventQueuePtr checkForInput[2];
18305b261ecSmrgextern int connBlockScreenStart;
18405b261ecSmrg
18505b261ecSmrgstatic void KillAllClients(void);
18605b261ecSmrg
18705b261ecSmrgstatic void DeleteClientFromAnySelections(ClientPtr client);
18805b261ecSmrg
18905b261ecSmrgstatic int nextFreeClientID; /* always MIN free client ID */
19005b261ecSmrg
19105b261ecSmrgstatic int	nClients;	/* number of authorized clients */
19205b261ecSmrg
19305b261ecSmrg_X_EXPORT CallbackListPtr ClientStateCallback;
19405b261ecSmrg
19505b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they
19605b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't
19705b261ecSmrg * need to actually check value in memory when used and may miss changes from
19805b261ecSmrg * signal handlers.
19905b261ecSmrg */
20005b261ecSmrg_X_EXPORT volatile char dispatchException = 0;
20105b261ecSmrg_X_EXPORT volatile char isItTimeToYield;
20205b261ecSmrg
20305b261ecSmrg/* Various of the DIX function interfaces were not designed to allow
20405b261ecSmrg * the client->errorValue to be set on BadValue and other errors.
20505b261ecSmrg * Rather than changing interfaces and breaking untold code we introduce
20605b261ecSmrg * a new global that dispatch can use.
20705b261ecSmrg */
20805b261ecSmrgXID clientErrorValue;   /* XXX this is a kludge */
20905b261ecSmrg
21005b261ecSmrg#define SAME_SCREENS(a, b) (\
21105b261ecSmrg    (a.pScreen == b.pScreen))
21205b261ecSmrg
21305b261ecSmrg_X_EXPORT void
21405b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
21505b261ecSmrg{
21605b261ecSmrg    checkForInput[0] = c0;
21705b261ecSmrg    checkForInput[1] = c1;
21805b261ecSmrg}
21905b261ecSmrg
22005b261ecSmrg_X_EXPORT void
22105b261ecSmrgUpdateCurrentTime(void)
22205b261ecSmrg{
22305b261ecSmrg    TimeStamp systime;
22405b261ecSmrg
22505b261ecSmrg    /* To avoid time running backwards, we must call GetTimeInMillis before
22605b261ecSmrg     * calling ProcessInputEvents.
22705b261ecSmrg     */
22805b261ecSmrg    systime.months = currentTime.months;
22905b261ecSmrg    systime.milliseconds = GetTimeInMillis();
23005b261ecSmrg    if (systime.milliseconds < currentTime.milliseconds)
23105b261ecSmrg	systime.months++;
23205b261ecSmrg    if (*checkForInput[0] != *checkForInput[1])
23305b261ecSmrg	ProcessInputEvents();
23405b261ecSmrg    if (CompareTimeStamps(systime, currentTime) == LATER)
23505b261ecSmrg	currentTime = systime;
23605b261ecSmrg}
23705b261ecSmrg
23805b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
23905b261ecSmrg_X_EXPORT void
24005b261ecSmrgUpdateCurrentTimeIf(void)
24105b261ecSmrg{
24205b261ecSmrg    TimeStamp systime;
24305b261ecSmrg
24405b261ecSmrg    systime.months = currentTime.months;
24505b261ecSmrg    systime.milliseconds = GetTimeInMillis();
24605b261ecSmrg    if (systime.milliseconds < currentTime.milliseconds)
24705b261ecSmrg	systime.months++;
24805b261ecSmrg    if (*checkForInput[0] == *checkForInput[1])
24905b261ecSmrg	currentTime = systime;
25005b261ecSmrg}
25105b261ecSmrg
25205b261ecSmrgvoid
25305b261ecSmrgInitSelections(void)
25405b261ecSmrg{
25505b261ecSmrg    if (CurrentSelections)
25605b261ecSmrg	xfree(CurrentSelections);
25705b261ecSmrg    CurrentSelections = (Selection *)NULL;
25805b261ecSmrg    NumCurrentSelections = 0;
25905b261ecSmrg}
26005b261ecSmrg
26105b261ecSmrgvoid
26205b261ecSmrgFlushClientCaches(XID id)
26305b261ecSmrg{
26405b261ecSmrg    int i;
26505b261ecSmrg    ClientPtr client;
26605b261ecSmrg
26705b261ecSmrg    client = clients[CLIENT_ID(id)];
26805b261ecSmrg    if (client == NullClient)
26905b261ecSmrg        return ;
27005b261ecSmrg    for (i=0; i<currentMaxClients; i++)
27105b261ecSmrg    {
27205b261ecSmrg	client = clients[i];
27305b261ecSmrg        if (client != NullClient)
27405b261ecSmrg	{
27505b261ecSmrg            if (client->lastDrawableID == id)
27605b261ecSmrg	    {
27705b261ecSmrg		client->lastDrawableID = WindowTable[0]->drawable.id;
27805b261ecSmrg		client->lastDrawable = (DrawablePtr)WindowTable[0];
27905b261ecSmrg	    }
28005b261ecSmrg            else if (client->lastGCID == id)
28105b261ecSmrg	    {
28205b261ecSmrg                client->lastGCID = INVALID;
28305b261ecSmrg		client->lastGC = (GCPtr)NULL;
28405b261ecSmrg	    }
28505b261ecSmrg	}
28605b261ecSmrg    }
28705b261ecSmrg}
28805b261ecSmrg#ifdef SMART_SCHEDULE
28905b261ecSmrg
29005b261ecSmrg#undef SMART_DEBUG
29105b261ecSmrg
29205b261ecSmrg#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
29305b261ecSmrg#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
29405b261ecSmrg
29505b261ecSmrgBool	    SmartScheduleDisable = FALSE;
29605b261ecSmrglong	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
29705b261ecSmrglong	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
29805b261ecSmrglong	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
29905b261ecSmrglong	    SmartScheduleTime;
30005b261ecSmrgstatic ClientPtr   SmartLastClient;
30105b261ecSmrgstatic int	   SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
30205b261ecSmrg
30305b261ecSmrg#ifdef SMART_DEBUG
30405b261ecSmrglong	    SmartLastPrint;
30505b261ecSmrg#endif
30605b261ecSmrg
30705b261ecSmrgvoid        Dispatch(void);
30805b261ecSmrgvoid        InitProcVectors(void);
30905b261ecSmrg
31005b261ecSmrgstatic int
31105b261ecSmrgSmartScheduleClient (int *clientReady, int nready)
31205b261ecSmrg{
31305b261ecSmrg    ClientPtr	pClient;
31405b261ecSmrg    int		i;
31505b261ecSmrg    int		client;
31605b261ecSmrg    int		bestPrio, best = 0;
31705b261ecSmrg    int		bestRobin, robin;
31805b261ecSmrg    long	now = SmartScheduleTime;
31905b261ecSmrg    long	idle;
32005b261ecSmrg
32105b261ecSmrg    bestPrio = -0x7fffffff;
32205b261ecSmrg    bestRobin = 0;
32305b261ecSmrg    idle = 2 * SmartScheduleSlice;
32405b261ecSmrg    for (i = 0; i < nready; i++)
32505b261ecSmrg    {
32605b261ecSmrg	client = clientReady[i];
32705b261ecSmrg	pClient = clients[client];
32805b261ecSmrg	/* Praise clients which are idle */
32905b261ecSmrg	if ((now - pClient->smart_check_tick) >= idle)
33005b261ecSmrg	{
33105b261ecSmrg	    if (pClient->smart_priority < 0)
33205b261ecSmrg		pClient->smart_priority++;
33305b261ecSmrg	}
33405b261ecSmrg	pClient->smart_check_tick = now;
33505b261ecSmrg
33605b261ecSmrg	/* check priority to select best client */
33705b261ecSmrg	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
33805b261ecSmrg	if (pClient->smart_priority > bestPrio ||
33905b261ecSmrg	    (pClient->smart_priority == bestPrio && robin > bestRobin))
34005b261ecSmrg	{
34105b261ecSmrg	    bestPrio = pClient->smart_priority;
34205b261ecSmrg	    bestRobin = robin;
34305b261ecSmrg	    best = client;
34405b261ecSmrg	}
34505b261ecSmrg#ifdef SMART_DEBUG
34605b261ecSmrg	if ((now - SmartLastPrint) >= 5000)
34705b261ecSmrg	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
34805b261ecSmrg#endif
34905b261ecSmrg    }
35005b261ecSmrg#ifdef SMART_DEBUG
35105b261ecSmrg    if ((now - SmartLastPrint) >= 5000)
35205b261ecSmrg    {
35305b261ecSmrg	fprintf (stderr, " use %2d\n", best);
35405b261ecSmrg	SmartLastPrint = now;
35505b261ecSmrg    }
35605b261ecSmrg#endif
35705b261ecSmrg    pClient = clients[best];
35805b261ecSmrg    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
35905b261ecSmrg    /*
36005b261ecSmrg     * Set current client pointer
36105b261ecSmrg     */
36205b261ecSmrg    if (SmartLastClient != pClient)
36305b261ecSmrg    {
36405b261ecSmrg	pClient->smart_start_tick = now;
36505b261ecSmrg	SmartLastClient = pClient;
36605b261ecSmrg    }
36705b261ecSmrg    /*
36805b261ecSmrg     * Adjust slice
36905b261ecSmrg     */
37005b261ecSmrg    if (nready == 1)
37105b261ecSmrg    {
37205b261ecSmrg	/*
37305b261ecSmrg	 * If it's been a long time since another client
37405b261ecSmrg	 * has run, bump the slice up to get maximal
37505b261ecSmrg	 * performance from a single client
37605b261ecSmrg	 */
37705b261ecSmrg	if ((now - pClient->smart_start_tick) > 1000 &&
37805b261ecSmrg	    SmartScheduleSlice < SmartScheduleMaxSlice)
37905b261ecSmrg	{
38005b261ecSmrg	    SmartScheduleSlice += SmartScheduleInterval;
38105b261ecSmrg	}
38205b261ecSmrg    }
38305b261ecSmrg    else
38405b261ecSmrg    {
38505b261ecSmrg	SmartScheduleSlice = SmartScheduleInterval;
38605b261ecSmrg    }
38705b261ecSmrg    return best;
38805b261ecSmrg}
38905b261ecSmrg#endif
39005b261ecSmrg
39105b261ecSmrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType
39205b261ecSmrg
39305b261ecSmrgvoid
39405b261ecSmrgDispatch(void)
39505b261ecSmrg{
39605b261ecSmrg    int        *clientReady;     /* array of request ready clients */
39705b261ecSmrg    int	result;
39805b261ecSmrg    ClientPtr	client;
39905b261ecSmrg    int	nready;
40005b261ecSmrg    HWEventQueuePtr* icheck = checkForInput;
40105b261ecSmrg#ifdef SMART_SCHEDULE
40205b261ecSmrg    long			start_tick;
40305b261ecSmrg#endif
40405b261ecSmrg
40505b261ecSmrg    nextFreeClientID = 1;
40605b261ecSmrg    InitSelections();
40705b261ecSmrg    nClients = 0;
40805b261ecSmrg
40905b261ecSmrg    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
41005b261ecSmrg    if (!clientReady)
41105b261ecSmrg	return;
41205b261ecSmrg
41305b261ecSmrg#ifdef XSERVER_DTRACE
41405b261ecSmrg    LoadRequestNames();
41505b261ecSmrg#endif
41605b261ecSmrg
41705b261ecSmrg    while (!dispatchException)
41805b261ecSmrg    {
41905b261ecSmrg        if (*icheck[0] != *icheck[1])
42005b261ecSmrg	{
42105b261ecSmrg	    ProcessInputEvents();
42205b261ecSmrg	    FlushIfCriticalOutputPending();
42305b261ecSmrg	}
42405b261ecSmrg
42505b261ecSmrg	nready = WaitForSomething(clientReady);
42605b261ecSmrg
42705b261ecSmrg#ifdef SMART_SCHEDULE
42805b261ecSmrg	if (nready && !SmartScheduleDisable)
42905b261ecSmrg	{
43005b261ecSmrg	    clientReady[0] = SmartScheduleClient (clientReady, nready);
43105b261ecSmrg	    nready = 1;
43205b261ecSmrg	}
43305b261ecSmrg#endif
43405b261ecSmrg       /*****************
43505b261ecSmrg	*  Handle events in round robin fashion, doing input between
43605b261ecSmrg	*  each round
43705b261ecSmrg	*****************/
43805b261ecSmrg
43905b261ecSmrg	while (!dispatchException && (--nready >= 0))
44005b261ecSmrg	{
44105b261ecSmrg	    client = clients[clientReady[nready]];
44205b261ecSmrg	    if (! client)
44305b261ecSmrg	    {
44405b261ecSmrg		/* KillClient can cause this to happen */
44505b261ecSmrg		continue;
44605b261ecSmrg	    }
44705b261ecSmrg	    /* GrabServer activation can cause this to be true */
44805b261ecSmrg	    if (grabState == GrabKickout)
44905b261ecSmrg	    {
45005b261ecSmrg		grabState = GrabActive;
45105b261ecSmrg		break;
45205b261ecSmrg	    }
45305b261ecSmrg	    isItTimeToYield = FALSE;
45405b261ecSmrg
45505b261ecSmrg            requestingClient = client;
45605b261ecSmrg#ifdef SMART_SCHEDULE
45705b261ecSmrg	    start_tick = SmartScheduleTime;
45805b261ecSmrg#endif
45905b261ecSmrg	    while (!isItTimeToYield)
46005b261ecSmrg	    {
46105b261ecSmrg	        if (*icheck[0] != *icheck[1])
46205b261ecSmrg		{
46305b261ecSmrg		    ProcessInputEvents();
46405b261ecSmrg		    FlushIfCriticalOutputPending();
46505b261ecSmrg		}
46605b261ecSmrg#ifdef SMART_SCHEDULE
46705b261ecSmrg		if (!SmartScheduleDisable &&
46805b261ecSmrg		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
46905b261ecSmrg		{
47005b261ecSmrg		    /* Penalize clients which consume ticks */
47105b261ecSmrg		    if (client->smart_priority > SMART_MIN_PRIORITY)
47205b261ecSmrg			client->smart_priority--;
47305b261ecSmrg		    break;
47405b261ecSmrg		}
47505b261ecSmrg#endif
47605b261ecSmrg		/* now, finally, deal with client requests */
47705b261ecSmrg
47805b261ecSmrg	        result = ReadRequestFromClient(client);
47905b261ecSmrg	        if (result <= 0)
48005b261ecSmrg	        {
48105b261ecSmrg		    if (result < 0)
48205b261ecSmrg			CloseDownClient(client);
48305b261ecSmrg		    break;
48405b261ecSmrg	        }
48505b261ecSmrg
48605b261ecSmrg		client->sequence++;
48705b261ecSmrg#ifdef DEBUG
48805b261ecSmrg		if (client->requestLogIndex == MAX_REQUEST_LOG)
48905b261ecSmrg		    client->requestLogIndex = 0;
49005b261ecSmrg		client->requestLog[client->requestLogIndex] = MAJOROP;
49105b261ecSmrg		client->requestLogIndex++;
49205b261ecSmrg#endif
49305b261ecSmrg#ifdef XSERVER_DTRACE
49405b261ecSmrg		XSERVER_REQUEST_START(GetRequestName(MAJOROP), MAJOROP,
49505b261ecSmrg			      ((xReq *)client->requestBuffer)->length,
49605b261ecSmrg			      client->index, client->requestBuffer);
49705b261ecSmrg#endif
49805b261ecSmrg		if (result > (maxBigRequestSize << 2))
49905b261ecSmrg		    result = BadLength;
50005b261ecSmrg		else {
50105b261ecSmrg		    XaceHook(XACE_AUDIT_BEGIN, client);
50205b261ecSmrg		    result = (* client->requestVector[MAJOROP])(client);
50305b261ecSmrg		    XaceHook(XACE_AUDIT_END, client, result);
50405b261ecSmrg		}
50505b261ecSmrg#ifdef XSERVER_DTRACE
50605b261ecSmrg		XSERVER_REQUEST_DONE(GetRequestName(MAJOROP), MAJOROP,
50705b261ecSmrg			      client->sequence, client->index, result);
50805b261ecSmrg#endif
50905b261ecSmrg
51005b261ecSmrg		if (result != Success)
51105b261ecSmrg		{
51205b261ecSmrg		    if (client->noClientException != Success)
51305b261ecSmrg                        CloseDownClient(client);
51405b261ecSmrg                    else
51505b261ecSmrg		        SendErrorToClient(client, MAJOROP,
51605b261ecSmrg					  MinorOpcodeOfRequest(client),
51705b261ecSmrg					  client->errorValue, result);
51805b261ecSmrg		    break;
51905b261ecSmrg	        }
52005b261ecSmrg#ifdef DAMAGEEXT
52105b261ecSmrg		FlushIfCriticalOutputPending ();
52205b261ecSmrg#endif
52305b261ecSmrg	    }
52405b261ecSmrg	    FlushAllOutput();
52505b261ecSmrg#ifdef SMART_SCHEDULE
52605b261ecSmrg	    client = clients[clientReady[nready]];
52705b261ecSmrg	    if (client)
52805b261ecSmrg		client->smart_stop_tick = SmartScheduleTime;
52905b261ecSmrg#endif
53005b261ecSmrg	    requestingClient = NULL;
53105b261ecSmrg	}
53205b261ecSmrg	dispatchException &= ~DE_PRIORITYCHANGE;
53305b261ecSmrg    }
53405b261ecSmrg#if defined(DDXBEFORERESET)
53505b261ecSmrg    ddxBeforeReset ();
53605b261ecSmrg#endif
53705b261ecSmrg    KillAllClients();
53805b261ecSmrg    DEALLOCATE_LOCAL(clientReady);
53905b261ecSmrg    dispatchException &= ~DE_RESET;
54005b261ecSmrg#ifdef XSERVER_DTRACE
54105b261ecSmrg    FreeRequestNames();
54205b261ecSmrg#endif
54305b261ecSmrg}
54405b261ecSmrg
54505b261ecSmrg#undef MAJOROP
54605b261ecSmrg
54705b261ecSmrg_X_EXPORT int
54805b261ecSmrgProcBadRequest(ClientPtr client)
54905b261ecSmrg{
55005b261ecSmrg    return (BadRequest);
55105b261ecSmrg}
55205b261ecSmrg
55305b261ecSmrgint
55405b261ecSmrgProcCreateWindow(ClientPtr client)
55505b261ecSmrg{
55605b261ecSmrg    WindowPtr pParent, pWin;
55705b261ecSmrg    REQUEST(xCreateWindowReq);
55805b261ecSmrg    int result, len, rc;
55905b261ecSmrg
56005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
56105b261ecSmrg
56205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->wid, client);
56305b261ecSmrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess);
56405b261ecSmrg    if (rc != Success)
56505b261ecSmrg        return rc;
56605b261ecSmrg    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
56705b261ecSmrg    if (Ones(stuff->mask) != len)
56805b261ecSmrg        return BadLength;
56905b261ecSmrg    if (!stuff->width || !stuff->height)
57005b261ecSmrg    {
57105b261ecSmrg	client->errorValue = 0;
57205b261ecSmrg        return BadValue;
57305b261ecSmrg    }
57405b261ecSmrg    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
57505b261ecSmrg			      stuff->y, stuff->width, stuff->height,
57605b261ecSmrg			      stuff->borderWidth, stuff->class,
57705b261ecSmrg			      stuff->mask, (XID *) &stuff[1],
57805b261ecSmrg			      (int)stuff->depth,
57905b261ecSmrg			      client, stuff->visual, &result);
58005b261ecSmrg    if (pWin)
58105b261ecSmrg    {
58205b261ecSmrg	Mask mask = pWin->eventMask;
58305b261ecSmrg
58405b261ecSmrg	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
58505b261ecSmrg	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
58605b261ecSmrg	    return BadAlloc;
58705b261ecSmrg	pWin->eventMask = mask;
58805b261ecSmrg    }
58905b261ecSmrg    if (client->noClientException != Success)
59005b261ecSmrg        return(client->noClientException);
59105b261ecSmrg    else
59205b261ecSmrg        return(result);
59305b261ecSmrg}
59405b261ecSmrg
59505b261ecSmrgint
59605b261ecSmrgProcChangeWindowAttributes(ClientPtr client)
59705b261ecSmrg{
59805b261ecSmrg    WindowPtr pWin;
59905b261ecSmrg    REQUEST(xChangeWindowAttributesReq);
60005b261ecSmrg    int result;
60105b261ecSmrg    int len, rc;
60205b261ecSmrg
60305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
60405b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
60505b261ecSmrg    if (rc != Success)
60605b261ecSmrg        return rc;
60705b261ecSmrg    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
60805b261ecSmrg    if (len != Ones(stuff->valueMask))
60905b261ecSmrg        return BadLength;
61005b261ecSmrg    result =  ChangeWindowAttributes(pWin,
61105b261ecSmrg				  stuff->valueMask,
61205b261ecSmrg				  (XID *) &stuff[1],
61305b261ecSmrg				  client);
61405b261ecSmrg    if (client->noClientException != Success)
61505b261ecSmrg        return(client->noClientException);
61605b261ecSmrg    else
61705b261ecSmrg        return(result);
61805b261ecSmrg}
61905b261ecSmrg
62005b261ecSmrgint
62105b261ecSmrgProcGetWindowAttributes(ClientPtr client)
62205b261ecSmrg{
62305b261ecSmrg    WindowPtr pWin;
62405b261ecSmrg    REQUEST(xResourceReq);
62505b261ecSmrg    xGetWindowAttributesReply wa;
62605b261ecSmrg    int rc;
62705b261ecSmrg
62805b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
62905b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
63005b261ecSmrg    if (rc != Success)
63105b261ecSmrg	return rc;
63205b261ecSmrg    GetWindowAttributes(pWin, client, &wa);
63305b261ecSmrg    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
63405b261ecSmrg    return(client->noClientException);
63505b261ecSmrg}
63605b261ecSmrg
63705b261ecSmrgint
63805b261ecSmrgProcDestroyWindow(ClientPtr client)
63905b261ecSmrg{
64005b261ecSmrg    WindowPtr pWin;
64105b261ecSmrg    REQUEST(xResourceReq);
64205b261ecSmrg    int rc;
64305b261ecSmrg
64405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
64505b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
64605b261ecSmrg    if (rc != Success)
64705b261ecSmrg	return rc;
64805b261ecSmrg    if (pWin->parent)
64905b261ecSmrg	FreeResource(stuff->id, RT_NONE);
65005b261ecSmrg    return(client->noClientException);
65105b261ecSmrg}
65205b261ecSmrg
65305b261ecSmrgint
65405b261ecSmrgProcDestroySubwindows(ClientPtr client)
65505b261ecSmrg{
65605b261ecSmrg    WindowPtr pWin;
65705b261ecSmrg    REQUEST(xResourceReq);
65805b261ecSmrg    int rc;
65905b261ecSmrg
66005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
66105b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
66205b261ecSmrg    if (rc != Success)
66305b261ecSmrg	return rc;
66405b261ecSmrg    DestroySubwindows(pWin, client);
66505b261ecSmrg    return(client->noClientException);
66605b261ecSmrg}
66705b261ecSmrg
66805b261ecSmrgint
66905b261ecSmrgProcChangeSaveSet(ClientPtr client)
67005b261ecSmrg{
67105b261ecSmrg    WindowPtr pWin;
67205b261ecSmrg    REQUEST(xChangeSaveSetReq);
67305b261ecSmrg    int result, rc;
67405b261ecSmrg
67505b261ecSmrg    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
67605b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
67705b261ecSmrg    if (rc != Success)
67805b261ecSmrg        return rc;
67905b261ecSmrg    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
68005b261ecSmrg        return BadMatch;
68105b261ecSmrg    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
68205b261ecSmrg    {
68305b261ecSmrg        result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
68405b261ecSmrg	if (client->noClientException != Success)
68505b261ecSmrg	    return(client->noClientException);
68605b261ecSmrg	else
68705b261ecSmrg            return(result);
68805b261ecSmrg    }
68905b261ecSmrg    else
69005b261ecSmrg    {
69105b261ecSmrg	client->errorValue = stuff->mode;
69205b261ecSmrg	return( BadValue );
69305b261ecSmrg    }
69405b261ecSmrg}
69505b261ecSmrg
69605b261ecSmrgint
69705b261ecSmrgProcReparentWindow(ClientPtr client)
69805b261ecSmrg{
69905b261ecSmrg    WindowPtr pWin, pParent;
70005b261ecSmrg    REQUEST(xReparentWindowReq);
70105b261ecSmrg    int result, rc;
70205b261ecSmrg
70305b261ecSmrg    REQUEST_SIZE_MATCH(xReparentWindowReq);
70405b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
70505b261ecSmrg    if (rc != Success)
70605b261ecSmrg        return rc;
70705b261ecSmrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess);
70805b261ecSmrg    if (rc != Success)
70905b261ecSmrg        return rc;
71005b261ecSmrg    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
71105b261ecSmrg    {
71205b261ecSmrg        if ((pWin->backgroundState == ParentRelative) &&
71305b261ecSmrg            (pParent->drawable.depth != pWin->drawable.depth))
71405b261ecSmrg            return BadMatch;
71505b261ecSmrg	if ((pWin->drawable.class != InputOnly) &&
71605b261ecSmrg	    (pParent->drawable.class == InputOnly))
71705b261ecSmrg	    return BadMatch;
71805b261ecSmrg        result =  ReparentWindow(pWin, pParent,
71905b261ecSmrg			 (short)stuff->x, (short)stuff->y, client);
72005b261ecSmrg	if (client->noClientException != Success)
72105b261ecSmrg            return(client->noClientException);
72205b261ecSmrg	else
72305b261ecSmrg            return(result);
72405b261ecSmrg    }
72505b261ecSmrg    else
72605b261ecSmrg        return (BadMatch);
72705b261ecSmrg}
72805b261ecSmrg
72905b261ecSmrgint
73005b261ecSmrgProcMapWindow(ClientPtr client)
73105b261ecSmrg{
73205b261ecSmrg    WindowPtr pWin;
73305b261ecSmrg    REQUEST(xResourceReq);
73405b261ecSmrg    int rc;
73505b261ecSmrg
73605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
73705b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
73805b261ecSmrg    if (rc != Success)
73905b261ecSmrg        return rc;
74005b261ecSmrg    MapWindow(pWin, client);
74105b261ecSmrg           /* update cache to say it is mapped */
74205b261ecSmrg    return(client->noClientException);
74305b261ecSmrg}
74405b261ecSmrg
74505b261ecSmrgint
74605b261ecSmrgProcMapSubwindows(ClientPtr client)
74705b261ecSmrg{
74805b261ecSmrg    WindowPtr pWin;
74905b261ecSmrg    REQUEST(xResourceReq);
75005b261ecSmrg    int rc;
75105b261ecSmrg
75205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
75305b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
75405b261ecSmrg    if (rc != Success)
75505b261ecSmrg        return rc;
75605b261ecSmrg    MapSubwindows(pWin, client);
75705b261ecSmrg           /* update cache to say it is mapped */
75805b261ecSmrg    return(client->noClientException);
75905b261ecSmrg}
76005b261ecSmrg
76105b261ecSmrgint
76205b261ecSmrgProcUnmapWindow(ClientPtr client)
76305b261ecSmrg{
76405b261ecSmrg    WindowPtr pWin;
76505b261ecSmrg    REQUEST(xResourceReq);
76605b261ecSmrg    int rc;
76705b261ecSmrg
76805b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
76905b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
77005b261ecSmrg    if (rc != Success)
77105b261ecSmrg        return rc;
77205b261ecSmrg    UnmapWindow(pWin, FALSE);
77305b261ecSmrg           /* update cache to say it is mapped */
77405b261ecSmrg    return(client->noClientException);
77505b261ecSmrg}
77605b261ecSmrg
77705b261ecSmrgint
77805b261ecSmrgProcUnmapSubwindows(ClientPtr client)
77905b261ecSmrg{
78005b261ecSmrg    WindowPtr pWin;
78105b261ecSmrg    REQUEST(xResourceReq);
78205b261ecSmrg    int rc;
78305b261ecSmrg
78405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
78505b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
78605b261ecSmrg    if (rc != Success)
78705b261ecSmrg        return rc;
78805b261ecSmrg    UnmapSubwindows(pWin);
78905b261ecSmrg    return(client->noClientException);
79005b261ecSmrg}
79105b261ecSmrg
79205b261ecSmrgint
79305b261ecSmrgProcConfigureWindow(ClientPtr client)
79405b261ecSmrg{
79505b261ecSmrg    WindowPtr pWin;
79605b261ecSmrg    REQUEST(xConfigureWindowReq);
79705b261ecSmrg    int result;
79805b261ecSmrg    int len, rc;
79905b261ecSmrg
80005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
80105b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
80205b261ecSmrg    if (rc != Success)
80305b261ecSmrg        return rc;
80405b261ecSmrg    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
80505b261ecSmrg    if (Ones((Mask)stuff->mask) != len)
80605b261ecSmrg        return BadLength;
80705b261ecSmrg    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
80805b261ecSmrg			      client);
80905b261ecSmrg    if (client->noClientException != Success)
81005b261ecSmrg        return(client->noClientException);
81105b261ecSmrg    else
81205b261ecSmrg        return(result);
81305b261ecSmrg}
81405b261ecSmrg
81505b261ecSmrgint
81605b261ecSmrgProcCirculateWindow(ClientPtr client)
81705b261ecSmrg{
81805b261ecSmrg    WindowPtr pWin;
81905b261ecSmrg    REQUEST(xCirculateWindowReq);
82005b261ecSmrg    int rc;
82105b261ecSmrg
82205b261ecSmrg    REQUEST_SIZE_MATCH(xCirculateWindowReq);
82305b261ecSmrg    if ((stuff->direction != RaiseLowest) &&
82405b261ecSmrg	(stuff->direction != LowerHighest))
82505b261ecSmrg    {
82605b261ecSmrg	client->errorValue = stuff->direction;
82705b261ecSmrg        return BadValue;
82805b261ecSmrg    }
82905b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
83005b261ecSmrg    if (rc != Success)
83105b261ecSmrg        return rc;
83205b261ecSmrg    CirculateWindow(pWin, (int)stuff->direction, client);
83305b261ecSmrg    return(client->noClientException);
83405b261ecSmrg}
83505b261ecSmrg
83605b261ecSmrgstatic int
83705b261ecSmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep)
83805b261ecSmrg{
83905b261ecSmrg    DrawablePtr pDraw;
84005b261ecSmrg    int rc;
84105b261ecSmrg    REQUEST(xResourceReq);
84205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
84305b261ecSmrg
84405b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixReadAccess);
84505b261ecSmrg    if (rc != Success)
84605b261ecSmrg	return rc;
84705b261ecSmrg
84805b261ecSmrg    rep->type = X_Reply;
84905b261ecSmrg    rep->length = 0;
85005b261ecSmrg    rep->sequenceNumber = client->sequence;
85105b261ecSmrg    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
85205b261ecSmrg    rep->depth = pDraw->depth;
85305b261ecSmrg    rep->width = pDraw->width;
85405b261ecSmrg    rep->height = pDraw->height;
85505b261ecSmrg
85605b261ecSmrg    /* XXX - Because the pixmap-implementation of the multibuffer extension
85705b261ecSmrg     *       may have the buffer-id's drawable resource value be a pointer
85805b261ecSmrg     *       to the buffer's window instead of the buffer itself
85905b261ecSmrg     *       (this happens if the buffer is the displayed buffer),
86005b261ecSmrg     *       we also have to check that the id matches before we can
86105b261ecSmrg     *       truly say that it is a DRAWABLE_WINDOW.
86205b261ecSmrg     */
86305b261ecSmrg
86405b261ecSmrg    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
86505b261ecSmrg        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
86605b261ecSmrg    {
86705b261ecSmrg        WindowPtr pWin = (WindowPtr)pDraw;
86805b261ecSmrg	rep->x = pWin->origin.x - wBorderWidth (pWin);
86905b261ecSmrg	rep->y = pWin->origin.y - wBorderWidth (pWin);
87005b261ecSmrg	rep->borderWidth = pWin->borderWidth;
87105b261ecSmrg    }
87205b261ecSmrg    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
87305b261ecSmrg    {
87405b261ecSmrg	rep->x = rep->y = rep->borderWidth = 0;
87505b261ecSmrg    }
87605b261ecSmrg
87705b261ecSmrg    return Success;
87805b261ecSmrg}
87905b261ecSmrg
88005b261ecSmrg
88105b261ecSmrgint
88205b261ecSmrgProcGetGeometry(ClientPtr client)
88305b261ecSmrg{
88405b261ecSmrg    xGetGeometryReply rep;
88505b261ecSmrg    int status;
88605b261ecSmrg
88705b261ecSmrg    if ((status = GetGeometry(client, &rep)) != Success)
88805b261ecSmrg	return status;
88905b261ecSmrg
89005b261ecSmrg    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
89105b261ecSmrg    return(client->noClientException);
89205b261ecSmrg}
89305b261ecSmrg
89405b261ecSmrg
89505b261ecSmrgint
89605b261ecSmrgProcQueryTree(ClientPtr client)
89705b261ecSmrg{
89805b261ecSmrg    xQueryTreeReply reply;
89905b261ecSmrg    int rc, numChildren = 0;
90005b261ecSmrg    WindowPtr pChild, pWin, pHead;
90105b261ecSmrg    Window  *childIDs = (Window *)NULL;
90205b261ecSmrg    REQUEST(xResourceReq);
90305b261ecSmrg
90405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
90505b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
90605b261ecSmrg    if (rc != Success)
90705b261ecSmrg        return rc;
90805b261ecSmrg    reply.type = X_Reply;
90905b261ecSmrg    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
91005b261ecSmrg    reply.sequenceNumber = client->sequence;
91105b261ecSmrg    if (pWin->parent)
91205b261ecSmrg	reply.parent = pWin->parent->drawable.id;
91305b261ecSmrg    else
91405b261ecSmrg        reply.parent = (Window)None;
91505b261ecSmrg    pHead = RealChildHead(pWin);
91605b261ecSmrg    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
91705b261ecSmrg	numChildren++;
91805b261ecSmrg    if (numChildren)
91905b261ecSmrg    {
92005b261ecSmrg	int curChild = 0;
92105b261ecSmrg
92205b261ecSmrg	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
92305b261ecSmrg	if (!childIDs)
92405b261ecSmrg	    return BadAlloc;
92505b261ecSmrg	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
92605b261ecSmrg	    childIDs[curChild++] = pChild->drawable.id;
92705b261ecSmrg    }
92805b261ecSmrg
92905b261ecSmrg    reply.nChildren = numChildren;
93005b261ecSmrg    reply.length = (numChildren * sizeof(Window)) >> 2;
93105b261ecSmrg
93205b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
93305b261ecSmrg    if (numChildren)
93405b261ecSmrg    {
93505b261ecSmrg    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
93605b261ecSmrg	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
93705b261ecSmrg	DEALLOCATE_LOCAL(childIDs);
93805b261ecSmrg    }
93905b261ecSmrg
94005b261ecSmrg    return(client->noClientException);
94105b261ecSmrg}
94205b261ecSmrg
94305b261ecSmrgint
94405b261ecSmrgProcInternAtom(ClientPtr client)
94505b261ecSmrg{
94605b261ecSmrg    Atom atom;
94705b261ecSmrg    char *tchar;
94805b261ecSmrg    REQUEST(xInternAtomReq);
94905b261ecSmrg
95005b261ecSmrg    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
95105b261ecSmrg    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
95205b261ecSmrg    {
95305b261ecSmrg	client->errorValue = stuff->onlyIfExists;
95405b261ecSmrg        return(BadValue);
95505b261ecSmrg    }
95605b261ecSmrg    tchar = (char *) &stuff[1];
95705b261ecSmrg    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
95805b261ecSmrg    if (atom != BAD_RESOURCE)
95905b261ecSmrg    {
96005b261ecSmrg	xInternAtomReply reply;
96105b261ecSmrg	reply.type = X_Reply;
96205b261ecSmrg	reply.length = 0;
96305b261ecSmrg	reply.sequenceNumber = client->sequence;
96405b261ecSmrg	reply.atom = atom;
96505b261ecSmrg	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
96605b261ecSmrg	return(client->noClientException);
96705b261ecSmrg    }
96805b261ecSmrg    else
96905b261ecSmrg	return (BadAlloc);
97005b261ecSmrg}
97105b261ecSmrg
97205b261ecSmrgint
97305b261ecSmrgProcGetAtomName(ClientPtr client)
97405b261ecSmrg{
97505b261ecSmrg    char *str;
97605b261ecSmrg    xGetAtomNameReply reply;
97705b261ecSmrg    int len;
97805b261ecSmrg    REQUEST(xResourceReq);
97905b261ecSmrg
98005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
98105b261ecSmrg    if ( (str = NameForAtom(stuff->id)) )
98205b261ecSmrg    {
98305b261ecSmrg	len = strlen(str);
98405b261ecSmrg	reply.type = X_Reply;
98505b261ecSmrg	reply.length = (len + 3) >> 2;
98605b261ecSmrg	reply.sequenceNumber = client->sequence;
98705b261ecSmrg	reply.nameLength = len;
98805b261ecSmrg	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
98905b261ecSmrg	(void)WriteToClient(client, len, str);
99005b261ecSmrg	return(client->noClientException);
99105b261ecSmrg    }
99205b261ecSmrg    else
99305b261ecSmrg    {
99405b261ecSmrg	client->errorValue = stuff->id;
99505b261ecSmrg	return (BadAtom);
99605b261ecSmrg    }
99705b261ecSmrg}
99805b261ecSmrg
99905b261ecSmrgint
100005b261ecSmrgProcSetSelectionOwner(ClientPtr client)
100105b261ecSmrg{
100205b261ecSmrg    WindowPtr pWin;
100305b261ecSmrg    TimeStamp time;
100405b261ecSmrg    REQUEST(xSetSelectionOwnerReq);
100505b261ecSmrg
100605b261ecSmrg    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
100705b261ecSmrg    UpdateCurrentTime();
100805b261ecSmrg    time = ClientTimeToServerTime(stuff->time);
100905b261ecSmrg
101005b261ecSmrg    /* If the client's time stamp is in the future relative to the server's
101105b261ecSmrg	time stamp, do not set the selection, just return success. */
101205b261ecSmrg    if (CompareTimeStamps(time, currentTime) == LATER)
101305b261ecSmrg    	return Success;
101405b261ecSmrg    if (stuff->window != None)
101505b261ecSmrg    {
101605b261ecSmrg	int rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
101705b261ecSmrg        if (rc != Success)
101805b261ecSmrg            return rc;
101905b261ecSmrg    }
102005b261ecSmrg    else
102105b261ecSmrg        pWin = (WindowPtr)None;
102205b261ecSmrg    if (ValidAtom(stuff->selection))
102305b261ecSmrg    {
102405b261ecSmrg	int i = 0;
102505b261ecSmrg
102605b261ecSmrg	/*
102705b261ecSmrg	 * First, see if the selection is already set...
102805b261ecSmrg	 */
102905b261ecSmrg	while ((i < NumCurrentSelections) &&
103005b261ecSmrg	       CurrentSelections[i].selection != stuff->selection)
103105b261ecSmrg            i++;
103205b261ecSmrg        if (i < NumCurrentSelections)
103305b261ecSmrg        {
103405b261ecSmrg	    xEvent event;
103505b261ecSmrg
103605b261ecSmrg	    /* If the timestamp in client's request is in the past relative
103705b261ecSmrg		to the time stamp indicating the last time the owner of the
103805b261ecSmrg		selection was set, do not set the selection, just return
103905b261ecSmrg		success. */
104005b261ecSmrg            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
104105b261ecSmrg		== EARLIER)
104205b261ecSmrg		return Success;
104305b261ecSmrg	    if (CurrentSelections[i].client &&
104405b261ecSmrg		(!pWin || (CurrentSelections[i].client != client)))
104505b261ecSmrg	    {
104605b261ecSmrg		event.u.u.type = SelectionClear;
104705b261ecSmrg		event.u.selectionClear.time = time.milliseconds;
104805b261ecSmrg		event.u.selectionClear.window = CurrentSelections[i].window;
104905b261ecSmrg		event.u.selectionClear.atom = CurrentSelections[i].selection;
105005b261ecSmrg		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
105105b261ecSmrg				NoEventMask, NoEventMask /* CantBeFiltered */,
105205b261ecSmrg				NullGrab);
105305b261ecSmrg	    }
105405b261ecSmrg	}
105505b261ecSmrg	else
105605b261ecSmrg	{
105705b261ecSmrg	    /*
105805b261ecSmrg	     * It doesn't exist, so add it...
105905b261ecSmrg	     */
106005b261ecSmrg	    Selection *newsels;
106105b261ecSmrg
106205b261ecSmrg	    if (i == 0)
106305b261ecSmrg		newsels = (Selection *)xalloc(sizeof(Selection));
106405b261ecSmrg	    else
106505b261ecSmrg		newsels = (Selection *)xrealloc(CurrentSelections,
106605b261ecSmrg			    (NumCurrentSelections + 1) * sizeof(Selection));
106705b261ecSmrg	    if (!newsels)
106805b261ecSmrg		return BadAlloc;
106905b261ecSmrg	    NumCurrentSelections++;
107005b261ecSmrg	    CurrentSelections = newsels;
107105b261ecSmrg	    CurrentSelections[i].selection = stuff->selection;
107205b261ecSmrg	}
107305b261ecSmrg        CurrentSelections[i].lastTimeChanged = time;
107405b261ecSmrg	CurrentSelections[i].window = stuff->window;
107505b261ecSmrg	CurrentSelections[i].pWin = pWin;
107605b261ecSmrg	CurrentSelections[i].client = (pWin ? client : NullClient);
107705b261ecSmrg	if (SelectionCallback)
107805b261ecSmrg	{
107905b261ecSmrg	    SelectionInfoRec	info;
108005b261ecSmrg
108105b261ecSmrg	    info.selection = &CurrentSelections[i];
108205b261ecSmrg	    info.kind= SelectionSetOwner;
108305b261ecSmrg	    CallCallbacks(&SelectionCallback, &info);
108405b261ecSmrg	}
108505b261ecSmrg	return (client->noClientException);
108605b261ecSmrg    }
108705b261ecSmrg    else
108805b261ecSmrg    {
108905b261ecSmrg	client->errorValue = stuff->selection;
109005b261ecSmrg        return (BadAtom);
109105b261ecSmrg    }
109205b261ecSmrg}
109305b261ecSmrg
109405b261ecSmrgint
109505b261ecSmrgProcGetSelectionOwner(ClientPtr client)
109605b261ecSmrg{
109705b261ecSmrg    REQUEST(xResourceReq);
109805b261ecSmrg
109905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
110005b261ecSmrg    if (ValidAtom(stuff->id))
110105b261ecSmrg    {
110205b261ecSmrg	int i;
110305b261ecSmrg        xGetSelectionOwnerReply reply;
110405b261ecSmrg
110505b261ecSmrg	i = 0;
110605b261ecSmrg        while ((i < NumCurrentSelections) &&
110705b261ecSmrg	       CurrentSelections[i].selection != stuff->id) i++;
110805b261ecSmrg        reply.type = X_Reply;
110905b261ecSmrg	reply.length = 0;
111005b261ecSmrg	reply.sequenceNumber = client->sequence;
111105b261ecSmrg        if (i < NumCurrentSelections)
111205b261ecSmrg            reply.owner = CurrentSelections[i].window;
111305b261ecSmrg        else
111405b261ecSmrg            reply.owner = None;
111505b261ecSmrg        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
111605b261ecSmrg        return(client->noClientException);
111705b261ecSmrg    }
111805b261ecSmrg    else
111905b261ecSmrg    {
112005b261ecSmrg	client->errorValue = stuff->id;
112105b261ecSmrg        return (BadAtom);
112205b261ecSmrg    }
112305b261ecSmrg}
112405b261ecSmrg
112505b261ecSmrgint
112605b261ecSmrgProcConvertSelection(ClientPtr client)
112705b261ecSmrg{
112805b261ecSmrg    Bool paramsOkay;
112905b261ecSmrg    xEvent event;
113005b261ecSmrg    WindowPtr pWin;
113105b261ecSmrg    REQUEST(xConvertSelectionReq);
113205b261ecSmrg    int rc;
113305b261ecSmrg
113405b261ecSmrg    REQUEST_SIZE_MATCH(xConvertSelectionReq);
113505b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->requestor, client, DixReadAccess);
113605b261ecSmrg    if (rc != Success)
113705b261ecSmrg        return rc;
113805b261ecSmrg
113905b261ecSmrg    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
114005b261ecSmrg    if (stuff->property != None)
114105b261ecSmrg	paramsOkay &= ValidAtom(stuff->property);
114205b261ecSmrg    if (paramsOkay)
114305b261ecSmrg    {
114405b261ecSmrg	int i;
114505b261ecSmrg
114605b261ecSmrg	i = 0;
114705b261ecSmrg	while ((i < NumCurrentSelections) &&
114805b261ecSmrg	       CurrentSelections[i].selection != stuff->selection) i++;
114905b261ecSmrg	if ((i < NumCurrentSelections) &&
115005b261ecSmrg	    (CurrentSelections[i].window != None) &&
115105b261ecSmrg	    XaceHook(XACE_RESOURCE_ACCESS, client,
115205b261ecSmrg		     CurrentSelections[i].window, RT_WINDOW,
115305b261ecSmrg		     DixReadAccess, CurrentSelections[i].pWin))
115405b261ecSmrg	{
115505b261ecSmrg	    event.u.u.type = SelectionRequest;
115605b261ecSmrg	    event.u.selectionRequest.time = stuff->time;
115705b261ecSmrg	    event.u.selectionRequest.owner =
115805b261ecSmrg			CurrentSelections[i].window;
115905b261ecSmrg	    event.u.selectionRequest.requestor = stuff->requestor;
116005b261ecSmrg	    event.u.selectionRequest.selection = stuff->selection;
116105b261ecSmrg	    event.u.selectionRequest.target = stuff->target;
116205b261ecSmrg	    event.u.selectionRequest.property = stuff->property;
116305b261ecSmrg	    if (TryClientEvents(
116405b261ecSmrg		CurrentSelections[i].client, &event, 1, NoEventMask,
116505b261ecSmrg		NoEventMask /* CantBeFiltered */, NullGrab))
116605b261ecSmrg		return (client->noClientException);
116705b261ecSmrg	}
116805b261ecSmrg	event.u.u.type = SelectionNotify;
116905b261ecSmrg	event.u.selectionNotify.time = stuff->time;
117005b261ecSmrg	event.u.selectionNotify.requestor = stuff->requestor;
117105b261ecSmrg	event.u.selectionNotify.selection = stuff->selection;
117205b261ecSmrg	event.u.selectionNotify.target = stuff->target;
117305b261ecSmrg	event.u.selectionNotify.property = None;
117405b261ecSmrg	(void) TryClientEvents(client, &event, 1, NoEventMask,
117505b261ecSmrg			       NoEventMask /* CantBeFiltered */, NullGrab);
117605b261ecSmrg	return (client->noClientException);
117705b261ecSmrg    }
117805b261ecSmrg    else
117905b261ecSmrg    {
118005b261ecSmrg	client->errorValue = stuff->property;
118105b261ecSmrg        return (BadAtom);
118205b261ecSmrg    }
118305b261ecSmrg}
118405b261ecSmrg
118505b261ecSmrgint
118605b261ecSmrgProcGrabServer(ClientPtr client)
118705b261ecSmrg{
118805b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
118905b261ecSmrg    if (grabState != GrabNone && client != grabClient)
119005b261ecSmrg    {
119105b261ecSmrg	ResetCurrentRequest(client);
119205b261ecSmrg	client->sequence--;
119305b261ecSmrg	BITSET(grabWaiters, client->index);
119405b261ecSmrg	IgnoreClient(client);
119505b261ecSmrg	return(client->noClientException);
119605b261ecSmrg    }
119705b261ecSmrg    OnlyListenToOneClient(client);
119805b261ecSmrg    grabState = GrabKickout;
119905b261ecSmrg    grabClient = client;
120005b261ecSmrg
120105b261ecSmrg    if (ServerGrabCallback)
120205b261ecSmrg    {
120305b261ecSmrg	ServerGrabInfoRec grabinfo;
120405b261ecSmrg	grabinfo.client = client;
120505b261ecSmrg	grabinfo.grabstate  = SERVER_GRABBED;
120605b261ecSmrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
120705b261ecSmrg    }
120805b261ecSmrg
120905b261ecSmrg    return(client->noClientException);
121005b261ecSmrg}
121105b261ecSmrg
121205b261ecSmrgstatic void
121305b261ecSmrgUngrabServer(ClientPtr client)
121405b261ecSmrg{
121505b261ecSmrg    int i;
121605b261ecSmrg
121705b261ecSmrg    grabState = GrabNone;
121805b261ecSmrg    ListenToAllClients();
121905b261ecSmrg    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
122005b261ecSmrg	;
122105b261ecSmrg    if (i >= 0)
122205b261ecSmrg    {
122305b261ecSmrg	i <<= 5;
122405b261ecSmrg	while (!GETBIT(grabWaiters, i))
122505b261ecSmrg	    i++;
122605b261ecSmrg	BITCLEAR(grabWaiters, i);
122705b261ecSmrg	AttendClient(clients[i]);
122805b261ecSmrg    }
122905b261ecSmrg
123005b261ecSmrg    if (ServerGrabCallback)
123105b261ecSmrg    {
123205b261ecSmrg	ServerGrabInfoRec grabinfo;
123305b261ecSmrg	grabinfo.client = client;
123405b261ecSmrg	grabinfo.grabstate  = SERVER_UNGRABBED;
123505b261ecSmrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
123605b261ecSmrg    }
123705b261ecSmrg}
123805b261ecSmrg
123905b261ecSmrgint
124005b261ecSmrgProcUngrabServer(ClientPtr client)
124105b261ecSmrg{
124205b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
124305b261ecSmrg    UngrabServer(client);
124405b261ecSmrg    return(client->noClientException);
124505b261ecSmrg}
124605b261ecSmrg
124705b261ecSmrgint
124805b261ecSmrgProcTranslateCoords(ClientPtr client)
124905b261ecSmrg{
125005b261ecSmrg    REQUEST(xTranslateCoordsReq);
125105b261ecSmrg
125205b261ecSmrg    WindowPtr pWin, pDst;
125305b261ecSmrg    xTranslateCoordsReply rep;
125405b261ecSmrg    int rc;
125505b261ecSmrg
125605b261ecSmrg    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
125705b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess);
125805b261ecSmrg    if (rc != Success)
125905b261ecSmrg        return rc;
126005b261ecSmrg    rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess);
126105b261ecSmrg    if (rc != Success)
126205b261ecSmrg        return rc;
126305b261ecSmrg    rep.type = X_Reply;
126405b261ecSmrg    rep.length = 0;
126505b261ecSmrg    rep.sequenceNumber = client->sequence;
126605b261ecSmrg    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
126705b261ecSmrg    {
126805b261ecSmrg	rep.sameScreen = xFalse;
126905b261ecSmrg        rep.child = None;
127005b261ecSmrg	rep.dstX = rep.dstY = 0;
127105b261ecSmrg    }
127205b261ecSmrg    else
127305b261ecSmrg    {
127405b261ecSmrg	INT16 x, y;
127505b261ecSmrg	rep.sameScreen = xTrue;
127605b261ecSmrg	rep.child = None;
127705b261ecSmrg	/* computing absolute coordinates -- adjust to destination later */
127805b261ecSmrg	x = pWin->drawable.x + stuff->srcX;
127905b261ecSmrg	y = pWin->drawable.y + stuff->srcY;
128005b261ecSmrg	pWin = pDst->firstChild;
128105b261ecSmrg	while (pWin)
128205b261ecSmrg	{
128305b261ecSmrg#ifdef SHAPE
128405b261ecSmrg	    BoxRec  box;
128505b261ecSmrg#endif
128605b261ecSmrg	    if ((pWin->mapped) &&
128705b261ecSmrg		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
128805b261ecSmrg		(x < pWin->drawable.x + (int)pWin->drawable.width +
128905b261ecSmrg		 wBorderWidth (pWin)) &&
129005b261ecSmrg		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
129105b261ecSmrg		(y < pWin->drawable.y + (int)pWin->drawable.height +
129205b261ecSmrg		 wBorderWidth (pWin))
129305b261ecSmrg#ifdef SHAPE
129405b261ecSmrg		/* When a window is shaped, a further check
129505b261ecSmrg		 * is made to see if the point is inside
129605b261ecSmrg		 * borderSize
129705b261ecSmrg		 */
129805b261ecSmrg		&& (!wBoundingShape(pWin) ||
129905b261ecSmrg		    POINT_IN_REGION(pWin->drawable.pScreen,
130005b261ecSmrg					&pWin->borderSize, x, y, &box))
130105b261ecSmrg
130205b261ecSmrg		&& (!wInputShape(pWin) ||
130305b261ecSmrg		    POINT_IN_REGION(pWin->drawable.pScreen,
130405b261ecSmrg				    wInputShape(pWin),
130505b261ecSmrg				    x - pWin->drawable.x,
130605b261ecSmrg				    y - pWin->drawable.y, &box))
130705b261ecSmrg#endif
130805b261ecSmrg		)
130905b261ecSmrg            {
131005b261ecSmrg		rep.child = pWin->drawable.id;
131105b261ecSmrg		pWin = (WindowPtr) NULL;
131205b261ecSmrg	    }
131305b261ecSmrg	    else
131405b261ecSmrg		pWin = pWin->nextSib;
131505b261ecSmrg	}
131605b261ecSmrg	/* adjust to destination coordinates */
131705b261ecSmrg	rep.dstX = x - pDst->drawable.x;
131805b261ecSmrg	rep.dstY = y - pDst->drawable.y;
131905b261ecSmrg    }
132005b261ecSmrg    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
132105b261ecSmrg    return(client->noClientException);
132205b261ecSmrg}
132305b261ecSmrg
132405b261ecSmrgint
132505b261ecSmrgProcOpenFont(ClientPtr client)
132605b261ecSmrg{
132705b261ecSmrg    int	err;
132805b261ecSmrg    REQUEST(xOpenFontReq);
132905b261ecSmrg
133005b261ecSmrg    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
133105b261ecSmrg    client->errorValue = stuff->fid;
133205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->fid, client);
133305b261ecSmrg    err = OpenFont(client, stuff->fid, (Mask) 0,
133405b261ecSmrg		stuff->nbytes, (char *)&stuff[1]);
133505b261ecSmrg    if (err == Success)
133605b261ecSmrg    {
133705b261ecSmrg	return(client->noClientException);
133805b261ecSmrg    }
133905b261ecSmrg    else
134005b261ecSmrg	return err;
134105b261ecSmrg}
134205b261ecSmrg
134305b261ecSmrgint
134405b261ecSmrgProcCloseFont(ClientPtr client)
134505b261ecSmrg{
134605b261ecSmrg    FontPtr pFont;
134705b261ecSmrg    REQUEST(xResourceReq);
134805b261ecSmrg
134905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
135005b261ecSmrg    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
135105b261ecSmrg					    DixDestroyAccess);
135205b261ecSmrg    if ( pFont != (FontPtr)NULL)	/* id was valid */
135305b261ecSmrg    {
135405b261ecSmrg        FreeResource(stuff->id, RT_NONE);
135505b261ecSmrg	return(client->noClientException);
135605b261ecSmrg    }
135705b261ecSmrg    else
135805b261ecSmrg    {
135905b261ecSmrg	client->errorValue = stuff->id;
136005b261ecSmrg        return (BadFont);
136105b261ecSmrg    }
136205b261ecSmrg}
136305b261ecSmrg
136405b261ecSmrgint
136505b261ecSmrgProcQueryFont(ClientPtr client)
136605b261ecSmrg{
136705b261ecSmrg    xQueryFontReply	*reply;
136805b261ecSmrg    FontPtr pFont;
136905b261ecSmrg    GC *pGC;
137005b261ecSmrg    REQUEST(xResourceReq);
137105b261ecSmrg
137205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
137305b261ecSmrg    client->errorValue = stuff->id;		/* EITHER font or gc */
137405b261ecSmrg    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
137505b261ecSmrg					    DixReadAccess);
137605b261ecSmrg    if (!pFont)
137705b261ecSmrg    {
137805b261ecSmrg	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
137905b261ecSmrg					    DixReadAccess);
138005b261ecSmrg        if (!pGC)
138105b261ecSmrg	{
138205b261ecSmrg	    client->errorValue = stuff->id;
138305b261ecSmrg            return(BadFont);     /* procotol spec says only error is BadFont */
138405b261ecSmrg	}
138505b261ecSmrg	pFont = pGC->font;
138605b261ecSmrg    }
138705b261ecSmrg
138805b261ecSmrg    {
138905b261ecSmrg	xCharInfo	*pmax = FONTINKMAX(pFont);
139005b261ecSmrg	xCharInfo	*pmin = FONTINKMIN(pFont);
139105b261ecSmrg	int		nprotoxcistructs;
139205b261ecSmrg	int		rlength;
139305b261ecSmrg
139405b261ecSmrg	nprotoxcistructs = (
139505b261ecSmrg	   pmax->rightSideBearing == pmin->rightSideBearing &&
139605b261ecSmrg	   pmax->leftSideBearing == pmin->leftSideBearing &&
139705b261ecSmrg	   pmax->descent == pmin->descent &&
139805b261ecSmrg	   pmax->ascent == pmin->ascent &&
139905b261ecSmrg	   pmax->characterWidth == pmin->characterWidth) ?
140005b261ecSmrg		0 : N2dChars(pFont);
140105b261ecSmrg
140205b261ecSmrg	rlength = sizeof(xQueryFontReply) +
140305b261ecSmrg	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
140405b261ecSmrg		     nprotoxcistructs * sizeof(xCharInfo);
140505b261ecSmrg	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
140605b261ecSmrg	if(!reply)
140705b261ecSmrg	{
140805b261ecSmrg	    return(BadAlloc);
140905b261ecSmrg	}
141005b261ecSmrg
141105b261ecSmrg	reply->type = X_Reply;
141205b261ecSmrg	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
141305b261ecSmrg	reply->sequenceNumber = client->sequence;
141405b261ecSmrg	QueryFont( pFont, reply, nprotoxcistructs);
141505b261ecSmrg
141605b261ecSmrg        WriteReplyToClient(client, rlength, reply);
141705b261ecSmrg	DEALLOCATE_LOCAL(reply);
141805b261ecSmrg	return(client->noClientException);
141905b261ecSmrg    }
142005b261ecSmrg}
142105b261ecSmrg
142205b261ecSmrgint
142305b261ecSmrgProcQueryTextExtents(ClientPtr client)
142405b261ecSmrg{
142505b261ecSmrg    REQUEST(xQueryTextExtentsReq);
142605b261ecSmrg    xQueryTextExtentsReply reply;
142705b261ecSmrg    FontPtr pFont;
142805b261ecSmrg    GC *pGC;
142905b261ecSmrg    ExtentInfoRec info;
143005b261ecSmrg    unsigned long length;
143105b261ecSmrg
143205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
143305b261ecSmrg
143405b261ecSmrg    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
143505b261ecSmrg					    DixReadAccess);
143605b261ecSmrg    if (!pFont)
143705b261ecSmrg    {
143805b261ecSmrg        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
143905b261ecSmrg					   DixReadAccess);
144005b261ecSmrg        if (!pGC)
144105b261ecSmrg	{
144205b261ecSmrg	    client->errorValue = stuff->fid;
144305b261ecSmrg            return(BadFont);
144405b261ecSmrg	}
144505b261ecSmrg	pFont = pGC->font;
144605b261ecSmrg    }
144705b261ecSmrg    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
144805b261ecSmrg    length = length << 1;
144905b261ecSmrg    if (stuff->oddLength)
145005b261ecSmrg    {
145105b261ecSmrg	if (length == 0)
145205b261ecSmrg	    return(BadLength);
145305b261ecSmrg        length--;
145405b261ecSmrg    }
145505b261ecSmrg    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
145605b261ecSmrg	return(BadAlloc);
145705b261ecSmrg    reply.type = X_Reply;
145805b261ecSmrg    reply.length = 0;
145905b261ecSmrg    reply.sequenceNumber = client->sequence;
146005b261ecSmrg    reply.drawDirection = info.drawDirection;
146105b261ecSmrg    reply.fontAscent = info.fontAscent;
146205b261ecSmrg    reply.fontDescent = info.fontDescent;
146305b261ecSmrg    reply.overallAscent = info.overallAscent;
146405b261ecSmrg    reply.overallDescent = info.overallDescent;
146505b261ecSmrg    reply.overallWidth = info.overallWidth;
146605b261ecSmrg    reply.overallLeft = info.overallLeft;
146705b261ecSmrg    reply.overallRight = info.overallRight;
146805b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
146905b261ecSmrg    return(client->noClientException);
147005b261ecSmrg}
147105b261ecSmrg
147205b261ecSmrgint
147305b261ecSmrgProcListFonts(ClientPtr client)
147405b261ecSmrg{
147505b261ecSmrg    REQUEST(xListFontsReq);
147605b261ecSmrg
147705b261ecSmrg    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
147805b261ecSmrg
147905b261ecSmrg    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
148005b261ecSmrg	stuff->maxNames);
148105b261ecSmrg}
148205b261ecSmrg
148305b261ecSmrgint
148405b261ecSmrgProcListFontsWithInfo(ClientPtr client)
148505b261ecSmrg{
148605b261ecSmrg    REQUEST(xListFontsWithInfoReq);
148705b261ecSmrg
148805b261ecSmrg    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
148905b261ecSmrg
149005b261ecSmrg    return StartListFontsWithInfo(client, stuff->nbytes,
149105b261ecSmrg				  (unsigned char *) &stuff[1], stuff->maxNames);
149205b261ecSmrg}
149305b261ecSmrg
149405b261ecSmrg/**
149505b261ecSmrg *
149605b261ecSmrg *  \param value must conform to DeleteType
149705b261ecSmrg */
149805b261ecSmrgint
149905b261ecSmrgdixDestroyPixmap(pointer value, XID pid)
150005b261ecSmrg{
150105b261ecSmrg    PixmapPtr pPixmap = (PixmapPtr)value;
150205b261ecSmrg    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
150305b261ecSmrg}
150405b261ecSmrg
150505b261ecSmrgint
150605b261ecSmrgProcCreatePixmap(ClientPtr client)
150705b261ecSmrg{
150805b261ecSmrg    PixmapPtr pMap;
150905b261ecSmrg    DrawablePtr pDraw;
151005b261ecSmrg    REQUEST(xCreatePixmapReq);
151105b261ecSmrg    DepthPtr pDepth;
151205b261ecSmrg    int i, rc;
151305b261ecSmrg
151405b261ecSmrg    REQUEST_SIZE_MATCH(xCreatePixmapReq);
151505b261ecSmrg    client->errorValue = stuff->pid;
151605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
151705b261ecSmrg
151805b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
151905b261ecSmrg			   DixReadAccess);
152005b261ecSmrg    if (rc != Success)
152105b261ecSmrg	return rc;
152205b261ecSmrg
152305b261ecSmrg    if (!stuff->width || !stuff->height)
152405b261ecSmrg    {
152505b261ecSmrg	client->errorValue = 0;
152605b261ecSmrg        return BadValue;
152705b261ecSmrg    }
152805b261ecSmrg    if (stuff->width > 32767 || stuff->height > 32767)
152905b261ecSmrg    {
153005b261ecSmrg	/* It is allowed to try and allocate a pixmap which is larger than
153105b261ecSmrg	 * 32767 in either dimension. However, all of the framebuffer code
153205b261ecSmrg	 * is buggy and does not reliably draw to such big pixmaps, basically
153305b261ecSmrg	 * because the Region data structure operates with signed shorts
153405b261ecSmrg	 * for the rectangles in it.
153505b261ecSmrg	 *
153605b261ecSmrg	 * Furthermore, several places in the X server computes the
153705b261ecSmrg	 * size in bytes of the pixmap and tries to store it in an
153805b261ecSmrg	 * integer. This integer can overflow and cause the allocated size
153905b261ecSmrg	 * to be much smaller.
154005b261ecSmrg	 *
154105b261ecSmrg	 * So, such big pixmaps are rejected here with a BadAlloc
154205b261ecSmrg	 */
154305b261ecSmrg	return BadAlloc;
154405b261ecSmrg    }
154505b261ecSmrg    if (stuff->depth != 1)
154605b261ecSmrg    {
154705b261ecSmrg        pDepth = pDraw->pScreen->allowedDepths;
154805b261ecSmrg        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
154905b261ecSmrg	   if (pDepth->depth == stuff->depth)
155005b261ecSmrg               goto CreatePmap;
155105b261ecSmrg	client->errorValue = stuff->depth;
155205b261ecSmrg        return BadValue;
155305b261ecSmrg    }
155405b261ecSmrgCreatePmap:
155505b261ecSmrg    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
155605b261ecSmrg		(pDraw->pScreen, stuff->width,
155705b261ecSmrg		 stuff->height, stuff->depth);
155805b261ecSmrg    if (pMap)
155905b261ecSmrg    {
156005b261ecSmrg	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
156105b261ecSmrg	pMap->drawable.id = stuff->pid;
156205b261ecSmrg	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
156305b261ecSmrg	    return(client->noClientException);
156405b261ecSmrg    }
156505b261ecSmrg    return (BadAlloc);
156605b261ecSmrg}
156705b261ecSmrg
156805b261ecSmrgint
156905b261ecSmrgProcFreePixmap(ClientPtr client)
157005b261ecSmrg{
157105b261ecSmrg    PixmapPtr pMap;
157205b261ecSmrg
157305b261ecSmrg    REQUEST(xResourceReq);
157405b261ecSmrg
157505b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
157605b261ecSmrg    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
157705b261ecSmrg					     DixDestroyAccess);
157805b261ecSmrg    if (pMap)
157905b261ecSmrg    {
158005b261ecSmrg	FreeResource(stuff->id, RT_NONE);
158105b261ecSmrg	return(client->noClientException);
158205b261ecSmrg    }
158305b261ecSmrg    else
158405b261ecSmrg    {
158505b261ecSmrg	client->errorValue = stuff->id;
158605b261ecSmrg	return (BadPixmap);
158705b261ecSmrg    }
158805b261ecSmrg}
158905b261ecSmrg
159005b261ecSmrgint
159105b261ecSmrgProcCreateGC(ClientPtr client)
159205b261ecSmrg{
159305b261ecSmrg    int error, rc;
159405b261ecSmrg    GC *pGC;
159505b261ecSmrg    DrawablePtr pDraw;
159605b261ecSmrg    unsigned len;
159705b261ecSmrg    REQUEST(xCreateGCReq);
159805b261ecSmrg
159905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
160005b261ecSmrg    client->errorValue = stuff->gc;
160105b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gc, client);
160205b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess);
160305b261ecSmrg    if (rc != Success)
160405b261ecSmrg	return rc;
160505b261ecSmrg
160605b261ecSmrg    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
160705b261ecSmrg    if (len != Ones(stuff->mask))
160805b261ecSmrg        return BadLength;
160905b261ecSmrg    pGC = (GC *)CreateGC(pDraw, stuff->mask,
161005b261ecSmrg			 (XID *) &stuff[1], &error);
161105b261ecSmrg    if (error != Success)
161205b261ecSmrg        return error;
161305b261ecSmrg    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
161405b261ecSmrg	return (BadAlloc);
161505b261ecSmrg    return(client->noClientException);
161605b261ecSmrg}
161705b261ecSmrg
161805b261ecSmrgint
161905b261ecSmrgProcChangeGC(ClientPtr client)
162005b261ecSmrg{
162105b261ecSmrg    GC *pGC;
162205b261ecSmrg    int result;
162305b261ecSmrg    unsigned len;
162405b261ecSmrg    REQUEST(xChangeGCReq);
162505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
162605b261ecSmrg
162705b261ecSmrg    result = dixLookupGC(&pGC, stuff->gc, client, DixWriteAccess);
162805b261ecSmrg    if (result != Success)
162905b261ecSmrg	return result;
163005b261ecSmrg
163105b261ecSmrg    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
163205b261ecSmrg    if (len != Ones(stuff->mask))
163305b261ecSmrg        return BadLength;
163405b261ecSmrg
163505b261ecSmrg    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
163605b261ecSmrg    if (client->noClientException != Success)
163705b261ecSmrg        return(client->noClientException);
163805b261ecSmrg    else
163905b261ecSmrg    {
164005b261ecSmrg	client->errorValue = clientErrorValue;
164105b261ecSmrg        return(result);
164205b261ecSmrg    }
164305b261ecSmrg}
164405b261ecSmrg
164505b261ecSmrgint
164605b261ecSmrgProcCopyGC(ClientPtr client)
164705b261ecSmrg{
164805b261ecSmrg    GC *dstGC;
164905b261ecSmrg    GC *pGC;
165005b261ecSmrg    int result;
165105b261ecSmrg    REQUEST(xCopyGCReq);
165205b261ecSmrg    REQUEST_SIZE_MATCH(xCopyGCReq);
165305b261ecSmrg
165405b261ecSmrg    result = dixLookupGC(&pGC, stuff->srcGC, client, DixReadAccess);
165505b261ecSmrg    if (result != Success)
165605b261ecSmrg	return result;
165705b261ecSmrg    result = dixLookupGC(&dstGC, stuff->dstGC, client, DixWriteAccess);
165805b261ecSmrg    if (result != Success)
165905b261ecSmrg	return result;
166005b261ecSmrg    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
166105b261ecSmrg        return (BadMatch);
166205b261ecSmrg    result = CopyGC(pGC, dstGC, stuff->mask);
166305b261ecSmrg    if (client->noClientException != Success)
166405b261ecSmrg        return(client->noClientException);
166505b261ecSmrg    else
166605b261ecSmrg    {
166705b261ecSmrg	client->errorValue = clientErrorValue;
166805b261ecSmrg        return(result);
166905b261ecSmrg    }
167005b261ecSmrg}
167105b261ecSmrg
167205b261ecSmrgint
167305b261ecSmrgProcSetDashes(ClientPtr client)
167405b261ecSmrg{
167505b261ecSmrg    GC *pGC;
167605b261ecSmrg    int result;
167705b261ecSmrg    REQUEST(xSetDashesReq);
167805b261ecSmrg
167905b261ecSmrg    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
168005b261ecSmrg    if (stuff->nDashes == 0)
168105b261ecSmrg    {
168205b261ecSmrg	 client->errorValue = 0;
168305b261ecSmrg         return BadValue;
168405b261ecSmrg    }
168505b261ecSmrg
168605b261ecSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess);
168705b261ecSmrg    if (result != Success)
168805b261ecSmrg	return result;
168905b261ecSmrg
169005b261ecSmrg    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
169105b261ecSmrg		       (unsigned char *)&stuff[1]);
169205b261ecSmrg    if (client->noClientException != Success)
169305b261ecSmrg        return(client->noClientException);
169405b261ecSmrg    else
169505b261ecSmrg    {
169605b261ecSmrg	client->errorValue = clientErrorValue;
169705b261ecSmrg        return(result);
169805b261ecSmrg    }
169905b261ecSmrg}
170005b261ecSmrg
170105b261ecSmrgint
170205b261ecSmrgProcSetClipRectangles(ClientPtr client)
170305b261ecSmrg{
170405b261ecSmrg    int	nr, result;
170505b261ecSmrg    GC *pGC;
170605b261ecSmrg    REQUEST(xSetClipRectanglesReq);
170705b261ecSmrg
170805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
170905b261ecSmrg    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
171005b261ecSmrg	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
171105b261ecSmrg    {
171205b261ecSmrg	client->errorValue = stuff->ordering;
171305b261ecSmrg        return BadValue;
171405b261ecSmrg    }
171505b261ecSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess);
171605b261ecSmrg    if (result != Success)
171705b261ecSmrg	return result;
171805b261ecSmrg
171905b261ecSmrg    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
172005b261ecSmrg    if (nr & 4)
172105b261ecSmrg	return(BadLength);
172205b261ecSmrg    nr >>= 3;
172305b261ecSmrg    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
172405b261ecSmrg			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
172505b261ecSmrg    if (client->noClientException != Success)
172605b261ecSmrg        return(client->noClientException);
172705b261ecSmrg    else
172805b261ecSmrg        return(result);
172905b261ecSmrg}
173005b261ecSmrg
173105b261ecSmrgint
173205b261ecSmrgProcFreeGC(ClientPtr client)
173305b261ecSmrg{
173405b261ecSmrg    GC *pGC;
173505b261ecSmrg    int rc;
173605b261ecSmrg    REQUEST(xResourceReq);
173705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
173805b261ecSmrg
173905b261ecSmrg    rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
174005b261ecSmrg    if (rc != Success)
174105b261ecSmrg	return rc;
174205b261ecSmrg
174305b261ecSmrg    FreeResource(stuff->id, RT_NONE);
174405b261ecSmrg    return(client->noClientException);
174505b261ecSmrg}
174605b261ecSmrg
174705b261ecSmrgint
174805b261ecSmrgProcClearToBackground(ClientPtr client)
174905b261ecSmrg{
175005b261ecSmrg    REQUEST(xClearAreaReq);
175105b261ecSmrg    WindowPtr pWin;
175205b261ecSmrg    int rc;
175305b261ecSmrg
175405b261ecSmrg    REQUEST_SIZE_MATCH(xClearAreaReq);
175505b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
175605b261ecSmrg    if (rc != Success)
175705b261ecSmrg        return rc;
175805b261ecSmrg    if (pWin->drawable.class == InputOnly)
175905b261ecSmrg    {
176005b261ecSmrg	client->errorValue = stuff->window;
176105b261ecSmrg	return (BadMatch);
176205b261ecSmrg    }
176305b261ecSmrg    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
176405b261ecSmrg    {
176505b261ecSmrg	client->errorValue = stuff->exposures;
176605b261ecSmrg        return(BadValue);
176705b261ecSmrg    }
176805b261ecSmrg    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
176905b261ecSmrg			       stuff->width, stuff->height,
177005b261ecSmrg			       (Bool)stuff->exposures);
177105b261ecSmrg    return(client->noClientException);
177205b261ecSmrg}
177305b261ecSmrg
177405b261ecSmrgint
177505b261ecSmrgProcCopyArea(ClientPtr client)
177605b261ecSmrg{
177705b261ecSmrg    DrawablePtr pDst;
177805b261ecSmrg    DrawablePtr pSrc;
177905b261ecSmrg    GC *pGC;
178005b261ecSmrg    REQUEST(xCopyAreaReq);
178105b261ecSmrg    RegionPtr pRgn;
178205b261ecSmrg    int rc;
178305b261ecSmrg
178405b261ecSmrg    REQUEST_SIZE_MATCH(xCopyAreaReq);
178505b261ecSmrg
178605b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
178705b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
178805b261ecSmrg    {
178905b261ecSmrg	rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
179005b261ecSmrg				 DixReadAccess);
179105b261ecSmrg	if (rc != Success)
179205b261ecSmrg	    return rc;
179305b261ecSmrg	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
179405b261ecSmrg	{
179505b261ecSmrg	    client->errorValue = stuff->dstDrawable;
179605b261ecSmrg	    return (BadMatch);
179705b261ecSmrg	}
179805b261ecSmrg    }
179905b261ecSmrg    else
180005b261ecSmrg        pSrc = pDst;
180105b261ecSmrg
180205b261ecSmrg    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
180305b261ecSmrg				 stuff->width, stuff->height,
180405b261ecSmrg				 stuff->dstX, stuff->dstY);
180505b261ecSmrg    if (pGC->graphicsExposures)
180605b261ecSmrg    {
180705b261ecSmrg	(*pDst->pScreen->SendGraphicsExpose)
180805b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
180905b261ecSmrg	if (pRgn)
181005b261ecSmrg	    REGION_DESTROY(pDst->pScreen, pRgn);
181105b261ecSmrg    }
181205b261ecSmrg
181305b261ecSmrg    return(client->noClientException);
181405b261ecSmrg}
181505b261ecSmrg
181605b261ecSmrgint
181705b261ecSmrgProcCopyPlane(ClientPtr client)
181805b261ecSmrg{
181905b261ecSmrg    DrawablePtr psrcDraw, pdstDraw;
182005b261ecSmrg    GC *pGC;
182105b261ecSmrg    REQUEST(xCopyPlaneReq);
182205b261ecSmrg    RegionPtr pRgn;
182305b261ecSmrg    int rc;
182405b261ecSmrg
182505b261ecSmrg    REQUEST_SIZE_MATCH(xCopyPlaneReq);
182605b261ecSmrg
182705b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
182805b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
182905b261ecSmrg    {
183005b261ecSmrg	rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
183105b261ecSmrg			       DixReadAccess);
183205b261ecSmrg	if (rc != Success)
183305b261ecSmrg	    return rc;
183405b261ecSmrg
183505b261ecSmrg	if (pdstDraw->pScreen != psrcDraw->pScreen)
183605b261ecSmrg	{
183705b261ecSmrg	    client->errorValue = stuff->dstDrawable;
183805b261ecSmrg	    return (BadMatch);
183905b261ecSmrg	}
184005b261ecSmrg    }
184105b261ecSmrg    else
184205b261ecSmrg        psrcDraw = pdstDraw;
184305b261ecSmrg
184405b261ecSmrg    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
184505b261ecSmrg    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
184605b261ecSmrg       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
184705b261ecSmrg    {
184805b261ecSmrg       client->errorValue = stuff->bitPlane;
184905b261ecSmrg       return(BadValue);
185005b261ecSmrg    }
185105b261ecSmrg
185205b261ecSmrg    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
185305b261ecSmrg				 stuff->width, stuff->height,
185405b261ecSmrg				 stuff->dstX, stuff->dstY, stuff->bitPlane);
185505b261ecSmrg    if (pGC->graphicsExposures)
185605b261ecSmrg    {
185705b261ecSmrg	(*pdstDraw->pScreen->SendGraphicsExpose)
185805b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
185905b261ecSmrg	if (pRgn)
186005b261ecSmrg	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
186105b261ecSmrg    }
186205b261ecSmrg    return(client->noClientException);
186305b261ecSmrg}
186405b261ecSmrg
186505b261ecSmrgint
186605b261ecSmrgProcPolyPoint(ClientPtr client)
186705b261ecSmrg{
186805b261ecSmrg    int npoint;
186905b261ecSmrg    GC *pGC;
187005b261ecSmrg    DrawablePtr pDraw;
187105b261ecSmrg    REQUEST(xPolyPointReq);
187205b261ecSmrg
187305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
187405b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
187505b261ecSmrg	(stuff->coordMode != CoordModePrevious))
187605b261ecSmrg    {
187705b261ecSmrg	client->errorValue = stuff->coordMode;
187805b261ecSmrg        return BadValue;
187905b261ecSmrg    }
188005b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
188105b261ecSmrg    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
188205b261ecSmrg    if (npoint)
188305b261ecSmrg        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
188405b261ecSmrg			  (xPoint *) &stuff[1]);
188505b261ecSmrg    return (client->noClientException);
188605b261ecSmrg}
188705b261ecSmrg
188805b261ecSmrgint
188905b261ecSmrgProcPolyLine(ClientPtr client)
189005b261ecSmrg{
189105b261ecSmrg    int npoint;
189205b261ecSmrg    GC *pGC;
189305b261ecSmrg    DrawablePtr pDraw;
189405b261ecSmrg    REQUEST(xPolyLineReq);
189505b261ecSmrg
189605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
189705b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
189805b261ecSmrg	(stuff->coordMode != CoordModePrevious))
189905b261ecSmrg    {
190005b261ecSmrg	client->errorValue = stuff->coordMode;
190105b261ecSmrg        return BadValue;
190205b261ecSmrg    }
190305b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
190405b261ecSmrg    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
190505b261ecSmrg    if (npoint > 1)
190605b261ecSmrg	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
190705b261ecSmrg			      (DDXPointPtr) &stuff[1]);
190805b261ecSmrg    return(client->noClientException);
190905b261ecSmrg}
191005b261ecSmrg
191105b261ecSmrgint
191205b261ecSmrgProcPolySegment(ClientPtr client)
191305b261ecSmrg{
191405b261ecSmrg    int nsegs;
191505b261ecSmrg    GC *pGC;
191605b261ecSmrg    DrawablePtr pDraw;
191705b261ecSmrg    REQUEST(xPolySegmentReq);
191805b261ecSmrg
191905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
192005b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
192105b261ecSmrg    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
192205b261ecSmrg    if (nsegs & 4)
192305b261ecSmrg	return(BadLength);
192405b261ecSmrg    nsegs >>= 3;
192505b261ecSmrg    if (nsegs)
192605b261ecSmrg        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
192705b261ecSmrg    return (client->noClientException);
192805b261ecSmrg}
192905b261ecSmrg
193005b261ecSmrgint
193105b261ecSmrgProcPolyRectangle (ClientPtr client)
193205b261ecSmrg{
193305b261ecSmrg    int nrects;
193405b261ecSmrg    GC *pGC;
193505b261ecSmrg    DrawablePtr pDraw;
193605b261ecSmrg    REQUEST(xPolyRectangleReq);
193705b261ecSmrg
193805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
193905b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
194005b261ecSmrg    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
194105b261ecSmrg    if (nrects & 4)
194205b261ecSmrg	return(BadLength);
194305b261ecSmrg    nrects >>= 3;
194405b261ecSmrg    if (nrects)
194505b261ecSmrg        (*pGC->ops->PolyRectangle)(pDraw, pGC,
194605b261ecSmrg		    nrects, (xRectangle *) &stuff[1]);
194705b261ecSmrg    return(client->noClientException);
194805b261ecSmrg}
194905b261ecSmrg
195005b261ecSmrgint
195105b261ecSmrgProcPolyArc(ClientPtr client)
195205b261ecSmrg{
195305b261ecSmrg    int		narcs;
195405b261ecSmrg    GC *pGC;
195505b261ecSmrg    DrawablePtr pDraw;
195605b261ecSmrg    REQUEST(xPolyArcReq);
195705b261ecSmrg
195805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
195905b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
196005b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
196105b261ecSmrg    if (narcs % sizeof(xArc))
196205b261ecSmrg	return(BadLength);
196305b261ecSmrg    narcs /= sizeof(xArc);
196405b261ecSmrg    if (narcs)
196505b261ecSmrg        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
196605b261ecSmrg    return (client->noClientException);
196705b261ecSmrg}
196805b261ecSmrg
196905b261ecSmrgint
197005b261ecSmrgProcFillPoly(ClientPtr client)
197105b261ecSmrg{
197205b261ecSmrg    int          things;
197305b261ecSmrg    GC *pGC;
197405b261ecSmrg    DrawablePtr pDraw;
197505b261ecSmrg    REQUEST(xFillPolyReq);
197605b261ecSmrg
197705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
197805b261ecSmrg    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
197905b261ecSmrg	(stuff->shape != Convex))
198005b261ecSmrg    {
198105b261ecSmrg	client->errorValue = stuff->shape;
198205b261ecSmrg        return BadValue;
198305b261ecSmrg    }
198405b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
198505b261ecSmrg	(stuff->coordMode != CoordModePrevious))
198605b261ecSmrg    {
198705b261ecSmrg	client->errorValue = stuff->coordMode;
198805b261ecSmrg        return BadValue;
198905b261ecSmrg    }
199005b261ecSmrg
199105b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
199205b261ecSmrg    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
199305b261ecSmrg    if (things)
199405b261ecSmrg        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
199505b261ecSmrg			 stuff->coordMode, things,
199605b261ecSmrg			 (DDXPointPtr) &stuff[1]);
199705b261ecSmrg    return(client->noClientException);
199805b261ecSmrg}
199905b261ecSmrg
200005b261ecSmrgint
200105b261ecSmrgProcPolyFillRectangle(ClientPtr client)
200205b261ecSmrg{
200305b261ecSmrg    int             things;
200405b261ecSmrg    GC *pGC;
200505b261ecSmrg    DrawablePtr pDraw;
200605b261ecSmrg    REQUEST(xPolyFillRectangleReq);
200705b261ecSmrg
200805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
200905b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
201005b261ecSmrg    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
201105b261ecSmrg    if (things & 4)
201205b261ecSmrg	return(BadLength);
201305b261ecSmrg    things >>= 3;
201405b261ecSmrg
201505b261ecSmrg    if (things)
201605b261ecSmrg        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
201705b261ecSmrg		      (xRectangle *) &stuff[1]);
201805b261ecSmrg    return (client->noClientException);
201905b261ecSmrg}
202005b261ecSmrg
202105b261ecSmrgint
202205b261ecSmrgProcPolyFillArc(ClientPtr client)
202305b261ecSmrg{
202405b261ecSmrg    int		narcs;
202505b261ecSmrg    GC *pGC;
202605b261ecSmrg    DrawablePtr pDraw;
202705b261ecSmrg    REQUEST(xPolyFillArcReq);
202805b261ecSmrg
202905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
203005b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
203105b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
203205b261ecSmrg    if (narcs % sizeof(xArc))
203305b261ecSmrg	return(BadLength);
203405b261ecSmrg    narcs /= sizeof(xArc);
203505b261ecSmrg    if (narcs)
203605b261ecSmrg        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
203705b261ecSmrg    return (client->noClientException);
203805b261ecSmrg}
203905b261ecSmrg
204005b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
204105b261ecSmrg
204205b261ecSmrgint
204305b261ecSmrgServerOrder (void)
204405b261ecSmrg{
204505b261ecSmrg    int	    whichbyte = 1;
204605b261ecSmrg
204705b261ecSmrg    if (*((char *) &whichbyte))
204805b261ecSmrg	return LSBFirst;
204905b261ecSmrg    return MSBFirst;
205005b261ecSmrg}
205105b261ecSmrg
205205b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
205305b261ecSmrg
205405b261ecSmrgvoid
205505b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order)
205605b261ecSmrg{
205705b261ecSmrg    switch (bpp) {
205805b261ecSmrg    case 1:	/* yuck */
205905b261ecSmrg	if (BITMAP_BIT_ORDER != order)
206005b261ecSmrg	    BitOrderInvert ((unsigned char *) base, nbytes);
206105b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
206205b261ecSmrg	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
206305b261ecSmrg#endif
206405b261ecSmrg	break;
206505b261ecSmrg    case 4:
206605b261ecSmrg	break;  /* yuck */
206705b261ecSmrg    case 8:
206805b261ecSmrg	break;
206905b261ecSmrg    case 16:
207005b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
207105b261ecSmrg	    TwoByteSwap ((unsigned char *) base, nbytes);
207205b261ecSmrg	break;
207305b261ecSmrg    case 32:
207405b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
207505b261ecSmrg	    FourByteSwap ((unsigned char *) base, nbytes);
207605b261ecSmrg	break;
207705b261ecSmrg    }
207805b261ecSmrg}
207905b261ecSmrg#else
208005b261ecSmrg#define ReformatImage(b,n,bpp,o)
208105b261ecSmrg#endif
208205b261ecSmrg
208305b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to
208405b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
208505b261ecSmrg * to use internally. Removes need for internal alignment checking.
208605b261ecSmrg * All of the PutImage functions could be changed individually, but
208705b261ecSmrg * as currently written, they call other routines which require things
208805b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here.
208905b261ecSmrg * If an image would be padded differently for 64- versus 32-, then
209005b261ecSmrg * copy each scanline to a 64-bit padded scanline.
209105b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit
209205b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction.
209305b261ecSmrg */
209405b261ecSmrgint
209505b261ecSmrgProcPutImage(ClientPtr client)
209605b261ecSmrg{
209705b261ecSmrg    GC *pGC;
209805b261ecSmrg    DrawablePtr pDraw;
209905b261ecSmrg    long	length; 	/* length of scanline server padded */
210005b261ecSmrg    long 	lengthProto; 	/* length of scanline protocol padded */
210105b261ecSmrg    char	*tmpImage;
210205b261ecSmrg    REQUEST(xPutImageReq);
210305b261ecSmrg
210405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPutImageReq);
210505b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
210605b261ecSmrg    if (stuff->format == XYBitmap)
210705b261ecSmrg    {
210805b261ecSmrg        if ((stuff->depth != 1) ||
210905b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
211005b261ecSmrg            return BadMatch;
211105b261ecSmrg        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
211205b261ecSmrg    }
211305b261ecSmrg    else if (stuff->format == XYPixmap)
211405b261ecSmrg    {
211505b261ecSmrg        if ((pDraw->depth != stuff->depth) ||
211605b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
211705b261ecSmrg            return BadMatch;
211805b261ecSmrg        length      = BitmapBytePad(stuff->width + stuff->leftPad);
211905b261ecSmrg	length      *= stuff->depth;
212005b261ecSmrg    }
212105b261ecSmrg    else if (stuff->format == ZPixmap)
212205b261ecSmrg    {
212305b261ecSmrg        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
212405b261ecSmrg            return BadMatch;
212505b261ecSmrg        length      = PixmapBytePad(stuff->width, stuff->depth);
212605b261ecSmrg    }
212705b261ecSmrg    else
212805b261ecSmrg    {
212905b261ecSmrg	client->errorValue = stuff->format;
213005b261ecSmrg        return BadValue;
213105b261ecSmrg    }
213205b261ecSmrg
213305b261ecSmrg    tmpImage = (char *)&stuff[1];
213405b261ecSmrg    lengthProto = length;
213505b261ecSmrg
213605b261ecSmrg    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
213705b261ecSmrg	(sizeof(xPutImageReq) >> 2)) != client->req_len)
213805b261ecSmrg	return BadLength;
213905b261ecSmrg
214005b261ecSmrg    ReformatImage (tmpImage, lengthProto * stuff->height,
214105b261ecSmrg		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
214205b261ecSmrg		   ClientOrder(client));
214305b261ecSmrg
214405b261ecSmrg    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
214505b261ecSmrg		  stuff->width, stuff->height,
214605b261ecSmrg		  stuff->leftPad, stuff->format, tmpImage);
214705b261ecSmrg
214805b261ecSmrg     return (client->noClientException);
214905b261ecSmrg}
215005b261ecSmrg
215105b261ecSmrgstatic int
215205b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable,
215305b261ecSmrg           int x, int y, int width, int height,
215405b261ecSmrg           Mask planemask, xGetImageReply **im_return)
215505b261ecSmrg{
215605b261ecSmrg    DrawablePtr		pDraw;
215705b261ecSmrg    int			nlines, linesPerBuf, rc;
215805b261ecSmrg    int	linesDone;
215905b261ecSmrg    long		widthBytesLine, length;
216005b261ecSmrg    Mask		plane = 0;
216105b261ecSmrg    char		*pBuf;
216205b261ecSmrg    xGetImageReply	xgi;
216305b261ecSmrg    RegionPtr pVisibleRegion = NULL;
216405b261ecSmrg
216505b261ecSmrg    if ((format != XYPixmap) && (format != ZPixmap))
216605b261ecSmrg    {
216705b261ecSmrg	client->errorValue = format;
216805b261ecSmrg        return(BadValue);
216905b261ecSmrg    }
217005b261ecSmrg    rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
217105b261ecSmrg    if (rc != Success)
217205b261ecSmrg	return rc;
217305b261ecSmrg
217405b261ecSmrg    if(pDraw->type == DRAWABLE_WINDOW)
217505b261ecSmrg    {
217605b261ecSmrg      if( /* check for being viewable */
217705b261ecSmrg	 !((WindowPtr) pDraw)->realized ||
217805b261ecSmrg	  /* check for being on screen */
217905b261ecSmrg         pDraw->x + x < 0 ||
218005b261ecSmrg 	 pDraw->x + x + width > pDraw->pScreen->width ||
218105b261ecSmrg         pDraw->y + y < 0 ||
218205b261ecSmrg         pDraw->y + y + height > pDraw->pScreen->height ||
218305b261ecSmrg          /* check for being inside of border */
218405b261ecSmrg         x < - wBorderWidth((WindowPtr)pDraw) ||
218505b261ecSmrg         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
218605b261ecSmrg         y < -wBorderWidth((WindowPtr)pDraw) ||
218705b261ecSmrg         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
218805b261ecSmrg        )
218905b261ecSmrg	    return(BadMatch);
219005b261ecSmrg	xgi.visual = wVisual (((WindowPtr) pDraw));
219105b261ecSmrg    }
219205b261ecSmrg    else
219305b261ecSmrg    {
219405b261ecSmrg      if(x < 0 ||
219505b261ecSmrg         x+width > (int)pDraw->width ||
219605b261ecSmrg         y < 0 ||
219705b261ecSmrg         y+height > (int)pDraw->height
219805b261ecSmrg        )
219905b261ecSmrg	    return(BadMatch);
220005b261ecSmrg	xgi.visual = None;
220105b261ecSmrg    }
220205b261ecSmrg
220305b261ecSmrg    xgi.type = X_Reply;
220405b261ecSmrg    xgi.sequenceNumber = client->sequence;
220505b261ecSmrg    xgi.depth = pDraw->depth;
220605b261ecSmrg    if(format == ZPixmap)
220705b261ecSmrg    {
220805b261ecSmrg	widthBytesLine = PixmapBytePad(width, pDraw->depth);
220905b261ecSmrg	length = widthBytesLine * height;
221005b261ecSmrg
221105b261ecSmrg    }
221205b261ecSmrg    else
221305b261ecSmrg    {
221405b261ecSmrg	widthBytesLine = BitmapBytePad(width);
221505b261ecSmrg	plane = ((Mask)1) << (pDraw->depth - 1);
221605b261ecSmrg	/* only planes asked for */
221705b261ecSmrg	length = widthBytesLine * height *
221805b261ecSmrg		 Ones(planemask & (plane | (plane - 1)));
221905b261ecSmrg
222005b261ecSmrg    }
222105b261ecSmrg
222205b261ecSmrg    xgi.length = length;
222305b261ecSmrg
222405b261ecSmrg    if (im_return) {
222505b261ecSmrg	pBuf = (char *)xalloc(sz_xGetImageReply + length);
222605b261ecSmrg	if (!pBuf)
222705b261ecSmrg	    return (BadAlloc);
222805b261ecSmrg	if (widthBytesLine == 0)
222905b261ecSmrg	    linesPerBuf = 0;
223005b261ecSmrg	else
223105b261ecSmrg	    linesPerBuf = height;
223205b261ecSmrg	*im_return = (xGetImageReply *)pBuf;
223305b261ecSmrg	*(xGetImageReply *)pBuf = xgi;
223405b261ecSmrg	pBuf += sz_xGetImageReply;
223505b261ecSmrg    } else {
223605b261ecSmrg	xgi.length = (xgi.length + 3) >> 2;
223705b261ecSmrg	if (widthBytesLine == 0 || height == 0)
223805b261ecSmrg	    linesPerBuf = 0;
223905b261ecSmrg	else if (widthBytesLine >= IMAGE_BUFSIZE)
224005b261ecSmrg	    linesPerBuf = 1;
224105b261ecSmrg	else
224205b261ecSmrg	{
224305b261ecSmrg	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
224405b261ecSmrg	    if (linesPerBuf > height)
224505b261ecSmrg		linesPerBuf = height;
224605b261ecSmrg	}
224705b261ecSmrg	length = linesPerBuf * widthBytesLine;
224805b261ecSmrg	if (linesPerBuf < height)
224905b261ecSmrg	{
225005b261ecSmrg	    /* we have to make sure intermediate buffers don't need padding */
225105b261ecSmrg	    while ((linesPerBuf > 1) &&
225205b261ecSmrg		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
225305b261ecSmrg	    {
225405b261ecSmrg		linesPerBuf--;
225505b261ecSmrg		length -= widthBytesLine;
225605b261ecSmrg	    }
225705b261ecSmrg	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
225805b261ecSmrg	    {
225905b261ecSmrg		linesPerBuf++;
226005b261ecSmrg		length += widthBytesLine;
226105b261ecSmrg	    }
226205b261ecSmrg	}
226305b261ecSmrg	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
226405b261ecSmrg	    return (BadAlloc);
226505b261ecSmrg	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
226605b261ecSmrg    }
226705b261ecSmrg
226805b261ecSmrg    if (pDraw->type == DRAWABLE_WINDOW &&
226905b261ecSmrg	!XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw))
227005b261ecSmrg    {
227105b261ecSmrg	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
227205b261ecSmrg	if (pVisibleRegion)
227305b261ecSmrg	{
227405b261ecSmrg	    REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion,
227505b261ecSmrg			     -pDraw->x, -pDraw->y);
227605b261ecSmrg	}
227705b261ecSmrg    }
227805b261ecSmrg
227905b261ecSmrg    if (linesPerBuf == 0)
228005b261ecSmrg    {
228105b261ecSmrg	/* nothing to do */
228205b261ecSmrg    }
228305b261ecSmrg    else if (format == ZPixmap)
228405b261ecSmrg    {
228505b261ecSmrg        linesDone = 0;
228605b261ecSmrg        while (height - linesDone > 0)
228705b261ecSmrg        {
228805b261ecSmrg	    nlines = min(linesPerBuf, height - linesDone);
228905b261ecSmrg	    (*pDraw->pScreen->GetImage) (pDraw,
229005b261ecSmrg	                                 x,
229105b261ecSmrg				         y + linesDone,
229205b261ecSmrg				         width,
229305b261ecSmrg				         nlines,
229405b261ecSmrg				         format,
229505b261ecSmrg				         planemask,
229605b261ecSmrg				         (pointer) pBuf);
229705b261ecSmrg	    if (pVisibleRegion)
229805b261ecSmrg		XaceCensorImage(client, pVisibleRegion, widthBytesLine,
229905b261ecSmrg			pDraw, x, y + linesDone, width,
230005b261ecSmrg			nlines, format, pBuf);
230105b261ecSmrg
230205b261ecSmrg	    /* Note that this is NOT a call to WriteSwappedDataToClient,
230305b261ecSmrg               as we do NOT byte swap */
230405b261ecSmrg	    if (!im_return)
230505b261ecSmrg	    {
230605b261ecSmrg		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
230705b261ecSmrg			       BitsPerPixel (pDraw->depth),
230805b261ecSmrg			       ClientOrder(client));
230905b261ecSmrg
231005b261ecSmrg/* Don't split me, gcc pukes when you do */
231105b261ecSmrg		(void)WriteToClient(client,
231205b261ecSmrg				    (int)(nlines * widthBytesLine),
231305b261ecSmrg				    pBuf);
231405b261ecSmrg	    }
231505b261ecSmrg	    linesDone += nlines;
231605b261ecSmrg        }
231705b261ecSmrg    }
231805b261ecSmrg    else /* XYPixmap */
231905b261ecSmrg    {
232005b261ecSmrg        for (; plane; plane >>= 1)
232105b261ecSmrg	{
232205b261ecSmrg	    if (planemask & plane)
232305b261ecSmrg	    {
232405b261ecSmrg	        linesDone = 0;
232505b261ecSmrg	        while (height - linesDone > 0)
232605b261ecSmrg	        {
232705b261ecSmrg		    nlines = min(linesPerBuf, height - linesDone);
232805b261ecSmrg	            (*pDraw->pScreen->GetImage) (pDraw,
232905b261ecSmrg	                                         x,
233005b261ecSmrg				                 y + linesDone,
233105b261ecSmrg				                 width,
233205b261ecSmrg				                 nlines,
233305b261ecSmrg				                 format,
233405b261ecSmrg				                 plane,
233505b261ecSmrg				                 (pointer)pBuf);
233605b261ecSmrg		    if (pVisibleRegion)
233705b261ecSmrg			XaceCensorImage(client, pVisibleRegion,
233805b261ecSmrg				widthBytesLine,
233905b261ecSmrg				pDraw, x, y + linesDone, width,
234005b261ecSmrg				nlines, format, pBuf);
234105b261ecSmrg
234205b261ecSmrg		    /* Note: NOT a call to WriteSwappedDataToClient,
234305b261ecSmrg		       as we do NOT byte swap */
234405b261ecSmrg		    if (im_return) {
234505b261ecSmrg			pBuf += nlines * widthBytesLine;
234605b261ecSmrg		    } else {
234705b261ecSmrg			ReformatImage (pBuf,
234805b261ecSmrg				       (int)(nlines * widthBytesLine),
234905b261ecSmrg				       1,
235005b261ecSmrg				       ClientOrder (client));
235105b261ecSmrg
235205b261ecSmrg/* Don't split me, gcc pukes when you do */
235305b261ecSmrg			(void)WriteToClient(client,
235405b261ecSmrg					(int)(nlines * widthBytesLine),
235505b261ecSmrg					pBuf);
235605b261ecSmrg		    }
235705b261ecSmrg		    linesDone += nlines;
235805b261ecSmrg		}
235905b261ecSmrg            }
236005b261ecSmrg	}
236105b261ecSmrg    }
236205b261ecSmrg    if (pVisibleRegion)
236305b261ecSmrg	REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
236405b261ecSmrg    if (!im_return)
236505b261ecSmrg	DEALLOCATE_LOCAL(pBuf);
236605b261ecSmrg    return (client->noClientException);
236705b261ecSmrg}
236805b261ecSmrg
236905b261ecSmrgint
237005b261ecSmrgProcGetImage(ClientPtr client)
237105b261ecSmrg{
237205b261ecSmrg    REQUEST(xGetImageReq);
237305b261ecSmrg
237405b261ecSmrg    REQUEST_SIZE_MATCH(xGetImageReq);
237505b261ecSmrg
237605b261ecSmrg    return DoGetImage(client, stuff->format, stuff->drawable,
237705b261ecSmrg		      stuff->x, stuff->y,
237805b261ecSmrg		      (int)stuff->width, (int)stuff->height,
237905b261ecSmrg		      stuff->planeMask, (xGetImageReply **)NULL);
238005b261ecSmrg}
238105b261ecSmrg
238205b261ecSmrgint
238305b261ecSmrgProcPolyText(ClientPtr client)
238405b261ecSmrg{
238505b261ecSmrg    int	err;
238605b261ecSmrg    REQUEST(xPolyTextReq);
238705b261ecSmrg    DrawablePtr pDraw;
238805b261ecSmrg    GC *pGC;
238905b261ecSmrg
239005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
239105b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
239205b261ecSmrg
239305b261ecSmrg    err = PolyText(client,
239405b261ecSmrg		   pDraw,
239505b261ecSmrg		   pGC,
239605b261ecSmrg		   (unsigned char *)&stuff[1],
239705b261ecSmrg		   ((unsigned char *) stuff) + (client->req_len << 2),
239805b261ecSmrg		   stuff->x,
239905b261ecSmrg		   stuff->y,
240005b261ecSmrg		   stuff->reqType,
240105b261ecSmrg		   stuff->drawable);
240205b261ecSmrg
240305b261ecSmrg    if (err == Success)
240405b261ecSmrg    {
240505b261ecSmrg	return(client->noClientException);
240605b261ecSmrg    }
240705b261ecSmrg    else
240805b261ecSmrg	return err;
240905b261ecSmrg}
241005b261ecSmrg
241105b261ecSmrgint
241205b261ecSmrgProcImageText8(ClientPtr client)
241305b261ecSmrg{
241405b261ecSmrg    int	err;
241505b261ecSmrg    DrawablePtr pDraw;
241605b261ecSmrg    GC *pGC;
241705b261ecSmrg
241805b261ecSmrg    REQUEST(xImageTextReq);
241905b261ecSmrg
242005b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
242105b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
242205b261ecSmrg
242305b261ecSmrg    err = ImageText(client,
242405b261ecSmrg		    pDraw,
242505b261ecSmrg		    pGC,
242605b261ecSmrg		    stuff->nChars,
242705b261ecSmrg		    (unsigned char *)&stuff[1],
242805b261ecSmrg		    stuff->x,
242905b261ecSmrg		    stuff->y,
243005b261ecSmrg		    stuff->reqType,
243105b261ecSmrg		    stuff->drawable);
243205b261ecSmrg
243305b261ecSmrg    if (err == Success)
243405b261ecSmrg    {
243505b261ecSmrg	return(client->noClientException);
243605b261ecSmrg    }
243705b261ecSmrg    else
243805b261ecSmrg	return err;
243905b261ecSmrg}
244005b261ecSmrg
244105b261ecSmrgint
244205b261ecSmrgProcImageText16(ClientPtr client)
244305b261ecSmrg{
244405b261ecSmrg    int	err;
244505b261ecSmrg    DrawablePtr pDraw;
244605b261ecSmrg    GC *pGC;
244705b261ecSmrg
244805b261ecSmrg    REQUEST(xImageTextReq);
244905b261ecSmrg
245005b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
245105b261ecSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
245205b261ecSmrg
245305b261ecSmrg    err = ImageText(client,
245405b261ecSmrg		    pDraw,
245505b261ecSmrg		    pGC,
245605b261ecSmrg		    stuff->nChars,
245705b261ecSmrg		    (unsigned char *)&stuff[1],
245805b261ecSmrg		    stuff->x,
245905b261ecSmrg		    stuff->y,
246005b261ecSmrg		    stuff->reqType,
246105b261ecSmrg		    stuff->drawable);
246205b261ecSmrg
246305b261ecSmrg    if (err == Success)
246405b261ecSmrg    {
246505b261ecSmrg	return(client->noClientException);
246605b261ecSmrg    }
246705b261ecSmrg    else
246805b261ecSmrg	return err;
246905b261ecSmrg}
247005b261ecSmrg
247105b261ecSmrg
247205b261ecSmrgint
247305b261ecSmrgProcCreateColormap(ClientPtr client)
247405b261ecSmrg{
247505b261ecSmrg    VisualPtr	pVisual;
247605b261ecSmrg    ColormapPtr	pmap;
247705b261ecSmrg    Colormap	mid;
247805b261ecSmrg    WindowPtr   pWin;
247905b261ecSmrg    ScreenPtr pScreen;
248005b261ecSmrg    REQUEST(xCreateColormapReq);
248105b261ecSmrg    int i, result;
248205b261ecSmrg
248305b261ecSmrg    REQUEST_SIZE_MATCH(xCreateColormapReq);
248405b261ecSmrg
248505b261ecSmrg    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
248605b261ecSmrg    {
248705b261ecSmrg	client->errorValue = stuff->alloc;
248805b261ecSmrg        return(BadValue);
248905b261ecSmrg    }
249005b261ecSmrg    mid = stuff->mid;
249105b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
249205b261ecSmrg    result = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
249305b261ecSmrg    if (result != Success)
249405b261ecSmrg        return result;
249505b261ecSmrg
249605b261ecSmrg    pScreen = pWin->drawable.pScreen;
249705b261ecSmrg    for (i = 0, pVisual = pScreen->visuals;
249805b261ecSmrg	 i < pScreen->numVisuals;
249905b261ecSmrg	 i++, pVisual++)
250005b261ecSmrg    {
250105b261ecSmrg	if (pVisual->vid != stuff->visual)
250205b261ecSmrg	    continue;
250305b261ecSmrg	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
250405b261ecSmrg				 (int)stuff->alloc, client->index);
250505b261ecSmrg	if (client->noClientException != Success)
250605b261ecSmrg	    return(client->noClientException);
250705b261ecSmrg	else
250805b261ecSmrg	    return(result);
250905b261ecSmrg    }
251005b261ecSmrg    client->errorValue = stuff->visual;
251105b261ecSmrg    return(BadMatch);
251205b261ecSmrg}
251305b261ecSmrg
251405b261ecSmrgint
251505b261ecSmrgProcFreeColormap(ClientPtr client)
251605b261ecSmrg{
251705b261ecSmrg    ColormapPtr pmap;
251805b261ecSmrg    REQUEST(xResourceReq);
251905b261ecSmrg
252005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
252105b261ecSmrg    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
252205b261ecSmrg						DixDestroyAccess);
252305b261ecSmrg    if (pmap)
252405b261ecSmrg    {
252505b261ecSmrg	/* Freeing a default colormap is a no-op */
252605b261ecSmrg	if (!(pmap->flags & IsDefault))
252705b261ecSmrg	    FreeResource(stuff->id, RT_NONE);
252805b261ecSmrg	return (client->noClientException);
252905b261ecSmrg    }
253005b261ecSmrg    else
253105b261ecSmrg    {
253205b261ecSmrg	client->errorValue = stuff->id;
253305b261ecSmrg	return (BadColor);
253405b261ecSmrg    }
253505b261ecSmrg}
253605b261ecSmrg
253705b261ecSmrg
253805b261ecSmrgint
253905b261ecSmrgProcCopyColormapAndFree(ClientPtr client)
254005b261ecSmrg{
254105b261ecSmrg    Colormap	mid;
254205b261ecSmrg    ColormapPtr	pSrcMap;
254305b261ecSmrg    REQUEST(xCopyColormapAndFreeReq);
254405b261ecSmrg    int result;
254505b261ecSmrg
254605b261ecSmrg    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
254705b261ecSmrg    mid = stuff->mid;
254805b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
254905b261ecSmrg    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
255005b261ecSmrg		RT_COLORMAP, DixReadAccess|DixWriteAccess)) )
255105b261ecSmrg    {
255205b261ecSmrg	result = CopyColormapAndFree(mid, pSrcMap, client->index);
255305b261ecSmrg	if (client->noClientException != Success)
255405b261ecSmrg            return(client->noClientException);
255505b261ecSmrg	else
255605b261ecSmrg            return(result);
255705b261ecSmrg    }
255805b261ecSmrg    else
255905b261ecSmrg    {
256005b261ecSmrg	client->errorValue = stuff->srcCmap;
256105b261ecSmrg	return(BadColor);
256205b261ecSmrg    }
256305b261ecSmrg}
256405b261ecSmrg
256505b261ecSmrgint
256605b261ecSmrgProcInstallColormap(ClientPtr client)
256705b261ecSmrg{
256805b261ecSmrg    ColormapPtr pcmp;
256905b261ecSmrg    REQUEST(xResourceReq);
257005b261ecSmrg
257105b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
257205b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
257305b261ecSmrg					    RT_COLORMAP, DixReadAccess);
257405b261ecSmrg    if (pcmp)
257505b261ecSmrg    {
257605b261ecSmrg        (*(pcmp->pScreen->InstallColormap)) (pcmp);
257705b261ecSmrg        return (client->noClientException);
257805b261ecSmrg    }
257905b261ecSmrg    else
258005b261ecSmrg    {
258105b261ecSmrg        client->errorValue = stuff->id;
258205b261ecSmrg        return (BadColor);
258305b261ecSmrg    }
258405b261ecSmrg}
258505b261ecSmrg
258605b261ecSmrgint
258705b261ecSmrgProcUninstallColormap(ClientPtr client)
258805b261ecSmrg{
258905b261ecSmrg    ColormapPtr pcmp;
259005b261ecSmrg    REQUEST(xResourceReq);
259105b261ecSmrg
259205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
259305b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
259405b261ecSmrg					RT_COLORMAP, DixReadAccess);
259505b261ecSmrg    if (pcmp)
259605b261ecSmrg    {
259705b261ecSmrg	if(pcmp->mid != pcmp->pScreen->defColormap)
259805b261ecSmrg            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
259905b261ecSmrg        return (client->noClientException);
260005b261ecSmrg    }
260105b261ecSmrg    else
260205b261ecSmrg    {
260305b261ecSmrg        client->errorValue = stuff->id;
260405b261ecSmrg        return (BadColor);
260505b261ecSmrg    }
260605b261ecSmrg}
260705b261ecSmrg
260805b261ecSmrgint
260905b261ecSmrgProcListInstalledColormaps(ClientPtr client)
261005b261ecSmrg{
261105b261ecSmrg    xListInstalledColormapsReply *preply;
261205b261ecSmrg    int nummaps, rc;
261305b261ecSmrg    WindowPtr pWin;
261405b261ecSmrg    REQUEST(xResourceReq);
261505b261ecSmrg
261605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
261705b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
261805b261ecSmrg    if (rc != Success)
261905b261ecSmrg        return rc;
262005b261ecSmrg
262105b261ecSmrg    preply = (xListInstalledColormapsReply *)
262205b261ecSmrg		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
262305b261ecSmrg		     pWin->drawable.pScreen->maxInstalledCmaps *
262405b261ecSmrg		     sizeof(Colormap));
262505b261ecSmrg    if(!preply)
262605b261ecSmrg        return(BadAlloc);
262705b261ecSmrg
262805b261ecSmrg    preply->type = X_Reply;
262905b261ecSmrg    preply->sequenceNumber = client->sequence;
263005b261ecSmrg    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
263105b261ecSmrg        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
263205b261ecSmrg    preply->nColormaps = nummaps;
263305b261ecSmrg    preply->length = nummaps;
263405b261ecSmrg    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
263505b261ecSmrg    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
263605b261ecSmrg    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
263705b261ecSmrg    DEALLOCATE_LOCAL(preply);
263805b261ecSmrg    return(client->noClientException);
263905b261ecSmrg}
264005b261ecSmrg
264105b261ecSmrgint
264205b261ecSmrgProcAllocColor (ClientPtr client)
264305b261ecSmrg{
264405b261ecSmrg    ColormapPtr pmap;
264505b261ecSmrg    int	retval;
264605b261ecSmrg    xAllocColorReply acr;
264705b261ecSmrg    REQUEST(xAllocColorReq);
264805b261ecSmrg
264905b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorReq);
265005b261ecSmrg    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
265105b261ecSmrg					RT_COLORMAP, DixWriteAccess);
265205b261ecSmrg    if (pmap)
265305b261ecSmrg    {
265405b261ecSmrg	acr.type = X_Reply;
265505b261ecSmrg	acr.length = 0;
265605b261ecSmrg	acr.sequenceNumber = client->sequence;
265705b261ecSmrg	acr.red = stuff->red;
265805b261ecSmrg	acr.green = stuff->green;
265905b261ecSmrg	acr.blue = stuff->blue;
266005b261ecSmrg	acr.pixel = 0;
266105b261ecSmrg	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
266205b261ecSmrg	                       &acr.pixel, client->index)) )
266305b261ecSmrg	{
266405b261ecSmrg            if (client->noClientException != Success)
266505b261ecSmrg                return(client->noClientException);
266605b261ecSmrg	    else
266705b261ecSmrg	        return (retval);
266805b261ecSmrg	}
266905b261ecSmrg#ifdef PANORAMIX
267005b261ecSmrg	if (noPanoramiXExtension || !pmap->pScreen->myNum)
267105b261ecSmrg#endif
267205b261ecSmrg        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
267305b261ecSmrg	return (client->noClientException);
267405b261ecSmrg
267505b261ecSmrg    }
267605b261ecSmrg    else
267705b261ecSmrg    {
267805b261ecSmrg        client->errorValue = stuff->cmap;
267905b261ecSmrg        return (BadColor);
268005b261ecSmrg    }
268105b261ecSmrg}
268205b261ecSmrg
268305b261ecSmrgint
268405b261ecSmrgProcAllocNamedColor (ClientPtr client)
268505b261ecSmrg{
268605b261ecSmrg    ColormapPtr pcmp;
268705b261ecSmrg    REQUEST(xAllocNamedColorReq);
268805b261ecSmrg
268905b261ecSmrg    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
269005b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
269105b261ecSmrg					    RT_COLORMAP, DixWriteAccess);
269205b261ecSmrg    if (pcmp)
269305b261ecSmrg    {
269405b261ecSmrg	int		retval;
269505b261ecSmrg
269605b261ecSmrg	xAllocNamedColorReply ancr;
269705b261ecSmrg
269805b261ecSmrg	ancr.type = X_Reply;
269905b261ecSmrg	ancr.length = 0;
270005b261ecSmrg	ancr.sequenceNumber = client->sequence;
270105b261ecSmrg
270205b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
270305b261ecSmrg	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
270405b261ecSmrg	{
270505b261ecSmrg	    ancr.screenRed = ancr.exactRed;
270605b261ecSmrg	    ancr.screenGreen = ancr.exactGreen;
270705b261ecSmrg	    ancr.screenBlue = ancr.exactBlue;
270805b261ecSmrg	    ancr.pixel = 0;
270905b261ecSmrg	    if( (retval = AllocColor(pcmp,
271005b261ecSmrg	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
271105b261ecSmrg			 &ancr.pixel, client->index)) )
271205b261ecSmrg	    {
271305b261ecSmrg                if (client->noClientException != Success)
271405b261ecSmrg                    return(client->noClientException);
271505b261ecSmrg                else
271605b261ecSmrg    	            return(retval);
271705b261ecSmrg	    }
271805b261ecSmrg#ifdef PANORAMIX
271905b261ecSmrg	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
272005b261ecSmrg#endif
272105b261ecSmrg            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
272205b261ecSmrg	    return (client->noClientException);
272305b261ecSmrg	}
272405b261ecSmrg	else
272505b261ecSmrg	    return(BadName);
272605b261ecSmrg
272705b261ecSmrg    }
272805b261ecSmrg    else
272905b261ecSmrg    {
273005b261ecSmrg        client->errorValue = stuff->cmap;
273105b261ecSmrg        return (BadColor);
273205b261ecSmrg    }
273305b261ecSmrg}
273405b261ecSmrg
273505b261ecSmrgint
273605b261ecSmrgProcAllocColorCells (ClientPtr client)
273705b261ecSmrg{
273805b261ecSmrg    ColormapPtr pcmp;
273905b261ecSmrg    REQUEST(xAllocColorCellsReq);
274005b261ecSmrg
274105b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
274205b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
274305b261ecSmrg					RT_COLORMAP, DixWriteAccess);
274405b261ecSmrg    if (pcmp)
274505b261ecSmrg    {
274605b261ecSmrg	xAllocColorCellsReply	accr;
274705b261ecSmrg	int			npixels, nmasks, retval;
274805b261ecSmrg	long			length;
274905b261ecSmrg	Pixel			*ppixels, *pmasks;
275005b261ecSmrg
275105b261ecSmrg	npixels = stuff->colors;
275205b261ecSmrg	if (!npixels)
275305b261ecSmrg	{
275405b261ecSmrg	    client->errorValue = npixels;
275505b261ecSmrg	    return (BadValue);
275605b261ecSmrg	}
275705b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
275805b261ecSmrg	{
275905b261ecSmrg	    client->errorValue = stuff->contiguous;
276005b261ecSmrg	    return (BadValue);
276105b261ecSmrg	}
276205b261ecSmrg	nmasks = stuff->planes;
276305b261ecSmrg	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
276405b261ecSmrg	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
276505b261ecSmrg	if(!ppixels)
276605b261ecSmrg            return(BadAlloc);
276705b261ecSmrg	pmasks = ppixels + npixels;
276805b261ecSmrg
276905b261ecSmrg	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
277005b261ecSmrg				    (Bool)stuff->contiguous, ppixels, pmasks)) )
277105b261ecSmrg	{
277205b261ecSmrg	    DEALLOCATE_LOCAL(ppixels);
277305b261ecSmrg            if (client->noClientException != Success)
277405b261ecSmrg                return(client->noClientException);
277505b261ecSmrg	    else
277605b261ecSmrg	        return(retval);
277705b261ecSmrg	}
277805b261ecSmrg#ifdef PANORAMIX
277905b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
278005b261ecSmrg#endif
278105b261ecSmrg	{
278205b261ecSmrg	    accr.type = X_Reply;
278305b261ecSmrg	    accr.length = length >> 2;
278405b261ecSmrg	    accr.sequenceNumber = client->sequence;
278505b261ecSmrg	    accr.nPixels = npixels;
278605b261ecSmrg	    accr.nMasks = nmasks;
278705b261ecSmrg	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
278805b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
278905b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
279005b261ecSmrg	}
279105b261ecSmrg	DEALLOCATE_LOCAL(ppixels);
279205b261ecSmrg        return (client->noClientException);
279305b261ecSmrg    }
279405b261ecSmrg    else
279505b261ecSmrg    {
279605b261ecSmrg        client->errorValue = stuff->cmap;
279705b261ecSmrg        return (BadColor);
279805b261ecSmrg    }
279905b261ecSmrg}
280005b261ecSmrg
280105b261ecSmrgint
280205b261ecSmrgProcAllocColorPlanes(ClientPtr client)
280305b261ecSmrg{
280405b261ecSmrg    ColormapPtr pcmp;
280505b261ecSmrg    REQUEST(xAllocColorPlanesReq);
280605b261ecSmrg
280705b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
280805b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
280905b261ecSmrg					RT_COLORMAP, DixWriteAccess);
281005b261ecSmrg    if (pcmp)
281105b261ecSmrg    {
281205b261ecSmrg	xAllocColorPlanesReply	acpr;
281305b261ecSmrg	int			npixels, retval;
281405b261ecSmrg	long			length;
281505b261ecSmrg	Pixel			*ppixels;
281605b261ecSmrg
281705b261ecSmrg	npixels = stuff->colors;
281805b261ecSmrg	if (!npixels)
281905b261ecSmrg	{
282005b261ecSmrg	    client->errorValue = npixels;
282105b261ecSmrg	    return (BadValue);
282205b261ecSmrg	}
282305b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
282405b261ecSmrg	{
282505b261ecSmrg	    client->errorValue = stuff->contiguous;
282605b261ecSmrg	    return (BadValue);
282705b261ecSmrg	}
282805b261ecSmrg	acpr.type = X_Reply;
282905b261ecSmrg	acpr.sequenceNumber = client->sequence;
283005b261ecSmrg	acpr.nPixels = npixels;
283105b261ecSmrg	length = (long)npixels * sizeof(Pixel);
283205b261ecSmrg	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
283305b261ecSmrg	if(!ppixels)
283405b261ecSmrg            return(BadAlloc);
283505b261ecSmrg	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
283605b261ecSmrg	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
283705b261ecSmrg	    (Bool)stuff->contiguous, ppixels,
283805b261ecSmrg	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
283905b261ecSmrg	{
284005b261ecSmrg            DEALLOCATE_LOCAL(ppixels);
284105b261ecSmrg            if (client->noClientException != Success)
284205b261ecSmrg                return(client->noClientException);
284305b261ecSmrg	    else
284405b261ecSmrg	        return(retval);
284505b261ecSmrg	}
284605b261ecSmrg	acpr.length = length >> 2;
284705b261ecSmrg#ifdef PANORAMIX
284805b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
284905b261ecSmrg#endif
285005b261ecSmrg	{
285105b261ecSmrg	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
285205b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
285305b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
285405b261ecSmrg	}
285505b261ecSmrg	DEALLOCATE_LOCAL(ppixels);
285605b261ecSmrg        return (client->noClientException);
285705b261ecSmrg    }
285805b261ecSmrg    else
285905b261ecSmrg    {
286005b261ecSmrg        client->errorValue = stuff->cmap;
286105b261ecSmrg        return (BadColor);
286205b261ecSmrg    }
286305b261ecSmrg}
286405b261ecSmrg
286505b261ecSmrgint
286605b261ecSmrgProcFreeColors(ClientPtr client)
286705b261ecSmrg{
286805b261ecSmrg    ColormapPtr pcmp;
286905b261ecSmrg    REQUEST(xFreeColorsReq);
287005b261ecSmrg
287105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
287205b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
287305b261ecSmrg					RT_COLORMAP, DixWriteAccess);
287405b261ecSmrg    if (pcmp)
287505b261ecSmrg    {
287605b261ecSmrg	int	count;
287705b261ecSmrg        int     retval;
287805b261ecSmrg
287905b261ecSmrg	if(pcmp->flags & AllAllocated)
288005b261ecSmrg	    return(BadAccess);
288105b261ecSmrg	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
288205b261ecSmrg	retval =  FreeColors(pcmp, client->index, count,
288305b261ecSmrg	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
288405b261ecSmrg        if (client->noClientException != Success)
288505b261ecSmrg            return(client->noClientException);
288605b261ecSmrg        else
288705b261ecSmrg	{
288805b261ecSmrg	    client->errorValue = clientErrorValue;
288905b261ecSmrg            return(retval);
289005b261ecSmrg	}
289105b261ecSmrg
289205b261ecSmrg    }
289305b261ecSmrg    else
289405b261ecSmrg    {
289505b261ecSmrg        client->errorValue = stuff->cmap;
289605b261ecSmrg        return (BadColor);
289705b261ecSmrg    }
289805b261ecSmrg}
289905b261ecSmrg
290005b261ecSmrgint
290105b261ecSmrgProcStoreColors (ClientPtr client)
290205b261ecSmrg{
290305b261ecSmrg    ColormapPtr pcmp;
290405b261ecSmrg    REQUEST(xStoreColorsReq);
290505b261ecSmrg
290605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
290705b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
290805b261ecSmrg					RT_COLORMAP, DixWriteAccess);
290905b261ecSmrg    if (pcmp)
291005b261ecSmrg    {
291105b261ecSmrg	int	count;
291205b261ecSmrg        int     retval;
291305b261ecSmrg
291405b261ecSmrg        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
291505b261ecSmrg	if (count % sizeof(xColorItem))
291605b261ecSmrg	    return(BadLength);
291705b261ecSmrg	count /= sizeof(xColorItem);
291805b261ecSmrg	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
291905b261ecSmrg        if (client->noClientException != Success)
292005b261ecSmrg            return(client->noClientException);
292105b261ecSmrg        else
292205b261ecSmrg	{
292305b261ecSmrg	    client->errorValue = clientErrorValue;
292405b261ecSmrg            return(retval);
292505b261ecSmrg	}
292605b261ecSmrg    }
292705b261ecSmrg    else
292805b261ecSmrg    {
292905b261ecSmrg        client->errorValue = stuff->cmap;
293005b261ecSmrg        return (BadColor);
293105b261ecSmrg    }
293205b261ecSmrg}
293305b261ecSmrg
293405b261ecSmrgint
293505b261ecSmrgProcStoreNamedColor (ClientPtr client)
293605b261ecSmrg{
293705b261ecSmrg    ColormapPtr pcmp;
293805b261ecSmrg    REQUEST(xStoreNamedColorReq);
293905b261ecSmrg
294005b261ecSmrg    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
294105b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
294205b261ecSmrg					RT_COLORMAP, DixWriteAccess);
294305b261ecSmrg    if (pcmp)
294405b261ecSmrg    {
294505b261ecSmrg	xColorItem	def;
294605b261ecSmrg        int             retval;
294705b261ecSmrg
294805b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
294905b261ecSmrg	                 stuff->nbytes, &def.red, &def.green, &def.blue))
295005b261ecSmrg	{
295105b261ecSmrg	    def.flags = stuff->flags;
295205b261ecSmrg	    def.pixel = stuff->pixel;
295305b261ecSmrg	    retval = StoreColors(pcmp, 1, &def);
295405b261ecSmrg            if (client->noClientException != Success)
295505b261ecSmrg                return(client->noClientException);
295605b261ecSmrg	    else
295705b261ecSmrg		return(retval);
295805b261ecSmrg	}
295905b261ecSmrg        return (BadName);
296005b261ecSmrg    }
296105b261ecSmrg    else
296205b261ecSmrg    {
296305b261ecSmrg        client->errorValue = stuff->cmap;
296405b261ecSmrg        return (BadColor);
296505b261ecSmrg    }
296605b261ecSmrg}
296705b261ecSmrg
296805b261ecSmrgint
296905b261ecSmrgProcQueryColors(ClientPtr client)
297005b261ecSmrg{
297105b261ecSmrg    ColormapPtr pcmp;
297205b261ecSmrg    REQUEST(xQueryColorsReq);
297305b261ecSmrg
297405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
297505b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
297605b261ecSmrg					RT_COLORMAP, DixReadAccess);
297705b261ecSmrg    if (pcmp)
297805b261ecSmrg    {
297905b261ecSmrg	int			count, retval;
298005b261ecSmrg	xrgb 			*prgbs;
298105b261ecSmrg	xQueryColorsReply	qcr;
298205b261ecSmrg
298305b261ecSmrg	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
298405b261ecSmrg	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
298505b261ecSmrg	if(!prgbs && count)
298605b261ecSmrg            return(BadAlloc);
298705b261ecSmrg	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
298805b261ecSmrg	{
298905b261ecSmrg   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
299005b261ecSmrg	    if (client->noClientException != Success)
299105b261ecSmrg                return(client->noClientException);
299205b261ecSmrg	    else
299305b261ecSmrg	    {
299405b261ecSmrg		client->errorValue = clientErrorValue;
299505b261ecSmrg	        return (retval);
299605b261ecSmrg	    }
299705b261ecSmrg	}
299805b261ecSmrg	qcr.type = X_Reply;
299905b261ecSmrg	qcr.length = (count * sizeof(xrgb)) >> 2;
300005b261ecSmrg	qcr.sequenceNumber = client->sequence;
300105b261ecSmrg	qcr.nColors = count;
300205b261ecSmrg	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
300305b261ecSmrg	if (count)
300405b261ecSmrg	{
300505b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
300605b261ecSmrg	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
300705b261ecSmrg	}
300805b261ecSmrg	if (prgbs) DEALLOCATE_LOCAL(prgbs);
300905b261ecSmrg	return(client->noClientException);
301005b261ecSmrg
301105b261ecSmrg    }
301205b261ecSmrg    else
301305b261ecSmrg    {
301405b261ecSmrg        client->errorValue = stuff->cmap;
301505b261ecSmrg        return (BadColor);
301605b261ecSmrg    }
301705b261ecSmrg}
301805b261ecSmrg
301905b261ecSmrgint
302005b261ecSmrgProcLookupColor(ClientPtr client)
302105b261ecSmrg{
302205b261ecSmrg    ColormapPtr pcmp;
302305b261ecSmrg    REQUEST(xLookupColorReq);
302405b261ecSmrg
302505b261ecSmrg    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
302605b261ecSmrg    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
302705b261ecSmrg					RT_COLORMAP, DixReadAccess);
302805b261ecSmrg    if (pcmp)
302905b261ecSmrg    {
303005b261ecSmrg	xLookupColorReply lcr;
303105b261ecSmrg
303205b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
303305b261ecSmrg	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
303405b261ecSmrg	{
303505b261ecSmrg	    lcr.type = X_Reply;
303605b261ecSmrg	    lcr.length = 0;
303705b261ecSmrg	    lcr.sequenceNumber = client->sequence;
303805b261ecSmrg	    lcr.screenRed = lcr.exactRed;
303905b261ecSmrg	    lcr.screenGreen = lcr.exactGreen;
304005b261ecSmrg	    lcr.screenBlue = lcr.exactBlue;
304105b261ecSmrg	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
304205b261ecSmrg	                                   &lcr.screenGreen,
304305b261ecSmrg					   &lcr.screenBlue,
304405b261ecSmrg					   pcmp->pVisual);
304505b261ecSmrg	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
304605b261ecSmrg	    return(client->noClientException);
304705b261ecSmrg	}
304805b261ecSmrg        return (BadName);
304905b261ecSmrg    }
305005b261ecSmrg    else
305105b261ecSmrg    {
305205b261ecSmrg        client->errorValue = stuff->cmap;
305305b261ecSmrg        return (BadColor);
305405b261ecSmrg    }
305505b261ecSmrg}
305605b261ecSmrg
305705b261ecSmrgint
305805b261ecSmrgProcCreateCursor (ClientPtr client)
305905b261ecSmrg{
306005b261ecSmrg    CursorPtr		pCursor;
306105b261ecSmrg    PixmapPtr 		src;
306205b261ecSmrg    PixmapPtr 		msk;
306305b261ecSmrg    unsigned char *	srcbits;
306405b261ecSmrg    unsigned char *	mskbits;
306505b261ecSmrg    unsigned short	width, height;
306605b261ecSmrg    long		n;
306705b261ecSmrg    CursorMetricRec 	cm;
306805b261ecSmrg
306905b261ecSmrg
307005b261ecSmrg    REQUEST(xCreateCursorReq);
307105b261ecSmrg
307205b261ecSmrg    REQUEST_SIZE_MATCH(xCreateCursorReq);
307305b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
307405b261ecSmrg
307505b261ecSmrg    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
307605b261ecSmrg					      RT_PIXMAP, DixReadAccess);
307705b261ecSmrg    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
307805b261ecSmrg					      RT_PIXMAP, DixReadAccess);
307905b261ecSmrg    if (   src == (PixmapPtr)NULL)
308005b261ecSmrg    {
308105b261ecSmrg	client->errorValue = stuff->source;
308205b261ecSmrg	return (BadPixmap);
308305b261ecSmrg    }
308405b261ecSmrg    if ( msk == (PixmapPtr)NULL)
308505b261ecSmrg    {
308605b261ecSmrg	if (stuff->mask != None)
308705b261ecSmrg	{
308805b261ecSmrg	    client->errorValue = stuff->mask;
308905b261ecSmrg	    return (BadPixmap);
309005b261ecSmrg	}
309105b261ecSmrg    }
309205b261ecSmrg    else if (  src->drawable.width != msk->drawable.width
309305b261ecSmrg	    || src->drawable.height != msk->drawable.height
309405b261ecSmrg	    || src->drawable.depth != 1
309505b261ecSmrg	    || msk->drawable.depth != 1)
309605b261ecSmrg	return (BadMatch);
309705b261ecSmrg
309805b261ecSmrg    width = src->drawable.width;
309905b261ecSmrg    height = src->drawable.height;
310005b261ecSmrg
310105b261ecSmrg    if ( stuff->x > width
310205b261ecSmrg      || stuff->y > height )
310305b261ecSmrg	return (BadMatch);
310405b261ecSmrg
310505b261ecSmrg    n = BitmapBytePad(width)*height;
310605b261ecSmrg    srcbits = (unsigned char *)xalloc(n);
310705b261ecSmrg    if (!srcbits)
310805b261ecSmrg	return (BadAlloc);
310905b261ecSmrg    mskbits = (unsigned char *)xalloc(n);
311005b261ecSmrg    if (!mskbits)
311105b261ecSmrg    {
311205b261ecSmrg	xfree(srcbits);
311305b261ecSmrg	return (BadAlloc);
311405b261ecSmrg    }
311505b261ecSmrg
311605b261ecSmrg    /* zeroing the (pad) bits helps some ddx cursor handling */
311705b261ecSmrg    bzero((char *)srcbits, n);
311805b261ecSmrg    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
311905b261ecSmrg					 XYPixmap, 1, (pointer)srcbits);
312005b261ecSmrg    if ( msk == (PixmapPtr)NULL)
312105b261ecSmrg    {
312205b261ecSmrg	unsigned char *bits = mskbits;
312305b261ecSmrg	while (--n >= 0)
312405b261ecSmrg	    *bits++ = ~0;
312505b261ecSmrg    }
312605b261ecSmrg    else
312705b261ecSmrg    {
312805b261ecSmrg	/* zeroing the (pad) bits helps some ddx cursor handling */
312905b261ecSmrg	bzero((char *)mskbits, n);
313005b261ecSmrg	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
313105b261ecSmrg					height, XYPixmap, 1, (pointer)mskbits);
313205b261ecSmrg    }
313305b261ecSmrg    cm.width = width;
313405b261ecSmrg    cm.height = height;
313505b261ecSmrg    cm.xhot = stuff->x;
313605b261ecSmrg    cm.yhot = stuff->y;
313705b261ecSmrg    pCursor = AllocCursor( srcbits, mskbits, &cm,
313805b261ecSmrg	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
313905b261ecSmrg	    stuff->backRed, stuff->backGreen, stuff->backBlue);
314005b261ecSmrg
314105b261ecSmrg    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
314205b261ecSmrg	    return (client->noClientException);
314305b261ecSmrg    return BadAlloc;
314405b261ecSmrg}
314505b261ecSmrg
314605b261ecSmrgint
314705b261ecSmrgProcCreateGlyphCursor (ClientPtr client)
314805b261ecSmrg{
314905b261ecSmrg    CursorPtr pCursor;
315005b261ecSmrg    int res;
315105b261ecSmrg
315205b261ecSmrg    REQUEST(xCreateGlyphCursorReq);
315305b261ecSmrg
315405b261ecSmrg    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
315505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
315605b261ecSmrg
315705b261ecSmrg    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
315805b261ecSmrg			   stuff->mask, stuff->maskChar,
315905b261ecSmrg			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
316005b261ecSmrg			   stuff->backRed, stuff->backGreen, stuff->backBlue,
316105b261ecSmrg			   &pCursor, client);
316205b261ecSmrg    if (res != Success)
316305b261ecSmrg	return res;
316405b261ecSmrg    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
316505b261ecSmrg	return client->noClientException;
316605b261ecSmrg    return BadAlloc;
316705b261ecSmrg}
316805b261ecSmrg
316905b261ecSmrg
317005b261ecSmrgint
317105b261ecSmrgProcFreeCursor (ClientPtr client)
317205b261ecSmrg{
317305b261ecSmrg    CursorPtr pCursor;
317405b261ecSmrg    REQUEST(xResourceReq);
317505b261ecSmrg
317605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
317705b261ecSmrg    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
317805b261ecSmrg					RT_CURSOR, DixDestroyAccess);
317905b261ecSmrg    if (pCursor)
318005b261ecSmrg    {
318105b261ecSmrg	FreeResource(stuff->id, RT_NONE);
318205b261ecSmrg	return (client->noClientException);
318305b261ecSmrg    }
318405b261ecSmrg    else
318505b261ecSmrg    {
318605b261ecSmrg	client->errorValue = stuff->id;
318705b261ecSmrg	return (BadCursor);
318805b261ecSmrg    }
318905b261ecSmrg}
319005b261ecSmrg
319105b261ecSmrgint
319205b261ecSmrgProcQueryBestSize (ClientPtr client)
319305b261ecSmrg{
319405b261ecSmrg    xQueryBestSizeReply	reply;
319505b261ecSmrg    DrawablePtr pDraw;
319605b261ecSmrg    ScreenPtr pScreen;
319705b261ecSmrg    int rc;
319805b261ecSmrg    REQUEST(xQueryBestSizeReq);
319905b261ecSmrg    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
320005b261ecSmrg
320105b261ecSmrg    if ((stuff->class != CursorShape) &&
320205b261ecSmrg	(stuff->class != TileShape) &&
320305b261ecSmrg	(stuff->class != StippleShape))
320405b261ecSmrg    {
320505b261ecSmrg	client->errorValue = stuff->class;
320605b261ecSmrg        return(BadValue);
320705b261ecSmrg    }
320805b261ecSmrg
320905b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
321005b261ecSmrg			   DixReadAccess);
321105b261ecSmrg    if (rc != Success)
321205b261ecSmrg	return rc;
321305b261ecSmrg    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
321405b261ecSmrg	return (BadMatch);
321505b261ecSmrg    pScreen = pDraw->pScreen;
321605b261ecSmrg    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
321705b261ecSmrg			       &stuff->height, pScreen);
321805b261ecSmrg    reply.type = X_Reply;
321905b261ecSmrg    reply.length = 0;
322005b261ecSmrg    reply.sequenceNumber = client->sequence;
322105b261ecSmrg    reply.width = stuff->width;
322205b261ecSmrg    reply.height = stuff->height;
322305b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
322405b261ecSmrg    return (client->noClientException);
322505b261ecSmrg}
322605b261ecSmrg
322705b261ecSmrg
322805b261ecSmrgint
322905b261ecSmrgProcSetScreenSaver (ClientPtr client)
323005b261ecSmrg{
323105b261ecSmrg    int blankingOption, exposureOption;
323205b261ecSmrg    REQUEST(xSetScreenSaverReq);
323305b261ecSmrg
323405b261ecSmrg    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
323505b261ecSmrg    blankingOption = stuff->preferBlank;
323605b261ecSmrg    if ((blankingOption != DontPreferBlanking) &&
323705b261ecSmrg        (blankingOption != PreferBlanking) &&
323805b261ecSmrg        (blankingOption != DefaultBlanking))
323905b261ecSmrg    {
324005b261ecSmrg	client->errorValue = blankingOption;
324105b261ecSmrg        return BadValue;
324205b261ecSmrg    }
324305b261ecSmrg    exposureOption = stuff->allowExpose;
324405b261ecSmrg    if ((exposureOption != DontAllowExposures) &&
324505b261ecSmrg        (exposureOption != AllowExposures) &&
324605b261ecSmrg        (exposureOption != DefaultExposures))
324705b261ecSmrg    {
324805b261ecSmrg	client->errorValue = exposureOption;
324905b261ecSmrg        return BadValue;
325005b261ecSmrg    }
325105b261ecSmrg    if (stuff->timeout < -1)
325205b261ecSmrg    {
325305b261ecSmrg	client->errorValue = stuff->timeout;
325405b261ecSmrg        return BadValue;
325505b261ecSmrg    }
325605b261ecSmrg    if (stuff->interval < -1)
325705b261ecSmrg    {
325805b261ecSmrg	client->errorValue = stuff->interval;
325905b261ecSmrg        return BadValue;
326005b261ecSmrg    }
326105b261ecSmrg
326205b261ecSmrg    if (blankingOption == DefaultBlanking)
326305b261ecSmrg	ScreenSaverBlanking = defaultScreenSaverBlanking;
326405b261ecSmrg    else
326505b261ecSmrg	ScreenSaverBlanking = blankingOption;
326605b261ecSmrg    if (exposureOption == DefaultExposures)
326705b261ecSmrg	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
326805b261ecSmrg    else
326905b261ecSmrg	ScreenSaverAllowExposures = exposureOption;
327005b261ecSmrg
327105b261ecSmrg    if (stuff->timeout >= 0)
327205b261ecSmrg	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
327305b261ecSmrg    else
327405b261ecSmrg	ScreenSaverTime = defaultScreenSaverTime;
327505b261ecSmrg    if (stuff->interval >= 0)
327605b261ecSmrg	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
327705b261ecSmrg    else
327805b261ecSmrg	ScreenSaverInterval = defaultScreenSaverInterval;
327905b261ecSmrg
328005b261ecSmrg    SetScreenSaverTimer();
328105b261ecSmrg    return (client->noClientException);
328205b261ecSmrg}
328305b261ecSmrg
328405b261ecSmrgint
328505b261ecSmrgProcGetScreenSaver(ClientPtr client)
328605b261ecSmrg{
328705b261ecSmrg    xGetScreenSaverReply rep;
328805b261ecSmrg
328905b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
329005b261ecSmrg    rep.type = X_Reply;
329105b261ecSmrg    rep.length = 0;
329205b261ecSmrg    rep.sequenceNumber = client->sequence;
329305b261ecSmrg    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
329405b261ecSmrg    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
329505b261ecSmrg    rep.preferBlanking = ScreenSaverBlanking;
329605b261ecSmrg    rep.allowExposures = ScreenSaverAllowExposures;
329705b261ecSmrg    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
329805b261ecSmrg    return (client->noClientException);
329905b261ecSmrg}
330005b261ecSmrg
330105b261ecSmrgint
330205b261ecSmrgProcChangeHosts(ClientPtr client)
330305b261ecSmrg{
330405b261ecSmrg    REQUEST(xChangeHostsReq);
330505b261ecSmrg    int result;
330605b261ecSmrg
330705b261ecSmrg    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
330805b261ecSmrg
330905b261ecSmrg    if(stuff->mode == HostInsert)
331005b261ecSmrg	result = AddHost(client, (int)stuff->hostFamily,
331105b261ecSmrg			 stuff->hostLength, (pointer)&stuff[1]);
331205b261ecSmrg    else if (stuff->mode == HostDelete)
331305b261ecSmrg	result = RemoveHost(client, (int)stuff->hostFamily,
331405b261ecSmrg			    stuff->hostLength, (pointer)&stuff[1]);
331505b261ecSmrg    else
331605b261ecSmrg    {
331705b261ecSmrg	client->errorValue = stuff->mode;
331805b261ecSmrg        return BadValue;
331905b261ecSmrg    }
332005b261ecSmrg    if (!result)
332105b261ecSmrg	result = client->noClientException;
332205b261ecSmrg    return (result);
332305b261ecSmrg}
332405b261ecSmrg
332505b261ecSmrgint
332605b261ecSmrgProcListHosts(ClientPtr client)
332705b261ecSmrg{
332805b261ecSmrg    xListHostsReply reply;
332905b261ecSmrg    int	len, nHosts, result;
333005b261ecSmrg    pointer	pdata;
333105b261ecSmrg    /* REQUEST(xListHostsReq); */
333205b261ecSmrg
333305b261ecSmrg    REQUEST_SIZE_MATCH(xListHostsReq);
333405b261ecSmrg
333505b261ecSmrg    /* untrusted clients can't list hosts */
333605b261ecSmrg    if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixReadAccess))
333705b261ecSmrg	return BadAccess;
333805b261ecSmrg
333905b261ecSmrg    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
334005b261ecSmrg    if (result != Success)
334105b261ecSmrg	return(result);
334205b261ecSmrg    reply.type = X_Reply;
334305b261ecSmrg    reply.sequenceNumber = client->sequence;
334405b261ecSmrg    reply.nHosts = nHosts;
334505b261ecSmrg    reply.length = len >> 2;
334605b261ecSmrg    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
334705b261ecSmrg    if (nHosts)
334805b261ecSmrg    {
334905b261ecSmrg	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
335005b261ecSmrg	WriteSwappedDataToClient(client, len, pdata);
335105b261ecSmrg    }
335205b261ecSmrg    xfree(pdata);
335305b261ecSmrg    return (client->noClientException);
335405b261ecSmrg}
335505b261ecSmrg
335605b261ecSmrgint
335705b261ecSmrgProcChangeAccessControl(ClientPtr client)
335805b261ecSmrg{
335905b261ecSmrg    int result;
336005b261ecSmrg    REQUEST(xSetAccessControlReq);
336105b261ecSmrg
336205b261ecSmrg    REQUEST_SIZE_MATCH(xSetAccessControlReq);
336305b261ecSmrg    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
336405b261ecSmrg    {
336505b261ecSmrg	client->errorValue = stuff->mode;
336605b261ecSmrg        return BadValue;
336705b261ecSmrg    }
336805b261ecSmrg    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
336905b261ecSmrg    if (!result)
337005b261ecSmrg	result = client->noClientException;
337105b261ecSmrg    return (result);
337205b261ecSmrg}
337305b261ecSmrg
337405b261ecSmrg/*********************
337505b261ecSmrg * CloseDownRetainedResources
337605b261ecSmrg *
337705b261ecSmrg *    Find all clients that are gone and have terminated in RetainTemporary
337805b261ecSmrg *    and destroy their resources.
337905b261ecSmrg *********************/
338005b261ecSmrg
338105b261ecSmrgstatic void
338205b261ecSmrgCloseDownRetainedResources(void)
338305b261ecSmrg{
338405b261ecSmrg    int i;
338505b261ecSmrg    ClientPtr client;
338605b261ecSmrg
338705b261ecSmrg    for (i=1; i<currentMaxClients; i++)
338805b261ecSmrg    {
338905b261ecSmrg        client = clients[i];
339005b261ecSmrg        if (client && (client->closeDownMode == RetainTemporary)
339105b261ecSmrg	    && (client->clientGone))
339205b261ecSmrg	    CloseDownClient(client);
339305b261ecSmrg    }
339405b261ecSmrg}
339505b261ecSmrg
339605b261ecSmrgint
339705b261ecSmrgProcKillClient(ClientPtr client)
339805b261ecSmrg{
339905b261ecSmrg    REQUEST(xResourceReq);
340005b261ecSmrg    ClientPtr killclient;
340105b261ecSmrg    int rc;
340205b261ecSmrg
340305b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
340405b261ecSmrg    if (stuff->id == AllTemporary)
340505b261ecSmrg    {
340605b261ecSmrg	CloseDownRetainedResources();
340705b261ecSmrg        return (client->noClientException);
340805b261ecSmrg    }
340905b261ecSmrg
341005b261ecSmrg    rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
341105b261ecSmrg    if (rc == Success) {
341205b261ecSmrg	CloseDownClient(killclient);
341305b261ecSmrg	/* if an LBX proxy gets killed, isItTimeToYield will be set */
341405b261ecSmrg	if (isItTimeToYield || (client == killclient))
341505b261ecSmrg	{
341605b261ecSmrg	    /* force yield and return Success, so that Dispatch()
341705b261ecSmrg	     * doesn't try to touch client
341805b261ecSmrg	     */
341905b261ecSmrg	    isItTimeToYield = TRUE;
342005b261ecSmrg	    return (Success);
342105b261ecSmrg	}
342205b261ecSmrg	return (client->noClientException);
342305b261ecSmrg    }
342405b261ecSmrg    else
342505b261ecSmrg	return rc;
342605b261ecSmrg}
342705b261ecSmrg
342805b261ecSmrgint
342905b261ecSmrgProcSetFontPath(ClientPtr client)
343005b261ecSmrg{
343105b261ecSmrg    unsigned char *ptr;
343205b261ecSmrg    unsigned long nbytes, total;
343305b261ecSmrg    long nfonts;
343405b261ecSmrg    int n, result;
343505b261ecSmrg    int error;
343605b261ecSmrg    REQUEST(xSetFontPathReq);
343705b261ecSmrg
343805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
343905b261ecSmrg
344005b261ecSmrg    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
344105b261ecSmrg    total = nbytes;
344205b261ecSmrg    ptr = (unsigned char *)&stuff[1];
344305b261ecSmrg    nfonts = stuff->nFonts;
344405b261ecSmrg    while (--nfonts >= 0)
344505b261ecSmrg    {
344605b261ecSmrg	if ((total == 0) || (total < (n = (*ptr + 1))))
344705b261ecSmrg	    return(BadLength);
344805b261ecSmrg	total -= n;
344905b261ecSmrg	ptr += n;
345005b261ecSmrg    }
345105b261ecSmrg    if (total >= 4)
345205b261ecSmrg	return(BadLength);
345305b261ecSmrg    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
345405b261ecSmrg			 &error);
345505b261ecSmrg    if (!result)
345605b261ecSmrg    {
345705b261ecSmrg	result = client->noClientException;
345805b261ecSmrg	client->errorValue = error;
345905b261ecSmrg    }
346005b261ecSmrg    return (result);
346105b261ecSmrg}
346205b261ecSmrg
346305b261ecSmrgint
346405b261ecSmrgProcGetFontPath(ClientPtr client)
346505b261ecSmrg{
346605b261ecSmrg    xGetFontPathReply reply;
346705b261ecSmrg    int stringLens, numpaths;
346805b261ecSmrg    unsigned char *bufferStart;
346905b261ecSmrg    /* REQUEST (xReq); */
347005b261ecSmrg
347105b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
347205b261ecSmrg    bufferStart = GetFontPath(&numpaths, &stringLens);
347305b261ecSmrg
347405b261ecSmrg    reply.type = X_Reply;
347505b261ecSmrg    reply.sequenceNumber = client->sequence;
347605b261ecSmrg    reply.length = (stringLens + numpaths + 3) >> 2;
347705b261ecSmrg    reply.nPaths = numpaths;
347805b261ecSmrg
347905b261ecSmrg    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
348005b261ecSmrg    if (stringLens || numpaths)
348105b261ecSmrg	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
348205b261ecSmrg    return(client->noClientException);
348305b261ecSmrg}
348405b261ecSmrg
348505b261ecSmrgint
348605b261ecSmrgProcChangeCloseDownMode(ClientPtr client)
348705b261ecSmrg{
348805b261ecSmrg    REQUEST(xSetCloseDownModeReq);
348905b261ecSmrg
349005b261ecSmrg    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
349105b261ecSmrg    if ((stuff->mode == AllTemporary) ||
349205b261ecSmrg	(stuff->mode == RetainPermanent) ||
349305b261ecSmrg	(stuff->mode == RetainTemporary))
349405b261ecSmrg    {
349505b261ecSmrg	client->closeDownMode = stuff->mode;
349605b261ecSmrg	return (client->noClientException);
349705b261ecSmrg    }
349805b261ecSmrg    else
349905b261ecSmrg    {
350005b261ecSmrg	client->errorValue = stuff->mode;
350105b261ecSmrg	return (BadValue);
350205b261ecSmrg    }
350305b261ecSmrg}
350405b261ecSmrg
350505b261ecSmrgint ProcForceScreenSaver(ClientPtr client)
350605b261ecSmrg{
350705b261ecSmrg    REQUEST(xForceScreenSaverReq);
350805b261ecSmrg
350905b261ecSmrg    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
351005b261ecSmrg
351105b261ecSmrg    if ((stuff->mode != ScreenSaverReset) &&
351205b261ecSmrg	(stuff->mode != ScreenSaverActive))
351305b261ecSmrg    {
351405b261ecSmrg	client->errorValue = stuff->mode;
351505b261ecSmrg        return BadValue;
351605b261ecSmrg    }
351705b261ecSmrg    SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
351805b261ecSmrg    return client->noClientException;
351905b261ecSmrg}
352005b261ecSmrg
352105b261ecSmrgint ProcNoOperation(ClientPtr client)
352205b261ecSmrg{
352305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xReq);
352405b261ecSmrg
352505b261ecSmrg    /* noop -- don't do anything */
352605b261ecSmrg    return(client->noClientException);
352705b261ecSmrg}
352805b261ecSmrg
352905b261ecSmrgvoid
353005b261ecSmrgInitProcVectors(void)
353105b261ecSmrg{
353205b261ecSmrg    int i;
353305b261ecSmrg    for (i = 0; i<256; i++)
353405b261ecSmrg    {
353505b261ecSmrg	if(!ProcVector[i])
353605b261ecSmrg	{
353705b261ecSmrg            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
353805b261ecSmrg	    ReplySwapVector[i] = ReplyNotSwappd;
353905b261ecSmrg	}
354005b261ecSmrg    }
354105b261ecSmrg    for(i = LASTEvent; i < 128; i++)
354205b261ecSmrg    {
354305b261ecSmrg	EventSwapVector[i] = NotImplemented;
354405b261ecSmrg    }
354505b261ecSmrg
354605b261ecSmrg}
354705b261ecSmrg
354805b261ecSmrg/**********************
354905b261ecSmrg * CloseDownClient
355005b261ecSmrg *
355105b261ecSmrg *  Client can either mark his resources destroy or retain.  If retained and
355205b261ecSmrg *  then killed again, the client is really destroyed.
355305b261ecSmrg *********************/
355405b261ecSmrg
355505b261ecSmrgchar dispatchExceptionAtReset = DE_RESET;
355605b261ecSmrg
355705b261ecSmrgvoid
355805b261ecSmrgCloseDownClient(ClientPtr client)
355905b261ecSmrg{
356005b261ecSmrg    Bool really_close_down = client->clientGone ||
356105b261ecSmrg			     client->closeDownMode == DestroyAll;
356205b261ecSmrg
356305b261ecSmrg    if (!client->clientGone)
356405b261ecSmrg    {
356505b261ecSmrg	/* ungrab server if grabbing client dies */
356605b261ecSmrg	if (grabState != GrabNone && grabClient == client)
356705b261ecSmrg	{
356805b261ecSmrg	    UngrabServer(client);
356905b261ecSmrg	}
357005b261ecSmrg	BITCLEAR(grabWaiters, client->index);
357105b261ecSmrg	DeleteClientFromAnySelections(client);
357205b261ecSmrg	ReleaseActiveGrabs(client);
357305b261ecSmrg	DeleteClientFontStuff(client);
357405b261ecSmrg	if (!really_close_down)
357505b261ecSmrg	{
357605b261ecSmrg	    /*  This frees resources that should never be retained
357705b261ecSmrg	     *  no matter what the close down mode is.  Actually we
357805b261ecSmrg	     *  could do this unconditionally, but it's probably
357905b261ecSmrg	     *  better not to traverse all the client's resources
358005b261ecSmrg	     *  twice (once here, once a few lines down in
358105b261ecSmrg	     *  FreeClientResources) in the common case of
358205b261ecSmrg	     *  really_close_down == TRUE.
358305b261ecSmrg	     */
358405b261ecSmrg	    FreeClientNeverRetainResources(client);
358505b261ecSmrg	    client->clientState = ClientStateRetained;
358605b261ecSmrg  	    if (ClientStateCallback)
358705b261ecSmrg            {
358805b261ecSmrg		NewClientInfoRec clientinfo;
358905b261ecSmrg
359005b261ecSmrg		clientinfo.client = client;
359105b261ecSmrg		clientinfo.prefix = (xConnSetupPrefix *)NULL;
359205b261ecSmrg		clientinfo.setup = (xConnSetup *) NULL;
359305b261ecSmrg		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
359405b261ecSmrg            }
359505b261ecSmrg	}
359605b261ecSmrg	client->clientGone = TRUE;  /* so events aren't sent to client */
359705b261ecSmrg	if (ClientIsAsleep(client))
359805b261ecSmrg	    ClientSignal (client);
359905b261ecSmrg	ProcessWorkQueueZombies();
360005b261ecSmrg	CloseDownConnection(client);
360105b261ecSmrg
360205b261ecSmrg	/* If the client made it to the Running stage, nClients has
360305b261ecSmrg	 * been incremented on its behalf, so we need to decrement it
360405b261ecSmrg	 * now.  If it hasn't gotten to Running, nClients has *not*
360505b261ecSmrg	 * been incremented, so *don't* decrement it.
360605b261ecSmrg	 */
360705b261ecSmrg	if (client->clientState != ClientStateInitial &&
360805b261ecSmrg	    client->clientState != ClientStateAuthenticating )
360905b261ecSmrg	{
361005b261ecSmrg	    --nClients;
361105b261ecSmrg	}
361205b261ecSmrg    }
361305b261ecSmrg
361405b261ecSmrg    if (really_close_down)
361505b261ecSmrg    {
361605b261ecSmrg	if (client->clientState == ClientStateRunning && nClients == 0)
361705b261ecSmrg	    dispatchException |= dispatchExceptionAtReset;
361805b261ecSmrg
361905b261ecSmrg	client->clientState = ClientStateGone;
362005b261ecSmrg	if (ClientStateCallback)
362105b261ecSmrg	{
362205b261ecSmrg	    NewClientInfoRec clientinfo;
362305b261ecSmrg
362405b261ecSmrg	    clientinfo.client = client;
362505b261ecSmrg	    clientinfo.prefix = (xConnSetupPrefix *)NULL;
362605b261ecSmrg	    clientinfo.setup = (xConnSetup *) NULL;
362705b261ecSmrg	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
362805b261ecSmrg	}
362905b261ecSmrg	FreeClientResources(client);
363005b261ecSmrg#ifdef XSERVER_DTRACE
363105b261ecSmrg	XSERVER_CLIENT_DISCONNECT(client->index);
363205b261ecSmrg#endif
363305b261ecSmrg	if (client->index < nextFreeClientID)
363405b261ecSmrg	    nextFreeClientID = client->index;
363505b261ecSmrg	clients[client->index] = NullClient;
363605b261ecSmrg#ifdef SMART_SCHEDULE
363705b261ecSmrg	SmartLastClient = NullClient;
363805b261ecSmrg#endif
363905b261ecSmrg	xfree(client);
364005b261ecSmrg
364105b261ecSmrg	while (!clients[currentMaxClients-1])
364205b261ecSmrg	    currentMaxClients--;
364305b261ecSmrg    }
364405b261ecSmrg}
364505b261ecSmrg
364605b261ecSmrgstatic void
364705b261ecSmrgKillAllClients(void)
364805b261ecSmrg{
364905b261ecSmrg    int i;
365005b261ecSmrg    for (i=1; i<currentMaxClients; i++)
365105b261ecSmrg        if (clients[i]) {
365205b261ecSmrg            /* Make sure Retained clients are released. */
365305b261ecSmrg            clients[i]->closeDownMode = DestroyAll;
365405b261ecSmrg            CloseDownClient(clients[i]);
365505b261ecSmrg        }
365605b261ecSmrg}
365705b261ecSmrg
365805b261ecSmrgextern int clientPrivateLen;
365905b261ecSmrgextern unsigned *clientPrivateSizes;
366005b261ecSmrgextern unsigned totalClientSize;
366105b261ecSmrg
366205b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv)
366305b261ecSmrg{
366405b261ecSmrg    client->index = i;
366505b261ecSmrg    client->sequence = 0;
366605b261ecSmrg    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
366705b261ecSmrg    client->clientGone = FALSE;
366805b261ecSmrg    if (i)
366905b261ecSmrg    {
367005b261ecSmrg	client->closeDownMode = DestroyAll;
367105b261ecSmrg	client->lastDrawable = (DrawablePtr)WindowTable[0];
367205b261ecSmrg	client->lastDrawableID = WindowTable[0]->drawable.id;
367305b261ecSmrg    }
367405b261ecSmrg    else
367505b261ecSmrg    {
367605b261ecSmrg	client->closeDownMode = RetainPermanent;
367705b261ecSmrg	client->lastDrawable = (DrawablePtr)NULL;
367805b261ecSmrg	client->lastDrawableID = INVALID;
367905b261ecSmrg    }
368005b261ecSmrg    client->lastGC = (GCPtr) NULL;
368105b261ecSmrg    client->lastGCID = INVALID;
368205b261ecSmrg    client->numSaved = 0;
368305b261ecSmrg    client->saveSet = (SaveSetElt *)NULL;
368405b261ecSmrg    client->noClientException = Success;
368505b261ecSmrg#ifdef DEBUG
368605b261ecSmrg    client->requestLogIndex = 0;
368705b261ecSmrg#endif
368805b261ecSmrg    client->requestVector = InitialVector;
368905b261ecSmrg    client->osPrivate = ospriv;
369005b261ecSmrg    client->swapped = FALSE;
369105b261ecSmrg    client->big_requests = FALSE;
369205b261ecSmrg    client->priority = 0;
369305b261ecSmrg    client->clientState = ClientStateInitial;
369405b261ecSmrg#ifdef XKB
369505b261ecSmrg    if (!noXkbExtension) {
369605b261ecSmrg	client->xkbClientFlags = 0;
369705b261ecSmrg	client->mapNotifyMask = 0;
369805b261ecSmrg	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
369905b261ecSmrg    }
370005b261ecSmrg#endif
370105b261ecSmrg    client->replyBytesRemaining = 0;
370205b261ecSmrg#ifdef XAPPGROUP
370305b261ecSmrg    client->appgroup = NULL;
370405b261ecSmrg#endif
370505b261ecSmrg    client->fontResFunc = NULL;
370605b261ecSmrg#ifdef SMART_SCHEDULE
370705b261ecSmrg    client->smart_priority = 0;
370805b261ecSmrg    client->smart_start_tick = SmartScheduleTime;
370905b261ecSmrg    client->smart_stop_tick = SmartScheduleTime;
371005b261ecSmrg    client->smart_check_tick = SmartScheduleTime;
371105b261ecSmrg#endif
371205b261ecSmrg}
371305b261ecSmrg
371405b261ecSmrgint
371505b261ecSmrgInitClientPrivates(ClientPtr client)
371605b261ecSmrg{
371705b261ecSmrg    char *ptr;
371805b261ecSmrg    DevUnion *ppriv;
371905b261ecSmrg    unsigned *sizes;
372005b261ecSmrg    unsigned size;
372105b261ecSmrg    int i;
372205b261ecSmrg
372305b261ecSmrg    if (totalClientSize == sizeof(ClientRec))
372405b261ecSmrg	ppriv = (DevUnion *)NULL;
372505b261ecSmrg    else if (client->index)
372605b261ecSmrg	ppriv = (DevUnion *)(client + 1);
372705b261ecSmrg    else
372805b261ecSmrg    {
372905b261ecSmrg	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
373005b261ecSmrg	if (!ppriv)
373105b261ecSmrg	    return 0;
373205b261ecSmrg    }
373305b261ecSmrg    client->devPrivates = ppriv;
373405b261ecSmrg    sizes = clientPrivateSizes;
373505b261ecSmrg    ptr = (char *)(ppriv + clientPrivateLen);
373605b261ecSmrg    if (ppriv)
373705b261ecSmrg	bzero(ppriv, totalClientSize - sizeof(ClientRec));
373805b261ecSmrg    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
373905b261ecSmrg    {
374005b261ecSmrg	if ( (size = *sizes) )
374105b261ecSmrg	{
374205b261ecSmrg	    ppriv->ptr = (pointer)ptr;
374305b261ecSmrg	    ptr += size;
374405b261ecSmrg	}
374505b261ecSmrg	else
374605b261ecSmrg	    ppriv->ptr = (pointer)NULL;
374705b261ecSmrg    }
374805b261ecSmrg
374905b261ecSmrg    /* Allow registrants to initialize the serverClient devPrivates */
375005b261ecSmrg    if (!client->index && ClientStateCallback)
375105b261ecSmrg    {
375205b261ecSmrg	NewClientInfoRec clientinfo;
375305b261ecSmrg
375405b261ecSmrg	clientinfo.client = client;
375505b261ecSmrg	clientinfo.prefix = (xConnSetupPrefix *)NULL;
375605b261ecSmrg	clientinfo.setup = (xConnSetup *) NULL;
375705b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
375805b261ecSmrg    }
375905b261ecSmrg    return 1;
376005b261ecSmrg}
376105b261ecSmrg
376205b261ecSmrg/************************
376305b261ecSmrg * int NextAvailableClient(ospriv)
376405b261ecSmrg *
376505b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes.
376605b261ecSmrg * Returns NULL if there are no free clients.
376705b261ecSmrg *************************/
376805b261ecSmrg
376905b261ecSmrgClientPtr NextAvailableClient(pointer ospriv)
377005b261ecSmrg{
377105b261ecSmrg    int i;
377205b261ecSmrg    ClientPtr client;
377305b261ecSmrg    xReq data;
377405b261ecSmrg
377505b261ecSmrg    i = nextFreeClientID;
377605b261ecSmrg    if (i == MAXCLIENTS)
377705b261ecSmrg	return (ClientPtr)NULL;
377805b261ecSmrg    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
377905b261ecSmrg    if (!client)
378005b261ecSmrg	return (ClientPtr)NULL;
378105b261ecSmrg    InitClient(client, i, ospriv);
378205b261ecSmrg    InitClientPrivates(client);
378305b261ecSmrg    if (!InitClientResources(client))
378405b261ecSmrg    {
378505b261ecSmrg	xfree(client);
378605b261ecSmrg	return (ClientPtr)NULL;
378705b261ecSmrg    }
378805b261ecSmrg    data.reqType = 1;
378905b261ecSmrg    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
379005b261ecSmrg    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
379105b261ecSmrg    {
379205b261ecSmrg	FreeClientResources(client);
379305b261ecSmrg	xfree(client);
379405b261ecSmrg	return (ClientPtr)NULL;
379505b261ecSmrg    }
379605b261ecSmrg    if (i == currentMaxClients)
379705b261ecSmrg	currentMaxClients++;
379805b261ecSmrg    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
379905b261ecSmrg	nextFreeClientID++;
380005b261ecSmrg    if (ClientStateCallback)
380105b261ecSmrg    {
380205b261ecSmrg	NewClientInfoRec clientinfo;
380305b261ecSmrg
380405b261ecSmrg        clientinfo.client = client;
380505b261ecSmrg        clientinfo.prefix = (xConnSetupPrefix *)NULL;
380605b261ecSmrg        clientinfo.setup = (xConnSetup *) NULL;
380705b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
380805b261ecSmrg    }
380905b261ecSmrg    return(client);
381005b261ecSmrg}
381105b261ecSmrg
381205b261ecSmrgint
381305b261ecSmrgProcInitialConnection(ClientPtr client)
381405b261ecSmrg{
381505b261ecSmrg    REQUEST(xReq);
381605b261ecSmrg    xConnClientPrefix *prefix;
381705b261ecSmrg    int whichbyte = 1;
381805b261ecSmrg
381905b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
382005b261ecSmrg    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
382105b261ecSmrg	return (client->noClientException = -1);
382205b261ecSmrg    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
382305b261ecSmrg	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
382405b261ecSmrg    {
382505b261ecSmrg	client->swapped = TRUE;
382605b261ecSmrg	SwapConnClientPrefix(prefix);
382705b261ecSmrg    }
382805b261ecSmrg    stuff->reqType = 2;
382905b261ecSmrg    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
383005b261ecSmrg		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
383105b261ecSmrg    if (client->swapped)
383205b261ecSmrg    {
383305b261ecSmrg	swaps(&stuff->length, whichbyte);
383405b261ecSmrg    }
383505b261ecSmrg    ResetCurrentRequest(client);
383605b261ecSmrg    return (client->noClientException);
383705b261ecSmrg}
383805b261ecSmrg
383905b261ecSmrgint
384005b261ecSmrgSendConnSetup(ClientPtr client, char *reason)
384105b261ecSmrg{
384205b261ecSmrg    xWindowRoot *root;
384305b261ecSmrg    int i;
384405b261ecSmrg    int numScreens;
384505b261ecSmrg    char* lConnectionInfo;
384605b261ecSmrg    xConnSetupPrefix* lconnSetupPrefix;
384705b261ecSmrg
384805b261ecSmrg    if (reason)
384905b261ecSmrg    {
385005b261ecSmrg	xConnSetupPrefix csp;
385105b261ecSmrg
385205b261ecSmrg	csp.success = xFalse;
385305b261ecSmrg	csp.lengthReason = strlen(reason);
385405b261ecSmrg	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
385505b261ecSmrg	csp.majorVersion = X_PROTOCOL;
385605b261ecSmrg	csp.minorVersion = X_PROTOCOL_REVISION;
385705b261ecSmrg	if (client->swapped)
385805b261ecSmrg	    WriteSConnSetupPrefix(client, &csp);
385905b261ecSmrg	else
386005b261ecSmrg	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
386105b261ecSmrg        (void)WriteToClient(client, (int)csp.lengthReason, reason);
386205b261ecSmrg	return (client->noClientException = -1);
386305b261ecSmrg    }
386405b261ecSmrg
386505b261ecSmrg    numScreens = screenInfo.numScreens;
386605b261ecSmrg    lConnectionInfo = ConnectionInfo;
386705b261ecSmrg    lconnSetupPrefix = &connSetupPrefix;
386805b261ecSmrg
386905b261ecSmrg    /* We're about to start speaking X protocol back to the client by
387005b261ecSmrg     * sending the connection setup info.  This means the authorization
387105b261ecSmrg     * step is complete, and we can count the client as an
387205b261ecSmrg     * authorized one.
387305b261ecSmrg     */
387405b261ecSmrg    nClients++;
387505b261ecSmrg
387605b261ecSmrg    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
387705b261ecSmrg    client->sequence = 0;
387805b261ecSmrg#ifdef XAPPGROUP
387905b261ecSmrg    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
388005b261ecSmrg#endif
388105b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
388205b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
388305b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
388405b261ecSmrg    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
388505b261ecSmrg    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
388605b261ecSmrg#endif
388705b261ecSmrg    /* fill in the "currentInputMask" */
388805b261ecSmrg    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
388905b261ecSmrg#ifdef PANORAMIX
389005b261ecSmrg    if (noPanoramiXExtension)
389105b261ecSmrg	numScreens = screenInfo.numScreens;
389205b261ecSmrg    else
389305b261ecSmrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
389405b261ecSmrg#endif
389505b261ecSmrg
389605b261ecSmrg    for (i=0; i<numScreens; i++)
389705b261ecSmrg    {
389805b261ecSmrg	unsigned int j;
389905b261ecSmrg	xDepth *pDepth;
390005b261ecSmrg
390105b261ecSmrg        root->currentInputMask = WindowTable[i]->eventMask |
390205b261ecSmrg			         wOtherEventMasks (WindowTable[i]);
390305b261ecSmrg	pDepth = (xDepth *)(root + 1);
390405b261ecSmrg	for (j = 0; j < root->nDepths; j++)
390505b261ecSmrg	{
390605b261ecSmrg	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
390705b261ecSmrg				pDepth->nVisuals * sizeof(xVisualType));
390805b261ecSmrg	}
390905b261ecSmrg	root = (xWindowRoot *)pDepth;
391005b261ecSmrg    }
391105b261ecSmrg
391205b261ecSmrg    if (client->swapped)
391305b261ecSmrg    {
391405b261ecSmrg	WriteSConnSetupPrefix(client, lconnSetupPrefix);
391505b261ecSmrg	WriteSConnectionInfo(client,
391605b261ecSmrg			     (unsigned long)(lconnSetupPrefix->length << 2),
391705b261ecSmrg			     lConnectionInfo);
391805b261ecSmrg    }
391905b261ecSmrg    else
392005b261ecSmrg    {
392105b261ecSmrg	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
392205b261ecSmrg			    (char *) lconnSetupPrefix);
392305b261ecSmrg	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
392405b261ecSmrg			    lConnectionInfo);
392505b261ecSmrg    }
392605b261ecSmrg    client->clientState = ClientStateRunning;
392705b261ecSmrg    if (ClientStateCallback)
392805b261ecSmrg    {
392905b261ecSmrg	NewClientInfoRec clientinfo;
393005b261ecSmrg
393105b261ecSmrg        clientinfo.client = client;
393205b261ecSmrg        clientinfo.prefix = lconnSetupPrefix;
393305b261ecSmrg        clientinfo.setup = (xConnSetup *)lConnectionInfo;
393405b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
393505b261ecSmrg    }
393605b261ecSmrg    return (client->noClientException);
393705b261ecSmrg}
393805b261ecSmrg
393905b261ecSmrgint
394005b261ecSmrgProcEstablishConnection(ClientPtr client)
394105b261ecSmrg{
394205b261ecSmrg    char *reason, *auth_proto, *auth_string;
394305b261ecSmrg    xConnClientPrefix *prefix;
394405b261ecSmrg    REQUEST(xReq);
394505b261ecSmrg
394605b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
394705b261ecSmrg    auth_proto = (char *)prefix + sz_xConnClientPrefix;
394805b261ecSmrg    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
394905b261ecSmrg    if ((prefix->majorVersion != X_PROTOCOL) ||
395005b261ecSmrg	(prefix->minorVersion != X_PROTOCOL_REVISION))
395105b261ecSmrg	reason = "Protocol version mismatch";
395205b261ecSmrg    else
395305b261ecSmrg	reason = ClientAuthorized(client,
395405b261ecSmrg				  (unsigned short)prefix->nbytesAuthProto,
395505b261ecSmrg				  auth_proto,
395605b261ecSmrg				  (unsigned short)prefix->nbytesAuthString,
395705b261ecSmrg				  auth_string);
395805b261ecSmrg    /*
395905b261ecSmrg     * If Kerberos is being used for this client, the clientState
396005b261ecSmrg     * will be set to ClientStateAuthenticating at this point.
396105b261ecSmrg     * More messages need to be exchanged among the X server, Kerberos
396205b261ecSmrg     * server, and client to figure out if everyone is authorized.
396305b261ecSmrg     * So we don't want to send the connection setup info yet, since
396405b261ecSmrg     * the auth step isn't really done.
396505b261ecSmrg     */
396605b261ecSmrg    if (client->clientState == ClientStateCheckingSecurity)
396705b261ecSmrg	client->clientState = ClientStateCheckedSecurity;
396805b261ecSmrg    else if (client->clientState != ClientStateAuthenticating)
396905b261ecSmrg	return(SendConnSetup(client, reason));
397005b261ecSmrg    return(client->noClientException);
397105b261ecSmrg}
397205b261ecSmrg
397305b261ecSmrg_X_EXPORT void
397405b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
397505b261ecSmrg                  XID resId, int errorCode)
397605b261ecSmrg{
397705b261ecSmrg    xError rep;
397805b261ecSmrg
397905b261ecSmrg    rep.type = X_Error;
398005b261ecSmrg    rep.sequenceNumber = client->sequence;
398105b261ecSmrg    rep.errorCode = errorCode;
398205b261ecSmrg    rep.majorCode = majorCode;
398305b261ecSmrg    rep.minorCode = minorCode;
398405b261ecSmrg    rep.resourceID = resId;
398505b261ecSmrg
398605b261ecSmrg    WriteEventsToClient (client, 1, (xEvent *)&rep);
398705b261ecSmrg}
398805b261ecSmrg
398905b261ecSmrgvoid
399005b261ecSmrgDeleteWindowFromAnySelections(WindowPtr pWin)
399105b261ecSmrg{
399205b261ecSmrg    int i;
399305b261ecSmrg
399405b261ecSmrg    for (i = 0; i< NumCurrentSelections; i++)
399505b261ecSmrg        if (CurrentSelections[i].pWin == pWin)
399605b261ecSmrg        {
399705b261ecSmrg	    if (SelectionCallback)
399805b261ecSmrg	    {
399905b261ecSmrg	        SelectionInfoRec    info;
400005b261ecSmrg
400105b261ecSmrg		info.selection = &CurrentSelections[i];
400205b261ecSmrg		info.kind = SelectionWindowDestroy;
400305b261ecSmrg		CallCallbacks(&SelectionCallback, &info);
400405b261ecSmrg	    }
400505b261ecSmrg            CurrentSelections[i].pWin = (WindowPtr)NULL;
400605b261ecSmrg            CurrentSelections[i].window = None;
400705b261ecSmrg	    CurrentSelections[i].client = NullClient;
400805b261ecSmrg	}
400905b261ecSmrg}
401005b261ecSmrg
401105b261ecSmrgstatic void
401205b261ecSmrgDeleteClientFromAnySelections(ClientPtr client)
401305b261ecSmrg{
401405b261ecSmrg    int i;
401505b261ecSmrg
401605b261ecSmrg    for (i = 0; i< NumCurrentSelections; i++)
401705b261ecSmrg        if (CurrentSelections[i].client == client)
401805b261ecSmrg        {
401905b261ecSmrg	    if (SelectionCallback)
402005b261ecSmrg	    {
402105b261ecSmrg	        SelectionInfoRec    info;
402205b261ecSmrg
402305b261ecSmrg		info.selection = &CurrentSelections[i];
402405b261ecSmrg		info.kind = SelectionWindowDestroy;
402505b261ecSmrg		CallCallbacks(&SelectionCallback, &info);
402605b261ecSmrg	    }
402705b261ecSmrg            CurrentSelections[i].pWin = (WindowPtr)NULL;
402805b261ecSmrg            CurrentSelections[i].window = None;
402905b261ecSmrg	    CurrentSelections[i].client = NullClient;
403005b261ecSmrg	}
403105b261ecSmrg}
403205b261ecSmrg
403305b261ecSmrgvoid
403405b261ecSmrgMarkClientException(ClientPtr client)
403505b261ecSmrg{
403605b261ecSmrg    client->noClientException = -1;
403705b261ecSmrg}
403805b261ecSmrg
403905b261ecSmrg#ifdef XSERVER_DTRACE
404005b261ecSmrg#include <ctype.h>
404105b261ecSmrg
404205b261ecSmrg/* Load table of request names for dtrace probes */
404305b261ecSmrgstatic void LoadRequestNames(void)
404405b261ecSmrg{
404505b261ecSmrg    int i;
404605b261ecSmrg    FILE *xedb;
404705b261ecSmrg    extern void LoadExtensionNames(char **RequestNames);
404805b261ecSmrg
404905b261ecSmrg    bzero(RequestNames, 256 * sizeof(char *));
405005b261ecSmrg
405105b261ecSmrg    xedb = fopen(XERRORDB_PATH, "r");
405205b261ecSmrg    if (xedb != NULL) {
405305b261ecSmrg	char buf[256];
405405b261ecSmrg	while (fgets(buf, sizeof(buf), xedb)) {
405505b261ecSmrg	    if ((strncmp("XRequest.", buf, 9) == 0) && (isdigit(buf[9]))) {
405605b261ecSmrg		char *name;
405705b261ecSmrg		i = strtol(buf + 9, &name, 10);
405805b261ecSmrg		if (RequestNames[i] == 0) {
405905b261ecSmrg		    char *end = strchr(name, '\n');
406005b261ecSmrg		    if (end) { *end = '\0'; }
406105b261ecSmrg		    RequestNames[i] = strdup(name + 1);
406205b261ecSmrg		}
406305b261ecSmrg	    }
406405b261ecSmrg	}
406505b261ecSmrg	fclose(xedb);
406605b261ecSmrg    }
406705b261ecSmrg
406805b261ecSmrg    LoadExtensionNames(RequestNames);
406905b261ecSmrg
407005b261ecSmrg    for (i = 0; i < 256; i++) {
407105b261ecSmrg	if (RequestNames[i] == 0) {
407205b261ecSmrg#define RN_SIZE 12 /* "Request#' + up to 3 digits + \0 */
407305b261ecSmrg	    RequestNames[i] = xalloc(RN_SIZE);
407405b261ecSmrg	    if (RequestNames[i]) {
407505b261ecSmrg		snprintf(RequestNames[i], RN_SIZE, "Request#%d", i);
407605b261ecSmrg	    }
407705b261ecSmrg	}
407805b261ecSmrg	/* fprintf(stderr, "%d: %s\n", i, RequestNames[i]); */
407905b261ecSmrg    }
408005b261ecSmrg}
408105b261ecSmrg
408205b261ecSmrgstatic void FreeRequestNames(void)
408305b261ecSmrg{
408405b261ecSmrg    int i;
408505b261ecSmrg
408605b261ecSmrg    for (i = 0; i < 256; i++) {
408705b261ecSmrg	if (RequestNames[i] != 0) {
408805b261ecSmrg	    free(RequestNames[i]);
408905b261ecSmrg	    RequestNames[i] = 0;
409005b261ecSmrg	}
409105b261ecSmrg    }
409205b261ecSmrg}
409305b261ecSmrg
409405b261ecSmrg#endif
4095