dispatch.c revision b1d344b3
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
1374642e01fSmrg#include "privates.h"
13805b261ecSmrg#include "xace.h"
13905b261ecSmrg#ifdef XKB
14005b261ecSmrg#ifndef XKB_IN_SERVER
14105b261ecSmrg#define XKB_IN_SERVER
14205b261ecSmrg#endif
14305b261ecSmrg#include "inputstr.h"
14405b261ecSmrg#include <xkbsrv.h>
14505b261ecSmrg#endif
14605b261ecSmrg
14705b261ecSmrg#ifdef XSERVER_DTRACE
1484642e01fSmrg#include "registry.h"
14905b261ecSmrg#include <sys/types.h>
15005b261ecSmrgtypedef const char *string;
15105b261ecSmrg#include "Xserver-dtrace.h"
15205b261ecSmrg#endif
15305b261ecSmrg
15405b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32)
15505b261ecSmrg#define BITMASK(i) (1U << ((i) & 31))
15605b261ecSmrg#define MASKIDX(i) ((i) >> 5)
15705b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)]
15805b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
15905b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
16005b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
16105b261ecSmrg
16205b261ecSmrgextern xConnSetupPrefix connSetupPrefix;
16305b261ecSmrg
16405b261ecSmrgstatic ClientPtr grabClient;
16505b261ecSmrg#define GrabNone 0
16605b261ecSmrg#define GrabActive 1
16705b261ecSmrg#define GrabKickout 2
16805b261ecSmrgstatic int grabState = GrabNone;
16905b261ecSmrgstatic long grabWaiters[mskcnt];
17005b261ecSmrg_X_EXPORT CallbackListPtr ServerGrabCallback = NULL;
17105b261ecSmrgHWEventQueuePtr checkForInput[2];
17205b261ecSmrgextern int connBlockScreenStart;
17305b261ecSmrg
17405b261ecSmrgstatic void KillAllClients(void);
17505b261ecSmrg
17605b261ecSmrgstatic int nextFreeClientID; /* always MIN free client ID */
17705b261ecSmrg
17805b261ecSmrgstatic int	nClients;	/* number of authorized clients */
17905b261ecSmrg
18005b261ecSmrg_X_EXPORT CallbackListPtr ClientStateCallback;
18105b261ecSmrg
18205b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they
18305b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't
18405b261ecSmrg * need to actually check value in memory when used and may miss changes from
18505b261ecSmrg * signal handlers.
18605b261ecSmrg */
18705b261ecSmrg_X_EXPORT volatile char dispatchException = 0;
18805b261ecSmrg_X_EXPORT volatile char isItTimeToYield;
18905b261ecSmrg
19005b261ecSmrg/* Various of the DIX function interfaces were not designed to allow
19105b261ecSmrg * the client->errorValue to be set on BadValue and other errors.
19205b261ecSmrg * Rather than changing interfaces and breaking untold code we introduce
19305b261ecSmrg * a new global that dispatch can use.
19405b261ecSmrg */
19505b261ecSmrgXID clientErrorValue;   /* XXX this is a kludge */
19605b261ecSmrg
19705b261ecSmrg#define SAME_SCREENS(a, b) (\
19805b261ecSmrg    (a.pScreen == b.pScreen))
19905b261ecSmrg
2004642e01fSmrgvoid
20105b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
20205b261ecSmrg{
20305b261ecSmrg    checkForInput[0] = c0;
20405b261ecSmrg    checkForInput[1] = c1;
20505b261ecSmrg}
20605b261ecSmrg
20705b261ecSmrg_X_EXPORT void
20805b261ecSmrgUpdateCurrentTime(void)
20905b261ecSmrg{
21005b261ecSmrg    TimeStamp systime;
21105b261ecSmrg
21205b261ecSmrg    /* To avoid time running backwards, we must call GetTimeInMillis before
21305b261ecSmrg     * calling ProcessInputEvents.
21405b261ecSmrg     */
21505b261ecSmrg    systime.months = currentTime.months;
21605b261ecSmrg    systime.milliseconds = GetTimeInMillis();
21705b261ecSmrg    if (systime.milliseconds < currentTime.milliseconds)
21805b261ecSmrg	systime.months++;
21905b261ecSmrg    if (*checkForInput[0] != *checkForInput[1])
22005b261ecSmrg	ProcessInputEvents();
22105b261ecSmrg    if (CompareTimeStamps(systime, currentTime) == LATER)
22205b261ecSmrg	currentTime = systime;
22305b261ecSmrg}
22405b261ecSmrg
22505b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
22605b261ecSmrg_X_EXPORT void
22705b261ecSmrgUpdateCurrentTimeIf(void)
22805b261ecSmrg{
22905b261ecSmrg    TimeStamp systime;
23005b261ecSmrg
23105b261ecSmrg    systime.months = currentTime.months;
23205b261ecSmrg    systime.milliseconds = GetTimeInMillis();
23305b261ecSmrg    if (systime.milliseconds < currentTime.milliseconds)
23405b261ecSmrg	systime.months++;
23505b261ecSmrg    if (*checkForInput[0] == *checkForInput[1])
23605b261ecSmrg	currentTime = systime;
23705b261ecSmrg}
23805b261ecSmrg
23905b261ecSmrg
24005b261ecSmrg#undef SMART_DEBUG
24105b261ecSmrg
24205b261ecSmrg#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
24305b261ecSmrg#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
24405b261ecSmrg
24505b261ecSmrgBool	    SmartScheduleDisable = FALSE;
24605b261ecSmrglong	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
24705b261ecSmrglong	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
24805b261ecSmrglong	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
24905b261ecSmrglong	    SmartScheduleTime;
250b1d344b3Smrgint	    SmartScheduleLatencyLimited = 0;
25105b261ecSmrgstatic ClientPtr   SmartLastClient;
25205b261ecSmrgstatic int	   SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
25305b261ecSmrg
25405b261ecSmrg#ifdef SMART_DEBUG
25505b261ecSmrglong	    SmartLastPrint;
25605b261ecSmrg#endif
25705b261ecSmrg
25805b261ecSmrgvoid        Dispatch(void);
25905b261ecSmrgvoid        InitProcVectors(void);
26005b261ecSmrg
26105b261ecSmrgstatic int
26205b261ecSmrgSmartScheduleClient (int *clientReady, int nready)
26305b261ecSmrg{
26405b261ecSmrg    ClientPtr	pClient;
26505b261ecSmrg    int		i;
26605b261ecSmrg    int		client;
26705b261ecSmrg    int		bestPrio, best = 0;
26805b261ecSmrg    int		bestRobin, robin;
26905b261ecSmrg    long	now = SmartScheduleTime;
27005b261ecSmrg    long	idle;
27105b261ecSmrg
27205b261ecSmrg    bestPrio = -0x7fffffff;
27305b261ecSmrg    bestRobin = 0;
27405b261ecSmrg    idle = 2 * SmartScheduleSlice;
27505b261ecSmrg    for (i = 0; i < nready; i++)
27605b261ecSmrg    {
27705b261ecSmrg	client = clientReady[i];
27805b261ecSmrg	pClient = clients[client];
27905b261ecSmrg	/* Praise clients which are idle */
28005b261ecSmrg	if ((now - pClient->smart_check_tick) >= idle)
28105b261ecSmrg	{
28205b261ecSmrg	    if (pClient->smart_priority < 0)
28305b261ecSmrg		pClient->smart_priority++;
28405b261ecSmrg	}
28505b261ecSmrg	pClient->smart_check_tick = now;
28605b261ecSmrg
28705b261ecSmrg	/* check priority to select best client */
28805b261ecSmrg	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
28905b261ecSmrg	if (pClient->smart_priority > bestPrio ||
29005b261ecSmrg	    (pClient->smart_priority == bestPrio && robin > bestRobin))
29105b261ecSmrg	{
29205b261ecSmrg	    bestPrio = pClient->smart_priority;
29305b261ecSmrg	    bestRobin = robin;
29405b261ecSmrg	    best = client;
29505b261ecSmrg	}
29605b261ecSmrg#ifdef SMART_DEBUG
29705b261ecSmrg	if ((now - SmartLastPrint) >= 5000)
29805b261ecSmrg	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
29905b261ecSmrg#endif
30005b261ecSmrg    }
30105b261ecSmrg#ifdef SMART_DEBUG
30205b261ecSmrg    if ((now - SmartLastPrint) >= 5000)
30305b261ecSmrg    {
30405b261ecSmrg	fprintf (stderr, " use %2d\n", best);
30505b261ecSmrg	SmartLastPrint = now;
30605b261ecSmrg    }
30705b261ecSmrg#endif
30805b261ecSmrg    pClient = clients[best];
30905b261ecSmrg    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
31005b261ecSmrg    /*
31105b261ecSmrg     * Set current client pointer
31205b261ecSmrg     */
31305b261ecSmrg    if (SmartLastClient != pClient)
31405b261ecSmrg    {
31505b261ecSmrg	pClient->smart_start_tick = now;
31605b261ecSmrg	SmartLastClient = pClient;
31705b261ecSmrg    }
31805b261ecSmrg    /*
31905b261ecSmrg     * Adjust slice
32005b261ecSmrg     */
321b1d344b3Smrg    if (nready == 1 && SmartScheduleLatencyLimited == 0)
32205b261ecSmrg    {
32305b261ecSmrg	/*
32405b261ecSmrg	 * If it's been a long time since another client
32505b261ecSmrg	 * has run, bump the slice up to get maximal
32605b261ecSmrg	 * performance from a single client
32705b261ecSmrg	 */
32805b261ecSmrg	if ((now - pClient->smart_start_tick) > 1000 &&
32905b261ecSmrg	    SmartScheduleSlice < SmartScheduleMaxSlice)
33005b261ecSmrg	{
33105b261ecSmrg	    SmartScheduleSlice += SmartScheduleInterval;
33205b261ecSmrg	}
33305b261ecSmrg    }
33405b261ecSmrg    else
33505b261ecSmrg    {
33605b261ecSmrg	SmartScheduleSlice = SmartScheduleInterval;
33705b261ecSmrg    }
33805b261ecSmrg    return best;
33905b261ecSmrg}
34005b261ecSmrg
341b1d344b3Smrgvoid
342b1d344b3SmrgEnableLimitedSchedulingLatency(void)
343b1d344b3Smrg{
344b1d344b3Smrg    ++SmartScheduleLatencyLimited;
345b1d344b3Smrg    SmartScheduleSlice = SmartScheduleInterval;
346b1d344b3Smrg}
347b1d344b3Smrg
348b1d344b3Smrgvoid
349b1d344b3SmrgDisableLimitedSchedulingLatency(void)
350b1d344b3Smrg{
351b1d344b3Smrg    --SmartScheduleLatencyLimited;
352b1d344b3Smrg
353b1d344b3Smrg    /* protect against bugs */
354b1d344b3Smrg    if (SmartScheduleLatencyLimited < 0)
355b1d344b3Smrg	SmartScheduleLatencyLimited = 0;
356b1d344b3Smrg}
357b1d344b3Smrg
35805b261ecSmrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType
35905b261ecSmrg
36005b261ecSmrgvoid
36105b261ecSmrgDispatch(void)
36205b261ecSmrg{
36305b261ecSmrg    int        *clientReady;     /* array of request ready clients */
36405b261ecSmrg    int	result;
36505b261ecSmrg    ClientPtr	client;
36605b261ecSmrg    int	nready;
36705b261ecSmrg    HWEventQueuePtr* icheck = checkForInput;
36805b261ecSmrg    long			start_tick;
36905b261ecSmrg
37005b261ecSmrg    nextFreeClientID = 1;
37105b261ecSmrg    nClients = 0;
37205b261ecSmrg
3734642e01fSmrg    clientReady = (int *) xalloc(sizeof(int) * MaxClients);
37405b261ecSmrg    if (!clientReady)
37505b261ecSmrg	return;
37605b261ecSmrg
377b1d344b3Smrg    SmartScheduleSlice = SmartScheduleInterval;
37805b261ecSmrg    while (!dispatchException)
37905b261ecSmrg    {
38005b261ecSmrg        if (*icheck[0] != *icheck[1])
38105b261ecSmrg	{
38205b261ecSmrg	    ProcessInputEvents();
38305b261ecSmrg	    FlushIfCriticalOutputPending();
38405b261ecSmrg	}
38505b261ecSmrg
38605b261ecSmrg	nready = WaitForSomething(clientReady);
38705b261ecSmrg
38805b261ecSmrg	if (nready && !SmartScheduleDisable)
38905b261ecSmrg	{
39005b261ecSmrg	    clientReady[0] = SmartScheduleClient (clientReady, nready);
39105b261ecSmrg	    nready = 1;
39205b261ecSmrg	}
39305b261ecSmrg       /*****************
39405b261ecSmrg	*  Handle events in round robin fashion, doing input between
39505b261ecSmrg	*  each round
39605b261ecSmrg	*****************/
39705b261ecSmrg
39805b261ecSmrg	while (!dispatchException && (--nready >= 0))
39905b261ecSmrg	{
40005b261ecSmrg	    client = clients[clientReady[nready]];
40105b261ecSmrg	    if (! client)
40205b261ecSmrg	    {
40305b261ecSmrg		/* KillClient can cause this to happen */
40405b261ecSmrg		continue;
40505b261ecSmrg	    }
40605b261ecSmrg	    /* GrabServer activation can cause this to be true */
40705b261ecSmrg	    if (grabState == GrabKickout)
40805b261ecSmrg	    {
40905b261ecSmrg		grabState = GrabActive;
41005b261ecSmrg		break;
41105b261ecSmrg	    }
41205b261ecSmrg	    isItTimeToYield = FALSE;
41305b261ecSmrg
41405b261ecSmrg	    start_tick = SmartScheduleTime;
41505b261ecSmrg	    while (!isItTimeToYield)
41605b261ecSmrg	    {
41705b261ecSmrg	        if (*icheck[0] != *icheck[1])
41805b261ecSmrg		    ProcessInputEvents();
4194642e01fSmrg
4204642e01fSmrg		FlushIfCriticalOutputPending();
42105b261ecSmrg		if (!SmartScheduleDisable &&
42205b261ecSmrg		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
42305b261ecSmrg		{
42405b261ecSmrg		    /* Penalize clients which consume ticks */
42505b261ecSmrg		    if (client->smart_priority > SMART_MIN_PRIORITY)
42605b261ecSmrg			client->smart_priority--;
42705b261ecSmrg		    break;
42805b261ecSmrg		}
42905b261ecSmrg		/* now, finally, deal with client requests */
43005b261ecSmrg
43105b261ecSmrg	        result = ReadRequestFromClient(client);
43205b261ecSmrg	        if (result <= 0)
43305b261ecSmrg	        {
43405b261ecSmrg		    if (result < 0)
43505b261ecSmrg			CloseDownClient(client);
43605b261ecSmrg		    break;
43705b261ecSmrg	        }
43805b261ecSmrg
43905b261ecSmrg		client->sequence++;
44005b261ecSmrg#ifdef DEBUG
44105b261ecSmrg		if (client->requestLogIndex == MAX_REQUEST_LOG)
44205b261ecSmrg		    client->requestLogIndex = 0;
44305b261ecSmrg		client->requestLog[client->requestLogIndex] = MAJOROP;
44405b261ecSmrg		client->requestLogIndex++;
44505b261ecSmrg#endif
44605b261ecSmrg#ifdef XSERVER_DTRACE
4474642e01fSmrg		XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
44805b261ecSmrg			      ((xReq *)client->requestBuffer)->length,
44905b261ecSmrg			      client->index, client->requestBuffer);
45005b261ecSmrg#endif
45105b261ecSmrg		if (result > (maxBigRequestSize << 2))
45205b261ecSmrg		    result = BadLength;
45305b261ecSmrg		else {
4544642e01fSmrg		    result = XaceHookDispatch(client, MAJOROP);
4554642e01fSmrg		    if (result == Success)
4564642e01fSmrg			result = (* client->requestVector[MAJOROP])(client);
4574642e01fSmrg		    XaceHookAuditEnd(client, result);
45805b261ecSmrg		}
45905b261ecSmrg#ifdef XSERVER_DTRACE
4604642e01fSmrg		XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
46105b261ecSmrg			      client->sequence, client->index, result);
46205b261ecSmrg#endif
46305b261ecSmrg
46405b261ecSmrg		if (result != Success)
46505b261ecSmrg		{
46605b261ecSmrg		    if (client->noClientException != Success)
46705b261ecSmrg                        CloseDownClient(client);
46805b261ecSmrg                    else
46905b261ecSmrg		        SendErrorToClient(client, MAJOROP,
47005b261ecSmrg					  MinorOpcodeOfRequest(client),
47105b261ecSmrg					  client->errorValue, result);
47205b261ecSmrg		    break;
47305b261ecSmrg	        }
47405b261ecSmrg	    }
47505b261ecSmrg	    FlushAllOutput();
47605b261ecSmrg	    client = clients[clientReady[nready]];
47705b261ecSmrg	    if (client)
47805b261ecSmrg		client->smart_stop_tick = SmartScheduleTime;
47905b261ecSmrg	}
48005b261ecSmrg	dispatchException &= ~DE_PRIORITYCHANGE;
48105b261ecSmrg    }
48205b261ecSmrg#if defined(DDXBEFORERESET)
48305b261ecSmrg    ddxBeforeReset ();
48405b261ecSmrg#endif
48505b261ecSmrg    KillAllClients();
4864642e01fSmrg    xfree(clientReady);
48705b261ecSmrg    dispatchException &= ~DE_RESET;
488b1d344b3Smrg    SmartScheduleLatencyLimited = 0;
48905b261ecSmrg}
49005b261ecSmrg
49105b261ecSmrg#undef MAJOROP
49205b261ecSmrg
49305b261ecSmrg_X_EXPORT int
49405b261ecSmrgProcBadRequest(ClientPtr client)
49505b261ecSmrg{
49605b261ecSmrg    return (BadRequest);
49705b261ecSmrg}
49805b261ecSmrg
49905b261ecSmrgint
50005b261ecSmrgProcCreateWindow(ClientPtr client)
50105b261ecSmrg{
50205b261ecSmrg    WindowPtr pParent, pWin;
50305b261ecSmrg    REQUEST(xCreateWindowReq);
5044642e01fSmrg    int len, rc;
50505b261ecSmrg
50605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
50705b261ecSmrg
50805b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->wid, client);
5094642e01fSmrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
51005b261ecSmrg    if (rc != Success)
51105b261ecSmrg        return rc;
51205b261ecSmrg    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
51305b261ecSmrg    if (Ones(stuff->mask) != len)
51405b261ecSmrg        return BadLength;
51505b261ecSmrg    if (!stuff->width || !stuff->height)
51605b261ecSmrg    {
51705b261ecSmrg	client->errorValue = 0;
51805b261ecSmrg        return BadValue;
51905b261ecSmrg    }
52005b261ecSmrg    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
52105b261ecSmrg			      stuff->y, stuff->width, stuff->height,
52205b261ecSmrg			      stuff->borderWidth, stuff->class,
52305b261ecSmrg			      stuff->mask, (XID *) &stuff[1],
52405b261ecSmrg			      (int)stuff->depth,
5254642e01fSmrg			      client, stuff->visual, &rc);
52605b261ecSmrg    if (pWin)
52705b261ecSmrg    {
52805b261ecSmrg	Mask mask = pWin->eventMask;
52905b261ecSmrg
53005b261ecSmrg	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
53105b261ecSmrg	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
53205b261ecSmrg	    return BadAlloc;
53305b261ecSmrg	pWin->eventMask = mask;
53405b261ecSmrg    }
53505b261ecSmrg    if (client->noClientException != Success)
53605b261ecSmrg        return(client->noClientException);
53705b261ecSmrg    else
5384642e01fSmrg        return rc;
53905b261ecSmrg}
54005b261ecSmrg
54105b261ecSmrgint
54205b261ecSmrgProcChangeWindowAttributes(ClientPtr client)
54305b261ecSmrg{
54405b261ecSmrg    WindowPtr pWin;
54505b261ecSmrg    REQUEST(xChangeWindowAttributesReq);
5464642e01fSmrg    int result, len, rc;
5474642e01fSmrg    Mask access_mode = 0;
54805b261ecSmrg
54905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
5504642e01fSmrg    access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
5514642e01fSmrg    access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
5524642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
55305b261ecSmrg    if (rc != Success)
55405b261ecSmrg        return rc;
55505b261ecSmrg    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
55605b261ecSmrg    if (len != Ones(stuff->valueMask))
55705b261ecSmrg        return BadLength;
55805b261ecSmrg    result =  ChangeWindowAttributes(pWin,
55905b261ecSmrg				  stuff->valueMask,
56005b261ecSmrg				  (XID *) &stuff[1],
56105b261ecSmrg				  client);
56205b261ecSmrg    if (client->noClientException != Success)
56305b261ecSmrg        return(client->noClientException);
56405b261ecSmrg    else
56505b261ecSmrg        return(result);
56605b261ecSmrg}
56705b261ecSmrg
56805b261ecSmrgint
56905b261ecSmrgProcGetWindowAttributes(ClientPtr client)
57005b261ecSmrg{
57105b261ecSmrg    WindowPtr pWin;
57205b261ecSmrg    REQUEST(xResourceReq);
57305b261ecSmrg    xGetWindowAttributesReply wa;
57405b261ecSmrg    int rc;
57505b261ecSmrg
57605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
5774642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
57805b261ecSmrg    if (rc != Success)
57905b261ecSmrg	return rc;
58005b261ecSmrg    GetWindowAttributes(pWin, client, &wa);
58105b261ecSmrg    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
58205b261ecSmrg    return(client->noClientException);
58305b261ecSmrg}
58405b261ecSmrg
58505b261ecSmrgint
58605b261ecSmrgProcDestroyWindow(ClientPtr client)
58705b261ecSmrg{
58805b261ecSmrg    WindowPtr pWin;
58905b261ecSmrg    REQUEST(xResourceReq);
59005b261ecSmrg    int rc;
59105b261ecSmrg
59205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
59305b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
59405b261ecSmrg    if (rc != Success)
59505b261ecSmrg	return rc;
5964642e01fSmrg    if (pWin->parent) {
5974642e01fSmrg	rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
5984642e01fSmrg			     DixRemoveAccess);
5994642e01fSmrg	if (rc != Success)
6004642e01fSmrg	    return rc;
60105b261ecSmrg	FreeResource(stuff->id, RT_NONE);
6024642e01fSmrg    }
60305b261ecSmrg    return(client->noClientException);
60405b261ecSmrg}
60505b261ecSmrg
60605b261ecSmrgint
60705b261ecSmrgProcDestroySubwindows(ClientPtr client)
60805b261ecSmrg{
60905b261ecSmrg    WindowPtr pWin;
61005b261ecSmrg    REQUEST(xResourceReq);
61105b261ecSmrg    int rc;
61205b261ecSmrg
61305b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
6144642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
61505b261ecSmrg    if (rc != Success)
61605b261ecSmrg	return rc;
61705b261ecSmrg    DestroySubwindows(pWin, client);
61805b261ecSmrg    return(client->noClientException);
61905b261ecSmrg}
62005b261ecSmrg
62105b261ecSmrgint
62205b261ecSmrgProcChangeSaveSet(ClientPtr client)
62305b261ecSmrg{
62405b261ecSmrg    WindowPtr pWin;
62505b261ecSmrg    REQUEST(xChangeSaveSetReq);
62605b261ecSmrg    int result, rc;
62705b261ecSmrg
62805b261ecSmrg    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
6294642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
63005b261ecSmrg    if (rc != Success)
63105b261ecSmrg        return rc;
63205b261ecSmrg    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
63305b261ecSmrg        return BadMatch;
63405b261ecSmrg    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
63505b261ecSmrg    {
63605b261ecSmrg        result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
63705b261ecSmrg	if (client->noClientException != Success)
63805b261ecSmrg	    return(client->noClientException);
63905b261ecSmrg	else
64005b261ecSmrg            return(result);
64105b261ecSmrg    }
64205b261ecSmrg    else
64305b261ecSmrg    {
64405b261ecSmrg	client->errorValue = stuff->mode;
64505b261ecSmrg	return( BadValue );
64605b261ecSmrg    }
64705b261ecSmrg}
64805b261ecSmrg
64905b261ecSmrgint
65005b261ecSmrgProcReparentWindow(ClientPtr client)
65105b261ecSmrg{
65205b261ecSmrg    WindowPtr pWin, pParent;
65305b261ecSmrg    REQUEST(xReparentWindowReq);
65405b261ecSmrg    int result, rc;
65505b261ecSmrg
65605b261ecSmrg    REQUEST_SIZE_MATCH(xReparentWindowReq);
6574642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
65805b261ecSmrg    if (rc != Success)
65905b261ecSmrg        return rc;
6604642e01fSmrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
66105b261ecSmrg    if (rc != Success)
66205b261ecSmrg        return rc;
66305b261ecSmrg    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
66405b261ecSmrg    {
66505b261ecSmrg        if ((pWin->backgroundState == ParentRelative) &&
66605b261ecSmrg            (pParent->drawable.depth != pWin->drawable.depth))
66705b261ecSmrg            return BadMatch;
66805b261ecSmrg	if ((pWin->drawable.class != InputOnly) &&
66905b261ecSmrg	    (pParent->drawable.class == InputOnly))
67005b261ecSmrg	    return BadMatch;
67105b261ecSmrg        result =  ReparentWindow(pWin, pParent,
67205b261ecSmrg			 (short)stuff->x, (short)stuff->y, client);
67305b261ecSmrg	if (client->noClientException != Success)
67405b261ecSmrg            return(client->noClientException);
67505b261ecSmrg	else
67605b261ecSmrg            return(result);
67705b261ecSmrg    }
67805b261ecSmrg    else
67905b261ecSmrg        return (BadMatch);
68005b261ecSmrg}
68105b261ecSmrg
68205b261ecSmrgint
68305b261ecSmrgProcMapWindow(ClientPtr client)
68405b261ecSmrg{
68505b261ecSmrg    WindowPtr pWin;
68605b261ecSmrg    REQUEST(xResourceReq);
68705b261ecSmrg    int rc;
68805b261ecSmrg
68905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
6904642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
69105b261ecSmrg    if (rc != Success)
69205b261ecSmrg        return rc;
69305b261ecSmrg    MapWindow(pWin, client);
69405b261ecSmrg           /* update cache to say it is mapped */
69505b261ecSmrg    return(client->noClientException);
69605b261ecSmrg}
69705b261ecSmrg
69805b261ecSmrgint
69905b261ecSmrgProcMapSubwindows(ClientPtr client)
70005b261ecSmrg{
70105b261ecSmrg    WindowPtr pWin;
70205b261ecSmrg    REQUEST(xResourceReq);
70305b261ecSmrg    int rc;
70405b261ecSmrg
70505b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
7064642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
70705b261ecSmrg    if (rc != Success)
70805b261ecSmrg        return rc;
70905b261ecSmrg    MapSubwindows(pWin, client);
71005b261ecSmrg           /* update cache to say it is mapped */
71105b261ecSmrg    return(client->noClientException);
71205b261ecSmrg}
71305b261ecSmrg
71405b261ecSmrgint
71505b261ecSmrgProcUnmapWindow(ClientPtr client)
71605b261ecSmrg{
71705b261ecSmrg    WindowPtr pWin;
71805b261ecSmrg    REQUEST(xResourceReq);
71905b261ecSmrg    int rc;
72005b261ecSmrg
72105b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
7224642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
72305b261ecSmrg    if (rc != Success)
72405b261ecSmrg        return rc;
72505b261ecSmrg    UnmapWindow(pWin, FALSE);
72605b261ecSmrg           /* update cache to say it is mapped */
72705b261ecSmrg    return(client->noClientException);
72805b261ecSmrg}
72905b261ecSmrg
73005b261ecSmrgint
73105b261ecSmrgProcUnmapSubwindows(ClientPtr client)
73205b261ecSmrg{
73305b261ecSmrg    WindowPtr pWin;
73405b261ecSmrg    REQUEST(xResourceReq);
73505b261ecSmrg    int rc;
73605b261ecSmrg
73705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
7384642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
73905b261ecSmrg    if (rc != Success)
74005b261ecSmrg        return rc;
74105b261ecSmrg    UnmapSubwindows(pWin);
74205b261ecSmrg    return(client->noClientException);
74305b261ecSmrg}
74405b261ecSmrg
74505b261ecSmrgint
74605b261ecSmrgProcConfigureWindow(ClientPtr client)
74705b261ecSmrg{
74805b261ecSmrg    WindowPtr pWin;
74905b261ecSmrg    REQUEST(xConfigureWindowReq);
75005b261ecSmrg    int result;
75105b261ecSmrg    int len, rc;
75205b261ecSmrg
75305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
7544642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client,
7554642e01fSmrg			 DixManageAccess|DixSetAttrAccess);
75605b261ecSmrg    if (rc != Success)
75705b261ecSmrg        return rc;
75805b261ecSmrg    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
75905b261ecSmrg    if (Ones((Mask)stuff->mask) != len)
76005b261ecSmrg        return BadLength;
76105b261ecSmrg    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
76205b261ecSmrg			      client);
76305b261ecSmrg    if (client->noClientException != Success)
76405b261ecSmrg        return(client->noClientException);
76505b261ecSmrg    else
76605b261ecSmrg        return(result);
76705b261ecSmrg}
76805b261ecSmrg
76905b261ecSmrgint
77005b261ecSmrgProcCirculateWindow(ClientPtr client)
77105b261ecSmrg{
77205b261ecSmrg    WindowPtr pWin;
77305b261ecSmrg    REQUEST(xCirculateWindowReq);
77405b261ecSmrg    int rc;
77505b261ecSmrg
77605b261ecSmrg    REQUEST_SIZE_MATCH(xCirculateWindowReq);
77705b261ecSmrg    if ((stuff->direction != RaiseLowest) &&
77805b261ecSmrg	(stuff->direction != LowerHighest))
77905b261ecSmrg    {
78005b261ecSmrg	client->errorValue = stuff->direction;
78105b261ecSmrg        return BadValue;
78205b261ecSmrg    }
7834642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
78405b261ecSmrg    if (rc != Success)
78505b261ecSmrg        return rc;
78605b261ecSmrg    CirculateWindow(pWin, (int)stuff->direction, client);
78705b261ecSmrg    return(client->noClientException);
78805b261ecSmrg}
78905b261ecSmrg
79005b261ecSmrgstatic int
79105b261ecSmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep)
79205b261ecSmrg{
79305b261ecSmrg    DrawablePtr pDraw;
79405b261ecSmrg    int rc;
79505b261ecSmrg    REQUEST(xResourceReq);
79605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
79705b261ecSmrg
7984642e01fSmrg    rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
79905b261ecSmrg    if (rc != Success)
80005b261ecSmrg	return rc;
80105b261ecSmrg
80205b261ecSmrg    rep->type = X_Reply;
80305b261ecSmrg    rep->length = 0;
80405b261ecSmrg    rep->sequenceNumber = client->sequence;
80505b261ecSmrg    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
80605b261ecSmrg    rep->depth = pDraw->depth;
80705b261ecSmrg    rep->width = pDraw->width;
80805b261ecSmrg    rep->height = pDraw->height;
80905b261ecSmrg
81005b261ecSmrg    /* XXX - Because the pixmap-implementation of the multibuffer extension
81105b261ecSmrg     *       may have the buffer-id's drawable resource value be a pointer
81205b261ecSmrg     *       to the buffer's window instead of the buffer itself
81305b261ecSmrg     *       (this happens if the buffer is the displayed buffer),
81405b261ecSmrg     *       we also have to check that the id matches before we can
81505b261ecSmrg     *       truly say that it is a DRAWABLE_WINDOW.
81605b261ecSmrg     */
81705b261ecSmrg
81805b261ecSmrg    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
81905b261ecSmrg        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
82005b261ecSmrg    {
82105b261ecSmrg        WindowPtr pWin = (WindowPtr)pDraw;
82205b261ecSmrg	rep->x = pWin->origin.x - wBorderWidth (pWin);
82305b261ecSmrg	rep->y = pWin->origin.y - wBorderWidth (pWin);
82405b261ecSmrg	rep->borderWidth = pWin->borderWidth;
82505b261ecSmrg    }
82605b261ecSmrg    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
82705b261ecSmrg    {
82805b261ecSmrg	rep->x = rep->y = rep->borderWidth = 0;
82905b261ecSmrg    }
83005b261ecSmrg
83105b261ecSmrg    return Success;
83205b261ecSmrg}
83305b261ecSmrg
83405b261ecSmrg
83505b261ecSmrgint
83605b261ecSmrgProcGetGeometry(ClientPtr client)
83705b261ecSmrg{
83805b261ecSmrg    xGetGeometryReply rep;
83905b261ecSmrg    int status;
84005b261ecSmrg
84105b261ecSmrg    if ((status = GetGeometry(client, &rep)) != Success)
84205b261ecSmrg	return status;
84305b261ecSmrg
84405b261ecSmrg    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
84505b261ecSmrg    return(client->noClientException);
84605b261ecSmrg}
84705b261ecSmrg
84805b261ecSmrg
84905b261ecSmrgint
85005b261ecSmrgProcQueryTree(ClientPtr client)
85105b261ecSmrg{
85205b261ecSmrg    xQueryTreeReply reply;
85305b261ecSmrg    int rc, numChildren = 0;
85405b261ecSmrg    WindowPtr pChild, pWin, pHead;
85505b261ecSmrg    Window  *childIDs = (Window *)NULL;
85605b261ecSmrg    REQUEST(xResourceReq);
85705b261ecSmrg
85805b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
8594642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
86005b261ecSmrg    if (rc != Success)
86105b261ecSmrg        return rc;
86205b261ecSmrg    reply.type = X_Reply;
86305b261ecSmrg    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
86405b261ecSmrg    reply.sequenceNumber = client->sequence;
86505b261ecSmrg    if (pWin->parent)
86605b261ecSmrg	reply.parent = pWin->parent->drawable.id;
86705b261ecSmrg    else
86805b261ecSmrg        reply.parent = (Window)None;
86905b261ecSmrg    pHead = RealChildHead(pWin);
87005b261ecSmrg    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
87105b261ecSmrg	numChildren++;
87205b261ecSmrg    if (numChildren)
87305b261ecSmrg    {
87405b261ecSmrg	int curChild = 0;
87505b261ecSmrg
8764642e01fSmrg	childIDs = (Window *) xalloc(numChildren * sizeof(Window));
87705b261ecSmrg	if (!childIDs)
87805b261ecSmrg	    return BadAlloc;
87905b261ecSmrg	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
88005b261ecSmrg	    childIDs[curChild++] = pChild->drawable.id;
88105b261ecSmrg    }
88205b261ecSmrg
88305b261ecSmrg    reply.nChildren = numChildren;
88405b261ecSmrg    reply.length = (numChildren * sizeof(Window)) >> 2;
88505b261ecSmrg
88605b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
88705b261ecSmrg    if (numChildren)
88805b261ecSmrg    {
88905b261ecSmrg    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
89005b261ecSmrg	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
8914642e01fSmrg	xfree(childIDs);
89205b261ecSmrg    }
89305b261ecSmrg
89405b261ecSmrg    return(client->noClientException);
89505b261ecSmrg}
89605b261ecSmrg
89705b261ecSmrgint
89805b261ecSmrgProcInternAtom(ClientPtr client)
89905b261ecSmrg{
90005b261ecSmrg    Atom atom;
90105b261ecSmrg    char *tchar;
90205b261ecSmrg    REQUEST(xInternAtomReq);
90305b261ecSmrg
90405b261ecSmrg    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
90505b261ecSmrg    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
90605b261ecSmrg    {
90705b261ecSmrg	client->errorValue = stuff->onlyIfExists;
90805b261ecSmrg        return(BadValue);
90905b261ecSmrg    }
91005b261ecSmrg    tchar = (char *) &stuff[1];
91105b261ecSmrg    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
91205b261ecSmrg    if (atom != BAD_RESOURCE)
91305b261ecSmrg    {
91405b261ecSmrg	xInternAtomReply reply;
91505b261ecSmrg	reply.type = X_Reply;
91605b261ecSmrg	reply.length = 0;
91705b261ecSmrg	reply.sequenceNumber = client->sequence;
91805b261ecSmrg	reply.atom = atom;
91905b261ecSmrg	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
92005b261ecSmrg	return(client->noClientException);
92105b261ecSmrg    }
92205b261ecSmrg    else
92305b261ecSmrg	return (BadAlloc);
92405b261ecSmrg}
92505b261ecSmrg
92605b261ecSmrgint
92705b261ecSmrgProcGetAtomName(ClientPtr client)
92805b261ecSmrg{
92905b261ecSmrg    char *str;
93005b261ecSmrg    xGetAtomNameReply reply;
93105b261ecSmrg    int len;
93205b261ecSmrg    REQUEST(xResourceReq);
93305b261ecSmrg
93405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
93505b261ecSmrg    if ( (str = NameForAtom(stuff->id)) )
93605b261ecSmrg    {
93705b261ecSmrg	len = strlen(str);
93805b261ecSmrg	reply.type = X_Reply;
93905b261ecSmrg	reply.length = (len + 3) >> 2;
94005b261ecSmrg	reply.sequenceNumber = client->sequence;
94105b261ecSmrg	reply.nameLength = len;
94205b261ecSmrg	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
94305b261ecSmrg	(void)WriteToClient(client, len, str);
94405b261ecSmrg	return(client->noClientException);
94505b261ecSmrg    }
94605b261ecSmrg    else
94705b261ecSmrg    {
94805b261ecSmrg	client->errorValue = stuff->id;
94905b261ecSmrg	return (BadAtom);
95005b261ecSmrg    }
95105b261ecSmrg}
95205b261ecSmrg
95305b261ecSmrgint
95405b261ecSmrgProcGrabServer(ClientPtr client)
95505b261ecSmrg{
9564642e01fSmrg    int rc;
95705b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
95805b261ecSmrg    if (grabState != GrabNone && client != grabClient)
95905b261ecSmrg    {
96005b261ecSmrg	ResetCurrentRequest(client);
96105b261ecSmrg	client->sequence--;
96205b261ecSmrg	BITSET(grabWaiters, client->index);
96305b261ecSmrg	IgnoreClient(client);
96405b261ecSmrg	return(client->noClientException);
96505b261ecSmrg    }
9664642e01fSmrg    rc = OnlyListenToOneClient(client);
9674642e01fSmrg    if (rc != Success)
9684642e01fSmrg	return rc;
96905b261ecSmrg    grabState = GrabKickout;
97005b261ecSmrg    grabClient = client;
97105b261ecSmrg
97205b261ecSmrg    if (ServerGrabCallback)
97305b261ecSmrg    {
97405b261ecSmrg	ServerGrabInfoRec grabinfo;
97505b261ecSmrg	grabinfo.client = client;
97605b261ecSmrg	grabinfo.grabstate  = SERVER_GRABBED;
97705b261ecSmrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
97805b261ecSmrg    }
97905b261ecSmrg
98005b261ecSmrg    return(client->noClientException);
98105b261ecSmrg}
98205b261ecSmrg
98305b261ecSmrgstatic void
98405b261ecSmrgUngrabServer(ClientPtr client)
98505b261ecSmrg{
98605b261ecSmrg    int i;
98705b261ecSmrg
98805b261ecSmrg    grabState = GrabNone;
98905b261ecSmrg    ListenToAllClients();
99005b261ecSmrg    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
99105b261ecSmrg	;
99205b261ecSmrg    if (i >= 0)
99305b261ecSmrg    {
99405b261ecSmrg	i <<= 5;
99505b261ecSmrg	while (!GETBIT(grabWaiters, i))
99605b261ecSmrg	    i++;
99705b261ecSmrg	BITCLEAR(grabWaiters, i);
99805b261ecSmrg	AttendClient(clients[i]);
99905b261ecSmrg    }
100005b261ecSmrg
100105b261ecSmrg    if (ServerGrabCallback)
100205b261ecSmrg    {
100305b261ecSmrg	ServerGrabInfoRec grabinfo;
100405b261ecSmrg	grabinfo.client = client;
100505b261ecSmrg	grabinfo.grabstate  = SERVER_UNGRABBED;
100605b261ecSmrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
100705b261ecSmrg    }
100805b261ecSmrg}
100905b261ecSmrg
101005b261ecSmrgint
101105b261ecSmrgProcUngrabServer(ClientPtr client)
101205b261ecSmrg{
101305b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
101405b261ecSmrg    UngrabServer(client);
101505b261ecSmrg    return(client->noClientException);
101605b261ecSmrg}
101705b261ecSmrg
101805b261ecSmrgint
101905b261ecSmrgProcTranslateCoords(ClientPtr client)
102005b261ecSmrg{
102105b261ecSmrg    REQUEST(xTranslateCoordsReq);
102205b261ecSmrg
102305b261ecSmrg    WindowPtr pWin, pDst;
102405b261ecSmrg    xTranslateCoordsReply rep;
102505b261ecSmrg    int rc;
102605b261ecSmrg
102705b261ecSmrg    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
10284642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
102905b261ecSmrg    if (rc != Success)
103005b261ecSmrg        return rc;
10314642e01fSmrg    rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
103205b261ecSmrg    if (rc != Success)
103305b261ecSmrg        return rc;
103405b261ecSmrg    rep.type = X_Reply;
103505b261ecSmrg    rep.length = 0;
103605b261ecSmrg    rep.sequenceNumber = client->sequence;
103705b261ecSmrg    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
103805b261ecSmrg    {
103905b261ecSmrg	rep.sameScreen = xFalse;
104005b261ecSmrg        rep.child = None;
104105b261ecSmrg	rep.dstX = rep.dstY = 0;
104205b261ecSmrg    }
104305b261ecSmrg    else
104405b261ecSmrg    {
104505b261ecSmrg	INT16 x, y;
104605b261ecSmrg	rep.sameScreen = xTrue;
104705b261ecSmrg	rep.child = None;
104805b261ecSmrg	/* computing absolute coordinates -- adjust to destination later */
104905b261ecSmrg	x = pWin->drawable.x + stuff->srcX;
105005b261ecSmrg	y = pWin->drawable.y + stuff->srcY;
105105b261ecSmrg	pWin = pDst->firstChild;
105205b261ecSmrg	while (pWin)
105305b261ecSmrg	{
105405b261ecSmrg	    BoxRec  box;
105505b261ecSmrg	    if ((pWin->mapped) &&
105605b261ecSmrg		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
105705b261ecSmrg		(x < pWin->drawable.x + (int)pWin->drawable.width +
105805b261ecSmrg		 wBorderWidth (pWin)) &&
105905b261ecSmrg		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
106005b261ecSmrg		(y < pWin->drawable.y + (int)pWin->drawable.height +
106105b261ecSmrg		 wBorderWidth (pWin))
106205b261ecSmrg		/* When a window is shaped, a further check
106305b261ecSmrg		 * is made to see if the point is inside
106405b261ecSmrg		 * borderSize
106505b261ecSmrg		 */
106605b261ecSmrg		&& (!wBoundingShape(pWin) ||
106705b261ecSmrg		    POINT_IN_REGION(pWin->drawable.pScreen,
106805b261ecSmrg					&pWin->borderSize, x, y, &box))
106905b261ecSmrg
107005b261ecSmrg		&& (!wInputShape(pWin) ||
107105b261ecSmrg		    POINT_IN_REGION(pWin->drawable.pScreen,
107205b261ecSmrg				    wInputShape(pWin),
107305b261ecSmrg				    x - pWin->drawable.x,
107405b261ecSmrg				    y - pWin->drawable.y, &box))
107505b261ecSmrg		)
107605b261ecSmrg            {
107705b261ecSmrg		rep.child = pWin->drawable.id;
107805b261ecSmrg		pWin = (WindowPtr) NULL;
107905b261ecSmrg	    }
108005b261ecSmrg	    else
108105b261ecSmrg		pWin = pWin->nextSib;
108205b261ecSmrg	}
108305b261ecSmrg	/* adjust to destination coordinates */
108405b261ecSmrg	rep.dstX = x - pDst->drawable.x;
108505b261ecSmrg	rep.dstY = y - pDst->drawable.y;
108605b261ecSmrg    }
108705b261ecSmrg    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
108805b261ecSmrg    return(client->noClientException);
108905b261ecSmrg}
109005b261ecSmrg
109105b261ecSmrgint
109205b261ecSmrgProcOpenFont(ClientPtr client)
109305b261ecSmrg{
109405b261ecSmrg    int	err;
109505b261ecSmrg    REQUEST(xOpenFontReq);
109605b261ecSmrg
109705b261ecSmrg    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
109805b261ecSmrg    client->errorValue = stuff->fid;
109905b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->fid, client);
110005b261ecSmrg    err = OpenFont(client, stuff->fid, (Mask) 0,
110105b261ecSmrg		stuff->nbytes, (char *)&stuff[1]);
110205b261ecSmrg    if (err == Success)
110305b261ecSmrg    {
110405b261ecSmrg	return(client->noClientException);
110505b261ecSmrg    }
110605b261ecSmrg    else
110705b261ecSmrg	return err;
110805b261ecSmrg}
110905b261ecSmrg
111005b261ecSmrgint
111105b261ecSmrgProcCloseFont(ClientPtr client)
111205b261ecSmrg{
111305b261ecSmrg    FontPtr pFont;
111405b261ecSmrg    REQUEST(xResourceReq);
111505b261ecSmrg
111605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
111705b261ecSmrg    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
111805b261ecSmrg					    DixDestroyAccess);
111905b261ecSmrg    if ( pFont != (FontPtr)NULL)	/* id was valid */
112005b261ecSmrg    {
112105b261ecSmrg        FreeResource(stuff->id, RT_NONE);
112205b261ecSmrg	return(client->noClientException);
112305b261ecSmrg    }
112405b261ecSmrg    else
112505b261ecSmrg    {
112605b261ecSmrg	client->errorValue = stuff->id;
112705b261ecSmrg        return (BadFont);
112805b261ecSmrg    }
112905b261ecSmrg}
113005b261ecSmrg
113105b261ecSmrgint
113205b261ecSmrgProcQueryFont(ClientPtr client)
113305b261ecSmrg{
113405b261ecSmrg    xQueryFontReply	*reply;
113505b261ecSmrg    FontPtr pFont;
113605b261ecSmrg    GC *pGC;
11374642e01fSmrg    int rc;
113805b261ecSmrg    REQUEST(xResourceReq);
113905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
11404642e01fSmrg
114105b261ecSmrg    client->errorValue = stuff->id;		/* EITHER font or gc */
1142b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, client,
1143b86d567bSmrg				 DixGetAttrAccess);
11444642e01fSmrg    if (rc == BadValue) {
1145b86d567bSmrg	rc = dixLookupResourceByType((pointer *)&pGC, stuff->id, RT_GC, client,
1146b86d567bSmrg				     DixGetAttrAccess);
11474642e01fSmrg	if (rc == Success)
11484642e01fSmrg	    pFont = pGC->font;
114905b261ecSmrg    }
11504642e01fSmrg    if (rc != Success)
11514642e01fSmrg	return (rc == BadValue) ? BadFont: rc;
115205b261ecSmrg
115305b261ecSmrg    {
115405b261ecSmrg	xCharInfo	*pmax = FONTINKMAX(pFont);
115505b261ecSmrg	xCharInfo	*pmin = FONTINKMIN(pFont);
115605b261ecSmrg	int		nprotoxcistructs;
115705b261ecSmrg	int		rlength;
115805b261ecSmrg
115905b261ecSmrg	nprotoxcistructs = (
116005b261ecSmrg	   pmax->rightSideBearing == pmin->rightSideBearing &&
116105b261ecSmrg	   pmax->leftSideBearing == pmin->leftSideBearing &&
116205b261ecSmrg	   pmax->descent == pmin->descent &&
116305b261ecSmrg	   pmax->ascent == pmin->ascent &&
116405b261ecSmrg	   pmax->characterWidth == pmin->characterWidth) ?
116505b261ecSmrg		0 : N2dChars(pFont);
116605b261ecSmrg
116705b261ecSmrg	rlength = sizeof(xQueryFontReply) +
116805b261ecSmrg	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
116905b261ecSmrg		     nprotoxcistructs * sizeof(xCharInfo);
11704642e01fSmrg	reply = (xQueryFontReply *)xalloc(rlength);
117105b261ecSmrg	if(!reply)
117205b261ecSmrg	{
117305b261ecSmrg	    return(BadAlloc);
117405b261ecSmrg	}
117505b261ecSmrg
117605b261ecSmrg	reply->type = X_Reply;
117705b261ecSmrg	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
117805b261ecSmrg	reply->sequenceNumber = client->sequence;
117905b261ecSmrg	QueryFont( pFont, reply, nprotoxcistructs);
118005b261ecSmrg
118105b261ecSmrg        WriteReplyToClient(client, rlength, reply);
11824642e01fSmrg	xfree(reply);
118305b261ecSmrg	return(client->noClientException);
118405b261ecSmrg    }
118505b261ecSmrg}
118605b261ecSmrg
118705b261ecSmrgint
118805b261ecSmrgProcQueryTextExtents(ClientPtr client)
118905b261ecSmrg{
119005b261ecSmrg    xQueryTextExtentsReply reply;
119105b261ecSmrg    FontPtr pFont;
119205b261ecSmrg    GC *pGC;
119305b261ecSmrg    ExtentInfoRec info;
119405b261ecSmrg    unsigned long length;
11954642e01fSmrg    int rc;
11964642e01fSmrg    REQUEST(xQueryTextExtentsReq);
119705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
119805b261ecSmrg
11994642e01fSmrg    client->errorValue = stuff->fid;		/* EITHER font or gc */
1200b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pFont, stuff->fid, RT_FONT, client,
1201b86d567bSmrg				 DixGetAttrAccess);
12024642e01fSmrg    if (rc == BadValue) {
1203b86d567bSmrg	rc = dixLookupResourceByType((pointer *)&pGC, stuff->fid, RT_GC, client,
12044642e01fSmrg			       DixGetAttrAccess);
12054642e01fSmrg	if (rc == Success)
12064642e01fSmrg	    pFont = pGC->font;
120705b261ecSmrg    }
12084642e01fSmrg    if (rc != Success)
12094642e01fSmrg	return (rc == BadValue) ? BadFont: rc;
12104642e01fSmrg
121105b261ecSmrg    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
121205b261ecSmrg    length = length << 1;
121305b261ecSmrg    if (stuff->oddLength)
121405b261ecSmrg    {
121505b261ecSmrg	if (length == 0)
121605b261ecSmrg	    return(BadLength);
121705b261ecSmrg        length--;
121805b261ecSmrg    }
121905b261ecSmrg    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
122005b261ecSmrg	return(BadAlloc);
122105b261ecSmrg    reply.type = X_Reply;
122205b261ecSmrg    reply.length = 0;
122305b261ecSmrg    reply.sequenceNumber = client->sequence;
122405b261ecSmrg    reply.drawDirection = info.drawDirection;
122505b261ecSmrg    reply.fontAscent = info.fontAscent;
122605b261ecSmrg    reply.fontDescent = info.fontDescent;
122705b261ecSmrg    reply.overallAscent = info.overallAscent;
122805b261ecSmrg    reply.overallDescent = info.overallDescent;
122905b261ecSmrg    reply.overallWidth = info.overallWidth;
123005b261ecSmrg    reply.overallLeft = info.overallLeft;
123105b261ecSmrg    reply.overallRight = info.overallRight;
123205b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
123305b261ecSmrg    return(client->noClientException);
123405b261ecSmrg}
123505b261ecSmrg
123605b261ecSmrgint
123705b261ecSmrgProcListFonts(ClientPtr client)
123805b261ecSmrg{
123905b261ecSmrg    REQUEST(xListFontsReq);
124005b261ecSmrg
124105b261ecSmrg    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
124205b261ecSmrg
124305b261ecSmrg    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
124405b261ecSmrg	stuff->maxNames);
124505b261ecSmrg}
124605b261ecSmrg
124705b261ecSmrgint
124805b261ecSmrgProcListFontsWithInfo(ClientPtr client)
124905b261ecSmrg{
125005b261ecSmrg    REQUEST(xListFontsWithInfoReq);
125105b261ecSmrg
125205b261ecSmrg    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
125305b261ecSmrg
125405b261ecSmrg    return StartListFontsWithInfo(client, stuff->nbytes,
125505b261ecSmrg				  (unsigned char *) &stuff[1], stuff->maxNames);
125605b261ecSmrg}
125705b261ecSmrg
125805b261ecSmrg/**
125905b261ecSmrg *
126005b261ecSmrg *  \param value must conform to DeleteType
126105b261ecSmrg */
126205b261ecSmrgint
126305b261ecSmrgdixDestroyPixmap(pointer value, XID pid)
126405b261ecSmrg{
126505b261ecSmrg    PixmapPtr pPixmap = (PixmapPtr)value;
126605b261ecSmrg    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
126705b261ecSmrg}
126805b261ecSmrg
126905b261ecSmrgint
127005b261ecSmrgProcCreatePixmap(ClientPtr client)
127105b261ecSmrg{
127205b261ecSmrg    PixmapPtr pMap;
127305b261ecSmrg    DrawablePtr pDraw;
127405b261ecSmrg    REQUEST(xCreatePixmapReq);
127505b261ecSmrg    DepthPtr pDepth;
127605b261ecSmrg    int i, rc;
127705b261ecSmrg
127805b261ecSmrg    REQUEST_SIZE_MATCH(xCreatePixmapReq);
127905b261ecSmrg    client->errorValue = stuff->pid;
128005b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
128105b261ecSmrg
128205b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
12834642e01fSmrg			   DixGetAttrAccess);
128405b261ecSmrg    if (rc != Success)
128505b261ecSmrg	return rc;
128605b261ecSmrg
128705b261ecSmrg    if (!stuff->width || !stuff->height)
128805b261ecSmrg    {
128905b261ecSmrg	client->errorValue = 0;
129005b261ecSmrg        return BadValue;
129105b261ecSmrg    }
129205b261ecSmrg    if (stuff->width > 32767 || stuff->height > 32767)
129305b261ecSmrg    {
129405b261ecSmrg	/* It is allowed to try and allocate a pixmap which is larger than
129505b261ecSmrg	 * 32767 in either dimension. However, all of the framebuffer code
129605b261ecSmrg	 * is buggy and does not reliably draw to such big pixmaps, basically
129705b261ecSmrg	 * because the Region data structure operates with signed shorts
129805b261ecSmrg	 * for the rectangles in it.
129905b261ecSmrg	 *
130005b261ecSmrg	 * Furthermore, several places in the X server computes the
130105b261ecSmrg	 * size in bytes of the pixmap and tries to store it in an
130205b261ecSmrg	 * integer. This integer can overflow and cause the allocated size
130305b261ecSmrg	 * to be much smaller.
130405b261ecSmrg	 *
130505b261ecSmrg	 * So, such big pixmaps are rejected here with a BadAlloc
130605b261ecSmrg	 */
130705b261ecSmrg	return BadAlloc;
130805b261ecSmrg    }
130905b261ecSmrg    if (stuff->depth != 1)
131005b261ecSmrg    {
131105b261ecSmrg        pDepth = pDraw->pScreen->allowedDepths;
131205b261ecSmrg        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
131305b261ecSmrg	   if (pDepth->depth == stuff->depth)
131405b261ecSmrg               goto CreatePmap;
131505b261ecSmrg	client->errorValue = stuff->depth;
131605b261ecSmrg        return BadValue;
131705b261ecSmrg    }
131805b261ecSmrgCreatePmap:
131905b261ecSmrg    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
132005b261ecSmrg		(pDraw->pScreen, stuff->width,
13214642e01fSmrg		 stuff->height, stuff->depth, 0);
132205b261ecSmrg    if (pMap)
132305b261ecSmrg    {
132405b261ecSmrg	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
132505b261ecSmrg	pMap->drawable.id = stuff->pid;
13264642e01fSmrg	/* security creation/labeling check */
13274642e01fSmrg	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
13284642e01fSmrg		      pMap, RT_NONE, NULL, DixCreateAccess);
13294642e01fSmrg	if (rc != Success) {
13304642e01fSmrg	    (*pDraw->pScreen->DestroyPixmap)(pMap);
13314642e01fSmrg	    return rc;
13324642e01fSmrg	}
133305b261ecSmrg	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
133405b261ecSmrg	    return(client->noClientException);
13354642e01fSmrg	(*pDraw->pScreen->DestroyPixmap)(pMap);
133605b261ecSmrg    }
133705b261ecSmrg    return (BadAlloc);
133805b261ecSmrg}
133905b261ecSmrg
134005b261ecSmrgint
134105b261ecSmrgProcFreePixmap(ClientPtr client)
134205b261ecSmrg{
134305b261ecSmrg    PixmapPtr pMap;
13444642e01fSmrg    int rc;
134505b261ecSmrg    REQUEST(xResourceReq);
134605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
13474642e01fSmrg
1348b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client,
13494642e01fSmrg			   DixDestroyAccess);
13504642e01fSmrg    if (rc == Success)
135105b261ecSmrg    {
135205b261ecSmrg	FreeResource(stuff->id, RT_NONE);
135305b261ecSmrg	return(client->noClientException);
135405b261ecSmrg    }
135505b261ecSmrg    else
135605b261ecSmrg    {
135705b261ecSmrg	client->errorValue = stuff->id;
13584642e01fSmrg	return (rc == BadValue) ? BadPixmap : rc;
135905b261ecSmrg    }
136005b261ecSmrg}
136105b261ecSmrg
136205b261ecSmrgint
136305b261ecSmrgProcCreateGC(ClientPtr client)
136405b261ecSmrg{
136505b261ecSmrg    int error, rc;
136605b261ecSmrg    GC *pGC;
136705b261ecSmrg    DrawablePtr pDraw;
136805b261ecSmrg    unsigned len;
136905b261ecSmrg    REQUEST(xCreateGCReq);
137005b261ecSmrg
137105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
137205b261ecSmrg    client->errorValue = stuff->gc;
137305b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gc, client);
13744642e01fSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
13754642e01fSmrg			   DixGetAttrAccess);
137605b261ecSmrg    if (rc != Success)
137705b261ecSmrg	return rc;
137805b261ecSmrg
137905b261ecSmrg    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
138005b261ecSmrg    if (len != Ones(stuff->mask))
138105b261ecSmrg        return BadLength;
13824642e01fSmrg    pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
13834642e01fSmrg			 stuff->gc, client);
138405b261ecSmrg    if (error != Success)
138505b261ecSmrg        return error;
138605b261ecSmrg    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
138705b261ecSmrg	return (BadAlloc);
138805b261ecSmrg    return(client->noClientException);
138905b261ecSmrg}
139005b261ecSmrg
139105b261ecSmrgint
139205b261ecSmrgProcChangeGC(ClientPtr client)
139305b261ecSmrg{
139405b261ecSmrg    GC *pGC;
139505b261ecSmrg    int result;
139605b261ecSmrg    unsigned len;
139705b261ecSmrg    REQUEST(xChangeGCReq);
139805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
139905b261ecSmrg
14004642e01fSmrg    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
140105b261ecSmrg    if (result != Success)
140205b261ecSmrg	return result;
140305b261ecSmrg
140405b261ecSmrg    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
140505b261ecSmrg    if (len != Ones(stuff->mask))
140605b261ecSmrg        return BadLength;
140705b261ecSmrg
140805b261ecSmrg    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
140905b261ecSmrg    if (client->noClientException != Success)
141005b261ecSmrg        return(client->noClientException);
141105b261ecSmrg    else
141205b261ecSmrg    {
141305b261ecSmrg	client->errorValue = clientErrorValue;
141405b261ecSmrg        return(result);
141505b261ecSmrg    }
141605b261ecSmrg}
141705b261ecSmrg
141805b261ecSmrgint
141905b261ecSmrgProcCopyGC(ClientPtr client)
142005b261ecSmrg{
142105b261ecSmrg    GC *dstGC;
142205b261ecSmrg    GC *pGC;
142305b261ecSmrg    int result;
142405b261ecSmrg    REQUEST(xCopyGCReq);
142505b261ecSmrg    REQUEST_SIZE_MATCH(xCopyGCReq);
142605b261ecSmrg
14274642e01fSmrg    result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
142805b261ecSmrg    if (result != Success)
142905b261ecSmrg	return result;
14304642e01fSmrg    result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
143105b261ecSmrg    if (result != Success)
143205b261ecSmrg	return result;
143305b261ecSmrg    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
143405b261ecSmrg        return (BadMatch);
143505b261ecSmrg    result = CopyGC(pGC, dstGC, stuff->mask);
143605b261ecSmrg    if (client->noClientException != Success)
143705b261ecSmrg        return(client->noClientException);
143805b261ecSmrg    else
143905b261ecSmrg    {
144005b261ecSmrg	client->errorValue = clientErrorValue;
144105b261ecSmrg        return(result);
144205b261ecSmrg    }
144305b261ecSmrg}
144405b261ecSmrg
144505b261ecSmrgint
144605b261ecSmrgProcSetDashes(ClientPtr client)
144705b261ecSmrg{
144805b261ecSmrg    GC *pGC;
144905b261ecSmrg    int result;
145005b261ecSmrg    REQUEST(xSetDashesReq);
145105b261ecSmrg
145205b261ecSmrg    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
145305b261ecSmrg    if (stuff->nDashes == 0)
145405b261ecSmrg    {
145505b261ecSmrg	 client->errorValue = 0;
145605b261ecSmrg         return BadValue;
145705b261ecSmrg    }
145805b261ecSmrg
14594642e01fSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
146005b261ecSmrg    if (result != Success)
146105b261ecSmrg	return result;
146205b261ecSmrg
146305b261ecSmrg    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
146405b261ecSmrg		       (unsigned char *)&stuff[1]);
146505b261ecSmrg    if (client->noClientException != Success)
146605b261ecSmrg        return(client->noClientException);
146705b261ecSmrg    else
146805b261ecSmrg    {
146905b261ecSmrg	client->errorValue = clientErrorValue;
147005b261ecSmrg        return(result);
147105b261ecSmrg    }
147205b261ecSmrg}
147305b261ecSmrg
147405b261ecSmrgint
147505b261ecSmrgProcSetClipRectangles(ClientPtr client)
147605b261ecSmrg{
147705b261ecSmrg    int	nr, result;
147805b261ecSmrg    GC *pGC;
147905b261ecSmrg    REQUEST(xSetClipRectanglesReq);
148005b261ecSmrg
148105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
148205b261ecSmrg    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
148305b261ecSmrg	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
148405b261ecSmrg    {
148505b261ecSmrg	client->errorValue = stuff->ordering;
148605b261ecSmrg        return BadValue;
148705b261ecSmrg    }
14884642e01fSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
148905b261ecSmrg    if (result != Success)
149005b261ecSmrg	return result;
149105b261ecSmrg
149205b261ecSmrg    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
149305b261ecSmrg    if (nr & 4)
149405b261ecSmrg	return(BadLength);
149505b261ecSmrg    nr >>= 3;
149605b261ecSmrg    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
149705b261ecSmrg			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
149805b261ecSmrg    if (client->noClientException != Success)
149905b261ecSmrg        return(client->noClientException);
150005b261ecSmrg    else
150105b261ecSmrg        return(result);
150205b261ecSmrg}
150305b261ecSmrg
150405b261ecSmrgint
150505b261ecSmrgProcFreeGC(ClientPtr client)
150605b261ecSmrg{
150705b261ecSmrg    GC *pGC;
150805b261ecSmrg    int rc;
150905b261ecSmrg    REQUEST(xResourceReq);
151005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
151105b261ecSmrg
151205b261ecSmrg    rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
151305b261ecSmrg    if (rc != Success)
151405b261ecSmrg	return rc;
151505b261ecSmrg
151605b261ecSmrg    FreeResource(stuff->id, RT_NONE);
151705b261ecSmrg    return(client->noClientException);
151805b261ecSmrg}
151905b261ecSmrg
152005b261ecSmrgint
152105b261ecSmrgProcClearToBackground(ClientPtr client)
152205b261ecSmrg{
152305b261ecSmrg    REQUEST(xClearAreaReq);
152405b261ecSmrg    WindowPtr pWin;
152505b261ecSmrg    int rc;
152605b261ecSmrg
152705b261ecSmrg    REQUEST_SIZE_MATCH(xClearAreaReq);
152805b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
152905b261ecSmrg    if (rc != Success)
153005b261ecSmrg        return rc;
153105b261ecSmrg    if (pWin->drawable.class == InputOnly)
153205b261ecSmrg    {
153305b261ecSmrg	client->errorValue = stuff->window;
153405b261ecSmrg	return (BadMatch);
153505b261ecSmrg    }
153605b261ecSmrg    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
153705b261ecSmrg    {
153805b261ecSmrg	client->errorValue = stuff->exposures;
153905b261ecSmrg        return(BadValue);
154005b261ecSmrg    }
154105b261ecSmrg    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
154205b261ecSmrg			       stuff->width, stuff->height,
154305b261ecSmrg			       (Bool)stuff->exposures);
154405b261ecSmrg    return(client->noClientException);
154505b261ecSmrg}
154605b261ecSmrg
154705b261ecSmrgint
154805b261ecSmrgProcCopyArea(ClientPtr client)
154905b261ecSmrg{
155005b261ecSmrg    DrawablePtr pDst;
155105b261ecSmrg    DrawablePtr pSrc;
155205b261ecSmrg    GC *pGC;
155305b261ecSmrg    REQUEST(xCopyAreaReq);
155405b261ecSmrg    RegionPtr pRgn;
155505b261ecSmrg    int rc;
155605b261ecSmrg
155705b261ecSmrg    REQUEST_SIZE_MATCH(xCopyAreaReq);
155805b261ecSmrg
15594642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
156005b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
156105b261ecSmrg    {
156205b261ecSmrg	rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
156305b261ecSmrg				 DixReadAccess);
156405b261ecSmrg	if (rc != Success)
156505b261ecSmrg	    return rc;
156605b261ecSmrg	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
156705b261ecSmrg	{
156805b261ecSmrg	    client->errorValue = stuff->dstDrawable;
156905b261ecSmrg	    return (BadMatch);
157005b261ecSmrg	}
157105b261ecSmrg    }
157205b261ecSmrg    else
157305b261ecSmrg        pSrc = pDst;
157405b261ecSmrg
157505b261ecSmrg    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
157605b261ecSmrg				 stuff->width, stuff->height,
157705b261ecSmrg				 stuff->dstX, stuff->dstY);
157805b261ecSmrg    if (pGC->graphicsExposures)
157905b261ecSmrg    {
158005b261ecSmrg	(*pDst->pScreen->SendGraphicsExpose)
158105b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
158205b261ecSmrg	if (pRgn)
158305b261ecSmrg	    REGION_DESTROY(pDst->pScreen, pRgn);
158405b261ecSmrg    }
158505b261ecSmrg
158605b261ecSmrg    return(client->noClientException);
158705b261ecSmrg}
158805b261ecSmrg
158905b261ecSmrgint
159005b261ecSmrgProcCopyPlane(ClientPtr client)
159105b261ecSmrg{
159205b261ecSmrg    DrawablePtr psrcDraw, pdstDraw;
159305b261ecSmrg    GC *pGC;
159405b261ecSmrg    REQUEST(xCopyPlaneReq);
159505b261ecSmrg    RegionPtr pRgn;
159605b261ecSmrg    int rc;
159705b261ecSmrg
159805b261ecSmrg    REQUEST_SIZE_MATCH(xCopyPlaneReq);
159905b261ecSmrg
16004642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
160105b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
160205b261ecSmrg    {
160305b261ecSmrg	rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
160405b261ecSmrg			       DixReadAccess);
160505b261ecSmrg	if (rc != Success)
160605b261ecSmrg	    return rc;
160705b261ecSmrg
160805b261ecSmrg	if (pdstDraw->pScreen != psrcDraw->pScreen)
160905b261ecSmrg	{
161005b261ecSmrg	    client->errorValue = stuff->dstDrawable;
161105b261ecSmrg	    return (BadMatch);
161205b261ecSmrg	}
161305b261ecSmrg    }
161405b261ecSmrg    else
161505b261ecSmrg        psrcDraw = pdstDraw;
161605b261ecSmrg
161705b261ecSmrg    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
161805b261ecSmrg    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
161905b261ecSmrg       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
162005b261ecSmrg    {
162105b261ecSmrg       client->errorValue = stuff->bitPlane;
162205b261ecSmrg       return(BadValue);
162305b261ecSmrg    }
162405b261ecSmrg
162505b261ecSmrg    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
162605b261ecSmrg				 stuff->width, stuff->height,
162705b261ecSmrg				 stuff->dstX, stuff->dstY, stuff->bitPlane);
162805b261ecSmrg    if (pGC->graphicsExposures)
162905b261ecSmrg    {
163005b261ecSmrg	(*pdstDraw->pScreen->SendGraphicsExpose)
163105b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
163205b261ecSmrg	if (pRgn)
163305b261ecSmrg	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
163405b261ecSmrg    }
163505b261ecSmrg    return(client->noClientException);
163605b261ecSmrg}
163705b261ecSmrg
163805b261ecSmrgint
163905b261ecSmrgProcPolyPoint(ClientPtr client)
164005b261ecSmrg{
164105b261ecSmrg    int npoint;
164205b261ecSmrg    GC *pGC;
164305b261ecSmrg    DrawablePtr pDraw;
164405b261ecSmrg    REQUEST(xPolyPointReq);
164505b261ecSmrg
164605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
164705b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
164805b261ecSmrg	(stuff->coordMode != CoordModePrevious))
164905b261ecSmrg    {
165005b261ecSmrg	client->errorValue = stuff->coordMode;
165105b261ecSmrg        return BadValue;
165205b261ecSmrg    }
16534642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
165405b261ecSmrg    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
165505b261ecSmrg    if (npoint)
165605b261ecSmrg        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
165705b261ecSmrg			  (xPoint *) &stuff[1]);
165805b261ecSmrg    return (client->noClientException);
165905b261ecSmrg}
166005b261ecSmrg
166105b261ecSmrgint
166205b261ecSmrgProcPolyLine(ClientPtr client)
166305b261ecSmrg{
166405b261ecSmrg    int npoint;
166505b261ecSmrg    GC *pGC;
166605b261ecSmrg    DrawablePtr pDraw;
166705b261ecSmrg    REQUEST(xPolyLineReq);
166805b261ecSmrg
166905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
167005b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
167105b261ecSmrg	(stuff->coordMode != CoordModePrevious))
167205b261ecSmrg    {
167305b261ecSmrg	client->errorValue = stuff->coordMode;
167405b261ecSmrg        return BadValue;
167505b261ecSmrg    }
16764642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
167705b261ecSmrg    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
167805b261ecSmrg    if (npoint > 1)
167905b261ecSmrg	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
168005b261ecSmrg			      (DDXPointPtr) &stuff[1]);
168105b261ecSmrg    return(client->noClientException);
168205b261ecSmrg}
168305b261ecSmrg
168405b261ecSmrgint
168505b261ecSmrgProcPolySegment(ClientPtr client)
168605b261ecSmrg{
168705b261ecSmrg    int nsegs;
168805b261ecSmrg    GC *pGC;
168905b261ecSmrg    DrawablePtr pDraw;
169005b261ecSmrg    REQUEST(xPolySegmentReq);
169105b261ecSmrg
169205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
16934642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
169405b261ecSmrg    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
169505b261ecSmrg    if (nsegs & 4)
169605b261ecSmrg	return(BadLength);
169705b261ecSmrg    nsegs >>= 3;
169805b261ecSmrg    if (nsegs)
169905b261ecSmrg        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
170005b261ecSmrg    return (client->noClientException);
170105b261ecSmrg}
170205b261ecSmrg
170305b261ecSmrgint
170405b261ecSmrgProcPolyRectangle (ClientPtr client)
170505b261ecSmrg{
170605b261ecSmrg    int nrects;
170705b261ecSmrg    GC *pGC;
170805b261ecSmrg    DrawablePtr pDraw;
170905b261ecSmrg    REQUEST(xPolyRectangleReq);
171005b261ecSmrg
171105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
17124642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
171305b261ecSmrg    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
171405b261ecSmrg    if (nrects & 4)
171505b261ecSmrg	return(BadLength);
171605b261ecSmrg    nrects >>= 3;
171705b261ecSmrg    if (nrects)
171805b261ecSmrg        (*pGC->ops->PolyRectangle)(pDraw, pGC,
171905b261ecSmrg		    nrects, (xRectangle *) &stuff[1]);
172005b261ecSmrg    return(client->noClientException);
172105b261ecSmrg}
172205b261ecSmrg
172305b261ecSmrgint
172405b261ecSmrgProcPolyArc(ClientPtr client)
172505b261ecSmrg{
172605b261ecSmrg    int		narcs;
172705b261ecSmrg    GC *pGC;
172805b261ecSmrg    DrawablePtr pDraw;
172905b261ecSmrg    REQUEST(xPolyArcReq);
173005b261ecSmrg
173105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
17324642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
173305b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
173405b261ecSmrg    if (narcs % sizeof(xArc))
173505b261ecSmrg	return(BadLength);
173605b261ecSmrg    narcs /= sizeof(xArc);
173705b261ecSmrg    if (narcs)
173805b261ecSmrg        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
173905b261ecSmrg    return (client->noClientException);
174005b261ecSmrg}
174105b261ecSmrg
174205b261ecSmrgint
174305b261ecSmrgProcFillPoly(ClientPtr client)
174405b261ecSmrg{
174505b261ecSmrg    int          things;
174605b261ecSmrg    GC *pGC;
174705b261ecSmrg    DrawablePtr pDraw;
174805b261ecSmrg    REQUEST(xFillPolyReq);
174905b261ecSmrg
175005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
175105b261ecSmrg    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
175205b261ecSmrg	(stuff->shape != Convex))
175305b261ecSmrg    {
175405b261ecSmrg	client->errorValue = stuff->shape;
175505b261ecSmrg        return BadValue;
175605b261ecSmrg    }
175705b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
175805b261ecSmrg	(stuff->coordMode != CoordModePrevious))
175905b261ecSmrg    {
176005b261ecSmrg	client->errorValue = stuff->coordMode;
176105b261ecSmrg        return BadValue;
176205b261ecSmrg    }
176305b261ecSmrg
17644642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
176505b261ecSmrg    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
176605b261ecSmrg    if (things)
176705b261ecSmrg        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
176805b261ecSmrg			 stuff->coordMode, things,
176905b261ecSmrg			 (DDXPointPtr) &stuff[1]);
177005b261ecSmrg    return(client->noClientException);
177105b261ecSmrg}
177205b261ecSmrg
177305b261ecSmrgint
177405b261ecSmrgProcPolyFillRectangle(ClientPtr client)
177505b261ecSmrg{
177605b261ecSmrg    int             things;
177705b261ecSmrg    GC *pGC;
177805b261ecSmrg    DrawablePtr pDraw;
177905b261ecSmrg    REQUEST(xPolyFillRectangleReq);
178005b261ecSmrg
178105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
17824642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
178305b261ecSmrg    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
178405b261ecSmrg    if (things & 4)
178505b261ecSmrg	return(BadLength);
178605b261ecSmrg    things >>= 3;
178705b261ecSmrg
178805b261ecSmrg    if (things)
178905b261ecSmrg        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
179005b261ecSmrg		      (xRectangle *) &stuff[1]);
179105b261ecSmrg    return (client->noClientException);
179205b261ecSmrg}
179305b261ecSmrg
179405b261ecSmrgint
179505b261ecSmrgProcPolyFillArc(ClientPtr client)
179605b261ecSmrg{
179705b261ecSmrg    int		narcs;
179805b261ecSmrg    GC *pGC;
179905b261ecSmrg    DrawablePtr pDraw;
180005b261ecSmrg    REQUEST(xPolyFillArcReq);
180105b261ecSmrg
180205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
18034642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
180405b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
180505b261ecSmrg    if (narcs % sizeof(xArc))
180605b261ecSmrg	return(BadLength);
180705b261ecSmrg    narcs /= sizeof(xArc);
180805b261ecSmrg    if (narcs)
180905b261ecSmrg        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
181005b261ecSmrg    return (client->noClientException);
181105b261ecSmrg}
181205b261ecSmrg
181305b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
181405b261ecSmrg
181505b261ecSmrgint
181605b261ecSmrgServerOrder (void)
181705b261ecSmrg{
181805b261ecSmrg    int	    whichbyte = 1;
181905b261ecSmrg
182005b261ecSmrg    if (*((char *) &whichbyte))
182105b261ecSmrg	return LSBFirst;
182205b261ecSmrg    return MSBFirst;
182305b261ecSmrg}
182405b261ecSmrg
182505b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
182605b261ecSmrg
182705b261ecSmrgvoid
182805b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order)
182905b261ecSmrg{
183005b261ecSmrg    switch (bpp) {
183105b261ecSmrg    case 1:	/* yuck */
183205b261ecSmrg	if (BITMAP_BIT_ORDER != order)
183305b261ecSmrg	    BitOrderInvert ((unsigned char *) base, nbytes);
183405b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
183505b261ecSmrg	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
183605b261ecSmrg#endif
183705b261ecSmrg	break;
183805b261ecSmrg    case 4:
183905b261ecSmrg	break;  /* yuck */
184005b261ecSmrg    case 8:
184105b261ecSmrg	break;
184205b261ecSmrg    case 16:
184305b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
184405b261ecSmrg	    TwoByteSwap ((unsigned char *) base, nbytes);
184505b261ecSmrg	break;
184605b261ecSmrg    case 32:
184705b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
184805b261ecSmrg	    FourByteSwap ((unsigned char *) base, nbytes);
184905b261ecSmrg	break;
185005b261ecSmrg    }
185105b261ecSmrg}
185205b261ecSmrg#else
185305b261ecSmrg#define ReformatImage(b,n,bpp,o)
185405b261ecSmrg#endif
185505b261ecSmrg
185605b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to
185705b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
185805b261ecSmrg * to use internally. Removes need for internal alignment checking.
185905b261ecSmrg * All of the PutImage functions could be changed individually, but
186005b261ecSmrg * as currently written, they call other routines which require things
186105b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here.
186205b261ecSmrg * If an image would be padded differently for 64- versus 32-, then
186305b261ecSmrg * copy each scanline to a 64-bit padded scanline.
186405b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit
186505b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction.
186605b261ecSmrg */
186705b261ecSmrgint
186805b261ecSmrgProcPutImage(ClientPtr client)
186905b261ecSmrg{
187005b261ecSmrg    GC *pGC;
187105b261ecSmrg    DrawablePtr pDraw;
187205b261ecSmrg    long	length; 	/* length of scanline server padded */
187305b261ecSmrg    long 	lengthProto; 	/* length of scanline protocol padded */
187405b261ecSmrg    char	*tmpImage;
187505b261ecSmrg    REQUEST(xPutImageReq);
187605b261ecSmrg
187705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPutImageReq);
18784642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
187905b261ecSmrg    if (stuff->format == XYBitmap)
188005b261ecSmrg    {
188105b261ecSmrg        if ((stuff->depth != 1) ||
188205b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
188305b261ecSmrg            return BadMatch;
188405b261ecSmrg        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
188505b261ecSmrg    }
188605b261ecSmrg    else if (stuff->format == XYPixmap)
188705b261ecSmrg    {
188805b261ecSmrg        if ((pDraw->depth != stuff->depth) ||
188905b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
189005b261ecSmrg            return BadMatch;
189105b261ecSmrg        length      = BitmapBytePad(stuff->width + stuff->leftPad);
189205b261ecSmrg	length      *= stuff->depth;
189305b261ecSmrg    }
189405b261ecSmrg    else if (stuff->format == ZPixmap)
189505b261ecSmrg    {
189605b261ecSmrg        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
189705b261ecSmrg            return BadMatch;
189805b261ecSmrg        length      = PixmapBytePad(stuff->width, stuff->depth);
189905b261ecSmrg    }
190005b261ecSmrg    else
190105b261ecSmrg    {
190205b261ecSmrg	client->errorValue = stuff->format;
190305b261ecSmrg        return BadValue;
190405b261ecSmrg    }
190505b261ecSmrg
190605b261ecSmrg    tmpImage = (char *)&stuff[1];
190705b261ecSmrg    lengthProto = length;
190805b261ecSmrg
190905b261ecSmrg    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
191005b261ecSmrg	(sizeof(xPutImageReq) >> 2)) != client->req_len)
191105b261ecSmrg	return BadLength;
191205b261ecSmrg
191305b261ecSmrg    ReformatImage (tmpImage, lengthProto * stuff->height,
191405b261ecSmrg		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
191505b261ecSmrg		   ClientOrder(client));
191605b261ecSmrg
191705b261ecSmrg    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
191805b261ecSmrg		  stuff->width, stuff->height,
191905b261ecSmrg		  stuff->leftPad, stuff->format, tmpImage);
192005b261ecSmrg
192105b261ecSmrg     return (client->noClientException);
192205b261ecSmrg}
192305b261ecSmrg
192405b261ecSmrgstatic int
192505b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable,
192605b261ecSmrg           int x, int y, int width, int height,
192705b261ecSmrg           Mask planemask, xGetImageReply **im_return)
192805b261ecSmrg{
192905b261ecSmrg    DrawablePtr		pDraw;
193005b261ecSmrg    int			nlines, linesPerBuf, rc;
193105b261ecSmrg    int	linesDone;
193205b261ecSmrg    long		widthBytesLine, length;
193305b261ecSmrg    Mask		plane = 0;
193405b261ecSmrg    char		*pBuf;
193505b261ecSmrg    xGetImageReply	xgi;
193605b261ecSmrg    RegionPtr pVisibleRegion = NULL;
193705b261ecSmrg
193805b261ecSmrg    if ((format != XYPixmap) && (format != ZPixmap))
193905b261ecSmrg    {
194005b261ecSmrg	client->errorValue = format;
194105b261ecSmrg        return(BadValue);
194205b261ecSmrg    }
194305b261ecSmrg    rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
194405b261ecSmrg    if (rc != Success)
194505b261ecSmrg	return rc;
194605b261ecSmrg
194705b261ecSmrg    if(pDraw->type == DRAWABLE_WINDOW)
194805b261ecSmrg    {
194905b261ecSmrg      if( /* check for being viewable */
195005b261ecSmrg	 !((WindowPtr) pDraw)->realized ||
195105b261ecSmrg	  /* check for being on screen */
195205b261ecSmrg         pDraw->x + x < 0 ||
195305b261ecSmrg 	 pDraw->x + x + width > pDraw->pScreen->width ||
195405b261ecSmrg         pDraw->y + y < 0 ||
195505b261ecSmrg         pDraw->y + y + height > pDraw->pScreen->height ||
195605b261ecSmrg          /* check for being inside of border */
195705b261ecSmrg         x < - wBorderWidth((WindowPtr)pDraw) ||
195805b261ecSmrg         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
195905b261ecSmrg         y < -wBorderWidth((WindowPtr)pDraw) ||
196005b261ecSmrg         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
196105b261ecSmrg        )
196205b261ecSmrg	    return(BadMatch);
196305b261ecSmrg	xgi.visual = wVisual (((WindowPtr) pDraw));
196405b261ecSmrg    }
196505b261ecSmrg    else
196605b261ecSmrg    {
196705b261ecSmrg      if(x < 0 ||
196805b261ecSmrg         x+width > (int)pDraw->width ||
196905b261ecSmrg         y < 0 ||
197005b261ecSmrg         y+height > (int)pDraw->height
197105b261ecSmrg        )
197205b261ecSmrg	    return(BadMatch);
197305b261ecSmrg	xgi.visual = None;
197405b261ecSmrg    }
197505b261ecSmrg
197605b261ecSmrg    xgi.type = X_Reply;
197705b261ecSmrg    xgi.sequenceNumber = client->sequence;
197805b261ecSmrg    xgi.depth = pDraw->depth;
197905b261ecSmrg    if(format == ZPixmap)
198005b261ecSmrg    {
198105b261ecSmrg	widthBytesLine = PixmapBytePad(width, pDraw->depth);
198205b261ecSmrg	length = widthBytesLine * height;
198305b261ecSmrg
198405b261ecSmrg    }
198505b261ecSmrg    else
198605b261ecSmrg    {
198705b261ecSmrg	widthBytesLine = BitmapBytePad(width);
198805b261ecSmrg	plane = ((Mask)1) << (pDraw->depth - 1);
198905b261ecSmrg	/* only planes asked for */
199005b261ecSmrg	length = widthBytesLine * height *
199105b261ecSmrg		 Ones(planemask & (plane | (plane - 1)));
199205b261ecSmrg
199305b261ecSmrg    }
199405b261ecSmrg
199505b261ecSmrg    xgi.length = length;
199605b261ecSmrg
199705b261ecSmrg    if (im_return) {
199805b261ecSmrg	pBuf = (char *)xalloc(sz_xGetImageReply + length);
199905b261ecSmrg	if (!pBuf)
200005b261ecSmrg	    return (BadAlloc);
200105b261ecSmrg	if (widthBytesLine == 0)
200205b261ecSmrg	    linesPerBuf = 0;
200305b261ecSmrg	else
200405b261ecSmrg	    linesPerBuf = height;
200505b261ecSmrg	*im_return = (xGetImageReply *)pBuf;
200605b261ecSmrg	*(xGetImageReply *)pBuf = xgi;
200705b261ecSmrg	pBuf += sz_xGetImageReply;
200805b261ecSmrg    } else {
200905b261ecSmrg	xgi.length = (xgi.length + 3) >> 2;
201005b261ecSmrg	if (widthBytesLine == 0 || height == 0)
201105b261ecSmrg	    linesPerBuf = 0;
201205b261ecSmrg	else if (widthBytesLine >= IMAGE_BUFSIZE)
201305b261ecSmrg	    linesPerBuf = 1;
201405b261ecSmrg	else
201505b261ecSmrg	{
201605b261ecSmrg	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
201705b261ecSmrg	    if (linesPerBuf > height)
201805b261ecSmrg		linesPerBuf = height;
201905b261ecSmrg	}
202005b261ecSmrg	length = linesPerBuf * widthBytesLine;
202105b261ecSmrg	if (linesPerBuf < height)
202205b261ecSmrg	{
202305b261ecSmrg	    /* we have to make sure intermediate buffers don't need padding */
202405b261ecSmrg	    while ((linesPerBuf > 1) &&
202505b261ecSmrg		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
202605b261ecSmrg	    {
202705b261ecSmrg		linesPerBuf--;
202805b261ecSmrg		length -= widthBytesLine;
202905b261ecSmrg	    }
203005b261ecSmrg	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
203105b261ecSmrg	    {
203205b261ecSmrg		linesPerBuf++;
203305b261ecSmrg		length += widthBytesLine;
203405b261ecSmrg	    }
203505b261ecSmrg	}
20364642e01fSmrg	if(!(pBuf = (char *) xalloc(length)))
203705b261ecSmrg	    return (BadAlloc);
203805b261ecSmrg	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
203905b261ecSmrg    }
204005b261ecSmrg
20414642e01fSmrg    if (pDraw->type == DRAWABLE_WINDOW)
204205b261ecSmrg    {
204305b261ecSmrg	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
204405b261ecSmrg	if (pVisibleRegion)
204505b261ecSmrg	{
204605b261ecSmrg	    REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion,
204705b261ecSmrg			     -pDraw->x, -pDraw->y);
204805b261ecSmrg	}
204905b261ecSmrg    }
205005b261ecSmrg
205105b261ecSmrg    if (linesPerBuf == 0)
205205b261ecSmrg    {
205305b261ecSmrg	/* nothing to do */
205405b261ecSmrg    }
205505b261ecSmrg    else if (format == ZPixmap)
205605b261ecSmrg    {
205705b261ecSmrg        linesDone = 0;
205805b261ecSmrg        while (height - linesDone > 0)
205905b261ecSmrg        {
206005b261ecSmrg	    nlines = min(linesPerBuf, height - linesDone);
206105b261ecSmrg	    (*pDraw->pScreen->GetImage) (pDraw,
206205b261ecSmrg	                                 x,
206305b261ecSmrg				         y + linesDone,
206405b261ecSmrg				         width,
206505b261ecSmrg				         nlines,
206605b261ecSmrg				         format,
206705b261ecSmrg				         planemask,
206805b261ecSmrg				         (pointer) pBuf);
206905b261ecSmrg	    if (pVisibleRegion)
207005b261ecSmrg		XaceCensorImage(client, pVisibleRegion, widthBytesLine,
207105b261ecSmrg			pDraw, x, y + linesDone, width,
207205b261ecSmrg			nlines, format, pBuf);
207305b261ecSmrg
207405b261ecSmrg	    /* Note that this is NOT a call to WriteSwappedDataToClient,
207505b261ecSmrg               as we do NOT byte swap */
207605b261ecSmrg	    if (!im_return)
207705b261ecSmrg	    {
207805b261ecSmrg		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
207905b261ecSmrg			       BitsPerPixel (pDraw->depth),
208005b261ecSmrg			       ClientOrder(client));
208105b261ecSmrg
208205b261ecSmrg/* Don't split me, gcc pukes when you do */
208305b261ecSmrg		(void)WriteToClient(client,
208405b261ecSmrg				    (int)(nlines * widthBytesLine),
208505b261ecSmrg				    pBuf);
208605b261ecSmrg	    }
208705b261ecSmrg	    linesDone += nlines;
208805b261ecSmrg        }
208905b261ecSmrg    }
209005b261ecSmrg    else /* XYPixmap */
209105b261ecSmrg    {
209205b261ecSmrg        for (; plane; plane >>= 1)
209305b261ecSmrg	{
209405b261ecSmrg	    if (planemask & plane)
209505b261ecSmrg	    {
209605b261ecSmrg	        linesDone = 0;
209705b261ecSmrg	        while (height - linesDone > 0)
209805b261ecSmrg	        {
209905b261ecSmrg		    nlines = min(linesPerBuf, height - linesDone);
210005b261ecSmrg	            (*pDraw->pScreen->GetImage) (pDraw,
210105b261ecSmrg	                                         x,
210205b261ecSmrg				                 y + linesDone,
210305b261ecSmrg				                 width,
210405b261ecSmrg				                 nlines,
210505b261ecSmrg				                 format,
210605b261ecSmrg				                 plane,
210705b261ecSmrg				                 (pointer)pBuf);
210805b261ecSmrg		    if (pVisibleRegion)
210905b261ecSmrg			XaceCensorImage(client, pVisibleRegion,
211005b261ecSmrg				widthBytesLine,
211105b261ecSmrg				pDraw, x, y + linesDone, width,
211205b261ecSmrg				nlines, format, pBuf);
211305b261ecSmrg
211405b261ecSmrg		    /* Note: NOT a call to WriteSwappedDataToClient,
211505b261ecSmrg		       as we do NOT byte swap */
211605b261ecSmrg		    if (im_return) {
211705b261ecSmrg			pBuf += nlines * widthBytesLine;
211805b261ecSmrg		    } else {
211905b261ecSmrg			ReformatImage (pBuf,
212005b261ecSmrg				       (int)(nlines * widthBytesLine),
212105b261ecSmrg				       1,
212205b261ecSmrg				       ClientOrder (client));
212305b261ecSmrg
212405b261ecSmrg/* Don't split me, gcc pukes when you do */
212505b261ecSmrg			(void)WriteToClient(client,
212605b261ecSmrg					(int)(nlines * widthBytesLine),
212705b261ecSmrg					pBuf);
212805b261ecSmrg		    }
212905b261ecSmrg		    linesDone += nlines;
213005b261ecSmrg		}
213105b261ecSmrg            }
213205b261ecSmrg	}
213305b261ecSmrg    }
213405b261ecSmrg    if (pVisibleRegion)
213505b261ecSmrg	REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
213605b261ecSmrg    if (!im_return)
21374642e01fSmrg	xfree(pBuf);
213805b261ecSmrg    return (client->noClientException);
213905b261ecSmrg}
214005b261ecSmrg
214105b261ecSmrgint
214205b261ecSmrgProcGetImage(ClientPtr client)
214305b261ecSmrg{
214405b261ecSmrg    REQUEST(xGetImageReq);
214505b261ecSmrg
214605b261ecSmrg    REQUEST_SIZE_MATCH(xGetImageReq);
214705b261ecSmrg
214805b261ecSmrg    return DoGetImage(client, stuff->format, stuff->drawable,
214905b261ecSmrg		      stuff->x, stuff->y,
215005b261ecSmrg		      (int)stuff->width, (int)stuff->height,
215105b261ecSmrg		      stuff->planeMask, (xGetImageReply **)NULL);
215205b261ecSmrg}
215305b261ecSmrg
215405b261ecSmrgint
215505b261ecSmrgProcPolyText(ClientPtr client)
215605b261ecSmrg{
215705b261ecSmrg    int	err;
215805b261ecSmrg    REQUEST(xPolyTextReq);
215905b261ecSmrg    DrawablePtr pDraw;
216005b261ecSmrg    GC *pGC;
216105b261ecSmrg
216205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
21634642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
216405b261ecSmrg
216505b261ecSmrg    err = PolyText(client,
216605b261ecSmrg		   pDraw,
216705b261ecSmrg		   pGC,
216805b261ecSmrg		   (unsigned char *)&stuff[1],
216905b261ecSmrg		   ((unsigned char *) stuff) + (client->req_len << 2),
217005b261ecSmrg		   stuff->x,
217105b261ecSmrg		   stuff->y,
217205b261ecSmrg		   stuff->reqType,
217305b261ecSmrg		   stuff->drawable);
217405b261ecSmrg
217505b261ecSmrg    if (err == Success)
217605b261ecSmrg    {
217705b261ecSmrg	return(client->noClientException);
217805b261ecSmrg    }
217905b261ecSmrg    else
218005b261ecSmrg	return err;
218105b261ecSmrg}
218205b261ecSmrg
218305b261ecSmrgint
218405b261ecSmrgProcImageText8(ClientPtr client)
218505b261ecSmrg{
218605b261ecSmrg    int	err;
218705b261ecSmrg    DrawablePtr pDraw;
218805b261ecSmrg    GC *pGC;
218905b261ecSmrg
219005b261ecSmrg    REQUEST(xImageTextReq);
219105b261ecSmrg
219205b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
21934642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
219405b261ecSmrg
219505b261ecSmrg    err = ImageText(client,
219605b261ecSmrg		    pDraw,
219705b261ecSmrg		    pGC,
219805b261ecSmrg		    stuff->nChars,
219905b261ecSmrg		    (unsigned char *)&stuff[1],
220005b261ecSmrg		    stuff->x,
220105b261ecSmrg		    stuff->y,
220205b261ecSmrg		    stuff->reqType,
220305b261ecSmrg		    stuff->drawable);
220405b261ecSmrg
220505b261ecSmrg    if (err == Success)
220605b261ecSmrg    {
220705b261ecSmrg	return(client->noClientException);
220805b261ecSmrg    }
220905b261ecSmrg    else
221005b261ecSmrg	return err;
221105b261ecSmrg}
221205b261ecSmrg
221305b261ecSmrgint
221405b261ecSmrgProcImageText16(ClientPtr client)
221505b261ecSmrg{
221605b261ecSmrg    int	err;
221705b261ecSmrg    DrawablePtr pDraw;
221805b261ecSmrg    GC *pGC;
221905b261ecSmrg
222005b261ecSmrg    REQUEST(xImageTextReq);
222105b261ecSmrg
222205b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
22234642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
222405b261ecSmrg
222505b261ecSmrg    err = ImageText(client,
222605b261ecSmrg		    pDraw,
222705b261ecSmrg		    pGC,
222805b261ecSmrg		    stuff->nChars,
222905b261ecSmrg		    (unsigned char *)&stuff[1],
223005b261ecSmrg		    stuff->x,
223105b261ecSmrg		    stuff->y,
223205b261ecSmrg		    stuff->reqType,
223305b261ecSmrg		    stuff->drawable);
223405b261ecSmrg
223505b261ecSmrg    if (err == Success)
223605b261ecSmrg    {
223705b261ecSmrg	return(client->noClientException);
223805b261ecSmrg    }
223905b261ecSmrg    else
224005b261ecSmrg	return err;
224105b261ecSmrg}
224205b261ecSmrg
224305b261ecSmrg
224405b261ecSmrgint
224505b261ecSmrgProcCreateColormap(ClientPtr client)
224605b261ecSmrg{
224705b261ecSmrg    VisualPtr	pVisual;
224805b261ecSmrg    ColormapPtr	pmap;
224905b261ecSmrg    Colormap	mid;
225005b261ecSmrg    WindowPtr   pWin;
225105b261ecSmrg    ScreenPtr pScreen;
225205b261ecSmrg    REQUEST(xCreateColormapReq);
225305b261ecSmrg    int i, result;
225405b261ecSmrg
225505b261ecSmrg    REQUEST_SIZE_MATCH(xCreateColormapReq);
225605b261ecSmrg
225705b261ecSmrg    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
225805b261ecSmrg    {
225905b261ecSmrg	client->errorValue = stuff->alloc;
226005b261ecSmrg        return(BadValue);
226105b261ecSmrg    }
226205b261ecSmrg    mid = stuff->mid;
226305b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
22644642e01fSmrg    result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
226505b261ecSmrg    if (result != Success)
226605b261ecSmrg        return result;
226705b261ecSmrg
226805b261ecSmrg    pScreen = pWin->drawable.pScreen;
226905b261ecSmrg    for (i = 0, pVisual = pScreen->visuals;
227005b261ecSmrg	 i < pScreen->numVisuals;
227105b261ecSmrg	 i++, pVisual++)
227205b261ecSmrg    {
227305b261ecSmrg	if (pVisual->vid != stuff->visual)
227405b261ecSmrg	    continue;
227505b261ecSmrg	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
227605b261ecSmrg				 (int)stuff->alloc, client->index);
227705b261ecSmrg	if (client->noClientException != Success)
227805b261ecSmrg	    return(client->noClientException);
227905b261ecSmrg	else
228005b261ecSmrg	    return(result);
228105b261ecSmrg    }
228205b261ecSmrg    client->errorValue = stuff->visual;
228305b261ecSmrg    return(BadMatch);
228405b261ecSmrg}
228505b261ecSmrg
228605b261ecSmrgint
228705b261ecSmrgProcFreeColormap(ClientPtr client)
228805b261ecSmrg{
228905b261ecSmrg    ColormapPtr pmap;
22904642e01fSmrg    int rc;
229105b261ecSmrg    REQUEST(xResourceReq);
229205b261ecSmrg
229305b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
2294b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client,
22954642e01fSmrg			   DixDestroyAccess);
22964642e01fSmrg    if (rc == Success)
229705b261ecSmrg    {
229805b261ecSmrg	/* Freeing a default colormap is a no-op */
229905b261ecSmrg	if (!(pmap->flags & IsDefault))
230005b261ecSmrg	    FreeResource(stuff->id, RT_NONE);
230105b261ecSmrg	return (client->noClientException);
230205b261ecSmrg    }
230305b261ecSmrg    else
230405b261ecSmrg    {
230505b261ecSmrg	client->errorValue = stuff->id;
23064642e01fSmrg	return (rc == BadValue) ? BadColor : rc;
230705b261ecSmrg    }
230805b261ecSmrg}
230905b261ecSmrg
231005b261ecSmrg
231105b261ecSmrgint
231205b261ecSmrgProcCopyColormapAndFree(ClientPtr client)
231305b261ecSmrg{
231405b261ecSmrg    Colormap	mid;
231505b261ecSmrg    ColormapPtr	pSrcMap;
231605b261ecSmrg    REQUEST(xCopyColormapAndFreeReq);
23174642e01fSmrg    int rc;
231805b261ecSmrg
231905b261ecSmrg    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
232005b261ecSmrg    mid = stuff->mid;
232105b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
2322b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP,
23234642e01fSmrg			   client, DixReadAccess|DixRemoveAccess);
23244642e01fSmrg    if (rc == Success)
232505b261ecSmrg    {
23264642e01fSmrg	rc = CopyColormapAndFree(mid, pSrcMap, client->index);
232705b261ecSmrg	if (client->noClientException != Success)
232805b261ecSmrg            return(client->noClientException);
232905b261ecSmrg	else
23304642e01fSmrg            return rc;
233105b261ecSmrg    }
233205b261ecSmrg    else
233305b261ecSmrg    {
233405b261ecSmrg	client->errorValue = stuff->srcCmap;
23354642e01fSmrg	return (rc == BadValue) ? BadColor : rc;
233605b261ecSmrg    }
233705b261ecSmrg}
233805b261ecSmrg
233905b261ecSmrgint
234005b261ecSmrgProcInstallColormap(ClientPtr client)
234105b261ecSmrg{
234205b261ecSmrg    ColormapPtr pcmp;
23434642e01fSmrg    int rc;
234405b261ecSmrg    REQUEST(xResourceReq);
234505b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
23464642e01fSmrg
2347b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
23484642e01fSmrg			   DixInstallAccess);
23494642e01fSmrg    if (rc != Success)
23504642e01fSmrg	goto out;
23514642e01fSmrg
23524642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
23534642e01fSmrg    if (rc != Success)
23544642e01fSmrg	goto out;
23554642e01fSmrg
23564642e01fSmrg    (*(pcmp->pScreen->InstallColormap)) (pcmp);
23574642e01fSmrg
23584642e01fSmrg    rc = client->noClientException;
23594642e01fSmrgout:
23604642e01fSmrg    client->errorValue = stuff->id;
23614642e01fSmrg    return (rc == BadValue) ? BadColor : rc;
236205b261ecSmrg}
236305b261ecSmrg
236405b261ecSmrgint
236505b261ecSmrgProcUninstallColormap(ClientPtr client)
236605b261ecSmrg{
236705b261ecSmrg    ColormapPtr pcmp;
23684642e01fSmrg    int rc;
236905b261ecSmrg    REQUEST(xResourceReq);
237005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
23714642e01fSmrg
2372b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
23734642e01fSmrg			   DixUninstallAccess);
23744642e01fSmrg    if (rc != Success)
23754642e01fSmrg	goto out;
23764642e01fSmrg
23774642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
23784642e01fSmrg    if (rc != Success)
23794642e01fSmrg	goto out;
23804642e01fSmrg
23814642e01fSmrg    if(pcmp->mid != pcmp->pScreen->defColormap)
23824642e01fSmrg	(*(pcmp->pScreen->UninstallColormap)) (pcmp);
23834642e01fSmrg
23844642e01fSmrg    rc = client->noClientException;
23854642e01fSmrgout:
23864642e01fSmrg    client->errorValue = stuff->id;
23874642e01fSmrg    return (rc == BadValue) ? BadColor : rc;
238805b261ecSmrg}
238905b261ecSmrg
239005b261ecSmrgint
239105b261ecSmrgProcListInstalledColormaps(ClientPtr client)
239205b261ecSmrg{
239305b261ecSmrg    xListInstalledColormapsReply *preply;
239405b261ecSmrg    int nummaps, rc;
239505b261ecSmrg    WindowPtr pWin;
239605b261ecSmrg    REQUEST(xResourceReq);
239705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
23984642e01fSmrg
23994642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
240005b261ecSmrg    if (rc != Success)
24014642e01fSmrg	goto out;
24024642e01fSmrg
24034642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
24044642e01fSmrg		  DixGetAttrAccess);
24054642e01fSmrg    if (rc != Success)
24064642e01fSmrg	goto out;
240705b261ecSmrg
240805b261ecSmrg    preply = (xListInstalledColormapsReply *)
24094642e01fSmrg		xalloc(sizeof(xListInstalledColormapsReply) +
241005b261ecSmrg		     pWin->drawable.pScreen->maxInstalledCmaps *
241105b261ecSmrg		     sizeof(Colormap));
241205b261ecSmrg    if(!preply)
241305b261ecSmrg        return(BadAlloc);
241405b261ecSmrg
241505b261ecSmrg    preply->type = X_Reply;
241605b261ecSmrg    preply->sequenceNumber = client->sequence;
241705b261ecSmrg    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
241805b261ecSmrg        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
241905b261ecSmrg    preply->nColormaps = nummaps;
242005b261ecSmrg    preply->length = nummaps;
242105b261ecSmrg    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
242205b261ecSmrg    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
242305b261ecSmrg    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
24244642e01fSmrg    xfree(preply);
24254642e01fSmrg    rc = client->noClientException;
24264642e01fSmrgout:
24274642e01fSmrg    return rc;
242805b261ecSmrg}
242905b261ecSmrg
243005b261ecSmrgint
243105b261ecSmrgProcAllocColor (ClientPtr client)
243205b261ecSmrg{
243305b261ecSmrg    ColormapPtr pmap;
24344642e01fSmrg    int rc;
243505b261ecSmrg    xAllocColorReply acr;
243605b261ecSmrg    REQUEST(xAllocColorReq);
243705b261ecSmrg
243805b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorReq);
2439b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client,
24404642e01fSmrg			   DixAddAccess);
24414642e01fSmrg    if (rc == Success)
244205b261ecSmrg    {
244305b261ecSmrg	acr.type = X_Reply;
244405b261ecSmrg	acr.length = 0;
244505b261ecSmrg	acr.sequenceNumber = client->sequence;
244605b261ecSmrg	acr.red = stuff->red;
244705b261ecSmrg	acr.green = stuff->green;
244805b261ecSmrg	acr.blue = stuff->blue;
244905b261ecSmrg	acr.pixel = 0;
24504642e01fSmrg	if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
245105b261ecSmrg	                       &acr.pixel, client->index)) )
245205b261ecSmrg	{
245305b261ecSmrg            if (client->noClientException != Success)
245405b261ecSmrg                return(client->noClientException);
245505b261ecSmrg	    else
24564642e01fSmrg	        return rc;
245705b261ecSmrg	}
245805b261ecSmrg#ifdef PANORAMIX
245905b261ecSmrg	if (noPanoramiXExtension || !pmap->pScreen->myNum)
246005b261ecSmrg#endif
246105b261ecSmrg        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
246205b261ecSmrg	return (client->noClientException);
246305b261ecSmrg
246405b261ecSmrg    }
246505b261ecSmrg    else
246605b261ecSmrg    {
246705b261ecSmrg        client->errorValue = stuff->cmap;
24684642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
246905b261ecSmrg    }
247005b261ecSmrg}
247105b261ecSmrg
247205b261ecSmrgint
247305b261ecSmrgProcAllocNamedColor (ClientPtr client)
247405b261ecSmrg{
247505b261ecSmrg    ColormapPtr pcmp;
24764642e01fSmrg    int rc;
247705b261ecSmrg    REQUEST(xAllocNamedColorReq);
247805b261ecSmrg
247905b261ecSmrg    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2480b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
24814642e01fSmrg			   DixAddAccess);
24824642e01fSmrg    if (rc == Success)
248305b261ecSmrg    {
248405b261ecSmrg	xAllocNamedColorReply ancr;
248505b261ecSmrg
248605b261ecSmrg	ancr.type = X_Reply;
248705b261ecSmrg	ancr.length = 0;
248805b261ecSmrg	ancr.sequenceNumber = client->sequence;
248905b261ecSmrg
249005b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
249105b261ecSmrg	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
249205b261ecSmrg	{
249305b261ecSmrg	    ancr.screenRed = ancr.exactRed;
249405b261ecSmrg	    ancr.screenGreen = ancr.exactGreen;
249505b261ecSmrg	    ancr.screenBlue = ancr.exactBlue;
249605b261ecSmrg	    ancr.pixel = 0;
24974642e01fSmrg	    if( (rc = AllocColor(pcmp,
249805b261ecSmrg	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
249905b261ecSmrg			 &ancr.pixel, client->index)) )
250005b261ecSmrg	    {
250105b261ecSmrg                if (client->noClientException != Success)
250205b261ecSmrg                    return(client->noClientException);
250305b261ecSmrg                else
25044642e01fSmrg		    return rc;
250505b261ecSmrg	    }
250605b261ecSmrg#ifdef PANORAMIX
250705b261ecSmrg	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
250805b261ecSmrg#endif
250905b261ecSmrg            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
251005b261ecSmrg	    return (client->noClientException);
251105b261ecSmrg	}
251205b261ecSmrg	else
251305b261ecSmrg	    return(BadName);
251405b261ecSmrg
251505b261ecSmrg    }
251605b261ecSmrg    else
251705b261ecSmrg    {
251805b261ecSmrg        client->errorValue = stuff->cmap;
25194642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
252005b261ecSmrg    }
252105b261ecSmrg}
252205b261ecSmrg
252305b261ecSmrgint
252405b261ecSmrgProcAllocColorCells (ClientPtr client)
252505b261ecSmrg{
252605b261ecSmrg    ColormapPtr pcmp;
25274642e01fSmrg    int rc;
252805b261ecSmrg    REQUEST(xAllocColorCellsReq);
252905b261ecSmrg
253005b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2531b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
25324642e01fSmrg			   DixAddAccess);
25334642e01fSmrg    if (rc == Success)
253405b261ecSmrg    {
253505b261ecSmrg	xAllocColorCellsReply	accr;
25364642e01fSmrg	int			npixels, nmasks;
253705b261ecSmrg	long			length;
253805b261ecSmrg	Pixel			*ppixels, *pmasks;
253905b261ecSmrg
254005b261ecSmrg	npixels = stuff->colors;
254105b261ecSmrg	if (!npixels)
254205b261ecSmrg	{
254305b261ecSmrg	    client->errorValue = npixels;
254405b261ecSmrg	    return (BadValue);
254505b261ecSmrg	}
254605b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
254705b261ecSmrg	{
254805b261ecSmrg	    client->errorValue = stuff->contiguous;
254905b261ecSmrg	    return (BadValue);
255005b261ecSmrg	}
255105b261ecSmrg	nmasks = stuff->planes;
255205b261ecSmrg	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
25534642e01fSmrg	ppixels = (Pixel *)xalloc(length);
255405b261ecSmrg	if(!ppixels)
255505b261ecSmrg            return(BadAlloc);
255605b261ecSmrg	pmasks = ppixels + npixels;
255705b261ecSmrg
25584642e01fSmrg	if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
255905b261ecSmrg				    (Bool)stuff->contiguous, ppixels, pmasks)) )
256005b261ecSmrg	{
25614642e01fSmrg	    xfree(ppixels);
256205b261ecSmrg            if (client->noClientException != Success)
256305b261ecSmrg                return(client->noClientException);
256405b261ecSmrg	    else
25654642e01fSmrg	        return rc;
256605b261ecSmrg	}
256705b261ecSmrg#ifdef PANORAMIX
256805b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
256905b261ecSmrg#endif
257005b261ecSmrg	{
257105b261ecSmrg	    accr.type = X_Reply;
257205b261ecSmrg	    accr.length = length >> 2;
257305b261ecSmrg	    accr.sequenceNumber = client->sequence;
257405b261ecSmrg	    accr.nPixels = npixels;
257505b261ecSmrg	    accr.nMasks = nmasks;
257605b261ecSmrg	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
257705b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
257805b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
257905b261ecSmrg	}
25804642e01fSmrg	xfree(ppixels);
258105b261ecSmrg        return (client->noClientException);
258205b261ecSmrg    }
258305b261ecSmrg    else
258405b261ecSmrg    {
258505b261ecSmrg        client->errorValue = stuff->cmap;
25864642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
258705b261ecSmrg    }
258805b261ecSmrg}
258905b261ecSmrg
259005b261ecSmrgint
259105b261ecSmrgProcAllocColorPlanes(ClientPtr client)
259205b261ecSmrg{
259305b261ecSmrg    ColormapPtr pcmp;
25944642e01fSmrg    int rc;
259505b261ecSmrg    REQUEST(xAllocColorPlanesReq);
259605b261ecSmrg
259705b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2598b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
25994642e01fSmrg			   DixAddAccess);
26004642e01fSmrg    if (rc == Success)
260105b261ecSmrg    {
260205b261ecSmrg	xAllocColorPlanesReply	acpr;
26034642e01fSmrg	int			npixels;
260405b261ecSmrg	long			length;
260505b261ecSmrg	Pixel			*ppixels;
260605b261ecSmrg
260705b261ecSmrg	npixels = stuff->colors;
260805b261ecSmrg	if (!npixels)
260905b261ecSmrg	{
261005b261ecSmrg	    client->errorValue = npixels;
261105b261ecSmrg	    return (BadValue);
261205b261ecSmrg	}
261305b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
261405b261ecSmrg	{
261505b261ecSmrg	    client->errorValue = stuff->contiguous;
261605b261ecSmrg	    return (BadValue);
261705b261ecSmrg	}
261805b261ecSmrg	acpr.type = X_Reply;
261905b261ecSmrg	acpr.sequenceNumber = client->sequence;
262005b261ecSmrg	acpr.nPixels = npixels;
262105b261ecSmrg	length = (long)npixels * sizeof(Pixel);
26224642e01fSmrg	ppixels = (Pixel *)xalloc(length);
262305b261ecSmrg	if(!ppixels)
262405b261ecSmrg            return(BadAlloc);
26254642e01fSmrg	if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
262605b261ecSmrg	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
262705b261ecSmrg	    (Bool)stuff->contiguous, ppixels,
262805b261ecSmrg	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
262905b261ecSmrg	{
26304642e01fSmrg            xfree(ppixels);
263105b261ecSmrg            if (client->noClientException != Success)
263205b261ecSmrg                return(client->noClientException);
263305b261ecSmrg	    else
26344642e01fSmrg	        return rc;
263505b261ecSmrg	}
263605b261ecSmrg	acpr.length = length >> 2;
263705b261ecSmrg#ifdef PANORAMIX
263805b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
263905b261ecSmrg#endif
264005b261ecSmrg	{
264105b261ecSmrg	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
264205b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
264305b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
264405b261ecSmrg	}
26454642e01fSmrg	xfree(ppixels);
264605b261ecSmrg        return (client->noClientException);
264705b261ecSmrg    }
264805b261ecSmrg    else
264905b261ecSmrg    {
265005b261ecSmrg        client->errorValue = stuff->cmap;
26514642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
265205b261ecSmrg    }
265305b261ecSmrg}
265405b261ecSmrg
265505b261ecSmrgint
265605b261ecSmrgProcFreeColors(ClientPtr client)
265705b261ecSmrg{
265805b261ecSmrg    ColormapPtr pcmp;
26594642e01fSmrg    int rc;
266005b261ecSmrg    REQUEST(xFreeColorsReq);
266105b261ecSmrg
266205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2663b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
26644642e01fSmrg			   DixRemoveAccess);
26654642e01fSmrg    if (rc == Success)
266605b261ecSmrg    {
266705b261ecSmrg	int	count;
266805b261ecSmrg
266905b261ecSmrg	if(pcmp->flags & AllAllocated)
267005b261ecSmrg	    return(BadAccess);
267105b261ecSmrg	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
26724642e01fSmrg	rc = FreeColors(pcmp, client->index, count,
267305b261ecSmrg	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
267405b261ecSmrg        if (client->noClientException != Success)
267505b261ecSmrg            return(client->noClientException);
267605b261ecSmrg        else
267705b261ecSmrg	{
267805b261ecSmrg	    client->errorValue = clientErrorValue;
26794642e01fSmrg            return rc;
268005b261ecSmrg	}
268105b261ecSmrg
268205b261ecSmrg    }
268305b261ecSmrg    else
268405b261ecSmrg    {
268505b261ecSmrg        client->errorValue = stuff->cmap;
26864642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
268705b261ecSmrg    }
268805b261ecSmrg}
268905b261ecSmrg
269005b261ecSmrgint
269105b261ecSmrgProcStoreColors (ClientPtr client)
269205b261ecSmrg{
269305b261ecSmrg    ColormapPtr pcmp;
26944642e01fSmrg    int rc;
269505b261ecSmrg    REQUEST(xStoreColorsReq);
269605b261ecSmrg
269705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2698b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
26994642e01fSmrg			   DixWriteAccess);
27004642e01fSmrg    if (rc == Success)
270105b261ecSmrg    {
270205b261ecSmrg	int	count;
270305b261ecSmrg
270405b261ecSmrg        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
270505b261ecSmrg	if (count % sizeof(xColorItem))
270605b261ecSmrg	    return(BadLength);
270705b261ecSmrg	count /= sizeof(xColorItem);
27084642e01fSmrg	rc = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
270905b261ecSmrg        if (client->noClientException != Success)
271005b261ecSmrg            return(client->noClientException);
271105b261ecSmrg        else
271205b261ecSmrg	{
271305b261ecSmrg	    client->errorValue = clientErrorValue;
27144642e01fSmrg            return rc;
271505b261ecSmrg	}
271605b261ecSmrg    }
271705b261ecSmrg    else
271805b261ecSmrg    {
271905b261ecSmrg        client->errorValue = stuff->cmap;
27204642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
272105b261ecSmrg    }
272205b261ecSmrg}
272305b261ecSmrg
272405b261ecSmrgint
272505b261ecSmrgProcStoreNamedColor (ClientPtr client)
272605b261ecSmrg{
272705b261ecSmrg    ColormapPtr pcmp;
27284642e01fSmrg    int rc;
272905b261ecSmrg    REQUEST(xStoreNamedColorReq);
273005b261ecSmrg
273105b261ecSmrg    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2732b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27334642e01fSmrg			   DixWriteAccess);
27344642e01fSmrg    if (rc == Success)
273505b261ecSmrg    {
273605b261ecSmrg	xColorItem	def;
273705b261ecSmrg
273805b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
273905b261ecSmrg	                 stuff->nbytes, &def.red, &def.green, &def.blue))
274005b261ecSmrg	{
274105b261ecSmrg	    def.flags = stuff->flags;
274205b261ecSmrg	    def.pixel = stuff->pixel;
27434642e01fSmrg	    rc = StoreColors(pcmp, 1, &def);
274405b261ecSmrg            if (client->noClientException != Success)
274505b261ecSmrg                return(client->noClientException);
274605b261ecSmrg	    else
27474642e01fSmrg		return rc;
274805b261ecSmrg	}
274905b261ecSmrg        return (BadName);
275005b261ecSmrg    }
275105b261ecSmrg    else
275205b261ecSmrg    {
275305b261ecSmrg        client->errorValue = stuff->cmap;
27544642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
275505b261ecSmrg    }
275605b261ecSmrg}
275705b261ecSmrg
275805b261ecSmrgint
275905b261ecSmrgProcQueryColors(ClientPtr client)
276005b261ecSmrg{
276105b261ecSmrg    ColormapPtr pcmp;
27624642e01fSmrg    int rc;
276305b261ecSmrg    REQUEST(xQueryColorsReq);
276405b261ecSmrg
276505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2766b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27674642e01fSmrg			   DixReadAccess);
27684642e01fSmrg    if (rc == Success)
276905b261ecSmrg    {
27704642e01fSmrg	int			count;
277105b261ecSmrg	xrgb 			*prgbs;
277205b261ecSmrg	xQueryColorsReply	qcr;
277305b261ecSmrg
277405b261ecSmrg	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
27754642e01fSmrg	prgbs = (xrgb *)xalloc(count * sizeof(xrgb));
277605b261ecSmrg	if(!prgbs && count)
277705b261ecSmrg            return(BadAlloc);
27784642e01fSmrg	if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
277905b261ecSmrg	{
27804642e01fSmrg   	    if (prgbs) xfree(prgbs);
278105b261ecSmrg	    if (client->noClientException != Success)
278205b261ecSmrg                return(client->noClientException);
278305b261ecSmrg	    else
278405b261ecSmrg	    {
278505b261ecSmrg		client->errorValue = clientErrorValue;
27864642e01fSmrg	        return rc;
278705b261ecSmrg	    }
278805b261ecSmrg	}
278905b261ecSmrg	qcr.type = X_Reply;
279005b261ecSmrg	qcr.length = (count * sizeof(xrgb)) >> 2;
279105b261ecSmrg	qcr.sequenceNumber = client->sequence;
279205b261ecSmrg	qcr.nColors = count;
279305b261ecSmrg	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
279405b261ecSmrg	if (count)
279505b261ecSmrg	{
279605b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
279705b261ecSmrg	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
279805b261ecSmrg	}
27994642e01fSmrg	if (prgbs) xfree(prgbs);
280005b261ecSmrg	return(client->noClientException);
280105b261ecSmrg
280205b261ecSmrg    }
280305b261ecSmrg    else
280405b261ecSmrg    {
280505b261ecSmrg        client->errorValue = stuff->cmap;
28064642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
280705b261ecSmrg    }
280805b261ecSmrg}
280905b261ecSmrg
281005b261ecSmrgint
281105b261ecSmrgProcLookupColor(ClientPtr client)
281205b261ecSmrg{
281305b261ecSmrg    ColormapPtr pcmp;
28144642e01fSmrg    int rc;
281505b261ecSmrg    REQUEST(xLookupColorReq);
281605b261ecSmrg
281705b261ecSmrg    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2818b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
28194642e01fSmrg			   DixReadAccess);
28204642e01fSmrg    if (rc == Success)
282105b261ecSmrg    {
282205b261ecSmrg	xLookupColorReply lcr;
282305b261ecSmrg
282405b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
282505b261ecSmrg	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
282605b261ecSmrg	{
282705b261ecSmrg	    lcr.type = X_Reply;
282805b261ecSmrg	    lcr.length = 0;
282905b261ecSmrg	    lcr.sequenceNumber = client->sequence;
283005b261ecSmrg	    lcr.screenRed = lcr.exactRed;
283105b261ecSmrg	    lcr.screenGreen = lcr.exactGreen;
283205b261ecSmrg	    lcr.screenBlue = lcr.exactBlue;
283305b261ecSmrg	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
283405b261ecSmrg	                                   &lcr.screenGreen,
283505b261ecSmrg					   &lcr.screenBlue,
283605b261ecSmrg					   pcmp->pVisual);
283705b261ecSmrg	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
283805b261ecSmrg	    return(client->noClientException);
283905b261ecSmrg	}
284005b261ecSmrg        return (BadName);
284105b261ecSmrg    }
284205b261ecSmrg    else
284305b261ecSmrg    {
284405b261ecSmrg        client->errorValue = stuff->cmap;
28454642e01fSmrg        return (rc == BadValue) ? BadColor : rc;
284605b261ecSmrg    }
284705b261ecSmrg}
284805b261ecSmrg
284905b261ecSmrgint
285005b261ecSmrgProcCreateCursor (ClientPtr client)
285105b261ecSmrg{
285205b261ecSmrg    CursorPtr		pCursor;
285305b261ecSmrg    PixmapPtr 		src;
285405b261ecSmrg    PixmapPtr 		msk;
285505b261ecSmrg    unsigned char *	srcbits;
285605b261ecSmrg    unsigned char *	mskbits;
285705b261ecSmrg    unsigned short	width, height;
285805b261ecSmrg    long		n;
285905b261ecSmrg    CursorMetricRec 	cm;
28604642e01fSmrg    int rc;
286105b261ecSmrg
286205b261ecSmrg    REQUEST(xCreateCursorReq);
286305b261ecSmrg
286405b261ecSmrg    REQUEST_SIZE_MATCH(xCreateCursorReq);
286505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
286605b261ecSmrg
2867b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client,
28684642e01fSmrg			   DixReadAccess);
28694642e01fSmrg    if (rc != Success) {
287005b261ecSmrg	client->errorValue = stuff->source;
28714642e01fSmrg	return (rc == BadValue) ? BadPixmap : rc;
287205b261ecSmrg    }
28734642e01fSmrg
2874b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
28754642e01fSmrg			   DixReadAccess);
28764642e01fSmrg    if (rc != Success)
287705b261ecSmrg    {
287805b261ecSmrg	if (stuff->mask != None)
287905b261ecSmrg	{
288005b261ecSmrg	    client->errorValue = stuff->mask;
28814642e01fSmrg	    return (rc == BadValue) ? BadPixmap : rc;
288205b261ecSmrg	}
288305b261ecSmrg    }
288405b261ecSmrg    else if (  src->drawable.width != msk->drawable.width
288505b261ecSmrg	    || src->drawable.height != msk->drawable.height
288605b261ecSmrg	    || src->drawable.depth != 1
288705b261ecSmrg	    || msk->drawable.depth != 1)
288805b261ecSmrg	return (BadMatch);
288905b261ecSmrg
289005b261ecSmrg    width = src->drawable.width;
289105b261ecSmrg    height = src->drawable.height;
289205b261ecSmrg
289305b261ecSmrg    if ( stuff->x > width
289405b261ecSmrg      || stuff->y > height )
289505b261ecSmrg	return (BadMatch);
289605b261ecSmrg
289705b261ecSmrg    n = BitmapBytePad(width)*height;
28984642e01fSmrg    srcbits = xcalloc(1, n);
289905b261ecSmrg    if (!srcbits)
290005b261ecSmrg	return (BadAlloc);
29014642e01fSmrg    mskbits = xalloc(n);
290205b261ecSmrg    if (!mskbits)
290305b261ecSmrg    {
290405b261ecSmrg	xfree(srcbits);
290505b261ecSmrg	return (BadAlloc);
290605b261ecSmrg    }
290705b261ecSmrg
290805b261ecSmrg    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
290905b261ecSmrg					 XYPixmap, 1, (pointer)srcbits);
291005b261ecSmrg    if ( msk == (PixmapPtr)NULL)
291105b261ecSmrg    {
291205b261ecSmrg	unsigned char *bits = mskbits;
291305b261ecSmrg	while (--n >= 0)
291405b261ecSmrg	    *bits++ = ~0;
291505b261ecSmrg    }
291605b261ecSmrg    else
291705b261ecSmrg    {
291805b261ecSmrg	/* zeroing the (pad) bits helps some ddx cursor handling */
291905b261ecSmrg	bzero((char *)mskbits, n);
292005b261ecSmrg	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
292105b261ecSmrg					height, XYPixmap, 1, (pointer)mskbits);
292205b261ecSmrg    }
292305b261ecSmrg    cm.width = width;
292405b261ecSmrg    cm.height = height;
292505b261ecSmrg    cm.xhot = stuff->x;
292605b261ecSmrg    cm.yhot = stuff->y;
29274642e01fSmrg    rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
29284642e01fSmrg			 stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
29294642e01fSmrg			 stuff->backRed, stuff->backGreen, stuff->backBlue,
29304642e01fSmrg			 &pCursor, client, stuff->cid);
293105b261ecSmrg
29324642e01fSmrg    if (rc != Success)
29334642e01fSmrg	return rc;
29344642e01fSmrg    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
29354642e01fSmrg	return BadAlloc;
29364642e01fSmrg
29374642e01fSmrg    return client->noClientException;
293805b261ecSmrg}
293905b261ecSmrg
294005b261ecSmrgint
294105b261ecSmrgProcCreateGlyphCursor (ClientPtr client)
294205b261ecSmrg{
294305b261ecSmrg    CursorPtr pCursor;
294405b261ecSmrg    int res;
294505b261ecSmrg
294605b261ecSmrg    REQUEST(xCreateGlyphCursorReq);
294705b261ecSmrg
294805b261ecSmrg    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
294905b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
295005b261ecSmrg
295105b261ecSmrg    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
295205b261ecSmrg			   stuff->mask, stuff->maskChar,
295305b261ecSmrg			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
295405b261ecSmrg			   stuff->backRed, stuff->backGreen, stuff->backBlue,
29554642e01fSmrg			   &pCursor, client, stuff->cid);
295605b261ecSmrg    if (res != Success)
295705b261ecSmrg	return res;
295805b261ecSmrg    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
295905b261ecSmrg	return client->noClientException;
296005b261ecSmrg    return BadAlloc;
296105b261ecSmrg}
296205b261ecSmrg
296305b261ecSmrg
296405b261ecSmrgint
296505b261ecSmrgProcFreeCursor (ClientPtr client)
296605b261ecSmrg{
296705b261ecSmrg    CursorPtr pCursor;
29684642e01fSmrg    int rc;
296905b261ecSmrg    REQUEST(xResourceReq);
297005b261ecSmrg
297105b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
2972b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client,
29734642e01fSmrg			   DixDestroyAccess);
29744642e01fSmrg    if (rc == Success)
297505b261ecSmrg    {
297605b261ecSmrg	FreeResource(stuff->id, RT_NONE);
297705b261ecSmrg	return (client->noClientException);
297805b261ecSmrg    }
297905b261ecSmrg    else
298005b261ecSmrg    {
298105b261ecSmrg	client->errorValue = stuff->id;
29824642e01fSmrg	return (rc == BadValue) ? BadCursor : rc;
298305b261ecSmrg    }
298405b261ecSmrg}
298505b261ecSmrg
298605b261ecSmrgint
298705b261ecSmrgProcQueryBestSize (ClientPtr client)
298805b261ecSmrg{
298905b261ecSmrg    xQueryBestSizeReply	reply;
299005b261ecSmrg    DrawablePtr pDraw;
299105b261ecSmrg    ScreenPtr pScreen;
299205b261ecSmrg    int rc;
299305b261ecSmrg    REQUEST(xQueryBestSizeReq);
299405b261ecSmrg    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
299505b261ecSmrg
299605b261ecSmrg    if ((stuff->class != CursorShape) &&
299705b261ecSmrg	(stuff->class != TileShape) &&
299805b261ecSmrg	(stuff->class != StippleShape))
299905b261ecSmrg    {
300005b261ecSmrg	client->errorValue = stuff->class;
300105b261ecSmrg        return(BadValue);
300205b261ecSmrg    }
300305b261ecSmrg
300405b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
30054642e01fSmrg			   DixGetAttrAccess);
300605b261ecSmrg    if (rc != Success)
300705b261ecSmrg	return rc;
300805b261ecSmrg    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
300905b261ecSmrg	return (BadMatch);
301005b261ecSmrg    pScreen = pDraw->pScreen;
30114642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
30124642e01fSmrg    if (rc != Success)
30134642e01fSmrg	return rc;
301405b261ecSmrg    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
301505b261ecSmrg			       &stuff->height, pScreen);
301605b261ecSmrg    reply.type = X_Reply;
301705b261ecSmrg    reply.length = 0;
301805b261ecSmrg    reply.sequenceNumber = client->sequence;
301905b261ecSmrg    reply.width = stuff->width;
302005b261ecSmrg    reply.height = stuff->height;
302105b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
302205b261ecSmrg    return (client->noClientException);
302305b261ecSmrg}
302405b261ecSmrg
302505b261ecSmrg
302605b261ecSmrgint
302705b261ecSmrgProcSetScreenSaver (ClientPtr client)
302805b261ecSmrg{
30294642e01fSmrg    int rc, i, blankingOption, exposureOption;
303005b261ecSmrg    REQUEST(xSetScreenSaverReq);
303105b261ecSmrg    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
30324642e01fSmrg
30334642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
30344642e01fSmrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
30354642e01fSmrg		      DixSetAttrAccess);
30364642e01fSmrg	if (rc != Success)
30374642e01fSmrg	    return rc;
30384642e01fSmrg    }
30394642e01fSmrg
304005b261ecSmrg    blankingOption = stuff->preferBlank;
304105b261ecSmrg    if ((blankingOption != DontPreferBlanking) &&
304205b261ecSmrg        (blankingOption != PreferBlanking) &&
304305b261ecSmrg        (blankingOption != DefaultBlanking))
304405b261ecSmrg    {
304505b261ecSmrg	client->errorValue = blankingOption;
304605b261ecSmrg        return BadValue;
304705b261ecSmrg    }
304805b261ecSmrg    exposureOption = stuff->allowExpose;
304905b261ecSmrg    if ((exposureOption != DontAllowExposures) &&
305005b261ecSmrg        (exposureOption != AllowExposures) &&
305105b261ecSmrg        (exposureOption != DefaultExposures))
305205b261ecSmrg    {
305305b261ecSmrg	client->errorValue = exposureOption;
305405b261ecSmrg        return BadValue;
305505b261ecSmrg    }
305605b261ecSmrg    if (stuff->timeout < -1)
305705b261ecSmrg    {
305805b261ecSmrg	client->errorValue = stuff->timeout;
305905b261ecSmrg        return BadValue;
306005b261ecSmrg    }
306105b261ecSmrg    if (stuff->interval < -1)
306205b261ecSmrg    {
306305b261ecSmrg	client->errorValue = stuff->interval;
306405b261ecSmrg        return BadValue;
306505b261ecSmrg    }
306605b261ecSmrg
306705b261ecSmrg    if (blankingOption == DefaultBlanking)
306805b261ecSmrg	ScreenSaverBlanking = defaultScreenSaverBlanking;
306905b261ecSmrg    else
307005b261ecSmrg	ScreenSaverBlanking = blankingOption;
307105b261ecSmrg    if (exposureOption == DefaultExposures)
307205b261ecSmrg	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
307305b261ecSmrg    else
307405b261ecSmrg	ScreenSaverAllowExposures = exposureOption;
307505b261ecSmrg
307605b261ecSmrg    if (stuff->timeout >= 0)
307705b261ecSmrg	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
307805b261ecSmrg    else
307905b261ecSmrg	ScreenSaverTime = defaultScreenSaverTime;
308005b261ecSmrg    if (stuff->interval >= 0)
308105b261ecSmrg	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
308205b261ecSmrg    else
308305b261ecSmrg	ScreenSaverInterval = defaultScreenSaverInterval;
308405b261ecSmrg
308505b261ecSmrg    SetScreenSaverTimer();
308605b261ecSmrg    return (client->noClientException);
308705b261ecSmrg}
308805b261ecSmrg
308905b261ecSmrgint
309005b261ecSmrgProcGetScreenSaver(ClientPtr client)
309105b261ecSmrg{
309205b261ecSmrg    xGetScreenSaverReply rep;
30934642e01fSmrg    int rc, i;
309405b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
30954642e01fSmrg
30964642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
30974642e01fSmrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
30984642e01fSmrg		      DixGetAttrAccess);
30994642e01fSmrg	if (rc != Success)
31004642e01fSmrg	    return rc;
31014642e01fSmrg    }
31024642e01fSmrg
310305b261ecSmrg    rep.type = X_Reply;
310405b261ecSmrg    rep.length = 0;
310505b261ecSmrg    rep.sequenceNumber = client->sequence;
310605b261ecSmrg    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
310705b261ecSmrg    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
310805b261ecSmrg    rep.preferBlanking = ScreenSaverBlanking;
310905b261ecSmrg    rep.allowExposures = ScreenSaverAllowExposures;
311005b261ecSmrg    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
311105b261ecSmrg    return (client->noClientException);
311205b261ecSmrg}
311305b261ecSmrg
311405b261ecSmrgint
311505b261ecSmrgProcChangeHosts(ClientPtr client)
311605b261ecSmrg{
311705b261ecSmrg    REQUEST(xChangeHostsReq);
311805b261ecSmrg    int result;
311905b261ecSmrg
312005b261ecSmrg    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
312105b261ecSmrg
312205b261ecSmrg    if(stuff->mode == HostInsert)
312305b261ecSmrg	result = AddHost(client, (int)stuff->hostFamily,
312405b261ecSmrg			 stuff->hostLength, (pointer)&stuff[1]);
312505b261ecSmrg    else if (stuff->mode == HostDelete)
312605b261ecSmrg	result = RemoveHost(client, (int)stuff->hostFamily,
312705b261ecSmrg			    stuff->hostLength, (pointer)&stuff[1]);
312805b261ecSmrg    else
312905b261ecSmrg    {
313005b261ecSmrg	client->errorValue = stuff->mode;
313105b261ecSmrg        return BadValue;
313205b261ecSmrg    }
313305b261ecSmrg    if (!result)
313405b261ecSmrg	result = client->noClientException;
313505b261ecSmrg    return (result);
313605b261ecSmrg}
313705b261ecSmrg
313805b261ecSmrgint
313905b261ecSmrgProcListHosts(ClientPtr client)
314005b261ecSmrg{
314105b261ecSmrg    xListHostsReply reply;
314205b261ecSmrg    int	len, nHosts, result;
314305b261ecSmrg    pointer	pdata;
314405b261ecSmrg    /* REQUEST(xListHostsReq); */
314505b261ecSmrg
314605b261ecSmrg    REQUEST_SIZE_MATCH(xListHostsReq);
314705b261ecSmrg
314805b261ecSmrg    /* untrusted clients can't list hosts */
31494642e01fSmrg    result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
31504642e01fSmrg    if (result != Success)
31514642e01fSmrg	return result;
315205b261ecSmrg
315305b261ecSmrg    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
315405b261ecSmrg    if (result != Success)
315505b261ecSmrg	return(result);
315605b261ecSmrg    reply.type = X_Reply;
315705b261ecSmrg    reply.sequenceNumber = client->sequence;
315805b261ecSmrg    reply.nHosts = nHosts;
315905b261ecSmrg    reply.length = len >> 2;
316005b261ecSmrg    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
316105b261ecSmrg    if (nHosts)
316205b261ecSmrg    {
316305b261ecSmrg	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
316405b261ecSmrg	WriteSwappedDataToClient(client, len, pdata);
316505b261ecSmrg    }
316605b261ecSmrg    xfree(pdata);
316705b261ecSmrg    return (client->noClientException);
316805b261ecSmrg}
316905b261ecSmrg
317005b261ecSmrgint
317105b261ecSmrgProcChangeAccessControl(ClientPtr client)
317205b261ecSmrg{
317305b261ecSmrg    int result;
317405b261ecSmrg    REQUEST(xSetAccessControlReq);
317505b261ecSmrg
317605b261ecSmrg    REQUEST_SIZE_MATCH(xSetAccessControlReq);
317705b261ecSmrg    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
317805b261ecSmrg    {
317905b261ecSmrg	client->errorValue = stuff->mode;
318005b261ecSmrg        return BadValue;
318105b261ecSmrg    }
318205b261ecSmrg    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
318305b261ecSmrg    if (!result)
318405b261ecSmrg	result = client->noClientException;
318505b261ecSmrg    return (result);
318605b261ecSmrg}
318705b261ecSmrg
318805b261ecSmrg/*********************
318905b261ecSmrg * CloseDownRetainedResources
319005b261ecSmrg *
319105b261ecSmrg *    Find all clients that are gone and have terminated in RetainTemporary
319205b261ecSmrg *    and destroy their resources.
319305b261ecSmrg *********************/
319405b261ecSmrg
319505b261ecSmrgstatic void
319605b261ecSmrgCloseDownRetainedResources(void)
319705b261ecSmrg{
319805b261ecSmrg    int i;
319905b261ecSmrg    ClientPtr client;
320005b261ecSmrg
320105b261ecSmrg    for (i=1; i<currentMaxClients; i++)
320205b261ecSmrg    {
320305b261ecSmrg        client = clients[i];
320405b261ecSmrg        if (client && (client->closeDownMode == RetainTemporary)
320505b261ecSmrg	    && (client->clientGone))
320605b261ecSmrg	    CloseDownClient(client);
320705b261ecSmrg    }
320805b261ecSmrg}
320905b261ecSmrg
321005b261ecSmrgint
321105b261ecSmrgProcKillClient(ClientPtr client)
321205b261ecSmrg{
321305b261ecSmrg    REQUEST(xResourceReq);
321405b261ecSmrg    ClientPtr killclient;
321505b261ecSmrg    int rc;
321605b261ecSmrg
321705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
321805b261ecSmrg    if (stuff->id == AllTemporary)
321905b261ecSmrg    {
322005b261ecSmrg	CloseDownRetainedResources();
322105b261ecSmrg        return (client->noClientException);
322205b261ecSmrg    }
322305b261ecSmrg
322405b261ecSmrg    rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
322505b261ecSmrg    if (rc == Success) {
322605b261ecSmrg	CloseDownClient(killclient);
322705b261ecSmrg	/* if an LBX proxy gets killed, isItTimeToYield will be set */
322805b261ecSmrg	if (isItTimeToYield || (client == killclient))
322905b261ecSmrg	{
323005b261ecSmrg	    /* force yield and return Success, so that Dispatch()
323105b261ecSmrg	     * doesn't try to touch client
323205b261ecSmrg	     */
323305b261ecSmrg	    isItTimeToYield = TRUE;
323405b261ecSmrg	    return (Success);
323505b261ecSmrg	}
323605b261ecSmrg	return (client->noClientException);
323705b261ecSmrg    }
323805b261ecSmrg    else
323905b261ecSmrg	return rc;
324005b261ecSmrg}
324105b261ecSmrg
324205b261ecSmrgint
324305b261ecSmrgProcSetFontPath(ClientPtr client)
324405b261ecSmrg{
324505b261ecSmrg    unsigned char *ptr;
324605b261ecSmrg    unsigned long nbytes, total;
324705b261ecSmrg    long nfonts;
324805b261ecSmrg    int n, result;
324905b261ecSmrg    int error;
325005b261ecSmrg    REQUEST(xSetFontPathReq);
325105b261ecSmrg
325205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
325305b261ecSmrg
325405b261ecSmrg    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
325505b261ecSmrg    total = nbytes;
325605b261ecSmrg    ptr = (unsigned char *)&stuff[1];
325705b261ecSmrg    nfonts = stuff->nFonts;
325805b261ecSmrg    while (--nfonts >= 0)
325905b261ecSmrg    {
326005b261ecSmrg	if ((total == 0) || (total < (n = (*ptr + 1))))
326105b261ecSmrg	    return(BadLength);
326205b261ecSmrg	total -= n;
326305b261ecSmrg	ptr += n;
326405b261ecSmrg    }
326505b261ecSmrg    if (total >= 4)
326605b261ecSmrg	return(BadLength);
326705b261ecSmrg    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
326805b261ecSmrg			 &error);
326905b261ecSmrg    if (!result)
327005b261ecSmrg    {
327105b261ecSmrg	result = client->noClientException;
327205b261ecSmrg	client->errorValue = error;
327305b261ecSmrg    }
327405b261ecSmrg    return (result);
327505b261ecSmrg}
327605b261ecSmrg
327705b261ecSmrgint
327805b261ecSmrgProcGetFontPath(ClientPtr client)
327905b261ecSmrg{
328005b261ecSmrg    xGetFontPathReply reply;
32814642e01fSmrg    int rc, stringLens, numpaths;
328205b261ecSmrg    unsigned char *bufferStart;
328305b261ecSmrg    /* REQUEST (xReq); */
328405b261ecSmrg
328505b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
32864642e01fSmrg    rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
32874642e01fSmrg    if (rc != Success)
32884642e01fSmrg	return rc;
328905b261ecSmrg
329005b261ecSmrg    reply.type = X_Reply;
329105b261ecSmrg    reply.sequenceNumber = client->sequence;
329205b261ecSmrg    reply.length = (stringLens + numpaths + 3) >> 2;
329305b261ecSmrg    reply.nPaths = numpaths;
329405b261ecSmrg
329505b261ecSmrg    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
329605b261ecSmrg    if (stringLens || numpaths)
329705b261ecSmrg	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
329805b261ecSmrg    return(client->noClientException);
329905b261ecSmrg}
330005b261ecSmrg
330105b261ecSmrgint
330205b261ecSmrgProcChangeCloseDownMode(ClientPtr client)
330305b261ecSmrg{
33044642e01fSmrg    int rc;
330505b261ecSmrg    REQUEST(xSetCloseDownModeReq);
330605b261ecSmrg    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
33074642e01fSmrg
33084642e01fSmrg    rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
33094642e01fSmrg    if (rc != Success)
33104642e01fSmrg	return rc;
33114642e01fSmrg
331205b261ecSmrg    if ((stuff->mode == AllTemporary) ||
331305b261ecSmrg	(stuff->mode == RetainPermanent) ||
331405b261ecSmrg	(stuff->mode == RetainTemporary))
331505b261ecSmrg    {
331605b261ecSmrg	client->closeDownMode = stuff->mode;
331705b261ecSmrg	return (client->noClientException);
331805b261ecSmrg    }
331905b261ecSmrg    else
332005b261ecSmrg    {
332105b261ecSmrg	client->errorValue = stuff->mode;
332205b261ecSmrg	return (BadValue);
332305b261ecSmrg    }
332405b261ecSmrg}
332505b261ecSmrg
332605b261ecSmrgint ProcForceScreenSaver(ClientPtr client)
332705b261ecSmrg{
33284642e01fSmrg    int rc;
332905b261ecSmrg    REQUEST(xForceScreenSaverReq);
333005b261ecSmrg
333105b261ecSmrg    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
333205b261ecSmrg
333305b261ecSmrg    if ((stuff->mode != ScreenSaverReset) &&
333405b261ecSmrg	(stuff->mode != ScreenSaverActive))
333505b261ecSmrg    {
333605b261ecSmrg	client->errorValue = stuff->mode;
333705b261ecSmrg        return BadValue;
333805b261ecSmrg    }
33394642e01fSmrg    rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode);
33404642e01fSmrg    if (rc != Success)
33414642e01fSmrg	return rc;
334205b261ecSmrg    return client->noClientException;
334305b261ecSmrg}
334405b261ecSmrg
334505b261ecSmrgint ProcNoOperation(ClientPtr client)
334605b261ecSmrg{
334705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xReq);
334805b261ecSmrg
334905b261ecSmrg    /* noop -- don't do anything */
335005b261ecSmrg    return(client->noClientException);
335105b261ecSmrg}
335205b261ecSmrg
335305b261ecSmrgvoid
335405b261ecSmrgInitProcVectors(void)
335505b261ecSmrg{
335605b261ecSmrg    int i;
335705b261ecSmrg    for (i = 0; i<256; i++)
335805b261ecSmrg    {
335905b261ecSmrg	if(!ProcVector[i])
336005b261ecSmrg	{
336105b261ecSmrg            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
336205b261ecSmrg	    ReplySwapVector[i] = ReplyNotSwappd;
336305b261ecSmrg	}
336405b261ecSmrg    }
336505b261ecSmrg    for(i = LASTEvent; i < 128; i++)
336605b261ecSmrg    {
336705b261ecSmrg	EventSwapVector[i] = NotImplemented;
336805b261ecSmrg    }
336905b261ecSmrg
337005b261ecSmrg}
337105b261ecSmrg
337205b261ecSmrg/**********************
337305b261ecSmrg * CloseDownClient
337405b261ecSmrg *
337505b261ecSmrg *  Client can either mark his resources destroy or retain.  If retained and
337605b261ecSmrg *  then killed again, the client is really destroyed.
337705b261ecSmrg *********************/
337805b261ecSmrg
337905b261ecSmrgchar dispatchExceptionAtReset = DE_RESET;
338005b261ecSmrg
338105b261ecSmrgvoid
338205b261ecSmrgCloseDownClient(ClientPtr client)
338305b261ecSmrg{
338405b261ecSmrg    Bool really_close_down = client->clientGone ||
338505b261ecSmrg			     client->closeDownMode == DestroyAll;
338605b261ecSmrg
338705b261ecSmrg    if (!client->clientGone)
338805b261ecSmrg    {
338905b261ecSmrg	/* ungrab server if grabbing client dies */
339005b261ecSmrg	if (grabState != GrabNone && grabClient == client)
339105b261ecSmrg	{
339205b261ecSmrg	    UngrabServer(client);
339305b261ecSmrg	}
339405b261ecSmrg	BITCLEAR(grabWaiters, client->index);
339505b261ecSmrg	DeleteClientFromAnySelections(client);
339605b261ecSmrg	ReleaseActiveGrabs(client);
339705b261ecSmrg	DeleteClientFontStuff(client);
339805b261ecSmrg	if (!really_close_down)
339905b261ecSmrg	{
340005b261ecSmrg	    /*  This frees resources that should never be retained
340105b261ecSmrg	     *  no matter what the close down mode is.  Actually we
340205b261ecSmrg	     *  could do this unconditionally, but it's probably
340305b261ecSmrg	     *  better not to traverse all the client's resources
340405b261ecSmrg	     *  twice (once here, once a few lines down in
340505b261ecSmrg	     *  FreeClientResources) in the common case of
340605b261ecSmrg	     *  really_close_down == TRUE.
340705b261ecSmrg	     */
340805b261ecSmrg	    FreeClientNeverRetainResources(client);
340905b261ecSmrg	    client->clientState = ClientStateRetained;
341005b261ecSmrg  	    if (ClientStateCallback)
341105b261ecSmrg            {
341205b261ecSmrg		NewClientInfoRec clientinfo;
341305b261ecSmrg
341405b261ecSmrg		clientinfo.client = client;
341505b261ecSmrg		clientinfo.prefix = (xConnSetupPrefix *)NULL;
341605b261ecSmrg		clientinfo.setup = (xConnSetup *) NULL;
341705b261ecSmrg		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
341805b261ecSmrg            }
341905b261ecSmrg	}
342005b261ecSmrg	client->clientGone = TRUE;  /* so events aren't sent to client */
342105b261ecSmrg	if (ClientIsAsleep(client))
342205b261ecSmrg	    ClientSignal (client);
342305b261ecSmrg	ProcessWorkQueueZombies();
342405b261ecSmrg	CloseDownConnection(client);
342505b261ecSmrg
342605b261ecSmrg	/* If the client made it to the Running stage, nClients has
342705b261ecSmrg	 * been incremented on its behalf, so we need to decrement it
342805b261ecSmrg	 * now.  If it hasn't gotten to Running, nClients has *not*
342905b261ecSmrg	 * been incremented, so *don't* decrement it.
343005b261ecSmrg	 */
343105b261ecSmrg	if (client->clientState != ClientStateInitial &&
343205b261ecSmrg	    client->clientState != ClientStateAuthenticating )
343305b261ecSmrg	{
343405b261ecSmrg	    --nClients;
343505b261ecSmrg	}
343605b261ecSmrg    }
343705b261ecSmrg
343805b261ecSmrg    if (really_close_down)
343905b261ecSmrg    {
344005b261ecSmrg	if (client->clientState == ClientStateRunning && nClients == 0)
344105b261ecSmrg	    dispatchException |= dispatchExceptionAtReset;
344205b261ecSmrg
344305b261ecSmrg	client->clientState = ClientStateGone;
344405b261ecSmrg	if (ClientStateCallback)
344505b261ecSmrg	{
344605b261ecSmrg	    NewClientInfoRec clientinfo;
344705b261ecSmrg
344805b261ecSmrg	    clientinfo.client = client;
344905b261ecSmrg	    clientinfo.prefix = (xConnSetupPrefix *)NULL;
345005b261ecSmrg	    clientinfo.setup = (xConnSetup *) NULL;
345105b261ecSmrg	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
345205b261ecSmrg	}
345305b261ecSmrg	FreeClientResources(client);
345405b261ecSmrg#ifdef XSERVER_DTRACE
345505b261ecSmrg	XSERVER_CLIENT_DISCONNECT(client->index);
345605b261ecSmrg#endif
345705b261ecSmrg	if (client->index < nextFreeClientID)
345805b261ecSmrg	    nextFreeClientID = client->index;
345905b261ecSmrg	clients[client->index] = NullClient;
346005b261ecSmrg	SmartLastClient = NullClient;
34614642e01fSmrg	dixFreePrivates(client->devPrivates);
346205b261ecSmrg	xfree(client);
346305b261ecSmrg
346405b261ecSmrg	while (!clients[currentMaxClients-1])
346505b261ecSmrg	    currentMaxClients--;
346605b261ecSmrg    }
346705b261ecSmrg}
346805b261ecSmrg
346905b261ecSmrgstatic void
347005b261ecSmrgKillAllClients(void)
347105b261ecSmrg{
347205b261ecSmrg    int i;
347305b261ecSmrg    for (i=1; i<currentMaxClients; i++)
347405b261ecSmrg        if (clients[i]) {
347505b261ecSmrg            /* Make sure Retained clients are released. */
347605b261ecSmrg            clients[i]->closeDownMode = DestroyAll;
347705b261ecSmrg            CloseDownClient(clients[i]);
347805b261ecSmrg        }
347905b261ecSmrg}
348005b261ecSmrg
348105b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv)
348205b261ecSmrg{
348305b261ecSmrg    client->index = i;
348405b261ecSmrg    client->sequence = 0;
348505b261ecSmrg    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
348605b261ecSmrg    client->clientGone = FALSE;
34874642e01fSmrg    client->closeDownMode = i ? DestroyAll : RetainPermanent;
348805b261ecSmrg    client->numSaved = 0;
348905b261ecSmrg    client->saveSet = (SaveSetElt *)NULL;
349005b261ecSmrg    client->noClientException = Success;
349105b261ecSmrg#ifdef DEBUG
349205b261ecSmrg    client->requestLogIndex = 0;
349305b261ecSmrg#endif
349405b261ecSmrg    client->requestVector = InitialVector;
349505b261ecSmrg    client->osPrivate = ospriv;
349605b261ecSmrg    client->swapped = FALSE;
349705b261ecSmrg    client->big_requests = FALSE;
349805b261ecSmrg    client->priority = 0;
349905b261ecSmrg    client->clientState = ClientStateInitial;
35004642e01fSmrg    client->devPrivates = NULL;
350105b261ecSmrg#ifdef XKB
350205b261ecSmrg    if (!noXkbExtension) {
350305b261ecSmrg	client->xkbClientFlags = 0;
350405b261ecSmrg	client->mapNotifyMask = 0;
35054642e01fSmrg	client->newKeyboardNotifyMask = 0;
35064642e01fSmrg	client->vMinor = client->vMajor = 0;
350705b261ecSmrg	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
350805b261ecSmrg    }
350905b261ecSmrg#endif
351005b261ecSmrg    client->replyBytesRemaining = 0;
351105b261ecSmrg    client->fontResFunc = NULL;
351205b261ecSmrg    client->smart_priority = 0;
351305b261ecSmrg    client->smart_start_tick = SmartScheduleTime;
351405b261ecSmrg    client->smart_stop_tick = SmartScheduleTime;
351505b261ecSmrg    client->smart_check_tick = SmartScheduleTime;
351605b261ecSmrg
35174642e01fSmrg    client->clientPtr = NULL;
351805b261ecSmrg}
351905b261ecSmrg
352005b261ecSmrg/************************
352105b261ecSmrg * int NextAvailableClient(ospriv)
352205b261ecSmrg *
352305b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes.
352405b261ecSmrg * Returns NULL if there are no free clients.
352505b261ecSmrg *************************/
352605b261ecSmrg
352705b261ecSmrgClientPtr NextAvailableClient(pointer ospriv)
352805b261ecSmrg{
352905b261ecSmrg    int i;
353005b261ecSmrg    ClientPtr client;
353105b261ecSmrg    xReq data;
353205b261ecSmrg
353305b261ecSmrg    i = nextFreeClientID;
353405b261ecSmrg    if (i == MAXCLIENTS)
353505b261ecSmrg	return (ClientPtr)NULL;
35364642e01fSmrg    clients[i] = client = (ClientPtr)xalloc(sizeof(ClientRec));
353705b261ecSmrg    if (!client)
353805b261ecSmrg	return (ClientPtr)NULL;
353905b261ecSmrg    InitClient(client, i, ospriv);
354005b261ecSmrg    if (!InitClientResources(client))
354105b261ecSmrg    {
354205b261ecSmrg	xfree(client);
354305b261ecSmrg	return (ClientPtr)NULL;
354405b261ecSmrg    }
354505b261ecSmrg    data.reqType = 1;
354605b261ecSmrg    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
354705b261ecSmrg    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
354805b261ecSmrg    {
354905b261ecSmrg	FreeClientResources(client);
355005b261ecSmrg	xfree(client);
355105b261ecSmrg	return (ClientPtr)NULL;
355205b261ecSmrg    }
355305b261ecSmrg    if (i == currentMaxClients)
355405b261ecSmrg	currentMaxClients++;
355505b261ecSmrg    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
355605b261ecSmrg	nextFreeClientID++;
355705b261ecSmrg    if (ClientStateCallback)
355805b261ecSmrg    {
355905b261ecSmrg	NewClientInfoRec clientinfo;
356005b261ecSmrg
356105b261ecSmrg        clientinfo.client = client;
356205b261ecSmrg        clientinfo.prefix = (xConnSetupPrefix *)NULL;
356305b261ecSmrg        clientinfo.setup = (xConnSetup *) NULL;
356405b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
356505b261ecSmrg    }
356605b261ecSmrg    return(client);
356705b261ecSmrg}
356805b261ecSmrg
356905b261ecSmrgint
357005b261ecSmrgProcInitialConnection(ClientPtr client)
357105b261ecSmrg{
357205b261ecSmrg    REQUEST(xReq);
357305b261ecSmrg    xConnClientPrefix *prefix;
357405b261ecSmrg    int whichbyte = 1;
357505b261ecSmrg
357605b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
357705b261ecSmrg    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
357805b261ecSmrg	return (client->noClientException = -1);
357905b261ecSmrg    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
358005b261ecSmrg	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
358105b261ecSmrg    {
358205b261ecSmrg	client->swapped = TRUE;
358305b261ecSmrg	SwapConnClientPrefix(prefix);
358405b261ecSmrg    }
358505b261ecSmrg    stuff->reqType = 2;
358605b261ecSmrg    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
358705b261ecSmrg		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
358805b261ecSmrg    if (client->swapped)
358905b261ecSmrg    {
359005b261ecSmrg	swaps(&stuff->length, whichbyte);
359105b261ecSmrg    }
359205b261ecSmrg    ResetCurrentRequest(client);
359305b261ecSmrg    return (client->noClientException);
359405b261ecSmrg}
359505b261ecSmrg
35964642e01fSmrgstatic int
359705b261ecSmrgSendConnSetup(ClientPtr client, char *reason)
359805b261ecSmrg{
359905b261ecSmrg    xWindowRoot *root;
360005b261ecSmrg    int i;
360105b261ecSmrg    int numScreens;
360205b261ecSmrg    char* lConnectionInfo;
360305b261ecSmrg    xConnSetupPrefix* lconnSetupPrefix;
360405b261ecSmrg
360505b261ecSmrg    if (reason)
360605b261ecSmrg    {
360705b261ecSmrg	xConnSetupPrefix csp;
360805b261ecSmrg
360905b261ecSmrg	csp.success = xFalse;
361005b261ecSmrg	csp.lengthReason = strlen(reason);
361105b261ecSmrg	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
361205b261ecSmrg	csp.majorVersion = X_PROTOCOL;
361305b261ecSmrg	csp.minorVersion = X_PROTOCOL_REVISION;
361405b261ecSmrg	if (client->swapped)
361505b261ecSmrg	    WriteSConnSetupPrefix(client, &csp);
361605b261ecSmrg	else
361705b261ecSmrg	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
361805b261ecSmrg        (void)WriteToClient(client, (int)csp.lengthReason, reason);
361905b261ecSmrg	return (client->noClientException = -1);
362005b261ecSmrg    }
362105b261ecSmrg
362205b261ecSmrg    numScreens = screenInfo.numScreens;
362305b261ecSmrg    lConnectionInfo = ConnectionInfo;
362405b261ecSmrg    lconnSetupPrefix = &connSetupPrefix;
362505b261ecSmrg
362605b261ecSmrg    /* We're about to start speaking X protocol back to the client by
362705b261ecSmrg     * sending the connection setup info.  This means the authorization
362805b261ecSmrg     * step is complete, and we can count the client as an
362905b261ecSmrg     * authorized one.
363005b261ecSmrg     */
363105b261ecSmrg    nClients++;
363205b261ecSmrg
363305b261ecSmrg    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
363405b261ecSmrg    client->sequence = 0;
363505b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
363605b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
363705b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
363805b261ecSmrg    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
363905b261ecSmrg    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
364005b261ecSmrg#endif
364105b261ecSmrg    /* fill in the "currentInputMask" */
364205b261ecSmrg    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
364305b261ecSmrg#ifdef PANORAMIX
364405b261ecSmrg    if (noPanoramiXExtension)
364505b261ecSmrg	numScreens = screenInfo.numScreens;
364605b261ecSmrg    else
364705b261ecSmrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
364805b261ecSmrg#endif
364905b261ecSmrg
365005b261ecSmrg    for (i=0; i<numScreens; i++)
365105b261ecSmrg    {
365205b261ecSmrg	unsigned int j;
365305b261ecSmrg	xDepth *pDepth;
365405b261ecSmrg
365505b261ecSmrg        root->currentInputMask = WindowTable[i]->eventMask |
365605b261ecSmrg			         wOtherEventMasks (WindowTable[i]);
365705b261ecSmrg	pDepth = (xDepth *)(root + 1);
365805b261ecSmrg	for (j = 0; j < root->nDepths; j++)
365905b261ecSmrg	{
366005b261ecSmrg	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
366105b261ecSmrg				pDepth->nVisuals * sizeof(xVisualType));
366205b261ecSmrg	}
366305b261ecSmrg	root = (xWindowRoot *)pDepth;
366405b261ecSmrg    }
366505b261ecSmrg
366605b261ecSmrg    if (client->swapped)
366705b261ecSmrg    {
366805b261ecSmrg	WriteSConnSetupPrefix(client, lconnSetupPrefix);
366905b261ecSmrg	WriteSConnectionInfo(client,
367005b261ecSmrg			     (unsigned long)(lconnSetupPrefix->length << 2),
367105b261ecSmrg			     lConnectionInfo);
367205b261ecSmrg    }
367305b261ecSmrg    else
367405b261ecSmrg    {
367505b261ecSmrg	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
367605b261ecSmrg			    (char *) lconnSetupPrefix);
367705b261ecSmrg	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
367805b261ecSmrg			    lConnectionInfo);
367905b261ecSmrg    }
368005b261ecSmrg    client->clientState = ClientStateRunning;
368105b261ecSmrg    if (ClientStateCallback)
368205b261ecSmrg    {
368305b261ecSmrg	NewClientInfoRec clientinfo;
368405b261ecSmrg
368505b261ecSmrg        clientinfo.client = client;
368605b261ecSmrg        clientinfo.prefix = lconnSetupPrefix;
368705b261ecSmrg        clientinfo.setup = (xConnSetup *)lConnectionInfo;
368805b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
368905b261ecSmrg    }
369005b261ecSmrg    return (client->noClientException);
369105b261ecSmrg}
369205b261ecSmrg
369305b261ecSmrgint
369405b261ecSmrgProcEstablishConnection(ClientPtr client)
369505b261ecSmrg{
369605b261ecSmrg    char *reason, *auth_proto, *auth_string;
369705b261ecSmrg    xConnClientPrefix *prefix;
369805b261ecSmrg    REQUEST(xReq);
369905b261ecSmrg
370005b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
370105b261ecSmrg    auth_proto = (char *)prefix + sz_xConnClientPrefix;
370205b261ecSmrg    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
370305b261ecSmrg    if ((prefix->majorVersion != X_PROTOCOL) ||
370405b261ecSmrg	(prefix->minorVersion != X_PROTOCOL_REVISION))
370505b261ecSmrg	reason = "Protocol version mismatch";
370605b261ecSmrg    else
370705b261ecSmrg	reason = ClientAuthorized(client,
370805b261ecSmrg				  (unsigned short)prefix->nbytesAuthProto,
370905b261ecSmrg				  auth_proto,
371005b261ecSmrg				  (unsigned short)prefix->nbytesAuthString,
371105b261ecSmrg				  auth_string);
371205b261ecSmrg    /*
371305b261ecSmrg     * If Kerberos is being used for this client, the clientState
371405b261ecSmrg     * will be set to ClientStateAuthenticating at this point.
371505b261ecSmrg     * More messages need to be exchanged among the X server, Kerberos
371605b261ecSmrg     * server, and client to figure out if everyone is authorized.
371705b261ecSmrg     * So we don't want to send the connection setup info yet, since
371805b261ecSmrg     * the auth step isn't really done.
371905b261ecSmrg     */
372005b261ecSmrg    if (client->clientState == ClientStateCheckingSecurity)
372105b261ecSmrg	client->clientState = ClientStateCheckedSecurity;
372205b261ecSmrg    else if (client->clientState != ClientStateAuthenticating)
372305b261ecSmrg	return(SendConnSetup(client, reason));
372405b261ecSmrg    return(client->noClientException);
372505b261ecSmrg}
372605b261ecSmrg
372705b261ecSmrg_X_EXPORT void
372805b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
372905b261ecSmrg                  XID resId, int errorCode)
373005b261ecSmrg{
373105b261ecSmrg    xError rep;
373205b261ecSmrg
373305b261ecSmrg    rep.type = X_Error;
373405b261ecSmrg    rep.sequenceNumber = client->sequence;
373505b261ecSmrg    rep.errorCode = errorCode;
373605b261ecSmrg    rep.majorCode = majorCode;
373705b261ecSmrg    rep.minorCode = minorCode;
373805b261ecSmrg    rep.resourceID = resId;
373905b261ecSmrg
374005b261ecSmrg    WriteEventsToClient (client, 1, (xEvent *)&rep);
374105b261ecSmrg}
374205b261ecSmrg
374305b261ecSmrgvoid
374405b261ecSmrgMarkClientException(ClientPtr client)
374505b261ecSmrg{
374605b261ecSmrg    client->noClientException = -1;
374705b261ecSmrg}
3748