dispatch.c revision 9ace9065
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:
789ace9065Smrg * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
7905b261ecSmrg *
8005b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
816747b715Smrg * copy of this software and associated documentation files (the "Software"),
826747b715Smrg * to deal in the Software without restriction, including without limitation
836747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
846747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the
856747b715Smrg * Software is furnished to do so, subject to the following conditions:
866747b715Smrg *
876747b715Smrg * The above copyright notice and this permission notice (including the next
886747b715Smrg * paragraph) shall be included in all copies or substantial portions of the
896747b715Smrg * Software.
906747b715Smrg *
916747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
926747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
936747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
946747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
956747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
966747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
976747b715Smrg * DEALINGS IN THE SOFTWARE.
9805b261ecSmrg */
9905b261ecSmrg
10005b261ecSmrg
10105b261ecSmrg
10205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
10305b261ecSmrg#include <dix-config.h>
1046747b715Smrg#include <version-config.h>
10505b261ecSmrg#endif
10605b261ecSmrg
10705b261ecSmrg#ifdef PANORAMIX_DEBUG
10805b261ecSmrg#include <stdio.h>
10905b261ecSmrgint ProcInitialConnection();
11005b261ecSmrg#endif
11105b261ecSmrg
11205b261ecSmrg#include "windowstr.h"
11305b261ecSmrg#include <X11/fonts/fontstruct.h>
11405b261ecSmrg#include "dixfontstr.h"
11505b261ecSmrg#include "gcstruct.h"
11605b261ecSmrg#include "selection.h"
11705b261ecSmrg#include "colormapst.h"
11805b261ecSmrg#include "cursorstr.h"
11905b261ecSmrg#include "scrnintstr.h"
12005b261ecSmrg#include "opaque.h"
12105b261ecSmrg#include "input.h"
12205b261ecSmrg#include "servermd.h"
12305b261ecSmrg#include "extnsionst.h"
12405b261ecSmrg#include "dixfont.h"
12505b261ecSmrg#include "dispatch.h"
12605b261ecSmrg#include "swaprep.h"
12705b261ecSmrg#include "swapreq.h"
1284642e01fSmrg#include "privates.h"
12905b261ecSmrg#include "xace.h"
13005b261ecSmrg#include "inputstr.h"
1316747b715Smrg#include "xkbsrv.h"
1326747b715Smrg#include "site.h"
13305b261ecSmrg
13405b261ecSmrg#ifdef XSERVER_DTRACE
1354642e01fSmrg#include "registry.h"
13605b261ecSmrg#include <sys/types.h>
13705b261ecSmrgtypedef const char *string;
13805b261ecSmrg#include "Xserver-dtrace.h"
13905b261ecSmrg#endif
14005b261ecSmrg
14105b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32)
14205b261ecSmrg#define BITMASK(i) (1U << ((i) & 31))
14305b261ecSmrg#define MASKIDX(i) ((i) >> 5)
14405b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)]
14505b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
14605b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
14705b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
14805b261ecSmrg
1496747b715SmrgxConnSetupPrefix connSetupPrefix;
1506747b715Smrg
1516747b715SmrgPaddingInfo PixmapWidthPaddingInfo[33];
15205b261ecSmrg
15305b261ecSmrgstatic ClientPtr grabClient;
15405b261ecSmrg#define GrabNone 0
15505b261ecSmrg#define GrabActive 1
15605b261ecSmrg#define GrabKickout 2
15705b261ecSmrgstatic int grabState = GrabNone;
15805b261ecSmrgstatic long grabWaiters[mskcnt];
1596747b715SmrgCallbackListPtr ServerGrabCallback = NULL;
16005b261ecSmrgHWEventQueuePtr checkForInput[2];
1616747b715Smrgint connBlockScreenStart;
16205b261ecSmrg
16305b261ecSmrgstatic void KillAllClients(void);
16405b261ecSmrg
16505b261ecSmrgstatic int nextFreeClientID; /* always MIN free client ID */
16605b261ecSmrg
16705b261ecSmrgstatic int	nClients;	/* number of authorized clients */
16805b261ecSmrg
1696747b715SmrgCallbackListPtr ClientStateCallback;
17005b261ecSmrg
17105b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they
17205b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't
17305b261ecSmrg * need to actually check value in memory when used and may miss changes from
17405b261ecSmrg * signal handlers.
17505b261ecSmrg */
1766747b715Smrgvolatile char dispatchException = 0;
1776747b715Smrgvolatile char isItTimeToYield;
17805b261ecSmrg
17905b261ecSmrg#define SAME_SCREENS(a, b) (\
18005b261ecSmrg    (a.pScreen == b.pScreen))
18105b261ecSmrg
1824642e01fSmrgvoid
18305b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
18405b261ecSmrg{
18505b261ecSmrg    checkForInput[0] = c0;
18605b261ecSmrg    checkForInput[1] = c1;
18705b261ecSmrg}
18805b261ecSmrg
1896747b715Smrgvoid
19005b261ecSmrgUpdateCurrentTime(void)
19105b261ecSmrg{
19205b261ecSmrg    TimeStamp systime;
19305b261ecSmrg
19405b261ecSmrg    /* To avoid time running backwards, we must call GetTimeInMillis before
19505b261ecSmrg     * calling ProcessInputEvents.
19605b261ecSmrg     */
19705b261ecSmrg    systime.months = currentTime.months;
19805b261ecSmrg    systime.milliseconds = GetTimeInMillis();
19905b261ecSmrg    if (systime.milliseconds < currentTime.milliseconds)
20005b261ecSmrg	systime.months++;
20105b261ecSmrg    if (*checkForInput[0] != *checkForInput[1])
20205b261ecSmrg	ProcessInputEvents();
20305b261ecSmrg    if (CompareTimeStamps(systime, currentTime) == LATER)
20405b261ecSmrg	currentTime = systime;
20505b261ecSmrg}
20605b261ecSmrg
20705b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
2086747b715Smrgvoid
20905b261ecSmrgUpdateCurrentTimeIf(void)
21005b261ecSmrg{
21105b261ecSmrg    TimeStamp systime;
21205b261ecSmrg
21305b261ecSmrg    systime.months = currentTime.months;
21405b261ecSmrg    systime.milliseconds = GetTimeInMillis();
21505b261ecSmrg    if (systime.milliseconds < currentTime.milliseconds)
21605b261ecSmrg	systime.months++;
21705b261ecSmrg    if (*checkForInput[0] == *checkForInput[1])
21805b261ecSmrg	currentTime = systime;
21905b261ecSmrg}
22005b261ecSmrg
22105b261ecSmrg
22205b261ecSmrg#undef SMART_DEBUG
22305b261ecSmrg
22405b261ecSmrg#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
22505b261ecSmrg#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
22605b261ecSmrg
2276747b715SmrgBool SmartScheduleDisable = FALSE;
2286747b715Smrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
2296747b715Smrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
2306747b715Smrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
2316747b715Smrglong SmartScheduleTime;
2326747b715Smrgint SmartScheduleLatencyLimited = 0;
23305b261ecSmrgstatic ClientPtr   SmartLastClient;
23405b261ecSmrgstatic int	   SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
23505b261ecSmrg
23605b261ecSmrg#ifdef SMART_DEBUG
23705b261ecSmrglong	    SmartLastPrint;
23805b261ecSmrg#endif
23905b261ecSmrg
24005b261ecSmrgvoid        Dispatch(void);
24105b261ecSmrg
24205b261ecSmrgstatic int
24305b261ecSmrgSmartScheduleClient (int *clientReady, int nready)
24405b261ecSmrg{
24505b261ecSmrg    ClientPtr	pClient;
24605b261ecSmrg    int		i;
24705b261ecSmrg    int		client;
24805b261ecSmrg    int		bestPrio, best = 0;
24905b261ecSmrg    int		bestRobin, robin;
25005b261ecSmrg    long	now = SmartScheduleTime;
25105b261ecSmrg    long	idle;
25205b261ecSmrg
25305b261ecSmrg    bestPrio = -0x7fffffff;
25405b261ecSmrg    bestRobin = 0;
25505b261ecSmrg    idle = 2 * SmartScheduleSlice;
25605b261ecSmrg    for (i = 0; i < nready; i++)
25705b261ecSmrg    {
25805b261ecSmrg	client = clientReady[i];
25905b261ecSmrg	pClient = clients[client];
26005b261ecSmrg	/* Praise clients which are idle */
26105b261ecSmrg	if ((now - pClient->smart_check_tick) >= idle)
26205b261ecSmrg	{
26305b261ecSmrg	    if (pClient->smart_priority < 0)
26405b261ecSmrg		pClient->smart_priority++;
26505b261ecSmrg	}
26605b261ecSmrg	pClient->smart_check_tick = now;
26705b261ecSmrg
26805b261ecSmrg	/* check priority to select best client */
26905b261ecSmrg	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
27005b261ecSmrg	if (pClient->smart_priority > bestPrio ||
27105b261ecSmrg	    (pClient->smart_priority == bestPrio && robin > bestRobin))
27205b261ecSmrg	{
27305b261ecSmrg	    bestPrio = pClient->smart_priority;
27405b261ecSmrg	    bestRobin = robin;
27505b261ecSmrg	    best = client;
27605b261ecSmrg	}
27705b261ecSmrg#ifdef SMART_DEBUG
27805b261ecSmrg	if ((now - SmartLastPrint) >= 5000)
27905b261ecSmrg	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
28005b261ecSmrg#endif
28105b261ecSmrg    }
28205b261ecSmrg#ifdef SMART_DEBUG
28305b261ecSmrg    if ((now - SmartLastPrint) >= 5000)
28405b261ecSmrg    {
28505b261ecSmrg	fprintf (stderr, " use %2d\n", best);
28605b261ecSmrg	SmartLastPrint = now;
28705b261ecSmrg    }
28805b261ecSmrg#endif
28905b261ecSmrg    pClient = clients[best];
29005b261ecSmrg    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
29105b261ecSmrg    /*
29205b261ecSmrg     * Set current client pointer
29305b261ecSmrg     */
29405b261ecSmrg    if (SmartLastClient != pClient)
29505b261ecSmrg    {
29605b261ecSmrg	pClient->smart_start_tick = now;
29705b261ecSmrg	SmartLastClient = pClient;
29805b261ecSmrg    }
29905b261ecSmrg    /*
30005b261ecSmrg     * Adjust slice
30105b261ecSmrg     */
302b1d344b3Smrg    if (nready == 1 && SmartScheduleLatencyLimited == 0)
30305b261ecSmrg    {
30405b261ecSmrg	/*
30505b261ecSmrg	 * If it's been a long time since another client
30605b261ecSmrg	 * has run, bump the slice up to get maximal
30705b261ecSmrg	 * performance from a single client
30805b261ecSmrg	 */
30905b261ecSmrg	if ((now - pClient->smart_start_tick) > 1000 &&
31005b261ecSmrg	    SmartScheduleSlice < SmartScheduleMaxSlice)
31105b261ecSmrg	{
31205b261ecSmrg	    SmartScheduleSlice += SmartScheduleInterval;
31305b261ecSmrg	}
31405b261ecSmrg    }
31505b261ecSmrg    else
31605b261ecSmrg    {
31705b261ecSmrg	SmartScheduleSlice = SmartScheduleInterval;
31805b261ecSmrg    }
31905b261ecSmrg    return best;
32005b261ecSmrg}
32105b261ecSmrg
322b1d344b3Smrgvoid
323b1d344b3SmrgEnableLimitedSchedulingLatency(void)
324b1d344b3Smrg{
325b1d344b3Smrg    ++SmartScheduleLatencyLimited;
326b1d344b3Smrg    SmartScheduleSlice = SmartScheduleInterval;
327b1d344b3Smrg}
328b1d344b3Smrg
329b1d344b3Smrgvoid
330b1d344b3SmrgDisableLimitedSchedulingLatency(void)
331b1d344b3Smrg{
332b1d344b3Smrg    --SmartScheduleLatencyLimited;
333b1d344b3Smrg
334b1d344b3Smrg    /* protect against bugs */
335b1d344b3Smrg    if (SmartScheduleLatencyLimited < 0)
336b1d344b3Smrg	SmartScheduleLatencyLimited = 0;
337b1d344b3Smrg}
338b1d344b3Smrg
33905b261ecSmrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType
34005b261ecSmrg
34105b261ecSmrgvoid
34205b261ecSmrgDispatch(void)
34305b261ecSmrg{
34405b261ecSmrg    int        *clientReady;     /* array of request ready clients */
34505b261ecSmrg    int	result;
34605b261ecSmrg    ClientPtr	client;
34705b261ecSmrg    int	nready;
34805b261ecSmrg    HWEventQueuePtr* icheck = checkForInput;
34905b261ecSmrg    long			start_tick;
35005b261ecSmrg
35105b261ecSmrg    nextFreeClientID = 1;
35205b261ecSmrg    nClients = 0;
35305b261ecSmrg
3546747b715Smrg    clientReady = malloc(sizeof(int) * MaxClients);
35505b261ecSmrg    if (!clientReady)
35605b261ecSmrg	return;
35705b261ecSmrg
358b1d344b3Smrg    SmartScheduleSlice = SmartScheduleInterval;
35905b261ecSmrg    while (!dispatchException)
36005b261ecSmrg    {
36105b261ecSmrg        if (*icheck[0] != *icheck[1])
36205b261ecSmrg	{
36305b261ecSmrg	    ProcessInputEvents();
36405b261ecSmrg	    FlushIfCriticalOutputPending();
36505b261ecSmrg	}
36605b261ecSmrg
36705b261ecSmrg	nready = WaitForSomething(clientReady);
36805b261ecSmrg
36905b261ecSmrg	if (nready && !SmartScheduleDisable)
37005b261ecSmrg	{
37105b261ecSmrg	    clientReady[0] = SmartScheduleClient (clientReady, nready);
37205b261ecSmrg	    nready = 1;
37305b261ecSmrg	}
37405b261ecSmrg       /*****************
37505b261ecSmrg	*  Handle events in round robin fashion, doing input between
37605b261ecSmrg	*  each round
37705b261ecSmrg	*****************/
37805b261ecSmrg
37905b261ecSmrg	while (!dispatchException && (--nready >= 0))
38005b261ecSmrg	{
38105b261ecSmrg	    client = clients[clientReady[nready]];
38205b261ecSmrg	    if (! client)
38305b261ecSmrg	    {
38405b261ecSmrg		/* KillClient can cause this to happen */
38505b261ecSmrg		continue;
38605b261ecSmrg	    }
38705b261ecSmrg	    /* GrabServer activation can cause this to be true */
38805b261ecSmrg	    if (grabState == GrabKickout)
38905b261ecSmrg	    {
39005b261ecSmrg		grabState = GrabActive;
39105b261ecSmrg		break;
39205b261ecSmrg	    }
39305b261ecSmrg	    isItTimeToYield = FALSE;
39405b261ecSmrg
39505b261ecSmrg	    start_tick = SmartScheduleTime;
39605b261ecSmrg	    while (!isItTimeToYield)
39705b261ecSmrg	    {
39805b261ecSmrg	        if (*icheck[0] != *icheck[1])
39905b261ecSmrg		    ProcessInputEvents();
4004642e01fSmrg
4014642e01fSmrg		FlushIfCriticalOutputPending();
40205b261ecSmrg		if (!SmartScheduleDisable &&
40305b261ecSmrg		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
40405b261ecSmrg		{
40505b261ecSmrg		    /* Penalize clients which consume ticks */
40605b261ecSmrg		    if (client->smart_priority > SMART_MIN_PRIORITY)
40705b261ecSmrg			client->smart_priority--;
40805b261ecSmrg		    break;
40905b261ecSmrg		}
41005b261ecSmrg		/* now, finally, deal with client requests */
41105b261ecSmrg
41205b261ecSmrg	        result = ReadRequestFromClient(client);
41305b261ecSmrg	        if (result <= 0)
41405b261ecSmrg	        {
41505b261ecSmrg		    if (result < 0)
41605b261ecSmrg			CloseDownClient(client);
41705b261ecSmrg		    break;
41805b261ecSmrg	        }
41905b261ecSmrg
42005b261ecSmrg		client->sequence++;
42105b261ecSmrg#ifdef XSERVER_DTRACE
4224642e01fSmrg		XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
42305b261ecSmrg			      ((xReq *)client->requestBuffer)->length,
42405b261ecSmrg			      client->index, client->requestBuffer);
42505b261ecSmrg#endif
42605b261ecSmrg		if (result > (maxBigRequestSize << 2))
42705b261ecSmrg		    result = BadLength;
42805b261ecSmrg		else {
4294642e01fSmrg		    result = XaceHookDispatch(client, MAJOROP);
4304642e01fSmrg		    if (result == Success)
4314642e01fSmrg			result = (* client->requestVector[MAJOROP])(client);
4324642e01fSmrg		    XaceHookAuditEnd(client, result);
43305b261ecSmrg		}
43405b261ecSmrg#ifdef XSERVER_DTRACE
4354642e01fSmrg		XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
43605b261ecSmrg			      client->sequence, client->index, result);
43705b261ecSmrg#endif
43805b261ecSmrg
4396747b715Smrg		if (client->noClientException != Success)
44005b261ecSmrg		{
4416747b715Smrg		    CloseDownClient(client);
44205b261ecSmrg		    break;
4436747b715Smrg		}
4446747b715Smrg		else if (result != Success)
4456747b715Smrg		{
4466747b715Smrg		    SendErrorToClient(client, MAJOROP,
4476747b715Smrg				      MinorOpcodeOfRequest(client),
4486747b715Smrg				      client->errorValue, result);
4496747b715Smrg		    break;
4506747b715Smrg		}
45105b261ecSmrg	    }
45205b261ecSmrg	    FlushAllOutput();
45305b261ecSmrg	    client = clients[clientReady[nready]];
45405b261ecSmrg	    if (client)
45505b261ecSmrg		client->smart_stop_tick = SmartScheduleTime;
45605b261ecSmrg	}
45705b261ecSmrg	dispatchException &= ~DE_PRIORITYCHANGE;
45805b261ecSmrg    }
45905b261ecSmrg#if defined(DDXBEFORERESET)
46005b261ecSmrg    ddxBeforeReset ();
46105b261ecSmrg#endif
46205b261ecSmrg    KillAllClients();
4636747b715Smrg    free(clientReady);
46405b261ecSmrg    dispatchException &= ~DE_RESET;
465b1d344b3Smrg    SmartScheduleLatencyLimited = 0;
46605b261ecSmrg}
46705b261ecSmrg
46805b261ecSmrg#undef MAJOROP
46905b261ecSmrg
4706747b715Smrgstatic int  VendorRelease = VENDOR_RELEASE;
4716747b715Smrgstatic char *VendorString = VENDOR_NAME;
4726747b715Smrg
4736747b715Smrgstatic const int padlength[4] = {0, 3, 2, 1};
4746747b715Smrg
4756747b715Smrgvoid
4766747b715SmrgSetVendorRelease(int release)
4776747b715Smrg{
4786747b715Smrg    VendorRelease = release;
4796747b715Smrg}
4806747b715Smrg
4816747b715Smrgvoid
4826747b715SmrgSetVendorString(char *string)
4836747b715Smrg{
4846747b715Smrg    VendorString = string;
4856747b715Smrg}
4866747b715Smrg
4876747b715SmrgBool
4886747b715SmrgCreateConnectionBlock(void)
4896747b715Smrg{
4906747b715Smrg    xConnSetup setup;
4916747b715Smrg    xWindowRoot root;
4926747b715Smrg    xDepth	depth;
4936747b715Smrg    xVisualType visual;
4946747b715Smrg    xPixmapFormat format;
4956747b715Smrg    unsigned long vid;
4966747b715Smrg    int i, j, k,
4976747b715Smrg        lenofblock,
4986747b715Smrg        sizesofar = 0;
4996747b715Smrg    char *pBuf;
5006747b715Smrg
5016747b715Smrg
5026747b715Smrg    memset(&setup, 0, sizeof(xConnSetup));
5036747b715Smrg    /* Leave off the ridBase and ridMask, these must be sent with
5046747b715Smrg       connection */
5056747b715Smrg
5066747b715Smrg    setup.release = VendorRelease;
5076747b715Smrg    /*
5086747b715Smrg     * per-server image and bitmap parameters are defined in Xmd.h
5096747b715Smrg     */
5106747b715Smrg    setup.imageByteOrder = screenInfo.imageByteOrder;
5116747b715Smrg
5126747b715Smrg    setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
5136747b715Smrg    setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
5146747b715Smrg
5156747b715Smrg    setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
5166747b715Smrg    setup.motionBufferSize = NumMotionEvents();
5176747b715Smrg    setup.numRoots = screenInfo.numScreens;
5186747b715Smrg    setup.nbytesVendor = strlen(VendorString);
5196747b715Smrg    setup.numFormats = screenInfo.numPixmapFormats;
5206747b715Smrg    setup.maxRequestSize = MAX_REQUEST_SIZE;
5216747b715Smrg    QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
5226747b715Smrg
5236747b715Smrg    lenofblock = sizeof(xConnSetup) +
5246747b715Smrg            pad_to_int32(setup.nbytesVendor) +
5256747b715Smrg	    (setup.numFormats * sizeof(xPixmapFormat)) +
5266747b715Smrg            (setup.numRoots * sizeof(xWindowRoot));
5276747b715Smrg    ConnectionInfo = malloc(lenofblock);
5286747b715Smrg    if (!ConnectionInfo)
5296747b715Smrg	return FALSE;
5306747b715Smrg
5316747b715Smrg    memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
5326747b715Smrg    sizesofar = sizeof(xConnSetup);
5336747b715Smrg    pBuf = ConnectionInfo + sizeof(xConnSetup);
5346747b715Smrg
5356747b715Smrg    memmove(pBuf, VendorString, (int)setup.nbytesVendor);
5366747b715Smrg    sizesofar += setup.nbytesVendor;
5376747b715Smrg    pBuf += setup.nbytesVendor;
5386747b715Smrg    i = padlength[setup.nbytesVendor & 3];
5396747b715Smrg    sizesofar += i;
5406747b715Smrg    while (--i >= 0)
5416747b715Smrg	*pBuf++ = 0;
5426747b715Smrg
5436747b715Smrg    memset(&format, 0, sizeof(xPixmapFormat));
5446747b715Smrg    for (i=0; i<screenInfo.numPixmapFormats; i++)
5456747b715Smrg    {
5466747b715Smrg	format.depth = screenInfo.formats[i].depth;
5476747b715Smrg	format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
5486747b715Smrg	format.scanLinePad = screenInfo.formats[i].scanlinePad;
5496747b715Smrg	memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
5506747b715Smrg	pBuf += sizeof(xPixmapFormat);
5516747b715Smrg	sizesofar += sizeof(xPixmapFormat);
5526747b715Smrg    }
5536747b715Smrg
5546747b715Smrg    connBlockScreenStart = sizesofar;
5556747b715Smrg    memset(&depth, 0, sizeof(xDepth));
5566747b715Smrg    memset(&visual, 0, sizeof(xVisualType));
5576747b715Smrg    for (i=0; i<screenInfo.numScreens; i++)
5586747b715Smrg    {
5596747b715Smrg	ScreenPtr	pScreen;
5606747b715Smrg	DepthPtr	pDepth;
5616747b715Smrg	VisualPtr	pVisual;
5626747b715Smrg
5636747b715Smrg	pScreen = screenInfo.screens[i];
5646747b715Smrg	root.windowId = pScreen->root->drawable.id;
5656747b715Smrg	root.defaultColormap = pScreen->defColormap;
5666747b715Smrg	root.whitePixel = pScreen->whitePixel;
5676747b715Smrg	root.blackPixel = pScreen->blackPixel;
5686747b715Smrg	root.currentInputMask = 0;    /* filled in when sent */
5696747b715Smrg	root.pixWidth = pScreen->width;
5706747b715Smrg	root.pixHeight = pScreen->height;
5716747b715Smrg	root.mmWidth = pScreen->mmWidth;
5726747b715Smrg	root.mmHeight = pScreen->mmHeight;
5736747b715Smrg	root.minInstalledMaps = pScreen->minInstalledCmaps;
5746747b715Smrg	root.maxInstalledMaps = pScreen->maxInstalledCmaps;
5756747b715Smrg	root.rootVisualID = pScreen->rootVisual;
5766747b715Smrg	root.backingStore = pScreen->backingStoreSupport;
5776747b715Smrg	root.saveUnders = FALSE;
5786747b715Smrg	root.rootDepth = pScreen->rootDepth;
5796747b715Smrg	root.nDepths = pScreen->numDepths;
5806747b715Smrg	memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
5816747b715Smrg	sizesofar += sizeof(xWindowRoot);
5826747b715Smrg	pBuf += sizeof(xWindowRoot);
5836747b715Smrg
5846747b715Smrg	pDepth = pScreen->allowedDepths;
5856747b715Smrg	for(j = 0; j < pScreen->numDepths; j++, pDepth++)
5866747b715Smrg	{
5876747b715Smrg	    lenofblock += sizeof(xDepth) +
5886747b715Smrg		    (pDepth->numVids * sizeof(xVisualType));
5896747b715Smrg	    pBuf = (char *)realloc(ConnectionInfo, lenofblock);
5906747b715Smrg	    if (!pBuf)
5916747b715Smrg	    {
5926747b715Smrg		free(ConnectionInfo);
5936747b715Smrg		return FALSE;
5946747b715Smrg	    }
5956747b715Smrg	    ConnectionInfo = pBuf;
5966747b715Smrg	    pBuf += sizesofar;
5976747b715Smrg	    depth.depth = pDepth->depth;
5986747b715Smrg	    depth.nVisuals = pDepth->numVids;
5996747b715Smrg	    memmove(pBuf, (char *)&depth, sizeof(xDepth));
6006747b715Smrg	    pBuf += sizeof(xDepth);
6016747b715Smrg	    sizesofar += sizeof(xDepth);
6026747b715Smrg	    for(k = 0; k < pDepth->numVids; k++)
6036747b715Smrg	    {
6046747b715Smrg		vid = pDepth->vids[k];
6056747b715Smrg		for (pVisual = pScreen->visuals;
6066747b715Smrg		     pVisual->vid != vid;
6076747b715Smrg		     pVisual++)
6086747b715Smrg		    ;
6096747b715Smrg		visual.visualID = vid;
6106747b715Smrg		visual.class = pVisual->class;
6116747b715Smrg		visual.bitsPerRGB = pVisual->bitsPerRGBValue;
6126747b715Smrg		visual.colormapEntries = pVisual->ColormapEntries;
6136747b715Smrg		visual.redMask = pVisual->redMask;
6146747b715Smrg		visual.greenMask = pVisual->greenMask;
6156747b715Smrg		visual.blueMask = pVisual->blueMask;
6166747b715Smrg		memmove(pBuf, (char *)&visual, sizeof(xVisualType));
6176747b715Smrg		pBuf += sizeof(xVisualType);
6186747b715Smrg		sizesofar += sizeof(xVisualType);
6196747b715Smrg	    }
6206747b715Smrg	}
6216747b715Smrg    }
6226747b715Smrg    connSetupPrefix.success = xTrue;
6236747b715Smrg    connSetupPrefix.length = lenofblock/4;
6246747b715Smrg    connSetupPrefix.majorVersion = X_PROTOCOL;
6256747b715Smrg    connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
6266747b715Smrg    return TRUE;
6276747b715Smrg}
6286747b715Smrg
6296747b715Smrg
6306747b715Smrgint
63105b261ecSmrgProcBadRequest(ClientPtr client)
63205b261ecSmrg{
6336747b715Smrg    return BadRequest;
63405b261ecSmrg}
63505b261ecSmrg
63605b261ecSmrgint
63705b261ecSmrgProcCreateWindow(ClientPtr client)
63805b261ecSmrg{
63905b261ecSmrg    WindowPtr pParent, pWin;
64005b261ecSmrg    REQUEST(xCreateWindowReq);
6414642e01fSmrg    int len, rc;
64205b261ecSmrg
64305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
64405b261ecSmrg
64505b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->wid, client);
6464642e01fSmrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
64705b261ecSmrg    if (rc != Success)
64805b261ecSmrg        return rc;
6496747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
65005b261ecSmrg    if (Ones(stuff->mask) != len)
65105b261ecSmrg        return BadLength;
65205b261ecSmrg    if (!stuff->width || !stuff->height)
65305b261ecSmrg    {
65405b261ecSmrg	client->errorValue = 0;
65505b261ecSmrg        return BadValue;
65605b261ecSmrg    }
65705b261ecSmrg    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
65805b261ecSmrg			      stuff->y, stuff->width, stuff->height,
65905b261ecSmrg			      stuff->borderWidth, stuff->class,
66005b261ecSmrg			      stuff->mask, (XID *) &stuff[1],
66105b261ecSmrg			      (int)stuff->depth,
6624642e01fSmrg			      client, stuff->visual, &rc);
66305b261ecSmrg    if (pWin)
66405b261ecSmrg    {
66505b261ecSmrg	Mask mask = pWin->eventMask;
66605b261ecSmrg
66705b261ecSmrg	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
66805b261ecSmrg	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
66905b261ecSmrg	    return BadAlloc;
67005b261ecSmrg	pWin->eventMask = mask;
67105b261ecSmrg    }
6726747b715Smrg    return rc;
67305b261ecSmrg}
67405b261ecSmrg
67505b261ecSmrgint
67605b261ecSmrgProcChangeWindowAttributes(ClientPtr client)
67705b261ecSmrg{
67805b261ecSmrg    WindowPtr pWin;
67905b261ecSmrg    REQUEST(xChangeWindowAttributesReq);
6806747b715Smrg    int len, rc;
6814642e01fSmrg    Mask access_mode = 0;
68205b261ecSmrg
68305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
6844642e01fSmrg    access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
6854642e01fSmrg    access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
6864642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
68705b261ecSmrg    if (rc != Success)
68805b261ecSmrg        return rc;
6896747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
69005b261ecSmrg    if (len != Ones(stuff->valueMask))
69105b261ecSmrg        return BadLength;
6926747b715Smrg    return ChangeWindowAttributes(pWin,
69305b261ecSmrg				  stuff->valueMask,
69405b261ecSmrg				  (XID *) &stuff[1],
69505b261ecSmrg				  client);
69605b261ecSmrg}
69705b261ecSmrg
69805b261ecSmrgint
69905b261ecSmrgProcGetWindowAttributes(ClientPtr client)
70005b261ecSmrg{
70105b261ecSmrg    WindowPtr pWin;
70205b261ecSmrg    REQUEST(xResourceReq);
70305b261ecSmrg    xGetWindowAttributesReply wa;
70405b261ecSmrg    int rc;
70505b261ecSmrg
70605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
7074642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
70805b261ecSmrg    if (rc != Success)
70905b261ecSmrg	return rc;
7106747b715Smrg    memset(&wa, 0, sizeof(xGetWindowAttributesReply));
71105b261ecSmrg    GetWindowAttributes(pWin, client, &wa);
71205b261ecSmrg    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
7136747b715Smrg    return Success;
71405b261ecSmrg}
71505b261ecSmrg
71605b261ecSmrgint
71705b261ecSmrgProcDestroyWindow(ClientPtr client)
71805b261ecSmrg{
71905b261ecSmrg    WindowPtr pWin;
72005b261ecSmrg    REQUEST(xResourceReq);
72105b261ecSmrg    int rc;
72205b261ecSmrg
72305b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
72405b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
72505b261ecSmrg    if (rc != Success)
72605b261ecSmrg	return rc;
7274642e01fSmrg    if (pWin->parent) {
7284642e01fSmrg	rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
7294642e01fSmrg			     DixRemoveAccess);
7304642e01fSmrg	if (rc != Success)
7314642e01fSmrg	    return rc;
73205b261ecSmrg	FreeResource(stuff->id, RT_NONE);
7334642e01fSmrg    }
7346747b715Smrg    return Success;
73505b261ecSmrg}
73605b261ecSmrg
73705b261ecSmrgint
73805b261ecSmrgProcDestroySubwindows(ClientPtr client)
73905b261ecSmrg{
74005b261ecSmrg    WindowPtr pWin;
74105b261ecSmrg    REQUEST(xResourceReq);
74205b261ecSmrg    int rc;
74305b261ecSmrg
74405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
7454642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
74605b261ecSmrg    if (rc != Success)
74705b261ecSmrg	return rc;
74805b261ecSmrg    DestroySubwindows(pWin, client);
7496747b715Smrg    return Success;
75005b261ecSmrg}
75105b261ecSmrg
75205b261ecSmrgint
75305b261ecSmrgProcChangeSaveSet(ClientPtr client)
75405b261ecSmrg{
75505b261ecSmrg    WindowPtr pWin;
75605b261ecSmrg    REQUEST(xChangeSaveSetReq);
7576747b715Smrg    int rc;
75805b261ecSmrg
75905b261ecSmrg    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
7604642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
76105b261ecSmrg    if (rc != Success)
76205b261ecSmrg        return rc;
76305b261ecSmrg    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
76405b261ecSmrg        return BadMatch;
76505b261ecSmrg    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
7666747b715Smrg        return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
7676747b715Smrg    client->errorValue = stuff->mode;
7686747b715Smrg    return BadValue;
76905b261ecSmrg}
77005b261ecSmrg
77105b261ecSmrgint
77205b261ecSmrgProcReparentWindow(ClientPtr client)
77305b261ecSmrg{
77405b261ecSmrg    WindowPtr pWin, pParent;
77505b261ecSmrg    REQUEST(xReparentWindowReq);
7766747b715Smrg    int rc;
77705b261ecSmrg
77805b261ecSmrg    REQUEST_SIZE_MATCH(xReparentWindowReq);
7794642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
78005b261ecSmrg    if (rc != Success)
78105b261ecSmrg        return rc;
7824642e01fSmrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
78305b261ecSmrg    if (rc != Success)
78405b261ecSmrg        return rc;
7856747b715Smrg    if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
7866747b715Smrg	return BadMatch;
7876747b715Smrg    if ((pWin->backgroundState == ParentRelative) &&
7886747b715Smrg	(pParent->drawable.depth != pWin->drawable.depth))
7896747b715Smrg	return BadMatch;
7906747b715Smrg    if ((pWin->drawable.class != InputOnly) &&
7916747b715Smrg	(pParent->drawable.class == InputOnly))
7926747b715Smrg	return BadMatch;
7936747b715Smrg    return ReparentWindow(pWin, pParent,
7946747b715Smrg		     (short)stuff->x, (short)stuff->y, client);
79505b261ecSmrg}
79605b261ecSmrg
79705b261ecSmrgint
79805b261ecSmrgProcMapWindow(ClientPtr client)
79905b261ecSmrg{
80005b261ecSmrg    WindowPtr pWin;
80105b261ecSmrg    REQUEST(xResourceReq);
80205b261ecSmrg    int rc;
80305b261ecSmrg
80405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
8054642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
80605b261ecSmrg    if (rc != Success)
80705b261ecSmrg        return rc;
80805b261ecSmrg    MapWindow(pWin, client);
80905b261ecSmrg           /* update cache to say it is mapped */
8106747b715Smrg    return Success;
81105b261ecSmrg}
81205b261ecSmrg
81305b261ecSmrgint
81405b261ecSmrgProcMapSubwindows(ClientPtr client)
81505b261ecSmrg{
81605b261ecSmrg    WindowPtr pWin;
81705b261ecSmrg    REQUEST(xResourceReq);
81805b261ecSmrg    int rc;
81905b261ecSmrg
82005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
8214642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
82205b261ecSmrg    if (rc != Success)
82305b261ecSmrg        return rc;
82405b261ecSmrg    MapSubwindows(pWin, client);
82505b261ecSmrg           /* update cache to say it is mapped */
8266747b715Smrg    return Success;
82705b261ecSmrg}
82805b261ecSmrg
82905b261ecSmrgint
83005b261ecSmrgProcUnmapWindow(ClientPtr client)
83105b261ecSmrg{
83205b261ecSmrg    WindowPtr pWin;
83305b261ecSmrg    REQUEST(xResourceReq);
83405b261ecSmrg    int rc;
83505b261ecSmrg
83605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
8374642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
83805b261ecSmrg    if (rc != Success)
83905b261ecSmrg        return rc;
84005b261ecSmrg    UnmapWindow(pWin, FALSE);
84105b261ecSmrg           /* update cache to say it is mapped */
8426747b715Smrg    return Success;
84305b261ecSmrg}
84405b261ecSmrg
84505b261ecSmrgint
84605b261ecSmrgProcUnmapSubwindows(ClientPtr client)
84705b261ecSmrg{
84805b261ecSmrg    WindowPtr pWin;
84905b261ecSmrg    REQUEST(xResourceReq);
85005b261ecSmrg    int rc;
85105b261ecSmrg
85205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
8534642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
85405b261ecSmrg    if (rc != Success)
85505b261ecSmrg        return rc;
85605b261ecSmrg    UnmapSubwindows(pWin);
8576747b715Smrg    return Success;
85805b261ecSmrg}
85905b261ecSmrg
86005b261ecSmrgint
86105b261ecSmrgProcConfigureWindow(ClientPtr client)
86205b261ecSmrg{
86305b261ecSmrg    WindowPtr pWin;
86405b261ecSmrg    REQUEST(xConfigureWindowReq);
86505b261ecSmrg    int len, rc;
86605b261ecSmrg
86705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
8684642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client,
8694642e01fSmrg			 DixManageAccess|DixSetAttrAccess);
87005b261ecSmrg    if (rc != Success)
87105b261ecSmrg        return rc;
8726747b715Smrg    len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
87305b261ecSmrg    if (Ones((Mask)stuff->mask) != len)
87405b261ecSmrg        return BadLength;
8756747b715Smrg    return ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], client);
87605b261ecSmrg}
87705b261ecSmrg
87805b261ecSmrgint
87905b261ecSmrgProcCirculateWindow(ClientPtr client)
88005b261ecSmrg{
88105b261ecSmrg    WindowPtr pWin;
88205b261ecSmrg    REQUEST(xCirculateWindowReq);
88305b261ecSmrg    int rc;
88405b261ecSmrg
88505b261ecSmrg    REQUEST_SIZE_MATCH(xCirculateWindowReq);
88605b261ecSmrg    if ((stuff->direction != RaiseLowest) &&
88705b261ecSmrg	(stuff->direction != LowerHighest))
88805b261ecSmrg    {
88905b261ecSmrg	client->errorValue = stuff->direction;
89005b261ecSmrg        return BadValue;
89105b261ecSmrg    }
8924642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
89305b261ecSmrg    if (rc != Success)
89405b261ecSmrg        return rc;
89505b261ecSmrg    CirculateWindow(pWin, (int)stuff->direction, client);
8966747b715Smrg    return Success;
89705b261ecSmrg}
89805b261ecSmrg
89905b261ecSmrgstatic int
90005b261ecSmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep)
90105b261ecSmrg{
90205b261ecSmrg    DrawablePtr pDraw;
90305b261ecSmrg    int rc;
90405b261ecSmrg    REQUEST(xResourceReq);
90505b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
90605b261ecSmrg
9074642e01fSmrg    rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
90805b261ecSmrg    if (rc != Success)
90905b261ecSmrg	return rc;
91005b261ecSmrg
91105b261ecSmrg    rep->type = X_Reply;
91205b261ecSmrg    rep->length = 0;
91305b261ecSmrg    rep->sequenceNumber = client->sequence;
9146747b715Smrg    rep->root = pDraw->pScreen->root->drawable.id;
91505b261ecSmrg    rep->depth = pDraw->depth;
91605b261ecSmrg    rep->width = pDraw->width;
91705b261ecSmrg    rep->height = pDraw->height;
91805b261ecSmrg
9199ace9065Smrg    if (WindowDrawable(pDraw->type))
92005b261ecSmrg    {
92105b261ecSmrg        WindowPtr pWin = (WindowPtr)pDraw;
92205b261ecSmrg	rep->x = pWin->origin.x - wBorderWidth (pWin);
92305b261ecSmrg	rep->y = pWin->origin.y - wBorderWidth (pWin);
92405b261ecSmrg	rep->borderWidth = pWin->borderWidth;
92505b261ecSmrg    }
9269ace9065Smrg    else /* DRAWABLE_PIXMAP */
92705b261ecSmrg    {
92805b261ecSmrg	rep->x = rep->y = rep->borderWidth = 0;
92905b261ecSmrg    }
93005b261ecSmrg
93105b261ecSmrg    return Success;
93205b261ecSmrg}
93305b261ecSmrg
93405b261ecSmrg
93505b261ecSmrgint
93605b261ecSmrgProcGetGeometry(ClientPtr client)
93705b261ecSmrg{
93805b261ecSmrg    xGetGeometryReply rep;
93905b261ecSmrg    int status;
94005b261ecSmrg
9416747b715Smrg    memset(&rep, 0, sizeof(xGetGeometryReply));
94205b261ecSmrg    if ((status = GetGeometry(client, &rep)) != Success)
94305b261ecSmrg	return status;
94405b261ecSmrg
94505b261ecSmrg    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
9466747b715Smrg    return Success;
94705b261ecSmrg}
94805b261ecSmrg
94905b261ecSmrg
95005b261ecSmrgint
95105b261ecSmrgProcQueryTree(ClientPtr client)
95205b261ecSmrg{
95305b261ecSmrg    xQueryTreeReply reply;
95405b261ecSmrg    int rc, numChildren = 0;
95505b261ecSmrg    WindowPtr pChild, pWin, pHead;
95605b261ecSmrg    Window  *childIDs = (Window *)NULL;
95705b261ecSmrg    REQUEST(xResourceReq);
95805b261ecSmrg
95905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
9604642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
96105b261ecSmrg    if (rc != Success)
96205b261ecSmrg        return rc;
9636747b715Smrg    memset(&reply, 0, sizeof(xQueryTreeReply));
96405b261ecSmrg    reply.type = X_Reply;
9656747b715Smrg    reply.root = pWin->drawable.pScreen->root->drawable.id;
96605b261ecSmrg    reply.sequenceNumber = client->sequence;
96705b261ecSmrg    if (pWin->parent)
96805b261ecSmrg	reply.parent = pWin->parent->drawable.id;
96905b261ecSmrg    else
97005b261ecSmrg        reply.parent = (Window)None;
97105b261ecSmrg    pHead = RealChildHead(pWin);
97205b261ecSmrg    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
97305b261ecSmrg	numChildren++;
97405b261ecSmrg    if (numChildren)
97505b261ecSmrg    {
97605b261ecSmrg	int curChild = 0;
97705b261ecSmrg
9786747b715Smrg	childIDs = malloc(numChildren * sizeof(Window));
97905b261ecSmrg	if (!childIDs)
98005b261ecSmrg	    return BadAlloc;
98105b261ecSmrg	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
98205b261ecSmrg	    childIDs[curChild++] = pChild->drawable.id;
98305b261ecSmrg    }
98405b261ecSmrg
98505b261ecSmrg    reply.nChildren = numChildren;
9866747b715Smrg    reply.length = bytes_to_int32(numChildren * sizeof(Window));
98705b261ecSmrg
98805b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
98905b261ecSmrg    if (numChildren)
99005b261ecSmrg    {
99105b261ecSmrg    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
99205b261ecSmrg	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
9936747b715Smrg	free(childIDs);
99405b261ecSmrg    }
99505b261ecSmrg
9966747b715Smrg    return Success;
99705b261ecSmrg}
99805b261ecSmrg
99905b261ecSmrgint
100005b261ecSmrgProcInternAtom(ClientPtr client)
100105b261ecSmrg{
100205b261ecSmrg    Atom atom;
100305b261ecSmrg    char *tchar;
100405b261ecSmrg    REQUEST(xInternAtomReq);
100505b261ecSmrg
100605b261ecSmrg    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
100705b261ecSmrg    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
100805b261ecSmrg    {
100905b261ecSmrg	client->errorValue = stuff->onlyIfExists;
10106747b715Smrg        return BadValue;
101105b261ecSmrg    }
101205b261ecSmrg    tchar = (char *) &stuff[1];
101305b261ecSmrg    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
101405b261ecSmrg    if (atom != BAD_RESOURCE)
101505b261ecSmrg    {
101605b261ecSmrg	xInternAtomReply reply;
10176747b715Smrg	memset(&reply, 0, sizeof(xInternAtomReply));
101805b261ecSmrg	reply.type = X_Reply;
101905b261ecSmrg	reply.length = 0;
102005b261ecSmrg	reply.sequenceNumber = client->sequence;
102105b261ecSmrg	reply.atom = atom;
102205b261ecSmrg	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
10236747b715Smrg	return Success;
102405b261ecSmrg    }
102505b261ecSmrg    else
10266747b715Smrg	return BadAlloc;
102705b261ecSmrg}
102805b261ecSmrg
102905b261ecSmrgint
103005b261ecSmrgProcGetAtomName(ClientPtr client)
103105b261ecSmrg{
10326747b715Smrg    const char *str;
103305b261ecSmrg    xGetAtomNameReply reply;
103405b261ecSmrg    int len;
103505b261ecSmrg    REQUEST(xResourceReq);
103605b261ecSmrg
103705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
103805b261ecSmrg    if ( (str = NameForAtom(stuff->id)) )
103905b261ecSmrg    {
104005b261ecSmrg	len = strlen(str);
10416747b715Smrg	memset(&reply, 0, sizeof(xGetAtomNameReply));
104205b261ecSmrg	reply.type = X_Reply;
10436747b715Smrg	reply.length = bytes_to_int32(len);
104405b261ecSmrg	reply.sequenceNumber = client->sequence;
104505b261ecSmrg	reply.nameLength = len;
104605b261ecSmrg	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
104705b261ecSmrg	(void)WriteToClient(client, len, str);
10486747b715Smrg	return Success;
104905b261ecSmrg    }
105005b261ecSmrg    else
105105b261ecSmrg    {
105205b261ecSmrg	client->errorValue = stuff->id;
10536747b715Smrg	return BadAtom;
105405b261ecSmrg    }
105505b261ecSmrg}
105605b261ecSmrg
105705b261ecSmrgint
105805b261ecSmrgProcGrabServer(ClientPtr client)
105905b261ecSmrg{
10604642e01fSmrg    int rc;
106105b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
106205b261ecSmrg    if (grabState != GrabNone && client != grabClient)
106305b261ecSmrg    {
106405b261ecSmrg	ResetCurrentRequest(client);
106505b261ecSmrg	client->sequence--;
106605b261ecSmrg	BITSET(grabWaiters, client->index);
106705b261ecSmrg	IgnoreClient(client);
10686747b715Smrg	return Success;
106905b261ecSmrg    }
10704642e01fSmrg    rc = OnlyListenToOneClient(client);
10714642e01fSmrg    if (rc != Success)
10724642e01fSmrg	return rc;
107305b261ecSmrg    grabState = GrabKickout;
107405b261ecSmrg    grabClient = client;
107505b261ecSmrg
107605b261ecSmrg    if (ServerGrabCallback)
107705b261ecSmrg    {
107805b261ecSmrg	ServerGrabInfoRec grabinfo;
107905b261ecSmrg	grabinfo.client = client;
108005b261ecSmrg	grabinfo.grabstate  = SERVER_GRABBED;
108105b261ecSmrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
108205b261ecSmrg    }
108305b261ecSmrg
10846747b715Smrg    return Success;
108505b261ecSmrg}
108605b261ecSmrg
108705b261ecSmrgstatic void
108805b261ecSmrgUngrabServer(ClientPtr client)
108905b261ecSmrg{
109005b261ecSmrg    int i;
109105b261ecSmrg
109205b261ecSmrg    grabState = GrabNone;
109305b261ecSmrg    ListenToAllClients();
109405b261ecSmrg    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
109505b261ecSmrg	;
109605b261ecSmrg    if (i >= 0)
109705b261ecSmrg    {
109805b261ecSmrg	i <<= 5;
109905b261ecSmrg	while (!GETBIT(grabWaiters, i))
110005b261ecSmrg	    i++;
110105b261ecSmrg	BITCLEAR(grabWaiters, i);
110205b261ecSmrg	AttendClient(clients[i]);
110305b261ecSmrg    }
110405b261ecSmrg
110505b261ecSmrg    if (ServerGrabCallback)
110605b261ecSmrg    {
110705b261ecSmrg	ServerGrabInfoRec grabinfo;
110805b261ecSmrg	grabinfo.client = client;
110905b261ecSmrg	grabinfo.grabstate  = SERVER_UNGRABBED;
111005b261ecSmrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
111105b261ecSmrg    }
111205b261ecSmrg}
111305b261ecSmrg
111405b261ecSmrgint
111505b261ecSmrgProcUngrabServer(ClientPtr client)
111605b261ecSmrg{
111705b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
111805b261ecSmrg    UngrabServer(client);
11196747b715Smrg    return Success;
112005b261ecSmrg}
112105b261ecSmrg
112205b261ecSmrgint
112305b261ecSmrgProcTranslateCoords(ClientPtr client)
112405b261ecSmrg{
112505b261ecSmrg    REQUEST(xTranslateCoordsReq);
112605b261ecSmrg
112705b261ecSmrg    WindowPtr pWin, pDst;
112805b261ecSmrg    xTranslateCoordsReply rep;
112905b261ecSmrg    int rc;
113005b261ecSmrg
113105b261ecSmrg    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
11324642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
113305b261ecSmrg    if (rc != Success)
113405b261ecSmrg        return rc;
11354642e01fSmrg    rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
113605b261ecSmrg    if (rc != Success)
113705b261ecSmrg        return rc;
11386747b715Smrg    memset(&rep, 0, sizeof(xTranslateCoordsReply));
113905b261ecSmrg    rep.type = X_Reply;
114005b261ecSmrg    rep.length = 0;
114105b261ecSmrg    rep.sequenceNumber = client->sequence;
114205b261ecSmrg    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
114305b261ecSmrg    {
114405b261ecSmrg	rep.sameScreen = xFalse;
114505b261ecSmrg        rep.child = None;
114605b261ecSmrg	rep.dstX = rep.dstY = 0;
114705b261ecSmrg    }
114805b261ecSmrg    else
114905b261ecSmrg    {
115005b261ecSmrg	INT16 x, y;
115105b261ecSmrg	rep.sameScreen = xTrue;
115205b261ecSmrg	rep.child = None;
115305b261ecSmrg	/* computing absolute coordinates -- adjust to destination later */
115405b261ecSmrg	x = pWin->drawable.x + stuff->srcX;
115505b261ecSmrg	y = pWin->drawable.y + stuff->srcY;
115605b261ecSmrg	pWin = pDst->firstChild;
115705b261ecSmrg	while (pWin)
115805b261ecSmrg	{
115905b261ecSmrg	    BoxRec  box;
116005b261ecSmrg	    if ((pWin->mapped) &&
116105b261ecSmrg		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
116205b261ecSmrg		(x < pWin->drawable.x + (int)pWin->drawable.width +
116305b261ecSmrg		 wBorderWidth (pWin)) &&
116405b261ecSmrg		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
116505b261ecSmrg		(y < pWin->drawable.y + (int)pWin->drawable.height +
116605b261ecSmrg		 wBorderWidth (pWin))
116705b261ecSmrg		/* When a window is shaped, a further check
116805b261ecSmrg		 * is made to see if the point is inside
116905b261ecSmrg		 * borderSize
117005b261ecSmrg		 */
117105b261ecSmrg		&& (!wBoundingShape(pWin) ||
11726747b715Smrg		    RegionContainsPoint(&pWin->borderSize, x, y, &box))
117305b261ecSmrg
117405b261ecSmrg		&& (!wInputShape(pWin) ||
11756747b715Smrg		    RegionContainsPoint(wInputShape(pWin),
11766747b715Smrg					x - pWin->drawable.x,
11776747b715Smrg					y - pWin->drawable.y, &box))
117805b261ecSmrg		)
117905b261ecSmrg            {
118005b261ecSmrg		rep.child = pWin->drawable.id;
118105b261ecSmrg		pWin = (WindowPtr) NULL;
118205b261ecSmrg	    }
118305b261ecSmrg	    else
118405b261ecSmrg		pWin = pWin->nextSib;
118505b261ecSmrg	}
118605b261ecSmrg	/* adjust to destination coordinates */
118705b261ecSmrg	rep.dstX = x - pDst->drawable.x;
118805b261ecSmrg	rep.dstY = y - pDst->drawable.y;
118905b261ecSmrg    }
119005b261ecSmrg    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
11916747b715Smrg    return Success;
119205b261ecSmrg}
119305b261ecSmrg
119405b261ecSmrgint
119505b261ecSmrgProcOpenFont(ClientPtr client)
119605b261ecSmrg{
119705b261ecSmrg    int	err;
119805b261ecSmrg    REQUEST(xOpenFontReq);
119905b261ecSmrg
120005b261ecSmrg    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
120105b261ecSmrg    client->errorValue = stuff->fid;
120205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->fid, client);
120305b261ecSmrg    err = OpenFont(client, stuff->fid, (Mask) 0,
120405b261ecSmrg		stuff->nbytes, (char *)&stuff[1]);
120505b261ecSmrg    if (err == Success)
120605b261ecSmrg    {
12076747b715Smrg	return Success;
120805b261ecSmrg    }
120905b261ecSmrg    else
121005b261ecSmrg	return err;
121105b261ecSmrg}
121205b261ecSmrg
121305b261ecSmrgint
121405b261ecSmrgProcCloseFont(ClientPtr client)
121505b261ecSmrg{
121605b261ecSmrg    FontPtr pFont;
12176747b715Smrg    int rc;
121805b261ecSmrg    REQUEST(xResourceReq);
121905b261ecSmrg
122005b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
12216747b715Smrg    rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT,
12226747b715Smrg				 client, DixDestroyAccess);
12236747b715Smrg    if (rc == Success)
122405b261ecSmrg    {
122505b261ecSmrg        FreeResource(stuff->id, RT_NONE);
12266747b715Smrg	return Success;
122705b261ecSmrg    }
122805b261ecSmrg    else
122905b261ecSmrg    {
123005b261ecSmrg	client->errorValue = stuff->id;
12316747b715Smrg        return rc;
123205b261ecSmrg    }
123305b261ecSmrg}
123405b261ecSmrg
123505b261ecSmrgint
123605b261ecSmrgProcQueryFont(ClientPtr client)
123705b261ecSmrg{
123805b261ecSmrg    xQueryFontReply	*reply;
123905b261ecSmrg    FontPtr pFont;
12404642e01fSmrg    int rc;
124105b261ecSmrg    REQUEST(xResourceReq);
124205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
12434642e01fSmrg
12446747b715Smrg    rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
12454642e01fSmrg    if (rc != Success)
12466747b715Smrg	return rc;
124705b261ecSmrg
124805b261ecSmrg    {
124905b261ecSmrg	xCharInfo	*pmax = FONTINKMAX(pFont);
125005b261ecSmrg	xCharInfo	*pmin = FONTINKMIN(pFont);
125105b261ecSmrg	int		nprotoxcistructs;
125205b261ecSmrg	int		rlength;
125305b261ecSmrg
125405b261ecSmrg	nprotoxcistructs = (
125505b261ecSmrg	   pmax->rightSideBearing == pmin->rightSideBearing &&
125605b261ecSmrg	   pmax->leftSideBearing == pmin->leftSideBearing &&
125705b261ecSmrg	   pmax->descent == pmin->descent &&
125805b261ecSmrg	   pmax->ascent == pmin->ascent &&
125905b261ecSmrg	   pmax->characterWidth == pmin->characterWidth) ?
126005b261ecSmrg		0 : N2dChars(pFont);
126105b261ecSmrg
126205b261ecSmrg	rlength = sizeof(xQueryFontReply) +
126305b261ecSmrg	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
126405b261ecSmrg		     nprotoxcistructs * sizeof(xCharInfo);
12656747b715Smrg	reply = calloc(1, rlength);
126605b261ecSmrg	if(!reply)
126705b261ecSmrg	{
12686747b715Smrg	    return BadAlloc;
126905b261ecSmrg	}
127005b261ecSmrg
127105b261ecSmrg	reply->type = X_Reply;
12726747b715Smrg	reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
127305b261ecSmrg	reply->sequenceNumber = client->sequence;
127405b261ecSmrg	QueryFont( pFont, reply, nprotoxcistructs);
127505b261ecSmrg
127605b261ecSmrg        WriteReplyToClient(client, rlength, reply);
12776747b715Smrg	free(reply);
12786747b715Smrg	return Success;
127905b261ecSmrg    }
128005b261ecSmrg}
128105b261ecSmrg
128205b261ecSmrgint
128305b261ecSmrgProcQueryTextExtents(ClientPtr client)
128405b261ecSmrg{
128505b261ecSmrg    xQueryTextExtentsReply reply;
128605b261ecSmrg    FontPtr pFont;
128705b261ecSmrg    ExtentInfoRec info;
128805b261ecSmrg    unsigned long length;
12894642e01fSmrg    int rc;
12904642e01fSmrg    REQUEST(xQueryTextExtentsReq);
129105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
129205b261ecSmrg
12936747b715Smrg    rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
12944642e01fSmrg    if (rc != Success)
12956747b715Smrg	return rc;
12964642e01fSmrg
12976747b715Smrg    length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
129805b261ecSmrg    length = length << 1;
129905b261ecSmrg    if (stuff->oddLength)
130005b261ecSmrg    {
130105b261ecSmrg	if (length == 0)
13026747b715Smrg	    return BadLength;
130305b261ecSmrg        length--;
130405b261ecSmrg    }
130505b261ecSmrg    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
13066747b715Smrg	return BadAlloc;
130705b261ecSmrg    reply.type = X_Reply;
130805b261ecSmrg    reply.length = 0;
130905b261ecSmrg    reply.sequenceNumber = client->sequence;
131005b261ecSmrg    reply.drawDirection = info.drawDirection;
131105b261ecSmrg    reply.fontAscent = info.fontAscent;
131205b261ecSmrg    reply.fontDescent = info.fontDescent;
131305b261ecSmrg    reply.overallAscent = info.overallAscent;
131405b261ecSmrg    reply.overallDescent = info.overallDescent;
131505b261ecSmrg    reply.overallWidth = info.overallWidth;
131605b261ecSmrg    reply.overallLeft = info.overallLeft;
131705b261ecSmrg    reply.overallRight = info.overallRight;
131805b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
13196747b715Smrg    return Success;
132005b261ecSmrg}
132105b261ecSmrg
132205b261ecSmrgint
132305b261ecSmrgProcListFonts(ClientPtr client)
132405b261ecSmrg{
132505b261ecSmrg    REQUEST(xListFontsReq);
132605b261ecSmrg
132705b261ecSmrg    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
132805b261ecSmrg
132905b261ecSmrg    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
133005b261ecSmrg	stuff->maxNames);
133105b261ecSmrg}
133205b261ecSmrg
133305b261ecSmrgint
133405b261ecSmrgProcListFontsWithInfo(ClientPtr client)
133505b261ecSmrg{
133605b261ecSmrg    REQUEST(xListFontsWithInfoReq);
133705b261ecSmrg
133805b261ecSmrg    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
133905b261ecSmrg
134005b261ecSmrg    return StartListFontsWithInfo(client, stuff->nbytes,
134105b261ecSmrg				  (unsigned char *) &stuff[1], stuff->maxNames);
134205b261ecSmrg}
134305b261ecSmrg
134405b261ecSmrg/**
134505b261ecSmrg *
134605b261ecSmrg *  \param value must conform to DeleteType
134705b261ecSmrg */
134805b261ecSmrgint
134905b261ecSmrgdixDestroyPixmap(pointer value, XID pid)
135005b261ecSmrg{
135105b261ecSmrg    PixmapPtr pPixmap = (PixmapPtr)value;
135205b261ecSmrg    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
135305b261ecSmrg}
135405b261ecSmrg
135505b261ecSmrgint
135605b261ecSmrgProcCreatePixmap(ClientPtr client)
135705b261ecSmrg{
135805b261ecSmrg    PixmapPtr pMap;
135905b261ecSmrg    DrawablePtr pDraw;
136005b261ecSmrg    REQUEST(xCreatePixmapReq);
136105b261ecSmrg    DepthPtr pDepth;
136205b261ecSmrg    int i, rc;
136305b261ecSmrg
136405b261ecSmrg    REQUEST_SIZE_MATCH(xCreatePixmapReq);
136505b261ecSmrg    client->errorValue = stuff->pid;
136605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
136705b261ecSmrg
136805b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
13694642e01fSmrg			   DixGetAttrAccess);
137005b261ecSmrg    if (rc != Success)
137105b261ecSmrg	return rc;
137205b261ecSmrg
137305b261ecSmrg    if (!stuff->width || !stuff->height)
137405b261ecSmrg    {
137505b261ecSmrg	client->errorValue = 0;
137605b261ecSmrg        return BadValue;
137705b261ecSmrg    }
137805b261ecSmrg    if (stuff->width > 32767 || stuff->height > 32767)
137905b261ecSmrg    {
138005b261ecSmrg	/* It is allowed to try and allocate a pixmap which is larger than
138105b261ecSmrg	 * 32767 in either dimension. However, all of the framebuffer code
138205b261ecSmrg	 * is buggy and does not reliably draw to such big pixmaps, basically
138305b261ecSmrg	 * because the Region data structure operates with signed shorts
138405b261ecSmrg	 * for the rectangles in it.
138505b261ecSmrg	 *
138605b261ecSmrg	 * Furthermore, several places in the X server computes the
138705b261ecSmrg	 * size in bytes of the pixmap and tries to store it in an
138805b261ecSmrg	 * integer. This integer can overflow and cause the allocated size
138905b261ecSmrg	 * to be much smaller.
139005b261ecSmrg	 *
139105b261ecSmrg	 * So, such big pixmaps are rejected here with a BadAlloc
139205b261ecSmrg	 */
139305b261ecSmrg	return BadAlloc;
139405b261ecSmrg    }
139505b261ecSmrg    if (stuff->depth != 1)
139605b261ecSmrg    {
139705b261ecSmrg        pDepth = pDraw->pScreen->allowedDepths;
139805b261ecSmrg        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
139905b261ecSmrg	   if (pDepth->depth == stuff->depth)
140005b261ecSmrg               goto CreatePmap;
140105b261ecSmrg	client->errorValue = stuff->depth;
140205b261ecSmrg        return BadValue;
140305b261ecSmrg    }
140405b261ecSmrgCreatePmap:
140505b261ecSmrg    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
140605b261ecSmrg		(pDraw->pScreen, stuff->width,
14074642e01fSmrg		 stuff->height, stuff->depth, 0);
140805b261ecSmrg    if (pMap)
140905b261ecSmrg    {
141005b261ecSmrg	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
141105b261ecSmrg	pMap->drawable.id = stuff->pid;
14124642e01fSmrg	/* security creation/labeling check */
14134642e01fSmrg	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
14144642e01fSmrg		      pMap, RT_NONE, NULL, DixCreateAccess);
14154642e01fSmrg	if (rc != Success) {
14164642e01fSmrg	    (*pDraw->pScreen->DestroyPixmap)(pMap);
14174642e01fSmrg	    return rc;
14184642e01fSmrg	}
141905b261ecSmrg	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
14206747b715Smrg	    return Success;
14214642e01fSmrg	(*pDraw->pScreen->DestroyPixmap)(pMap);
142205b261ecSmrg    }
14236747b715Smrg    return BadAlloc;
142405b261ecSmrg}
142505b261ecSmrg
142605b261ecSmrgint
142705b261ecSmrgProcFreePixmap(ClientPtr client)
142805b261ecSmrg{
142905b261ecSmrg    PixmapPtr pMap;
14304642e01fSmrg    int rc;
143105b261ecSmrg    REQUEST(xResourceReq);
143205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
14334642e01fSmrg
1434b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client,
14354642e01fSmrg			   DixDestroyAccess);
14364642e01fSmrg    if (rc == Success)
143705b261ecSmrg    {
143805b261ecSmrg	FreeResource(stuff->id, RT_NONE);
14396747b715Smrg	return Success;
144005b261ecSmrg    }
144105b261ecSmrg    else
144205b261ecSmrg    {
144305b261ecSmrg	client->errorValue = stuff->id;
14446747b715Smrg	return rc;
144505b261ecSmrg    }
144605b261ecSmrg}
144705b261ecSmrg
144805b261ecSmrgint
144905b261ecSmrgProcCreateGC(ClientPtr client)
145005b261ecSmrg{
145105b261ecSmrg    int error, rc;
145205b261ecSmrg    GC *pGC;
145305b261ecSmrg    DrawablePtr pDraw;
145405b261ecSmrg    unsigned len;
145505b261ecSmrg    REQUEST(xCreateGCReq);
145605b261ecSmrg
145705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
145805b261ecSmrg    client->errorValue = stuff->gc;
145905b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gc, client);
14604642e01fSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
14614642e01fSmrg			   DixGetAttrAccess);
146205b261ecSmrg    if (rc != Success)
146305b261ecSmrg	return rc;
146405b261ecSmrg
14656747b715Smrg    len = client->req_len -  bytes_to_int32(sizeof(xCreateGCReq));
146605b261ecSmrg    if (len != Ones(stuff->mask))
146705b261ecSmrg        return BadLength;
14684642e01fSmrg    pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
14694642e01fSmrg			 stuff->gc, client);
147005b261ecSmrg    if (error != Success)
147105b261ecSmrg        return error;
147205b261ecSmrg    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
14736747b715Smrg	return BadAlloc;
14746747b715Smrg    return Success;
147505b261ecSmrg}
147605b261ecSmrg
147705b261ecSmrgint
147805b261ecSmrgProcChangeGC(ClientPtr client)
147905b261ecSmrg{
148005b261ecSmrg    GC *pGC;
148105b261ecSmrg    int result;
148205b261ecSmrg    unsigned len;
148305b261ecSmrg    REQUEST(xChangeGCReq);
148405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
148505b261ecSmrg
14864642e01fSmrg    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
148705b261ecSmrg    if (result != Success)
148805b261ecSmrg	return result;
148905b261ecSmrg
14906747b715Smrg    len = client->req_len -  bytes_to_int32(sizeof(xChangeGCReq));
149105b261ecSmrg    if (len != Ones(stuff->mask))
149205b261ecSmrg        return BadLength;
149305b261ecSmrg
14946747b715Smrg    return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
149505b261ecSmrg}
149605b261ecSmrg
149705b261ecSmrgint
149805b261ecSmrgProcCopyGC(ClientPtr client)
149905b261ecSmrg{
150005b261ecSmrg    GC *dstGC;
150105b261ecSmrg    GC *pGC;
150205b261ecSmrg    int result;
150305b261ecSmrg    REQUEST(xCopyGCReq);
150405b261ecSmrg    REQUEST_SIZE_MATCH(xCopyGCReq);
150505b261ecSmrg
15064642e01fSmrg    result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
150705b261ecSmrg    if (result != Success)
150805b261ecSmrg	return result;
15094642e01fSmrg    result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
151005b261ecSmrg    if (result != Success)
151105b261ecSmrg	return result;
151205b261ecSmrg    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
15136747b715Smrg        return BadMatch;
15146747b715Smrg    if (stuff->mask & ~GCAllBits)
151505b261ecSmrg    {
15166747b715Smrg	client->errorValue = stuff->mask;
15176747b715Smrg	return BadValue;
151805b261ecSmrg    }
15196747b715Smrg    return CopyGC(pGC, dstGC, stuff->mask);
152005b261ecSmrg}
152105b261ecSmrg
152205b261ecSmrgint
152305b261ecSmrgProcSetDashes(ClientPtr client)
152405b261ecSmrg{
152505b261ecSmrg    GC *pGC;
152605b261ecSmrg    int result;
152705b261ecSmrg    REQUEST(xSetDashesReq);
152805b261ecSmrg
152905b261ecSmrg    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
153005b261ecSmrg    if (stuff->nDashes == 0)
153105b261ecSmrg    {
153205b261ecSmrg	 client->errorValue = 0;
153305b261ecSmrg         return BadValue;
153405b261ecSmrg    }
153505b261ecSmrg
15364642e01fSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
153705b261ecSmrg    if (result != Success)
153805b261ecSmrg	return result;
153905b261ecSmrg
15406747b715Smrg    /* If there's an error, either there's no sensible errorValue,
15416747b715Smrg     * or there was a dash segment of 0. */
15426747b715Smrg    client->errorValue = 0;
15436747b715Smrg    return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
154405b261ecSmrg		       (unsigned char *)&stuff[1]);
154505b261ecSmrg}
154605b261ecSmrg
154705b261ecSmrgint
154805b261ecSmrgProcSetClipRectangles(ClientPtr client)
154905b261ecSmrg{
155005b261ecSmrg    int	nr, result;
155105b261ecSmrg    GC *pGC;
155205b261ecSmrg    REQUEST(xSetClipRectanglesReq);
155305b261ecSmrg
155405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
155505b261ecSmrg    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
155605b261ecSmrg	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
155705b261ecSmrg    {
155805b261ecSmrg	client->errorValue = stuff->ordering;
155905b261ecSmrg        return BadValue;
156005b261ecSmrg    }
15614642e01fSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
156205b261ecSmrg    if (result != Success)
156305b261ecSmrg	return result;
156405b261ecSmrg
156505b261ecSmrg    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
156605b261ecSmrg    if (nr & 4)
15676747b715Smrg	return BadLength;
156805b261ecSmrg    nr >>= 3;
15696747b715Smrg    return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
157005b261ecSmrg			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
157105b261ecSmrg}
157205b261ecSmrg
157305b261ecSmrgint
157405b261ecSmrgProcFreeGC(ClientPtr client)
157505b261ecSmrg{
157605b261ecSmrg    GC *pGC;
157705b261ecSmrg    int rc;
157805b261ecSmrg    REQUEST(xResourceReq);
157905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
158005b261ecSmrg
158105b261ecSmrg    rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
158205b261ecSmrg    if (rc != Success)
158305b261ecSmrg	return rc;
158405b261ecSmrg
158505b261ecSmrg    FreeResource(stuff->id, RT_NONE);
15866747b715Smrg    return Success;
158705b261ecSmrg}
158805b261ecSmrg
158905b261ecSmrgint
159005b261ecSmrgProcClearToBackground(ClientPtr client)
159105b261ecSmrg{
159205b261ecSmrg    REQUEST(xClearAreaReq);
159305b261ecSmrg    WindowPtr pWin;
159405b261ecSmrg    int rc;
159505b261ecSmrg
159605b261ecSmrg    REQUEST_SIZE_MATCH(xClearAreaReq);
159705b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
159805b261ecSmrg    if (rc != Success)
159905b261ecSmrg        return rc;
160005b261ecSmrg    if (pWin->drawable.class == InputOnly)
160105b261ecSmrg    {
160205b261ecSmrg	client->errorValue = stuff->window;
16036747b715Smrg	return BadMatch;
160405b261ecSmrg    }
160505b261ecSmrg    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
160605b261ecSmrg    {
160705b261ecSmrg	client->errorValue = stuff->exposures;
16086747b715Smrg        return BadValue;
160905b261ecSmrg    }
161005b261ecSmrg    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
161105b261ecSmrg			       stuff->width, stuff->height,
161205b261ecSmrg			       (Bool)stuff->exposures);
16136747b715Smrg    return Success;
161405b261ecSmrg}
161505b261ecSmrg
161605b261ecSmrgint
161705b261ecSmrgProcCopyArea(ClientPtr client)
161805b261ecSmrg{
161905b261ecSmrg    DrawablePtr pDst;
162005b261ecSmrg    DrawablePtr pSrc;
162105b261ecSmrg    GC *pGC;
162205b261ecSmrg    REQUEST(xCopyAreaReq);
162305b261ecSmrg    RegionPtr pRgn;
162405b261ecSmrg    int rc;
162505b261ecSmrg
162605b261ecSmrg    REQUEST_SIZE_MATCH(xCopyAreaReq);
162705b261ecSmrg
16284642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
162905b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
163005b261ecSmrg    {
163105b261ecSmrg	rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
163205b261ecSmrg				 DixReadAccess);
163305b261ecSmrg	if (rc != Success)
163405b261ecSmrg	    return rc;
163505b261ecSmrg	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
163605b261ecSmrg	{
163705b261ecSmrg	    client->errorValue = stuff->dstDrawable;
16386747b715Smrg	    return BadMatch;
163905b261ecSmrg	}
164005b261ecSmrg    }
164105b261ecSmrg    else
164205b261ecSmrg        pSrc = pDst;
164305b261ecSmrg
164405b261ecSmrg    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
164505b261ecSmrg				 stuff->width, stuff->height,
164605b261ecSmrg				 stuff->dstX, stuff->dstY);
164705b261ecSmrg    if (pGC->graphicsExposures)
164805b261ecSmrg    {
164905b261ecSmrg	(*pDst->pScreen->SendGraphicsExpose)
165005b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
165105b261ecSmrg	if (pRgn)
16526747b715Smrg	    RegionDestroy(pRgn);
165305b261ecSmrg    }
165405b261ecSmrg
16556747b715Smrg    return Success;
165605b261ecSmrg}
165705b261ecSmrg
165805b261ecSmrgint
165905b261ecSmrgProcCopyPlane(ClientPtr client)
166005b261ecSmrg{
166105b261ecSmrg    DrawablePtr psrcDraw, pdstDraw;
166205b261ecSmrg    GC *pGC;
166305b261ecSmrg    REQUEST(xCopyPlaneReq);
166405b261ecSmrg    RegionPtr pRgn;
166505b261ecSmrg    int rc;
166605b261ecSmrg
166705b261ecSmrg    REQUEST_SIZE_MATCH(xCopyPlaneReq);
166805b261ecSmrg
16694642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
167005b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
167105b261ecSmrg    {
167205b261ecSmrg	rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
167305b261ecSmrg			       DixReadAccess);
167405b261ecSmrg	if (rc != Success)
167505b261ecSmrg	    return rc;
167605b261ecSmrg
167705b261ecSmrg	if (pdstDraw->pScreen != psrcDraw->pScreen)
167805b261ecSmrg	{
167905b261ecSmrg	    client->errorValue = stuff->dstDrawable;
16806747b715Smrg	    return BadMatch;
168105b261ecSmrg	}
168205b261ecSmrg    }
168305b261ecSmrg    else
168405b261ecSmrg        psrcDraw = pdstDraw;
168505b261ecSmrg
168605b261ecSmrg    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
168705b261ecSmrg    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
168805b261ecSmrg       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
168905b261ecSmrg    {
169005b261ecSmrg       client->errorValue = stuff->bitPlane;
16916747b715Smrg       return BadValue;
169205b261ecSmrg    }
169305b261ecSmrg
169405b261ecSmrg    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
169505b261ecSmrg				 stuff->width, stuff->height,
169605b261ecSmrg				 stuff->dstX, stuff->dstY, stuff->bitPlane);
169705b261ecSmrg    if (pGC->graphicsExposures)
169805b261ecSmrg    {
169905b261ecSmrg	(*pdstDraw->pScreen->SendGraphicsExpose)
170005b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
170105b261ecSmrg	if (pRgn)
17026747b715Smrg	    RegionDestroy(pRgn);
170305b261ecSmrg    }
17046747b715Smrg    return Success;
170505b261ecSmrg}
170605b261ecSmrg
170705b261ecSmrgint
170805b261ecSmrgProcPolyPoint(ClientPtr client)
170905b261ecSmrg{
171005b261ecSmrg    int npoint;
171105b261ecSmrg    GC *pGC;
171205b261ecSmrg    DrawablePtr pDraw;
171305b261ecSmrg    REQUEST(xPolyPointReq);
171405b261ecSmrg
171505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
171605b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
171705b261ecSmrg	(stuff->coordMode != CoordModePrevious))
171805b261ecSmrg    {
171905b261ecSmrg	client->errorValue = stuff->coordMode;
172005b261ecSmrg        return BadValue;
172105b261ecSmrg    }
17224642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
17236747b715Smrg    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
172405b261ecSmrg    if (npoint)
172505b261ecSmrg        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
172605b261ecSmrg			  (xPoint *) &stuff[1]);
17276747b715Smrg    return Success;
172805b261ecSmrg}
172905b261ecSmrg
173005b261ecSmrgint
173105b261ecSmrgProcPolyLine(ClientPtr client)
173205b261ecSmrg{
173305b261ecSmrg    int npoint;
173405b261ecSmrg    GC *pGC;
173505b261ecSmrg    DrawablePtr pDraw;
173605b261ecSmrg    REQUEST(xPolyLineReq);
173705b261ecSmrg
173805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
173905b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
174005b261ecSmrg	(stuff->coordMode != CoordModePrevious))
174105b261ecSmrg    {
174205b261ecSmrg	client->errorValue = stuff->coordMode;
174305b261ecSmrg        return BadValue;
174405b261ecSmrg    }
17454642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
17466747b715Smrg    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
174705b261ecSmrg    if (npoint > 1)
174805b261ecSmrg	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
174905b261ecSmrg			      (DDXPointPtr) &stuff[1]);
17506747b715Smrg    return Success;
175105b261ecSmrg}
175205b261ecSmrg
175305b261ecSmrgint
175405b261ecSmrgProcPolySegment(ClientPtr client)
175505b261ecSmrg{
175605b261ecSmrg    int nsegs;
175705b261ecSmrg    GC *pGC;
175805b261ecSmrg    DrawablePtr pDraw;
175905b261ecSmrg    REQUEST(xPolySegmentReq);
176005b261ecSmrg
176105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
17624642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
176305b261ecSmrg    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
176405b261ecSmrg    if (nsegs & 4)
17656747b715Smrg	return BadLength;
176605b261ecSmrg    nsegs >>= 3;
176705b261ecSmrg    if (nsegs)
176805b261ecSmrg        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
17696747b715Smrg    return Success;
177005b261ecSmrg}
177105b261ecSmrg
177205b261ecSmrgint
177305b261ecSmrgProcPolyRectangle (ClientPtr client)
177405b261ecSmrg{
177505b261ecSmrg    int nrects;
177605b261ecSmrg    GC *pGC;
177705b261ecSmrg    DrawablePtr pDraw;
177805b261ecSmrg    REQUEST(xPolyRectangleReq);
177905b261ecSmrg
178005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
17814642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
178205b261ecSmrg    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
178305b261ecSmrg    if (nrects & 4)
17846747b715Smrg	return BadLength;
178505b261ecSmrg    nrects >>= 3;
178605b261ecSmrg    if (nrects)
178705b261ecSmrg        (*pGC->ops->PolyRectangle)(pDraw, pGC,
178805b261ecSmrg		    nrects, (xRectangle *) &stuff[1]);
17896747b715Smrg    return Success;
179005b261ecSmrg}
179105b261ecSmrg
179205b261ecSmrgint
179305b261ecSmrgProcPolyArc(ClientPtr client)
179405b261ecSmrg{
179505b261ecSmrg    int		narcs;
179605b261ecSmrg    GC *pGC;
179705b261ecSmrg    DrawablePtr pDraw;
179805b261ecSmrg    REQUEST(xPolyArcReq);
179905b261ecSmrg
180005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
18014642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
180205b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
180305b261ecSmrg    if (narcs % sizeof(xArc))
18046747b715Smrg	return BadLength;
180505b261ecSmrg    narcs /= sizeof(xArc);
180605b261ecSmrg    if (narcs)
180705b261ecSmrg        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
18086747b715Smrg    return Success;
180905b261ecSmrg}
181005b261ecSmrg
181105b261ecSmrgint
181205b261ecSmrgProcFillPoly(ClientPtr client)
181305b261ecSmrg{
181405b261ecSmrg    int          things;
181505b261ecSmrg    GC *pGC;
181605b261ecSmrg    DrawablePtr pDraw;
181705b261ecSmrg    REQUEST(xFillPolyReq);
181805b261ecSmrg
181905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
182005b261ecSmrg    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
182105b261ecSmrg	(stuff->shape != Convex))
182205b261ecSmrg    {
182305b261ecSmrg	client->errorValue = stuff->shape;
182405b261ecSmrg        return BadValue;
182505b261ecSmrg    }
182605b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
182705b261ecSmrg	(stuff->coordMode != CoordModePrevious))
182805b261ecSmrg    {
182905b261ecSmrg	client->errorValue = stuff->coordMode;
183005b261ecSmrg        return BadValue;
183105b261ecSmrg    }
183205b261ecSmrg
18334642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
18346747b715Smrg    things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
183505b261ecSmrg    if (things)
183605b261ecSmrg        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
183705b261ecSmrg			 stuff->coordMode, things,
183805b261ecSmrg			 (DDXPointPtr) &stuff[1]);
18396747b715Smrg    return Success;
184005b261ecSmrg}
184105b261ecSmrg
184205b261ecSmrgint
184305b261ecSmrgProcPolyFillRectangle(ClientPtr client)
184405b261ecSmrg{
184505b261ecSmrg    int             things;
184605b261ecSmrg    GC *pGC;
184705b261ecSmrg    DrawablePtr pDraw;
184805b261ecSmrg    REQUEST(xPolyFillRectangleReq);
184905b261ecSmrg
185005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
18514642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
185205b261ecSmrg    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
185305b261ecSmrg    if (things & 4)
18546747b715Smrg	return BadLength;
185505b261ecSmrg    things >>= 3;
185605b261ecSmrg
185705b261ecSmrg    if (things)
185805b261ecSmrg        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
185905b261ecSmrg		      (xRectangle *) &stuff[1]);
18606747b715Smrg    return Success;
186105b261ecSmrg}
186205b261ecSmrg
186305b261ecSmrgint
186405b261ecSmrgProcPolyFillArc(ClientPtr client)
186505b261ecSmrg{
186605b261ecSmrg    int		narcs;
186705b261ecSmrg    GC *pGC;
186805b261ecSmrg    DrawablePtr pDraw;
186905b261ecSmrg    REQUEST(xPolyFillArcReq);
187005b261ecSmrg
187105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
18724642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
187305b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
187405b261ecSmrg    if (narcs % sizeof(xArc))
18756747b715Smrg	return BadLength;
187605b261ecSmrg    narcs /= sizeof(xArc);
187705b261ecSmrg    if (narcs)
187805b261ecSmrg        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
18796747b715Smrg    return Success;
188005b261ecSmrg}
188105b261ecSmrg
188205b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
188305b261ecSmrg
188405b261ecSmrgint
188505b261ecSmrgServerOrder (void)
188605b261ecSmrg{
188705b261ecSmrg    int	    whichbyte = 1;
188805b261ecSmrg
188905b261ecSmrg    if (*((char *) &whichbyte))
189005b261ecSmrg	return LSBFirst;
189105b261ecSmrg    return MSBFirst;
189205b261ecSmrg}
189305b261ecSmrg
189405b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
189505b261ecSmrg
189605b261ecSmrgvoid
189705b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order)
189805b261ecSmrg{
189905b261ecSmrg    switch (bpp) {
190005b261ecSmrg    case 1:	/* yuck */
190105b261ecSmrg	if (BITMAP_BIT_ORDER != order)
190205b261ecSmrg	    BitOrderInvert ((unsigned char *) base, nbytes);
190305b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
190405b261ecSmrg	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
190505b261ecSmrg#endif
190605b261ecSmrg	break;
190705b261ecSmrg    case 4:
190805b261ecSmrg	break;  /* yuck */
190905b261ecSmrg    case 8:
191005b261ecSmrg	break;
191105b261ecSmrg    case 16:
191205b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
191305b261ecSmrg	    TwoByteSwap ((unsigned char *) base, nbytes);
191405b261ecSmrg	break;
191505b261ecSmrg    case 32:
191605b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
191705b261ecSmrg	    FourByteSwap ((unsigned char *) base, nbytes);
191805b261ecSmrg	break;
191905b261ecSmrg    }
192005b261ecSmrg}
192105b261ecSmrg#else
192205b261ecSmrg#define ReformatImage(b,n,bpp,o)
192305b261ecSmrg#endif
192405b261ecSmrg
192505b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to
192605b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
192705b261ecSmrg * to use internally. Removes need for internal alignment checking.
192805b261ecSmrg * All of the PutImage functions could be changed individually, but
192905b261ecSmrg * as currently written, they call other routines which require things
193005b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here.
193105b261ecSmrg * If an image would be padded differently for 64- versus 32-, then
193205b261ecSmrg * copy each scanline to a 64-bit padded scanline.
193305b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit
193405b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction.
193505b261ecSmrg */
193605b261ecSmrgint
193705b261ecSmrgProcPutImage(ClientPtr client)
193805b261ecSmrg{
193905b261ecSmrg    GC *pGC;
194005b261ecSmrg    DrawablePtr pDraw;
194105b261ecSmrg    long	length; 	/* length of scanline server padded */
194205b261ecSmrg    long 	lengthProto; 	/* length of scanline protocol padded */
194305b261ecSmrg    char	*tmpImage;
194405b261ecSmrg    REQUEST(xPutImageReq);
194505b261ecSmrg
194605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPutImageReq);
19474642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
194805b261ecSmrg    if (stuff->format == XYBitmap)
194905b261ecSmrg    {
195005b261ecSmrg        if ((stuff->depth != 1) ||
195105b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
195205b261ecSmrg            return BadMatch;
195305b261ecSmrg        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
195405b261ecSmrg    }
195505b261ecSmrg    else if (stuff->format == XYPixmap)
195605b261ecSmrg    {
195705b261ecSmrg        if ((pDraw->depth != stuff->depth) ||
195805b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
195905b261ecSmrg            return BadMatch;
196005b261ecSmrg        length      = BitmapBytePad(stuff->width + stuff->leftPad);
196105b261ecSmrg	length      *= stuff->depth;
196205b261ecSmrg    }
196305b261ecSmrg    else if (stuff->format == ZPixmap)
196405b261ecSmrg    {
196505b261ecSmrg        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
196605b261ecSmrg            return BadMatch;
196705b261ecSmrg        length      = PixmapBytePad(stuff->width, stuff->depth);
196805b261ecSmrg    }
196905b261ecSmrg    else
197005b261ecSmrg    {
197105b261ecSmrg	client->errorValue = stuff->format;
197205b261ecSmrg        return BadValue;
197305b261ecSmrg    }
197405b261ecSmrg
197505b261ecSmrg    tmpImage = (char *)&stuff[1];
197605b261ecSmrg    lengthProto = length;
197705b261ecSmrg
19786747b715Smrg    if ((bytes_to_int32(lengthProto * stuff->height) +
19796747b715Smrg	bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
198005b261ecSmrg	return BadLength;
198105b261ecSmrg
198205b261ecSmrg    ReformatImage (tmpImage, lengthProto * stuff->height,
198305b261ecSmrg		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
198405b261ecSmrg		   ClientOrder(client));
198505b261ecSmrg
198605b261ecSmrg    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
198705b261ecSmrg		  stuff->width, stuff->height,
198805b261ecSmrg		  stuff->leftPad, stuff->format, tmpImage);
198905b261ecSmrg
19906747b715Smrg     return Success;
199105b261ecSmrg}
199205b261ecSmrg
199305b261ecSmrgstatic int
199405b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable,
199505b261ecSmrg           int x, int y, int width, int height,
199605b261ecSmrg           Mask planemask, xGetImageReply **im_return)
199705b261ecSmrg{
19986747b715Smrg    DrawablePtr		pDraw, pBoundingDraw;
199905b261ecSmrg    int			nlines, linesPerBuf, rc;
20006747b715Smrg    int			linesDone;
20016747b715Smrg    /* coordinates relative to the bounding drawable */
20026747b715Smrg    int			relx, rely;
200305b261ecSmrg    long		widthBytesLine, length;
200405b261ecSmrg    Mask		plane = 0;
200505b261ecSmrg    char		*pBuf;
200605b261ecSmrg    xGetImageReply	xgi;
200705b261ecSmrg    RegionPtr pVisibleRegion = NULL;
200805b261ecSmrg
200905b261ecSmrg    if ((format != XYPixmap) && (format != ZPixmap))
201005b261ecSmrg    {
201105b261ecSmrg	client->errorValue = format;
20126747b715Smrg        return BadValue;
201305b261ecSmrg    }
201405b261ecSmrg    rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
201505b261ecSmrg    if (rc != Success)
201605b261ecSmrg	return rc;
201705b261ecSmrg
20186747b715Smrg    memset(&xgi, 0, sizeof(xGetImageReply));
20196747b715Smrg
20206747b715Smrg    relx = x;
20216747b715Smrg    rely = y;
20226747b715Smrg
202305b261ecSmrg    if(pDraw->type == DRAWABLE_WINDOW)
202405b261ecSmrg    {
20256747b715Smrg	WindowPtr pWin = (WindowPtr)pDraw;
20266747b715Smrg
20276747b715Smrg	/* "If the drawable is a window, the window must be viewable ... or a
20286747b715Smrg	 * BadMatch error results" */
20296747b715Smrg	if (!pWin->viewable)
20306747b715Smrg	    return BadMatch;
20316747b715Smrg
20326747b715Smrg	relx += pDraw->x;
20336747b715Smrg	rely += pDraw->y;
20346747b715Smrg
20356747b715Smrg	if (pDraw->pScreen->GetWindowPixmap) {
20366747b715Smrg	    PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
20376747b715Smrg
20386747b715Smrg	    pBoundingDraw = &pPix->drawable;
20396747b715Smrg#ifdef COMPOSITE
20406747b715Smrg	    relx -= pPix->screen_x;
20416747b715Smrg	    rely -= pPix->screen_y;
20426747b715Smrg#endif
20436747b715Smrg	}
20446747b715Smrg	else
20456747b715Smrg	{
20466747b715Smrg	    pBoundingDraw = (DrawablePtr)pDraw->pScreen->root;
20476747b715Smrg	}
20486747b715Smrg
20496747b715Smrg	xgi.visual = wVisual (pWin);
205005b261ecSmrg    }
205105b261ecSmrg    else
205205b261ecSmrg    {
20536747b715Smrg	pBoundingDraw = pDraw;
205405b261ecSmrg	xgi.visual = None;
205505b261ecSmrg    }
205605b261ecSmrg
20576747b715Smrg    /* "If the drawable is a pixmap, the given rectangle must be wholly
20586747b715Smrg     *  contained within the pixmap, or a BadMatch error results.  If the
20596747b715Smrg     *  drawable is a window [...] it must be the case that if there were no
20606747b715Smrg     *  inferiors or overlapping windows, the specified rectangle of the window
20616747b715Smrg     *  would be fully visible on the screen and wholly contained within the
20626747b715Smrg     *  outside edges of the window, or a BadMatch error results."
20636747b715Smrg     *
20646747b715Smrg     * We relax the window case slightly to mean that the rectangle must exist
20656747b715Smrg     * within the bounds of the window's backing pixmap.  In particular, this
20666747b715Smrg     * means that a GetImage request may succeed or fail with BadMatch depending
20676747b715Smrg     * on whether any of its ancestor windows are redirected.  */
20686747b715Smrg    if(relx < 0 || relx + width > (int)pBoundingDraw->width ||
20696747b715Smrg       rely < 0 || rely + height > (int)pBoundingDraw->height)
20706747b715Smrg	return BadMatch;
20716747b715Smrg
207205b261ecSmrg    xgi.type = X_Reply;
207305b261ecSmrg    xgi.sequenceNumber = client->sequence;
207405b261ecSmrg    xgi.depth = pDraw->depth;
207505b261ecSmrg    if(format == ZPixmap)
207605b261ecSmrg    {
207705b261ecSmrg	widthBytesLine = PixmapBytePad(width, pDraw->depth);
207805b261ecSmrg	length = widthBytesLine * height;
207905b261ecSmrg
208005b261ecSmrg    }
208105b261ecSmrg    else
208205b261ecSmrg    {
208305b261ecSmrg	widthBytesLine = BitmapBytePad(width);
208405b261ecSmrg	plane = ((Mask)1) << (pDraw->depth - 1);
208505b261ecSmrg	/* only planes asked for */
208605b261ecSmrg	length = widthBytesLine * height *
208705b261ecSmrg		 Ones(planemask & (plane | (plane - 1)));
208805b261ecSmrg
208905b261ecSmrg    }
209005b261ecSmrg
209105b261ecSmrg    xgi.length = length;
209205b261ecSmrg
209305b261ecSmrg    if (im_return) {
20946747b715Smrg	pBuf = calloc(1, sz_xGetImageReply + length);
209505b261ecSmrg	if (!pBuf)
20966747b715Smrg	    return BadAlloc;
209705b261ecSmrg	if (widthBytesLine == 0)
209805b261ecSmrg	    linesPerBuf = 0;
209905b261ecSmrg	else
210005b261ecSmrg	    linesPerBuf = height;
210105b261ecSmrg	*im_return = (xGetImageReply *)pBuf;
210205b261ecSmrg	*(xGetImageReply *)pBuf = xgi;
210305b261ecSmrg	pBuf += sz_xGetImageReply;
210405b261ecSmrg    } else {
21056747b715Smrg	xgi.length = bytes_to_int32(xgi.length);
210605b261ecSmrg	if (widthBytesLine == 0 || height == 0)
210705b261ecSmrg	    linesPerBuf = 0;
210805b261ecSmrg	else if (widthBytesLine >= IMAGE_BUFSIZE)
210905b261ecSmrg	    linesPerBuf = 1;
211005b261ecSmrg	else
211105b261ecSmrg	{
211205b261ecSmrg	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
211305b261ecSmrg	    if (linesPerBuf > height)
211405b261ecSmrg		linesPerBuf = height;
211505b261ecSmrg	}
211605b261ecSmrg	length = linesPerBuf * widthBytesLine;
211705b261ecSmrg	if (linesPerBuf < height)
211805b261ecSmrg	{
211905b261ecSmrg	    /* we have to make sure intermediate buffers don't need padding */
212005b261ecSmrg	    while ((linesPerBuf > 1) &&
212105b261ecSmrg		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
212205b261ecSmrg	    {
212305b261ecSmrg		linesPerBuf--;
212405b261ecSmrg		length -= widthBytesLine;
212505b261ecSmrg	    }
212605b261ecSmrg	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
212705b261ecSmrg	    {
212805b261ecSmrg		linesPerBuf++;
212905b261ecSmrg		length += widthBytesLine;
213005b261ecSmrg	    }
213105b261ecSmrg	}
21326747b715Smrg	if(!(pBuf = calloc(1, length)))
21336747b715Smrg	    return BadAlloc;
213405b261ecSmrg	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
213505b261ecSmrg    }
213605b261ecSmrg
21374642e01fSmrg    if (pDraw->type == DRAWABLE_WINDOW)
213805b261ecSmrg    {
213905b261ecSmrg	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
214005b261ecSmrg	if (pVisibleRegion)
214105b261ecSmrg	{
21426747b715Smrg	    RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
214305b261ecSmrg	}
214405b261ecSmrg    }
214505b261ecSmrg
214605b261ecSmrg    if (linesPerBuf == 0)
214705b261ecSmrg    {
214805b261ecSmrg	/* nothing to do */
214905b261ecSmrg    }
215005b261ecSmrg    else if (format == ZPixmap)
215105b261ecSmrg    {
215205b261ecSmrg        linesDone = 0;
215305b261ecSmrg        while (height - linesDone > 0)
215405b261ecSmrg        {
215505b261ecSmrg	    nlines = min(linesPerBuf, height - linesDone);
215605b261ecSmrg	    (*pDraw->pScreen->GetImage) (pDraw,
215705b261ecSmrg	                                 x,
215805b261ecSmrg				         y + linesDone,
215905b261ecSmrg				         width,
216005b261ecSmrg				         nlines,
216105b261ecSmrg				         format,
216205b261ecSmrg				         planemask,
216305b261ecSmrg				         (pointer) pBuf);
216405b261ecSmrg	    if (pVisibleRegion)
216505b261ecSmrg		XaceCensorImage(client, pVisibleRegion, widthBytesLine,
216605b261ecSmrg			pDraw, x, y + linesDone, width,
216705b261ecSmrg			nlines, format, pBuf);
216805b261ecSmrg
216905b261ecSmrg	    /* Note that this is NOT a call to WriteSwappedDataToClient,
217005b261ecSmrg               as we do NOT byte swap */
217105b261ecSmrg	    if (!im_return)
217205b261ecSmrg	    {
217305b261ecSmrg		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
217405b261ecSmrg			       BitsPerPixel (pDraw->depth),
217505b261ecSmrg			       ClientOrder(client));
217605b261ecSmrg
217705b261ecSmrg/* Don't split me, gcc pukes when you do */
217805b261ecSmrg		(void)WriteToClient(client,
217905b261ecSmrg				    (int)(nlines * widthBytesLine),
218005b261ecSmrg				    pBuf);
218105b261ecSmrg	    }
218205b261ecSmrg	    linesDone += nlines;
218305b261ecSmrg        }
218405b261ecSmrg    }
218505b261ecSmrg    else /* XYPixmap */
218605b261ecSmrg    {
218705b261ecSmrg        for (; plane; plane >>= 1)
218805b261ecSmrg	{
218905b261ecSmrg	    if (planemask & plane)
219005b261ecSmrg	    {
219105b261ecSmrg	        linesDone = 0;
219205b261ecSmrg	        while (height - linesDone > 0)
219305b261ecSmrg	        {
219405b261ecSmrg		    nlines = min(linesPerBuf, height - linesDone);
219505b261ecSmrg	            (*pDraw->pScreen->GetImage) (pDraw,
219605b261ecSmrg	                                         x,
219705b261ecSmrg				                 y + linesDone,
219805b261ecSmrg				                 width,
219905b261ecSmrg				                 nlines,
220005b261ecSmrg				                 format,
220105b261ecSmrg				                 plane,
220205b261ecSmrg				                 (pointer)pBuf);
220305b261ecSmrg		    if (pVisibleRegion)
220405b261ecSmrg			XaceCensorImage(client, pVisibleRegion,
220505b261ecSmrg				widthBytesLine,
220605b261ecSmrg				pDraw, x, y + linesDone, width,
220705b261ecSmrg				nlines, format, pBuf);
220805b261ecSmrg
220905b261ecSmrg		    /* Note: NOT a call to WriteSwappedDataToClient,
221005b261ecSmrg		       as we do NOT byte swap */
221105b261ecSmrg		    if (im_return) {
221205b261ecSmrg			pBuf += nlines * widthBytesLine;
221305b261ecSmrg		    } else {
221405b261ecSmrg			ReformatImage (pBuf,
221505b261ecSmrg				       (int)(nlines * widthBytesLine),
221605b261ecSmrg				       1,
221705b261ecSmrg				       ClientOrder (client));
221805b261ecSmrg
221905b261ecSmrg/* Don't split me, gcc pukes when you do */
222005b261ecSmrg			(void)WriteToClient(client,
222105b261ecSmrg					(int)(nlines * widthBytesLine),
222205b261ecSmrg					pBuf);
222305b261ecSmrg		    }
222405b261ecSmrg		    linesDone += nlines;
222505b261ecSmrg		}
222605b261ecSmrg            }
222705b261ecSmrg	}
222805b261ecSmrg    }
222905b261ecSmrg    if (pVisibleRegion)
22306747b715Smrg	RegionDestroy(pVisibleRegion);
223105b261ecSmrg    if (!im_return)
22326747b715Smrg	free(pBuf);
22336747b715Smrg    return Success;
223405b261ecSmrg}
223505b261ecSmrg
223605b261ecSmrgint
223705b261ecSmrgProcGetImage(ClientPtr client)
223805b261ecSmrg{
223905b261ecSmrg    REQUEST(xGetImageReq);
224005b261ecSmrg
224105b261ecSmrg    REQUEST_SIZE_MATCH(xGetImageReq);
224205b261ecSmrg
224305b261ecSmrg    return DoGetImage(client, stuff->format, stuff->drawable,
224405b261ecSmrg		      stuff->x, stuff->y,
224505b261ecSmrg		      (int)stuff->width, (int)stuff->height,
224605b261ecSmrg		      stuff->planeMask, (xGetImageReply **)NULL);
224705b261ecSmrg}
224805b261ecSmrg
224905b261ecSmrgint
225005b261ecSmrgProcPolyText(ClientPtr client)
225105b261ecSmrg{
225205b261ecSmrg    int	err;
225305b261ecSmrg    REQUEST(xPolyTextReq);
225405b261ecSmrg    DrawablePtr pDraw;
225505b261ecSmrg    GC *pGC;
225605b261ecSmrg
225705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
22584642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
225905b261ecSmrg
226005b261ecSmrg    err = PolyText(client,
226105b261ecSmrg		   pDraw,
226205b261ecSmrg		   pGC,
226305b261ecSmrg		   (unsigned char *)&stuff[1],
226405b261ecSmrg		   ((unsigned char *) stuff) + (client->req_len << 2),
226505b261ecSmrg		   stuff->x,
226605b261ecSmrg		   stuff->y,
226705b261ecSmrg		   stuff->reqType,
226805b261ecSmrg		   stuff->drawable);
226905b261ecSmrg
227005b261ecSmrg    if (err == Success)
227105b261ecSmrg    {
22726747b715Smrg	return Success;
227305b261ecSmrg    }
227405b261ecSmrg    else
227505b261ecSmrg	return err;
227605b261ecSmrg}
227705b261ecSmrg
227805b261ecSmrgint
227905b261ecSmrgProcImageText8(ClientPtr client)
228005b261ecSmrg{
228105b261ecSmrg    int	err;
228205b261ecSmrg    DrawablePtr pDraw;
228305b261ecSmrg    GC *pGC;
228405b261ecSmrg
228505b261ecSmrg    REQUEST(xImageTextReq);
228605b261ecSmrg
228705b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
22884642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
228905b261ecSmrg
229005b261ecSmrg    err = ImageText(client,
229105b261ecSmrg		    pDraw,
229205b261ecSmrg		    pGC,
229305b261ecSmrg		    stuff->nChars,
229405b261ecSmrg		    (unsigned char *)&stuff[1],
229505b261ecSmrg		    stuff->x,
229605b261ecSmrg		    stuff->y,
229705b261ecSmrg		    stuff->reqType,
229805b261ecSmrg		    stuff->drawable);
229905b261ecSmrg
230005b261ecSmrg    if (err == Success)
230105b261ecSmrg    {
23026747b715Smrg	return Success;
230305b261ecSmrg    }
230405b261ecSmrg    else
230505b261ecSmrg	return err;
230605b261ecSmrg}
230705b261ecSmrg
230805b261ecSmrgint
230905b261ecSmrgProcImageText16(ClientPtr client)
231005b261ecSmrg{
231105b261ecSmrg    int	err;
231205b261ecSmrg    DrawablePtr pDraw;
231305b261ecSmrg    GC *pGC;
231405b261ecSmrg
231505b261ecSmrg    REQUEST(xImageTextReq);
231605b261ecSmrg
231705b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
23184642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
231905b261ecSmrg
232005b261ecSmrg    err = ImageText(client,
232105b261ecSmrg		    pDraw,
232205b261ecSmrg		    pGC,
232305b261ecSmrg		    stuff->nChars,
232405b261ecSmrg		    (unsigned char *)&stuff[1],
232505b261ecSmrg		    stuff->x,
232605b261ecSmrg		    stuff->y,
232705b261ecSmrg		    stuff->reqType,
232805b261ecSmrg		    stuff->drawable);
232905b261ecSmrg
233005b261ecSmrg    if (err == Success)
233105b261ecSmrg    {
23326747b715Smrg	return Success;
233305b261ecSmrg    }
233405b261ecSmrg    else
233505b261ecSmrg	return err;
233605b261ecSmrg}
233705b261ecSmrg
233805b261ecSmrg
233905b261ecSmrgint
234005b261ecSmrgProcCreateColormap(ClientPtr client)
234105b261ecSmrg{
234205b261ecSmrg    VisualPtr	pVisual;
234305b261ecSmrg    ColormapPtr	pmap;
234405b261ecSmrg    Colormap	mid;
234505b261ecSmrg    WindowPtr   pWin;
234605b261ecSmrg    ScreenPtr pScreen;
234705b261ecSmrg    REQUEST(xCreateColormapReq);
234805b261ecSmrg    int i, result;
234905b261ecSmrg
235005b261ecSmrg    REQUEST_SIZE_MATCH(xCreateColormapReq);
235105b261ecSmrg
235205b261ecSmrg    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
235305b261ecSmrg    {
235405b261ecSmrg	client->errorValue = stuff->alloc;
23556747b715Smrg        return BadValue;
235605b261ecSmrg    }
235705b261ecSmrg    mid = stuff->mid;
235805b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
23594642e01fSmrg    result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
236005b261ecSmrg    if (result != Success)
236105b261ecSmrg        return result;
236205b261ecSmrg
236305b261ecSmrg    pScreen = pWin->drawable.pScreen;
236405b261ecSmrg    for (i = 0, pVisual = pScreen->visuals;
236505b261ecSmrg	 i < pScreen->numVisuals;
236605b261ecSmrg	 i++, pVisual++)
236705b261ecSmrg    {
236805b261ecSmrg	if (pVisual->vid != stuff->visual)
236905b261ecSmrg	    continue;
23706747b715Smrg	return CreateColormap(mid, pScreen, pVisual, &pmap,
237105b261ecSmrg				 (int)stuff->alloc, client->index);
237205b261ecSmrg    }
237305b261ecSmrg    client->errorValue = stuff->visual;
23746747b715Smrg    return BadMatch;
237505b261ecSmrg}
237605b261ecSmrg
237705b261ecSmrgint
237805b261ecSmrgProcFreeColormap(ClientPtr client)
237905b261ecSmrg{
238005b261ecSmrg    ColormapPtr pmap;
23814642e01fSmrg    int rc;
238205b261ecSmrg    REQUEST(xResourceReq);
238305b261ecSmrg
238405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
2385b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client,
23864642e01fSmrg			   DixDestroyAccess);
23874642e01fSmrg    if (rc == Success)
238805b261ecSmrg    {
238905b261ecSmrg	/* Freeing a default colormap is a no-op */
239005b261ecSmrg	if (!(pmap->flags & IsDefault))
239105b261ecSmrg	    FreeResource(stuff->id, RT_NONE);
23926747b715Smrg	return Success;
239305b261ecSmrg    }
239405b261ecSmrg    else
239505b261ecSmrg    {
239605b261ecSmrg	client->errorValue = stuff->id;
23976747b715Smrg	return rc;
239805b261ecSmrg    }
239905b261ecSmrg}
240005b261ecSmrg
240105b261ecSmrg
240205b261ecSmrgint
240305b261ecSmrgProcCopyColormapAndFree(ClientPtr client)
240405b261ecSmrg{
240505b261ecSmrg    Colormap	mid;
240605b261ecSmrg    ColormapPtr	pSrcMap;
240705b261ecSmrg    REQUEST(xCopyColormapAndFreeReq);
24084642e01fSmrg    int rc;
240905b261ecSmrg
241005b261ecSmrg    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
241105b261ecSmrg    mid = stuff->mid;
241205b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
2413b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP,
24144642e01fSmrg			   client, DixReadAccess|DixRemoveAccess);
24154642e01fSmrg    if (rc == Success)
24166747b715Smrg	return CopyColormapAndFree(mid, pSrcMap, client->index);
24176747b715Smrg    client->errorValue = stuff->srcCmap;
24186747b715Smrg    return rc;
241905b261ecSmrg}
242005b261ecSmrg
242105b261ecSmrgint
242205b261ecSmrgProcInstallColormap(ClientPtr client)
242305b261ecSmrg{
242405b261ecSmrg    ColormapPtr pcmp;
24254642e01fSmrg    int rc;
242605b261ecSmrg    REQUEST(xResourceReq);
242705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
24284642e01fSmrg
2429b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
24304642e01fSmrg			   DixInstallAccess);
24314642e01fSmrg    if (rc != Success)
24324642e01fSmrg	goto out;
24334642e01fSmrg
24344642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
24356747b715Smrg    if (rc != Success) {
24366747b715Smrg	if (rc == BadValue)
24376747b715Smrg	    rc = BadColor;
24384642e01fSmrg	goto out;
24396747b715Smrg    }
24404642e01fSmrg
24414642e01fSmrg    (*(pcmp->pScreen->InstallColormap)) (pcmp);
24426747b715Smrg    return Success;
24434642e01fSmrg
24444642e01fSmrgout:
24454642e01fSmrg    client->errorValue = stuff->id;
24466747b715Smrg    return rc;
244705b261ecSmrg}
244805b261ecSmrg
244905b261ecSmrgint
245005b261ecSmrgProcUninstallColormap(ClientPtr client)
245105b261ecSmrg{
245205b261ecSmrg    ColormapPtr pcmp;
24534642e01fSmrg    int rc;
245405b261ecSmrg    REQUEST(xResourceReq);
245505b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
24564642e01fSmrg
2457b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
24584642e01fSmrg			   DixUninstallAccess);
24594642e01fSmrg    if (rc != Success)
24604642e01fSmrg	goto out;
24614642e01fSmrg
24624642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
24636747b715Smrg    if (rc != Success) {
24646747b715Smrg	if (rc == BadValue)
24656747b715Smrg	    rc = BadColor;
24664642e01fSmrg	goto out;
24676747b715Smrg    }
24684642e01fSmrg
24694642e01fSmrg    if(pcmp->mid != pcmp->pScreen->defColormap)
24704642e01fSmrg	(*(pcmp->pScreen->UninstallColormap)) (pcmp);
24716747b715Smrg    return Success;
24724642e01fSmrg
24734642e01fSmrgout:
24744642e01fSmrg    client->errorValue = stuff->id;
24756747b715Smrg    return rc;
247605b261ecSmrg}
247705b261ecSmrg
247805b261ecSmrgint
247905b261ecSmrgProcListInstalledColormaps(ClientPtr client)
248005b261ecSmrg{
248105b261ecSmrg    xListInstalledColormapsReply *preply;
248205b261ecSmrg    int nummaps, rc;
248305b261ecSmrg    WindowPtr pWin;
248405b261ecSmrg    REQUEST(xResourceReq);
248505b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
24864642e01fSmrg
24874642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
248805b261ecSmrg    if (rc != Success)
24896747b715Smrg	return rc;
24904642e01fSmrg
24914642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
24924642e01fSmrg		  DixGetAttrAccess);
24934642e01fSmrg    if (rc != Success)
24946747b715Smrg	return rc;
249505b261ecSmrg
24966747b715Smrg    preply = malloc(sizeof(xListInstalledColormapsReply) +
249705b261ecSmrg		     pWin->drawable.pScreen->maxInstalledCmaps *
249805b261ecSmrg		     sizeof(Colormap));
249905b261ecSmrg    if(!preply)
25006747b715Smrg        return BadAlloc;
250105b261ecSmrg
250205b261ecSmrg    preply->type = X_Reply;
250305b261ecSmrg    preply->sequenceNumber = client->sequence;
250405b261ecSmrg    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
250505b261ecSmrg        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
250605b261ecSmrg    preply->nColormaps = nummaps;
250705b261ecSmrg    preply->length = nummaps;
250805b261ecSmrg    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
250905b261ecSmrg    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
251005b261ecSmrg    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
25116747b715Smrg    free(preply);
25126747b715Smrg    return Success;
251305b261ecSmrg}
251405b261ecSmrg
251505b261ecSmrgint
251605b261ecSmrgProcAllocColor (ClientPtr client)
251705b261ecSmrg{
251805b261ecSmrg    ColormapPtr pmap;
25194642e01fSmrg    int rc;
252005b261ecSmrg    xAllocColorReply acr;
252105b261ecSmrg    REQUEST(xAllocColorReq);
252205b261ecSmrg
252305b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorReq);
2524b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client,
25254642e01fSmrg			   DixAddAccess);
25264642e01fSmrg    if (rc == Success)
252705b261ecSmrg    {
252805b261ecSmrg	acr.type = X_Reply;
252905b261ecSmrg	acr.length = 0;
253005b261ecSmrg	acr.sequenceNumber = client->sequence;
253105b261ecSmrg	acr.red = stuff->red;
253205b261ecSmrg	acr.green = stuff->green;
253305b261ecSmrg	acr.blue = stuff->blue;
253405b261ecSmrg	acr.pixel = 0;
25354642e01fSmrg	if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
253605b261ecSmrg	                       &acr.pixel, client->index)) )
25376747b715Smrg	    return rc;
253805b261ecSmrg#ifdef PANORAMIX
253905b261ecSmrg	if (noPanoramiXExtension || !pmap->pScreen->myNum)
254005b261ecSmrg#endif
254105b261ecSmrg        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
25426747b715Smrg	return Success;
254305b261ecSmrg
254405b261ecSmrg    }
254505b261ecSmrg    else
254605b261ecSmrg    {
254705b261ecSmrg        client->errorValue = stuff->cmap;
25486747b715Smrg        return rc;
254905b261ecSmrg    }
255005b261ecSmrg}
255105b261ecSmrg
255205b261ecSmrgint
255305b261ecSmrgProcAllocNamedColor (ClientPtr client)
255405b261ecSmrg{
255505b261ecSmrg    ColormapPtr pcmp;
25564642e01fSmrg    int rc;
255705b261ecSmrg    REQUEST(xAllocNamedColorReq);
255805b261ecSmrg
255905b261ecSmrg    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2560b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
25614642e01fSmrg			   DixAddAccess);
25624642e01fSmrg    if (rc == Success)
256305b261ecSmrg    {
256405b261ecSmrg	xAllocNamedColorReply ancr;
256505b261ecSmrg
256605b261ecSmrg	ancr.type = X_Reply;
256705b261ecSmrg	ancr.length = 0;
256805b261ecSmrg	ancr.sequenceNumber = client->sequence;
256905b261ecSmrg
257005b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
257105b261ecSmrg	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
257205b261ecSmrg	{
257305b261ecSmrg	    ancr.screenRed = ancr.exactRed;
257405b261ecSmrg	    ancr.screenGreen = ancr.exactGreen;
257505b261ecSmrg	    ancr.screenBlue = ancr.exactBlue;
257605b261ecSmrg	    ancr.pixel = 0;
25774642e01fSmrg	    if( (rc = AllocColor(pcmp,
257805b261ecSmrg	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
257905b261ecSmrg			 &ancr.pixel, client->index)) )
25806747b715Smrg		return rc;
258105b261ecSmrg#ifdef PANORAMIX
258205b261ecSmrg	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
258305b261ecSmrg#endif
258405b261ecSmrg            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
25856747b715Smrg	    return Success;
258605b261ecSmrg	}
258705b261ecSmrg	else
25886747b715Smrg	    return BadName;
258905b261ecSmrg
259005b261ecSmrg    }
259105b261ecSmrg    else
259205b261ecSmrg    {
259305b261ecSmrg        client->errorValue = stuff->cmap;
25946747b715Smrg        return rc;
259505b261ecSmrg    }
259605b261ecSmrg}
259705b261ecSmrg
259805b261ecSmrgint
259905b261ecSmrgProcAllocColorCells (ClientPtr client)
260005b261ecSmrg{
260105b261ecSmrg    ColormapPtr pcmp;
26024642e01fSmrg    int rc;
260305b261ecSmrg    REQUEST(xAllocColorCellsReq);
260405b261ecSmrg
260505b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2606b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
26074642e01fSmrg			   DixAddAccess);
26084642e01fSmrg    if (rc == Success)
260905b261ecSmrg    {
261005b261ecSmrg	xAllocColorCellsReply	accr;
26114642e01fSmrg	int			npixels, nmasks;
261205b261ecSmrg	long			length;
261305b261ecSmrg	Pixel			*ppixels, *pmasks;
261405b261ecSmrg
261505b261ecSmrg	npixels = stuff->colors;
261605b261ecSmrg	if (!npixels)
261705b261ecSmrg	{
261805b261ecSmrg	    client->errorValue = npixels;
26196747b715Smrg	    return BadValue;
262005b261ecSmrg	}
262105b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
262205b261ecSmrg	{
262305b261ecSmrg	    client->errorValue = stuff->contiguous;
26246747b715Smrg	    return BadValue;
262505b261ecSmrg	}
262605b261ecSmrg	nmasks = stuff->planes;
262705b261ecSmrg	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
26286747b715Smrg	ppixels = malloc(length);
262905b261ecSmrg	if(!ppixels)
26306747b715Smrg            return BadAlloc;
263105b261ecSmrg	pmasks = ppixels + npixels;
263205b261ecSmrg
26334642e01fSmrg	if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
263405b261ecSmrg				    (Bool)stuff->contiguous, ppixels, pmasks)) )
263505b261ecSmrg	{
26366747b715Smrg	    free(ppixels);
26376747b715Smrg	    return rc;
263805b261ecSmrg	}
263905b261ecSmrg#ifdef PANORAMIX
264005b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
264105b261ecSmrg#endif
264205b261ecSmrg	{
264305b261ecSmrg	    accr.type = X_Reply;
26446747b715Smrg	    accr.length = bytes_to_int32(length);
264505b261ecSmrg	    accr.sequenceNumber = client->sequence;
264605b261ecSmrg	    accr.nPixels = npixels;
264705b261ecSmrg	    accr.nMasks = nmasks;
264805b261ecSmrg	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
264905b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
265005b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
265105b261ecSmrg	}
26526747b715Smrg	free(ppixels);
26536747b715Smrg        return Success;
265405b261ecSmrg    }
265505b261ecSmrg    else
265605b261ecSmrg    {
265705b261ecSmrg        client->errorValue = stuff->cmap;
26586747b715Smrg        return rc;
265905b261ecSmrg    }
266005b261ecSmrg}
266105b261ecSmrg
266205b261ecSmrgint
266305b261ecSmrgProcAllocColorPlanes(ClientPtr client)
266405b261ecSmrg{
266505b261ecSmrg    ColormapPtr pcmp;
26664642e01fSmrg    int rc;
266705b261ecSmrg    REQUEST(xAllocColorPlanesReq);
266805b261ecSmrg
266905b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2670b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
26714642e01fSmrg			   DixAddAccess);
26724642e01fSmrg    if (rc == Success)
267305b261ecSmrg    {
267405b261ecSmrg	xAllocColorPlanesReply	acpr;
26754642e01fSmrg	int			npixels;
267605b261ecSmrg	long			length;
267705b261ecSmrg	Pixel			*ppixels;
267805b261ecSmrg
267905b261ecSmrg	npixels = stuff->colors;
268005b261ecSmrg	if (!npixels)
268105b261ecSmrg	{
268205b261ecSmrg	    client->errorValue = npixels;
26836747b715Smrg	    return BadValue;
268405b261ecSmrg	}
268505b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
268605b261ecSmrg	{
268705b261ecSmrg	    client->errorValue = stuff->contiguous;
26886747b715Smrg	    return BadValue;
268905b261ecSmrg	}
269005b261ecSmrg	acpr.type = X_Reply;
269105b261ecSmrg	acpr.sequenceNumber = client->sequence;
269205b261ecSmrg	acpr.nPixels = npixels;
269305b261ecSmrg	length = (long)npixels * sizeof(Pixel);
26946747b715Smrg	ppixels = malloc(length);
269505b261ecSmrg	if(!ppixels)
26966747b715Smrg            return BadAlloc;
26974642e01fSmrg	if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
269805b261ecSmrg	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
269905b261ecSmrg	    (Bool)stuff->contiguous, ppixels,
270005b261ecSmrg	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
270105b261ecSmrg	{
27026747b715Smrg            free(ppixels);
27036747b715Smrg	    return rc;
270405b261ecSmrg	}
27056747b715Smrg	acpr.length = bytes_to_int32(length);
270605b261ecSmrg#ifdef PANORAMIX
270705b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
270805b261ecSmrg#endif
270905b261ecSmrg	{
271005b261ecSmrg	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
271105b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
271205b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
271305b261ecSmrg	}
27146747b715Smrg	free(ppixels);
27156747b715Smrg        return Success;
271605b261ecSmrg    }
271705b261ecSmrg    else
271805b261ecSmrg    {
271905b261ecSmrg        client->errorValue = stuff->cmap;
27206747b715Smrg        return rc;
272105b261ecSmrg    }
272205b261ecSmrg}
272305b261ecSmrg
272405b261ecSmrgint
272505b261ecSmrgProcFreeColors(ClientPtr client)
272605b261ecSmrg{
272705b261ecSmrg    ColormapPtr pcmp;
27284642e01fSmrg    int rc;
272905b261ecSmrg    REQUEST(xFreeColorsReq);
273005b261ecSmrg
273105b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2732b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27334642e01fSmrg			   DixRemoveAccess);
27344642e01fSmrg    if (rc == Success)
273505b261ecSmrg    {
273605b261ecSmrg	int	count;
273705b261ecSmrg
273805b261ecSmrg	if(pcmp->flags & AllAllocated)
27396747b715Smrg	    return BadAccess;
27406747b715Smrg	count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
27416747b715Smrg	return FreeColors(pcmp, client->index, count,
274205b261ecSmrg	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
274305b261ecSmrg    }
274405b261ecSmrg    else
274505b261ecSmrg    {
274605b261ecSmrg        client->errorValue = stuff->cmap;
27476747b715Smrg        return rc;
274805b261ecSmrg    }
274905b261ecSmrg}
275005b261ecSmrg
275105b261ecSmrgint
275205b261ecSmrgProcStoreColors (ClientPtr client)
275305b261ecSmrg{
275405b261ecSmrg    ColormapPtr pcmp;
27554642e01fSmrg    int rc;
275605b261ecSmrg    REQUEST(xStoreColorsReq);
275705b261ecSmrg
275805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2759b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27604642e01fSmrg			   DixWriteAccess);
27614642e01fSmrg    if (rc == Success)
276205b261ecSmrg    {
276305b261ecSmrg	int	count;
276405b261ecSmrg
276505b261ecSmrg        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
276605b261ecSmrg	if (count % sizeof(xColorItem))
27676747b715Smrg	    return BadLength;
276805b261ecSmrg	count /= sizeof(xColorItem);
27696747b715Smrg	return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client);
277005b261ecSmrg    }
277105b261ecSmrg    else
277205b261ecSmrg    {
277305b261ecSmrg        client->errorValue = stuff->cmap;
27746747b715Smrg        return rc;
277505b261ecSmrg    }
277605b261ecSmrg}
277705b261ecSmrg
277805b261ecSmrgint
277905b261ecSmrgProcStoreNamedColor (ClientPtr client)
278005b261ecSmrg{
278105b261ecSmrg    ColormapPtr pcmp;
27824642e01fSmrg    int rc;
278305b261ecSmrg    REQUEST(xStoreNamedColorReq);
278405b261ecSmrg
278505b261ecSmrg    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2786b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27874642e01fSmrg			   DixWriteAccess);
27884642e01fSmrg    if (rc == Success)
278905b261ecSmrg    {
279005b261ecSmrg	xColorItem	def;
279105b261ecSmrg
279205b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
279305b261ecSmrg	                 stuff->nbytes, &def.red, &def.green, &def.blue))
279405b261ecSmrg	{
279505b261ecSmrg	    def.flags = stuff->flags;
279605b261ecSmrg	    def.pixel = stuff->pixel;
27976747b715Smrg	    return StoreColors(pcmp, 1, &def, client);
279805b261ecSmrg	}
27996747b715Smrg        return BadName;
280005b261ecSmrg    }
280105b261ecSmrg    else
280205b261ecSmrg    {
280305b261ecSmrg        client->errorValue = stuff->cmap;
28046747b715Smrg        return rc;
280505b261ecSmrg    }
280605b261ecSmrg}
280705b261ecSmrg
280805b261ecSmrgint
280905b261ecSmrgProcQueryColors(ClientPtr client)
281005b261ecSmrg{
281105b261ecSmrg    ColormapPtr pcmp;
28124642e01fSmrg    int rc;
281305b261ecSmrg    REQUEST(xQueryColorsReq);
281405b261ecSmrg
281505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2816b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
28174642e01fSmrg			   DixReadAccess);
28184642e01fSmrg    if (rc == Success)
281905b261ecSmrg    {
28204642e01fSmrg	int			count;
282105b261ecSmrg	xrgb 			*prgbs;
282205b261ecSmrg	xQueryColorsReply	qcr;
282305b261ecSmrg
28246747b715Smrg	count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
28256747b715Smrg	prgbs = calloc(1, count * sizeof(xrgb));
282605b261ecSmrg	if(!prgbs && count)
28276747b715Smrg            return BadAlloc;
28286747b715Smrg	if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) )
282905b261ecSmrg	{
28306747b715Smrg	    free(prgbs);
28316747b715Smrg	    return rc;
283205b261ecSmrg	}
28336747b715Smrg	memset(&qcr, 0, sizeof(xQueryColorsReply));
283405b261ecSmrg	qcr.type = X_Reply;
28356747b715Smrg	qcr.length = bytes_to_int32(count * sizeof(xrgb));
283605b261ecSmrg	qcr.sequenceNumber = client->sequence;
283705b261ecSmrg	qcr.nColors = count;
283805b261ecSmrg	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
283905b261ecSmrg	if (count)
284005b261ecSmrg	{
284105b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
284205b261ecSmrg	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
284305b261ecSmrg	}
28446747b715Smrg	free(prgbs);
28456747b715Smrg	return Success;
284605b261ecSmrg
284705b261ecSmrg    }
284805b261ecSmrg    else
284905b261ecSmrg    {
285005b261ecSmrg        client->errorValue = stuff->cmap;
28516747b715Smrg        return rc;
285205b261ecSmrg    }
285305b261ecSmrg}
285405b261ecSmrg
285505b261ecSmrgint
285605b261ecSmrgProcLookupColor(ClientPtr client)
285705b261ecSmrg{
285805b261ecSmrg    ColormapPtr pcmp;
28594642e01fSmrg    int rc;
286005b261ecSmrg    REQUEST(xLookupColorReq);
286105b261ecSmrg
286205b261ecSmrg    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2863b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
28644642e01fSmrg			   DixReadAccess);
28654642e01fSmrg    if (rc == Success)
286605b261ecSmrg    {
286705b261ecSmrg	xLookupColorReply lcr;
286805b261ecSmrg
286905b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
287005b261ecSmrg	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
287105b261ecSmrg	{
287205b261ecSmrg	    lcr.type = X_Reply;
287305b261ecSmrg	    lcr.length = 0;
287405b261ecSmrg	    lcr.sequenceNumber = client->sequence;
287505b261ecSmrg	    lcr.screenRed = lcr.exactRed;
287605b261ecSmrg	    lcr.screenGreen = lcr.exactGreen;
287705b261ecSmrg	    lcr.screenBlue = lcr.exactBlue;
287805b261ecSmrg	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
287905b261ecSmrg	                                   &lcr.screenGreen,
288005b261ecSmrg					   &lcr.screenBlue,
288105b261ecSmrg					   pcmp->pVisual);
288205b261ecSmrg	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
28836747b715Smrg	    return Success;
288405b261ecSmrg	}
28856747b715Smrg        return BadName;
288605b261ecSmrg    }
288705b261ecSmrg    else
288805b261ecSmrg    {
288905b261ecSmrg        client->errorValue = stuff->cmap;
28906747b715Smrg        return rc;
289105b261ecSmrg    }
289205b261ecSmrg}
289305b261ecSmrg
289405b261ecSmrgint
289505b261ecSmrgProcCreateCursor (ClientPtr client)
289605b261ecSmrg{
289705b261ecSmrg    CursorPtr		pCursor;
289805b261ecSmrg    PixmapPtr 		src;
289905b261ecSmrg    PixmapPtr 		msk;
290005b261ecSmrg    unsigned char *	srcbits;
290105b261ecSmrg    unsigned char *	mskbits;
290205b261ecSmrg    unsigned short	width, height;
290305b261ecSmrg    long		n;
290405b261ecSmrg    CursorMetricRec 	cm;
29054642e01fSmrg    int rc;
290605b261ecSmrg
290705b261ecSmrg    REQUEST(xCreateCursorReq);
290805b261ecSmrg
290905b261ecSmrg    REQUEST_SIZE_MATCH(xCreateCursorReq);
291005b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
291105b261ecSmrg
2912b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client,
29134642e01fSmrg			   DixReadAccess);
29144642e01fSmrg    if (rc != Success) {
291505b261ecSmrg	client->errorValue = stuff->source;
29166747b715Smrg	return rc;
291705b261ecSmrg    }
29184642e01fSmrg
2919b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
29204642e01fSmrg			   DixReadAccess);
29214642e01fSmrg    if (rc != Success)
292205b261ecSmrg    {
292305b261ecSmrg	if (stuff->mask != None)
292405b261ecSmrg	{
292505b261ecSmrg	    client->errorValue = stuff->mask;
29266747b715Smrg	    return rc;
292705b261ecSmrg	}
292805b261ecSmrg    }
292905b261ecSmrg    else if (  src->drawable.width != msk->drawable.width
293005b261ecSmrg	    || src->drawable.height != msk->drawable.height
293105b261ecSmrg	    || src->drawable.depth != 1
293205b261ecSmrg	    || msk->drawable.depth != 1)
29336747b715Smrg	return BadMatch;
293405b261ecSmrg
293505b261ecSmrg    width = src->drawable.width;
293605b261ecSmrg    height = src->drawable.height;
293705b261ecSmrg
293805b261ecSmrg    if ( stuff->x > width
293905b261ecSmrg      || stuff->y > height )
29406747b715Smrg	return BadMatch;
294105b261ecSmrg
294205b261ecSmrg    n = BitmapBytePad(width)*height;
29436747b715Smrg    srcbits = calloc(1, n);
294405b261ecSmrg    if (!srcbits)
29456747b715Smrg	return BadAlloc;
29466747b715Smrg    mskbits = malloc(n);
294705b261ecSmrg    if (!mskbits)
294805b261ecSmrg    {
29496747b715Smrg	free(srcbits);
29506747b715Smrg	return BadAlloc;
295105b261ecSmrg    }
295205b261ecSmrg
295305b261ecSmrg    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
295405b261ecSmrg					 XYPixmap, 1, (pointer)srcbits);
295505b261ecSmrg    if ( msk == (PixmapPtr)NULL)
295605b261ecSmrg    {
295705b261ecSmrg	unsigned char *bits = mskbits;
295805b261ecSmrg	while (--n >= 0)
295905b261ecSmrg	    *bits++ = ~0;
296005b261ecSmrg    }
296105b261ecSmrg    else
296205b261ecSmrg    {
296305b261ecSmrg	/* zeroing the (pad) bits helps some ddx cursor handling */
29646747b715Smrg	memset((char *)mskbits, 0, n);
296505b261ecSmrg	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
296605b261ecSmrg					height, XYPixmap, 1, (pointer)mskbits);
296705b261ecSmrg    }
296805b261ecSmrg    cm.width = width;
296905b261ecSmrg    cm.height = height;
297005b261ecSmrg    cm.xhot = stuff->x;
297105b261ecSmrg    cm.yhot = stuff->y;
29724642e01fSmrg    rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
29734642e01fSmrg			 stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
29744642e01fSmrg			 stuff->backRed, stuff->backGreen, stuff->backBlue,
29754642e01fSmrg			 &pCursor, client, stuff->cid);
297605b261ecSmrg
29774642e01fSmrg    if (rc != Success)
29784642e01fSmrg	return rc;
29794642e01fSmrg    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
29804642e01fSmrg	return BadAlloc;
29814642e01fSmrg
29826747b715Smrg    return Success;
298305b261ecSmrg}
298405b261ecSmrg
298505b261ecSmrgint
298605b261ecSmrgProcCreateGlyphCursor (ClientPtr client)
298705b261ecSmrg{
298805b261ecSmrg    CursorPtr pCursor;
298905b261ecSmrg    int res;
299005b261ecSmrg
299105b261ecSmrg    REQUEST(xCreateGlyphCursorReq);
299205b261ecSmrg
299305b261ecSmrg    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
299405b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
299505b261ecSmrg
299605b261ecSmrg    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
299705b261ecSmrg			   stuff->mask, stuff->maskChar,
299805b261ecSmrg			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
299905b261ecSmrg			   stuff->backRed, stuff->backGreen, stuff->backBlue,
30004642e01fSmrg			   &pCursor, client, stuff->cid);
300105b261ecSmrg    if (res != Success)
300205b261ecSmrg	return res;
300305b261ecSmrg    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
30046747b715Smrg	return Success;
300505b261ecSmrg    return BadAlloc;
300605b261ecSmrg}
300705b261ecSmrg
300805b261ecSmrg
300905b261ecSmrgint
301005b261ecSmrgProcFreeCursor (ClientPtr client)
301105b261ecSmrg{
301205b261ecSmrg    CursorPtr pCursor;
30134642e01fSmrg    int rc;
301405b261ecSmrg    REQUEST(xResourceReq);
301505b261ecSmrg
301605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
3017b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client,
30184642e01fSmrg			   DixDestroyAccess);
30194642e01fSmrg    if (rc == Success)
302005b261ecSmrg    {
302105b261ecSmrg	FreeResource(stuff->id, RT_NONE);
30226747b715Smrg	return Success;
302305b261ecSmrg    }
302405b261ecSmrg    else
302505b261ecSmrg    {
302605b261ecSmrg	client->errorValue = stuff->id;
30276747b715Smrg	return rc;
302805b261ecSmrg    }
302905b261ecSmrg}
303005b261ecSmrg
303105b261ecSmrgint
303205b261ecSmrgProcQueryBestSize (ClientPtr client)
303305b261ecSmrg{
303405b261ecSmrg    xQueryBestSizeReply	reply;
303505b261ecSmrg    DrawablePtr pDraw;
303605b261ecSmrg    ScreenPtr pScreen;
303705b261ecSmrg    int rc;
303805b261ecSmrg    REQUEST(xQueryBestSizeReq);
303905b261ecSmrg    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
304005b261ecSmrg
304105b261ecSmrg    if ((stuff->class != CursorShape) &&
304205b261ecSmrg	(stuff->class != TileShape) &&
304305b261ecSmrg	(stuff->class != StippleShape))
304405b261ecSmrg    {
304505b261ecSmrg	client->errorValue = stuff->class;
30466747b715Smrg        return BadValue;
304705b261ecSmrg    }
304805b261ecSmrg
304905b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
30504642e01fSmrg			   DixGetAttrAccess);
305105b261ecSmrg    if (rc != Success)
305205b261ecSmrg	return rc;
305305b261ecSmrg    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
30546747b715Smrg	return BadMatch;
305505b261ecSmrg    pScreen = pDraw->pScreen;
30564642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
30574642e01fSmrg    if (rc != Success)
30584642e01fSmrg	return rc;
305905b261ecSmrg    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
306005b261ecSmrg			       &stuff->height, pScreen);
30616747b715Smrg    memset(&reply, 0, sizeof(xQueryBestSizeReply));
306205b261ecSmrg    reply.type = X_Reply;
306305b261ecSmrg    reply.length = 0;
306405b261ecSmrg    reply.sequenceNumber = client->sequence;
306505b261ecSmrg    reply.width = stuff->width;
306605b261ecSmrg    reply.height = stuff->height;
306705b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
30686747b715Smrg    return Success;
306905b261ecSmrg}
307005b261ecSmrg
307105b261ecSmrg
307205b261ecSmrgint
307305b261ecSmrgProcSetScreenSaver (ClientPtr client)
307405b261ecSmrg{
30754642e01fSmrg    int rc, i, blankingOption, exposureOption;
307605b261ecSmrg    REQUEST(xSetScreenSaverReq);
307705b261ecSmrg    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
30784642e01fSmrg
30794642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
30804642e01fSmrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
30814642e01fSmrg		      DixSetAttrAccess);
30824642e01fSmrg	if (rc != Success)
30834642e01fSmrg	    return rc;
30844642e01fSmrg    }
30854642e01fSmrg
308605b261ecSmrg    blankingOption = stuff->preferBlank;
308705b261ecSmrg    if ((blankingOption != DontPreferBlanking) &&
308805b261ecSmrg        (blankingOption != PreferBlanking) &&
308905b261ecSmrg        (blankingOption != DefaultBlanking))
309005b261ecSmrg    {
309105b261ecSmrg	client->errorValue = blankingOption;
309205b261ecSmrg        return BadValue;
309305b261ecSmrg    }
309405b261ecSmrg    exposureOption = stuff->allowExpose;
309505b261ecSmrg    if ((exposureOption != DontAllowExposures) &&
309605b261ecSmrg        (exposureOption != AllowExposures) &&
309705b261ecSmrg        (exposureOption != DefaultExposures))
309805b261ecSmrg    {
309905b261ecSmrg	client->errorValue = exposureOption;
310005b261ecSmrg        return BadValue;
310105b261ecSmrg    }
310205b261ecSmrg    if (stuff->timeout < -1)
310305b261ecSmrg    {
310405b261ecSmrg	client->errorValue = stuff->timeout;
310505b261ecSmrg        return BadValue;
310605b261ecSmrg    }
310705b261ecSmrg    if (stuff->interval < -1)
310805b261ecSmrg    {
310905b261ecSmrg	client->errorValue = stuff->interval;
311005b261ecSmrg        return BadValue;
311105b261ecSmrg    }
311205b261ecSmrg
311305b261ecSmrg    if (blankingOption == DefaultBlanking)
311405b261ecSmrg	ScreenSaverBlanking = defaultScreenSaverBlanking;
311505b261ecSmrg    else
311605b261ecSmrg	ScreenSaverBlanking = blankingOption;
311705b261ecSmrg    if (exposureOption == DefaultExposures)
311805b261ecSmrg	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
311905b261ecSmrg    else
312005b261ecSmrg	ScreenSaverAllowExposures = exposureOption;
312105b261ecSmrg
312205b261ecSmrg    if (stuff->timeout >= 0)
312305b261ecSmrg	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
312405b261ecSmrg    else
312505b261ecSmrg	ScreenSaverTime = defaultScreenSaverTime;
312605b261ecSmrg    if (stuff->interval >= 0)
312705b261ecSmrg	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
312805b261ecSmrg    else
312905b261ecSmrg	ScreenSaverInterval = defaultScreenSaverInterval;
313005b261ecSmrg
313105b261ecSmrg    SetScreenSaverTimer();
31326747b715Smrg    return Success;
313305b261ecSmrg}
313405b261ecSmrg
313505b261ecSmrgint
313605b261ecSmrgProcGetScreenSaver(ClientPtr client)
313705b261ecSmrg{
313805b261ecSmrg    xGetScreenSaverReply rep;
31394642e01fSmrg    int rc, i;
314005b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
31414642e01fSmrg
31424642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
31434642e01fSmrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
31444642e01fSmrg		      DixGetAttrAccess);
31454642e01fSmrg	if (rc != Success)
31464642e01fSmrg	    return rc;
31474642e01fSmrg    }
31484642e01fSmrg
314905b261ecSmrg    rep.type = X_Reply;
315005b261ecSmrg    rep.length = 0;
315105b261ecSmrg    rep.sequenceNumber = client->sequence;
315205b261ecSmrg    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
315305b261ecSmrg    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
315405b261ecSmrg    rep.preferBlanking = ScreenSaverBlanking;
315505b261ecSmrg    rep.allowExposures = ScreenSaverAllowExposures;
315605b261ecSmrg    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
31576747b715Smrg    return Success;
315805b261ecSmrg}
315905b261ecSmrg
316005b261ecSmrgint
316105b261ecSmrgProcChangeHosts(ClientPtr client)
316205b261ecSmrg{
316305b261ecSmrg    REQUEST(xChangeHostsReq);
316405b261ecSmrg
316505b261ecSmrg    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
316605b261ecSmrg
316705b261ecSmrg    if(stuff->mode == HostInsert)
31686747b715Smrg	return AddHost(client, (int)stuff->hostFamily,
316905b261ecSmrg			 stuff->hostLength, (pointer)&stuff[1]);
31706747b715Smrg    if (stuff->mode == HostDelete)
31716747b715Smrg	return RemoveHost(client, (int)stuff->hostFamily,
317205b261ecSmrg			    stuff->hostLength, (pointer)&stuff[1]);
31736747b715Smrg    client->errorValue = stuff->mode;
31746747b715Smrg    return BadValue;
317505b261ecSmrg}
317605b261ecSmrg
317705b261ecSmrgint
317805b261ecSmrgProcListHosts(ClientPtr client)
317905b261ecSmrg{
318005b261ecSmrg    xListHostsReply reply;
318105b261ecSmrg    int	len, nHosts, result;
318205b261ecSmrg    pointer	pdata;
318305b261ecSmrg    /* REQUEST(xListHostsReq); */
318405b261ecSmrg
318505b261ecSmrg    REQUEST_SIZE_MATCH(xListHostsReq);
318605b261ecSmrg
318705b261ecSmrg    /* untrusted clients can't list hosts */
31884642e01fSmrg    result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
31894642e01fSmrg    if (result != Success)
31904642e01fSmrg	return result;
319105b261ecSmrg
319205b261ecSmrg    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
319305b261ecSmrg    if (result != Success)
31946747b715Smrg	return result;
319505b261ecSmrg    reply.type = X_Reply;
319605b261ecSmrg    reply.sequenceNumber = client->sequence;
319705b261ecSmrg    reply.nHosts = nHosts;
31986747b715Smrg    reply.length = bytes_to_int32(len);
319905b261ecSmrg    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
320005b261ecSmrg    if (nHosts)
320105b261ecSmrg    {
320205b261ecSmrg	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
320305b261ecSmrg	WriteSwappedDataToClient(client, len, pdata);
320405b261ecSmrg    }
32056747b715Smrg    free(pdata);
32066747b715Smrg    return Success;
320705b261ecSmrg}
320805b261ecSmrg
320905b261ecSmrgint
321005b261ecSmrgProcChangeAccessControl(ClientPtr client)
321105b261ecSmrg{
321205b261ecSmrg    REQUEST(xSetAccessControlReq);
321305b261ecSmrg
321405b261ecSmrg    REQUEST_SIZE_MATCH(xSetAccessControlReq);
321505b261ecSmrg    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
321605b261ecSmrg    {
321705b261ecSmrg	client->errorValue = stuff->mode;
321805b261ecSmrg        return BadValue;
321905b261ecSmrg    }
32206747b715Smrg    return ChangeAccessControl(client, stuff->mode == EnableAccess);
322105b261ecSmrg}
322205b261ecSmrg
322305b261ecSmrg/*********************
322405b261ecSmrg * CloseDownRetainedResources
322505b261ecSmrg *
322605b261ecSmrg *    Find all clients that are gone and have terminated in RetainTemporary
322705b261ecSmrg *    and destroy their resources.
322805b261ecSmrg *********************/
322905b261ecSmrg
323005b261ecSmrgstatic void
323105b261ecSmrgCloseDownRetainedResources(void)
323205b261ecSmrg{
323305b261ecSmrg    int i;
323405b261ecSmrg    ClientPtr client;
323505b261ecSmrg
323605b261ecSmrg    for (i=1; i<currentMaxClients; i++)
323705b261ecSmrg    {
323805b261ecSmrg        client = clients[i];
323905b261ecSmrg        if (client && (client->closeDownMode == RetainTemporary)
324005b261ecSmrg	    && (client->clientGone))
324105b261ecSmrg	    CloseDownClient(client);
324205b261ecSmrg    }
324305b261ecSmrg}
324405b261ecSmrg
324505b261ecSmrgint
324605b261ecSmrgProcKillClient(ClientPtr client)
324705b261ecSmrg{
324805b261ecSmrg    REQUEST(xResourceReq);
324905b261ecSmrg    ClientPtr killclient;
325005b261ecSmrg    int rc;
325105b261ecSmrg
325205b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
325305b261ecSmrg    if (stuff->id == AllTemporary)
325405b261ecSmrg    {
325505b261ecSmrg	CloseDownRetainedResources();
32566747b715Smrg        return Success;
325705b261ecSmrg    }
325805b261ecSmrg
325905b261ecSmrg    rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
326005b261ecSmrg    if (rc == Success) {
326105b261ecSmrg	CloseDownClient(killclient);
326205b261ecSmrg	/* if an LBX proxy gets killed, isItTimeToYield will be set */
326305b261ecSmrg	if (isItTimeToYield || (client == killclient))
326405b261ecSmrg	{
326505b261ecSmrg	    /* force yield and return Success, so that Dispatch()
326605b261ecSmrg	     * doesn't try to touch client
326705b261ecSmrg	     */
326805b261ecSmrg	    isItTimeToYield = TRUE;
32696747b715Smrg	    return Success;
327005b261ecSmrg	}
32716747b715Smrg	return Success;
327205b261ecSmrg    }
327305b261ecSmrg    else
327405b261ecSmrg	return rc;
327505b261ecSmrg}
327605b261ecSmrg
327705b261ecSmrgint
327805b261ecSmrgProcSetFontPath(ClientPtr client)
327905b261ecSmrg{
328005b261ecSmrg    unsigned char *ptr;
328105b261ecSmrg    unsigned long nbytes, total;
328205b261ecSmrg    long nfonts;
32836747b715Smrg    int n;
328405b261ecSmrg    REQUEST(xSetFontPathReq);
328505b261ecSmrg
328605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
328705b261ecSmrg
328805b261ecSmrg    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
328905b261ecSmrg    total = nbytes;
329005b261ecSmrg    ptr = (unsigned char *)&stuff[1];
329105b261ecSmrg    nfonts = stuff->nFonts;
329205b261ecSmrg    while (--nfonts >= 0)
329305b261ecSmrg    {
329405b261ecSmrg	if ((total == 0) || (total < (n = (*ptr + 1))))
32956747b715Smrg	    return BadLength;
329605b261ecSmrg	total -= n;
329705b261ecSmrg	ptr += n;
329805b261ecSmrg    }
329905b261ecSmrg    if (total >= 4)
33006747b715Smrg	return BadLength;
33016747b715Smrg    return SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]);
330205b261ecSmrg}
330305b261ecSmrg
330405b261ecSmrgint
330505b261ecSmrgProcGetFontPath(ClientPtr client)
330605b261ecSmrg{
330705b261ecSmrg    xGetFontPathReply reply;
33084642e01fSmrg    int rc, stringLens, numpaths;
330905b261ecSmrg    unsigned char *bufferStart;
331005b261ecSmrg    /* REQUEST (xReq); */
331105b261ecSmrg
331205b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
33134642e01fSmrg    rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
33144642e01fSmrg    if (rc != Success)
33154642e01fSmrg	return rc;
331605b261ecSmrg
331705b261ecSmrg    reply.type = X_Reply;
331805b261ecSmrg    reply.sequenceNumber = client->sequence;
33196747b715Smrg    reply.length = bytes_to_int32(stringLens + numpaths);
332005b261ecSmrg    reply.nPaths = numpaths;
332105b261ecSmrg
332205b261ecSmrg    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
332305b261ecSmrg    if (stringLens || numpaths)
332405b261ecSmrg	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
33256747b715Smrg    return Success;
332605b261ecSmrg}
332705b261ecSmrg
332805b261ecSmrgint
332905b261ecSmrgProcChangeCloseDownMode(ClientPtr client)
333005b261ecSmrg{
33314642e01fSmrg    int rc;
333205b261ecSmrg    REQUEST(xSetCloseDownModeReq);
333305b261ecSmrg    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
33344642e01fSmrg
33354642e01fSmrg    rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
33364642e01fSmrg    if (rc != Success)
33374642e01fSmrg	return rc;
33384642e01fSmrg
333905b261ecSmrg    if ((stuff->mode == AllTemporary) ||
334005b261ecSmrg	(stuff->mode == RetainPermanent) ||
334105b261ecSmrg	(stuff->mode == RetainTemporary))
334205b261ecSmrg    {
334305b261ecSmrg	client->closeDownMode = stuff->mode;
33446747b715Smrg	return Success;
334505b261ecSmrg    }
334605b261ecSmrg    else
334705b261ecSmrg    {
334805b261ecSmrg	client->errorValue = stuff->mode;
33496747b715Smrg	return BadValue;
335005b261ecSmrg    }
335105b261ecSmrg}
335205b261ecSmrg
335305b261ecSmrgint ProcForceScreenSaver(ClientPtr client)
335405b261ecSmrg{
33554642e01fSmrg    int rc;
335605b261ecSmrg    REQUEST(xForceScreenSaverReq);
335705b261ecSmrg
335805b261ecSmrg    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
335905b261ecSmrg
336005b261ecSmrg    if ((stuff->mode != ScreenSaverReset) &&
336105b261ecSmrg	(stuff->mode != ScreenSaverActive))
336205b261ecSmrg    {
336305b261ecSmrg	client->errorValue = stuff->mode;
336405b261ecSmrg        return BadValue;
336505b261ecSmrg    }
33664642e01fSmrg    rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode);
33674642e01fSmrg    if (rc != Success)
33684642e01fSmrg	return rc;
33696747b715Smrg    return Success;
337005b261ecSmrg}
337105b261ecSmrg
337205b261ecSmrgint ProcNoOperation(ClientPtr client)
337305b261ecSmrg{
337405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xReq);
337505b261ecSmrg
337605b261ecSmrg    /* noop -- don't do anything */
33776747b715Smrg    return Success;
337805b261ecSmrg}
337905b261ecSmrg
338005b261ecSmrg/**********************
338105b261ecSmrg * CloseDownClient
338205b261ecSmrg *
338305b261ecSmrg *  Client can either mark his resources destroy or retain.  If retained and
338405b261ecSmrg *  then killed again, the client is really destroyed.
338505b261ecSmrg *********************/
338605b261ecSmrg
338705b261ecSmrgchar dispatchExceptionAtReset = DE_RESET;
338805b261ecSmrg
338905b261ecSmrgvoid
339005b261ecSmrgCloseDownClient(ClientPtr client)
339105b261ecSmrg{
339205b261ecSmrg    Bool really_close_down = client->clientGone ||
339305b261ecSmrg			     client->closeDownMode == DestroyAll;
339405b261ecSmrg
339505b261ecSmrg    if (!client->clientGone)
339605b261ecSmrg    {
339705b261ecSmrg	/* ungrab server if grabbing client dies */
339805b261ecSmrg	if (grabState != GrabNone && grabClient == client)
339905b261ecSmrg	{
340005b261ecSmrg	    UngrabServer(client);
340105b261ecSmrg	}
340205b261ecSmrg	BITCLEAR(grabWaiters, client->index);
340305b261ecSmrg	DeleteClientFromAnySelections(client);
340405b261ecSmrg	ReleaseActiveGrabs(client);
340505b261ecSmrg	DeleteClientFontStuff(client);
340605b261ecSmrg	if (!really_close_down)
340705b261ecSmrg	{
340805b261ecSmrg	    /*  This frees resources that should never be retained
340905b261ecSmrg	     *  no matter what the close down mode is.  Actually we
341005b261ecSmrg	     *  could do this unconditionally, but it's probably
341105b261ecSmrg	     *  better not to traverse all the client's resources
341205b261ecSmrg	     *  twice (once here, once a few lines down in
341305b261ecSmrg	     *  FreeClientResources) in the common case of
341405b261ecSmrg	     *  really_close_down == TRUE.
341505b261ecSmrg	     */
341605b261ecSmrg	    FreeClientNeverRetainResources(client);
341705b261ecSmrg	    client->clientState = ClientStateRetained;
341805b261ecSmrg  	    if (ClientStateCallback)
341905b261ecSmrg            {
342005b261ecSmrg		NewClientInfoRec clientinfo;
342105b261ecSmrg
342205b261ecSmrg		clientinfo.client = client;
342305b261ecSmrg		clientinfo.prefix = (xConnSetupPrefix *)NULL;
342405b261ecSmrg		clientinfo.setup = (xConnSetup *) NULL;
342505b261ecSmrg		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
342605b261ecSmrg            }
342705b261ecSmrg	}
342805b261ecSmrg	client->clientGone = TRUE;  /* so events aren't sent to client */
342905b261ecSmrg	if (ClientIsAsleep(client))
343005b261ecSmrg	    ClientSignal (client);
343105b261ecSmrg	ProcessWorkQueueZombies();
343205b261ecSmrg	CloseDownConnection(client);
343305b261ecSmrg
343405b261ecSmrg	/* If the client made it to the Running stage, nClients has
343505b261ecSmrg	 * been incremented on its behalf, so we need to decrement it
343605b261ecSmrg	 * now.  If it hasn't gotten to Running, nClients has *not*
343705b261ecSmrg	 * been incremented, so *don't* decrement it.
343805b261ecSmrg	 */
343905b261ecSmrg	if (client->clientState != ClientStateInitial &&
344005b261ecSmrg	    client->clientState != ClientStateAuthenticating )
344105b261ecSmrg	{
344205b261ecSmrg	    --nClients;
344305b261ecSmrg	}
344405b261ecSmrg    }
344505b261ecSmrg
344605b261ecSmrg    if (really_close_down)
344705b261ecSmrg    {
344805b261ecSmrg	if (client->clientState == ClientStateRunning && nClients == 0)
344905b261ecSmrg	    dispatchException |= dispatchExceptionAtReset;
345005b261ecSmrg
345105b261ecSmrg	client->clientState = ClientStateGone;
345205b261ecSmrg	if (ClientStateCallback)
345305b261ecSmrg	{
345405b261ecSmrg	    NewClientInfoRec clientinfo;
345505b261ecSmrg
345605b261ecSmrg	    clientinfo.client = client;
345705b261ecSmrg	    clientinfo.prefix = (xConnSetupPrefix *)NULL;
345805b261ecSmrg	    clientinfo.setup = (xConnSetup *) NULL;
345905b261ecSmrg	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
346005b261ecSmrg	}
346105b261ecSmrg	FreeClientResources(client);
346205b261ecSmrg#ifdef XSERVER_DTRACE
346305b261ecSmrg	XSERVER_CLIENT_DISCONNECT(client->index);
346405b261ecSmrg#endif
346505b261ecSmrg	if (client->index < nextFreeClientID)
346605b261ecSmrg	    nextFreeClientID = client->index;
346705b261ecSmrg	clients[client->index] = NullClient;
346805b261ecSmrg	SmartLastClient = NullClient;
34696747b715Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
347005b261ecSmrg
347105b261ecSmrg	while (!clients[currentMaxClients-1])
347205b261ecSmrg	    currentMaxClients--;
347305b261ecSmrg    }
347405b261ecSmrg}
347505b261ecSmrg
347605b261ecSmrgstatic void
347705b261ecSmrgKillAllClients(void)
347805b261ecSmrg{
347905b261ecSmrg    int i;
348005b261ecSmrg    for (i=1; i<currentMaxClients; i++)
348105b261ecSmrg        if (clients[i]) {
348205b261ecSmrg            /* Make sure Retained clients are released. */
348305b261ecSmrg            clients[i]->closeDownMode = DestroyAll;
348405b261ecSmrg            CloseDownClient(clients[i]);
348505b261ecSmrg        }
348605b261ecSmrg}
348705b261ecSmrg
348805b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv)
348905b261ecSmrg{
349005b261ecSmrg    client->index = i;
349105b261ecSmrg    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
34924642e01fSmrg    client->closeDownMode = i ? DestroyAll : RetainPermanent;
349305b261ecSmrg    client->requestVector = InitialVector;
349405b261ecSmrg    client->osPrivate = ospriv;
34956747b715Smrg    QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
349605b261ecSmrg    client->smart_start_tick = SmartScheduleTime;
349705b261ecSmrg    client->smart_stop_tick = SmartScheduleTime;
349805b261ecSmrg    client->smart_check_tick = SmartScheduleTime;
349905b261ecSmrg}
350005b261ecSmrg
350105b261ecSmrg/************************
350205b261ecSmrg * int NextAvailableClient(ospriv)
350305b261ecSmrg *
350405b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes.
350505b261ecSmrg * Returns NULL if there are no free clients.
350605b261ecSmrg *************************/
350705b261ecSmrg
350805b261ecSmrgClientPtr NextAvailableClient(pointer ospriv)
350905b261ecSmrg{
351005b261ecSmrg    int i;
351105b261ecSmrg    ClientPtr client;
351205b261ecSmrg    xReq data;
351305b261ecSmrg
351405b261ecSmrg    i = nextFreeClientID;
351505b261ecSmrg    if (i == MAXCLIENTS)
351605b261ecSmrg	return (ClientPtr)NULL;
35176747b715Smrg    clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
351805b261ecSmrg    if (!client)
351905b261ecSmrg	return (ClientPtr)NULL;
352005b261ecSmrg    InitClient(client, i, ospriv);
352105b261ecSmrg    if (!InitClientResources(client))
352205b261ecSmrg    {
35236747b715Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
352405b261ecSmrg	return (ClientPtr)NULL;
352505b261ecSmrg    }
352605b261ecSmrg    data.reqType = 1;
35276747b715Smrg    data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
352805b261ecSmrg    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
352905b261ecSmrg    {
353005b261ecSmrg	FreeClientResources(client);
35316747b715Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
353205b261ecSmrg	return (ClientPtr)NULL;
353305b261ecSmrg    }
353405b261ecSmrg    if (i == currentMaxClients)
353505b261ecSmrg	currentMaxClients++;
353605b261ecSmrg    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
353705b261ecSmrg	nextFreeClientID++;
353805b261ecSmrg    if (ClientStateCallback)
353905b261ecSmrg    {
354005b261ecSmrg	NewClientInfoRec clientinfo;
354105b261ecSmrg
354205b261ecSmrg        clientinfo.client = client;
354305b261ecSmrg        clientinfo.prefix = (xConnSetupPrefix *)NULL;
354405b261ecSmrg        clientinfo.setup = (xConnSetup *) NULL;
354505b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
354605b261ecSmrg    }
35476747b715Smrg    return client;
354805b261ecSmrg}
354905b261ecSmrg
355005b261ecSmrgint
355105b261ecSmrgProcInitialConnection(ClientPtr client)
355205b261ecSmrg{
355305b261ecSmrg    REQUEST(xReq);
355405b261ecSmrg    xConnClientPrefix *prefix;
355505b261ecSmrg    int whichbyte = 1;
355605b261ecSmrg
355705b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
355805b261ecSmrg    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
35596747b715Smrg	return client->noClientException = -1;
356005b261ecSmrg    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
356105b261ecSmrg	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
356205b261ecSmrg    {
356305b261ecSmrg	client->swapped = TRUE;
356405b261ecSmrg	SwapConnClientPrefix(prefix);
356505b261ecSmrg    }
356605b261ecSmrg    stuff->reqType = 2;
35676747b715Smrg    stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
35686747b715Smrg		     bytes_to_int32(prefix->nbytesAuthString);
356905b261ecSmrg    if (client->swapped)
357005b261ecSmrg    {
357105b261ecSmrg	swaps(&stuff->length, whichbyte);
357205b261ecSmrg    }
357305b261ecSmrg    ResetCurrentRequest(client);
35746747b715Smrg    return Success;
357505b261ecSmrg}
357605b261ecSmrg
35774642e01fSmrgstatic int
357805b261ecSmrgSendConnSetup(ClientPtr client, char *reason)
357905b261ecSmrg{
358005b261ecSmrg    xWindowRoot *root;
358105b261ecSmrg    int i;
358205b261ecSmrg    int numScreens;
358305b261ecSmrg    char* lConnectionInfo;
358405b261ecSmrg    xConnSetupPrefix* lconnSetupPrefix;
358505b261ecSmrg
358605b261ecSmrg    if (reason)
358705b261ecSmrg    {
358805b261ecSmrg	xConnSetupPrefix csp;
358905b261ecSmrg
359005b261ecSmrg	csp.success = xFalse;
359105b261ecSmrg	csp.lengthReason = strlen(reason);
35926747b715Smrg	csp.length = bytes_to_int32(csp.lengthReason);
359305b261ecSmrg	csp.majorVersion = X_PROTOCOL;
359405b261ecSmrg	csp.minorVersion = X_PROTOCOL_REVISION;
359505b261ecSmrg	if (client->swapped)
359605b261ecSmrg	    WriteSConnSetupPrefix(client, &csp);
359705b261ecSmrg	else
359805b261ecSmrg	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
359905b261ecSmrg        (void)WriteToClient(client, (int)csp.lengthReason, reason);
36006747b715Smrg	return client->noClientException = -1;
360105b261ecSmrg    }
360205b261ecSmrg
360305b261ecSmrg    numScreens = screenInfo.numScreens;
360405b261ecSmrg    lConnectionInfo = ConnectionInfo;
360505b261ecSmrg    lconnSetupPrefix = &connSetupPrefix;
360605b261ecSmrg
360705b261ecSmrg    /* We're about to start speaking X protocol back to the client by
360805b261ecSmrg     * sending the connection setup info.  This means the authorization
360905b261ecSmrg     * step is complete, and we can count the client as an
361005b261ecSmrg     * authorized one.
361105b261ecSmrg     */
361205b261ecSmrg    nClients++;
361305b261ecSmrg
361405b261ecSmrg    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
361505b261ecSmrg    client->sequence = 0;
361605b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
361705b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
361805b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
361905b261ecSmrg    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
362005b261ecSmrg    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
362105b261ecSmrg#endif
362205b261ecSmrg    /* fill in the "currentInputMask" */
362305b261ecSmrg    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
362405b261ecSmrg#ifdef PANORAMIX
362505b261ecSmrg    if (noPanoramiXExtension)
362605b261ecSmrg	numScreens = screenInfo.numScreens;
362705b261ecSmrg    else
362805b261ecSmrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
362905b261ecSmrg#endif
363005b261ecSmrg
363105b261ecSmrg    for (i=0; i<numScreens; i++)
363205b261ecSmrg    {
363305b261ecSmrg	unsigned int j;
363405b261ecSmrg	xDepth *pDepth;
36356747b715Smrg	WindowPtr pRoot = screenInfo.screens[i]->root;
363605b261ecSmrg
36376747b715Smrg        root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
363805b261ecSmrg	pDepth = (xDepth *)(root + 1);
363905b261ecSmrg	for (j = 0; j < root->nDepths; j++)
364005b261ecSmrg	{
364105b261ecSmrg	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
364205b261ecSmrg				pDepth->nVisuals * sizeof(xVisualType));
364305b261ecSmrg	}
364405b261ecSmrg	root = (xWindowRoot *)pDepth;
364505b261ecSmrg    }
364605b261ecSmrg
364705b261ecSmrg    if (client->swapped)
364805b261ecSmrg    {
364905b261ecSmrg	WriteSConnSetupPrefix(client, lconnSetupPrefix);
365005b261ecSmrg	WriteSConnectionInfo(client,
365105b261ecSmrg			     (unsigned long)(lconnSetupPrefix->length << 2),
365205b261ecSmrg			     lConnectionInfo);
365305b261ecSmrg    }
365405b261ecSmrg    else
365505b261ecSmrg    {
365605b261ecSmrg	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
365705b261ecSmrg			    (char *) lconnSetupPrefix);
365805b261ecSmrg	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
365905b261ecSmrg			    lConnectionInfo);
366005b261ecSmrg    }
366105b261ecSmrg    client->clientState = ClientStateRunning;
366205b261ecSmrg    if (ClientStateCallback)
366305b261ecSmrg    {
366405b261ecSmrg	NewClientInfoRec clientinfo;
366505b261ecSmrg
366605b261ecSmrg        clientinfo.client = client;
366705b261ecSmrg        clientinfo.prefix = lconnSetupPrefix;
366805b261ecSmrg        clientinfo.setup = (xConnSetup *)lConnectionInfo;
366905b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
367005b261ecSmrg    }
36716747b715Smrg    return Success;
367205b261ecSmrg}
367305b261ecSmrg
367405b261ecSmrgint
367505b261ecSmrgProcEstablishConnection(ClientPtr client)
367605b261ecSmrg{
367705b261ecSmrg    char *reason, *auth_proto, *auth_string;
367805b261ecSmrg    xConnClientPrefix *prefix;
367905b261ecSmrg    REQUEST(xReq);
368005b261ecSmrg
368105b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
368205b261ecSmrg    auth_proto = (char *)prefix + sz_xConnClientPrefix;
36836747b715Smrg    auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
368405b261ecSmrg    if ((prefix->majorVersion != X_PROTOCOL) ||
368505b261ecSmrg	(prefix->minorVersion != X_PROTOCOL_REVISION))
368605b261ecSmrg	reason = "Protocol version mismatch";
368705b261ecSmrg    else
368805b261ecSmrg	reason = ClientAuthorized(client,
368905b261ecSmrg				  (unsigned short)prefix->nbytesAuthProto,
369005b261ecSmrg				  auth_proto,
369105b261ecSmrg				  (unsigned short)prefix->nbytesAuthString,
369205b261ecSmrg				  auth_string);
369305b261ecSmrg    /*
369405b261ecSmrg     * If Kerberos is being used for this client, the clientState
369505b261ecSmrg     * will be set to ClientStateAuthenticating at this point.
369605b261ecSmrg     * More messages need to be exchanged among the X server, Kerberos
369705b261ecSmrg     * server, and client to figure out if everyone is authorized.
369805b261ecSmrg     * So we don't want to send the connection setup info yet, since
369905b261ecSmrg     * the auth step isn't really done.
370005b261ecSmrg     */
370105b261ecSmrg    if (client->clientState == ClientStateCheckingSecurity)
370205b261ecSmrg	client->clientState = ClientStateCheckedSecurity;
370305b261ecSmrg    else if (client->clientState != ClientStateAuthenticating)
370405b261ecSmrg	return(SendConnSetup(client, reason));
37056747b715Smrg    return Success;
370605b261ecSmrg}
370705b261ecSmrg
37086747b715Smrgvoid
370905b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
371005b261ecSmrg                  XID resId, int errorCode)
371105b261ecSmrg{
371205b261ecSmrg    xError rep;
371305b261ecSmrg
37146747b715Smrg    memset(&rep, 0, sizeof(xError));
371505b261ecSmrg    rep.type = X_Error;
371605b261ecSmrg    rep.errorCode = errorCode;
371705b261ecSmrg    rep.majorCode = majorCode;
371805b261ecSmrg    rep.minorCode = minorCode;
371905b261ecSmrg    rep.resourceID = resId;
372005b261ecSmrg
372105b261ecSmrg    WriteEventsToClient (client, 1, (xEvent *)&rep);
372205b261ecSmrg}
372305b261ecSmrg
372405b261ecSmrgvoid
372505b261ecSmrgMarkClientException(ClientPtr client)
372605b261ecSmrg{
372705b261ecSmrg    client->noClientException = -1;
372805b261ecSmrg}
37296747b715Smrg
37306747b715Smrg/*
37316747b715Smrg * This array encodes the answer to the question "what is the log base 2
37326747b715Smrg * of the number of pixels that fit in a scanline pad unit?"
37336747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
37346747b715Smrg */
37356747b715Smrgstatic int answer[6][4] = {
37366747b715Smrg	/* pad   pad   pad     pad*/
37376747b715Smrg	/*  8     16    32    64 */
37386747b715Smrg
37396747b715Smrg	{   3,     4,    5 ,   6 },	/* 1 bit per pixel */
37406747b715Smrg	{   1,     2,    3 ,   4 },	/* 4 bits per pixel */
37416747b715Smrg	{   0,     1,    2 ,   3 },	/* 8 bits per pixel */
37426747b715Smrg	{   ~0,    0,    1 ,   2 },	/* 16 bits per pixel */
37436747b715Smrg	{   ~0,    ~0,   0 ,   1 },	/* 24 bits per pixel */
37446747b715Smrg	{   ~0,    ~0,   0 ,   1 }	/* 32 bits per pixel */
37456747b715Smrg};
37466747b715Smrg
37476747b715Smrg/*
37486747b715Smrg * This array gives the answer to the question "what is the first index for
37496747b715Smrg * the answer array above given the number of bits per pixel?"
37506747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
37516747b715Smrg */
37526747b715Smrgstatic int indexForBitsPerPixel[ 33 ] = {
37536747b715Smrg	~0, 0, ~0, ~0,	/* 1 bit per pixel */
37546747b715Smrg	1, ~0, ~0, ~0,	/* 4 bits per pixel */
37556747b715Smrg	2, ~0, ~0, ~0,	/* 8 bits per pixel */
37566747b715Smrg	~0,~0, ~0, ~0,
37576747b715Smrg	3, ~0, ~0, ~0,	/* 16 bits per pixel */
37586747b715Smrg	~0,~0, ~0, ~0,
37596747b715Smrg	4, ~0, ~0, ~0,	/* 24 bits per pixel */
37606747b715Smrg	~0,~0, ~0, ~0,
37616747b715Smrg	5		/* 32 bits per pixel */
37626747b715Smrg};
37636747b715Smrg
37646747b715Smrg/*
37656747b715Smrg * This array gives the bytesperPixel value for cases where the number
37666747b715Smrg * of bits per pixel is a multiple of 8 but not a power of 2.
37676747b715Smrg */
37686747b715Smrgstatic int answerBytesPerPixel[ 33 ] = {
37696747b715Smrg	~0, 0, ~0, ~0,	/* 1 bit per pixel */
37706747b715Smrg	0, ~0, ~0, ~0,	/* 4 bits per pixel */
37716747b715Smrg	0, ~0, ~0, ~0,	/* 8 bits per pixel */
37726747b715Smrg	~0,~0, ~0, ~0,
37736747b715Smrg	0, ~0, ~0, ~0,	/* 16 bits per pixel */
37746747b715Smrg	~0,~0, ~0, ~0,
37756747b715Smrg	3, ~0, ~0, ~0,	/* 24 bits per pixel */
37766747b715Smrg	~0,~0, ~0, ~0,
37776747b715Smrg	0		/* 32 bits per pixel */
37786747b715Smrg};
37796747b715Smrg
37806747b715Smrg/*
37816747b715Smrg * This array gives the answer to the question "what is the second index for
37826747b715Smrg * the answer array above given the number of bits per scanline pad unit?"
37836747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
37846747b715Smrg */
37856747b715Smrgstatic int indexForScanlinePad[ 65 ] = {
37866747b715Smrg	~0, ~0, ~0, ~0,
37876747b715Smrg	~0, ~0, ~0, ~0,
37886747b715Smrg	 0, ~0, ~0, ~0,	/* 8 bits per scanline pad unit */
37896747b715Smrg	~0, ~0, ~0, ~0,
37906747b715Smrg	 1, ~0, ~0, ~0,	/* 16 bits per scanline pad unit */
37916747b715Smrg	~0, ~0, ~0, ~0,
37926747b715Smrg	~0, ~0, ~0, ~0,
37936747b715Smrg	~0, ~0, ~0, ~0,
37946747b715Smrg	 2, ~0, ~0, ~0,	/* 32 bits per scanline pad unit */
37956747b715Smrg	~0, ~0, ~0, ~0,
37966747b715Smrg	~0, ~0, ~0, ~0,
37976747b715Smrg	~0, ~0, ~0, ~0,
37986747b715Smrg	~0, ~0, ~0, ~0,
37996747b715Smrg	~0, ~0, ~0, ~0,
38006747b715Smrg	~0, ~0, ~0, ~0,
38016747b715Smrg	~0, ~0, ~0, ~0,
38026747b715Smrg	 3		/* 64 bits per scanline pad unit */
38036747b715Smrg};
38046747b715Smrg
38056747b715Smrg/*
38066747b715Smrg	grow the array of screenRecs if necessary.
38076747b715Smrg	call the device-supplied initialization procedure
38086747b715Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv.
38096747b715Smrg	return the number of successfully installed screens.
38106747b715Smrg
38116747b715Smrg*/
38126747b715Smrg
38136747b715Smrgint
38146747b715SmrgAddScreen(
38156747b715Smrg    Bool	(* pfnInit)(
38166747b715Smrg	int /*index*/,
38176747b715Smrg	ScreenPtr /*pScreen*/,
38186747b715Smrg	int /*argc*/,
38196747b715Smrg	char ** /*argv*/
38206747b715Smrg		),
38216747b715Smrg    int argc,
38226747b715Smrg    char **argv)
38236747b715Smrg{
38246747b715Smrg
38256747b715Smrg    int i;
38266747b715Smrg    int scanlinepad, format, depth, bitsPerPixel, j, k;
38276747b715Smrg    ScreenPtr pScreen;
38286747b715Smrg
38296747b715Smrg    i = screenInfo.numScreens;
38306747b715Smrg    if (i == MAXSCREENS)
38316747b715Smrg	return -1;
38326747b715Smrg
38336747b715Smrg    pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
38346747b715Smrg    if (!pScreen)
38356747b715Smrg	return -1;
38366747b715Smrg
38376747b715Smrg    if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
38386747b715Smrg	free (pScreen);
38396747b715Smrg	return -1;
38406747b715Smrg    }
38416747b715Smrg    pScreen->myNum = i;
38426747b715Smrg    pScreen->totalPixmapSize = 0;	/* computed in CreateScratchPixmapForScreen */
38436747b715Smrg    pScreen->ClipNotify = 0;	/* for R4 ddx compatibility */
38446747b715Smrg    pScreen->CreateScreenResources = 0;
38456747b715Smrg
38466747b715Smrg    /*
38476747b715Smrg     * This loop gets run once for every Screen that gets added,
38486747b715Smrg     * but thats ok.  If the ddx layer initializes the formats
38496747b715Smrg     * one at a time calling AddScreen() after each, then each
38506747b715Smrg     * iteration will make it a little more accurate.  Worst case
38516747b715Smrg     * we do this loop N * numPixmapFormats where N is # of screens.
38526747b715Smrg     * Anyway, this must be called after InitOutput and before the
38536747b715Smrg     * screen init routine is called.
38546747b715Smrg     */
38556747b715Smrg    for (format=0; format<screenInfo.numPixmapFormats; format++)
38566747b715Smrg    {
38576747b715Smrg	depth = screenInfo.formats[format].depth;
38586747b715Smrg	bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
38596747b715Smrg	scanlinepad = screenInfo.formats[format].scanlinePad;
38606747b715Smrg	j = indexForBitsPerPixel[ bitsPerPixel ];
38616747b715Smrg	k = indexForScanlinePad[ scanlinepad ];
38626747b715Smrg	PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
38636747b715Smrg	PixmapWidthPaddingInfo[ depth ].padRoundUp =
38646747b715Smrg	    (scanlinepad/bitsPerPixel) - 1;
38656747b715Smrg	j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
38666747b715Smrg	PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
38676747b715Smrg	PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
38686747b715Smrg	if (answerBytesPerPixel[bitsPerPixel])
38696747b715Smrg	{
38706747b715Smrg	    PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
38716747b715Smrg	    PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
38726747b715Smrg		answerBytesPerPixel[bitsPerPixel];
38736747b715Smrg	}
38746747b715Smrg	else
38756747b715Smrg	{
38766747b715Smrg	    PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
38776747b715Smrg	}
38786747b715Smrg    }
38796747b715Smrg
38806747b715Smrg    /* This is where screen specific stuff gets initialized.  Load the
38816747b715Smrg       screen structure, call the hardware, whatever.
38826747b715Smrg       This is also where the default colormap should be allocated and
38836747b715Smrg       also pixel values for blackPixel, whitePixel, and the cursor
38846747b715Smrg       Note that InitScreen is NOT allowed to modify argc, argv, or
38856747b715Smrg       any of the strings pointed to by argv.  They may be passed to
38866747b715Smrg       multiple screens.
38876747b715Smrg    */
38886747b715Smrg    screenInfo.screens[i] = pScreen;
38896747b715Smrg    screenInfo.numScreens++;
38906747b715Smrg    if (!(*pfnInit)(i, pScreen, argc, argv))
38916747b715Smrg    {
38926747b715Smrg	dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
38936747b715Smrg	free(pScreen);
38946747b715Smrg	screenInfo.numScreens--;
38956747b715Smrg	return -1;
38966747b715Smrg    }
38976747b715Smrg
38986747b715Smrg    dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0);
38996747b715Smrg
39006747b715Smrg    return i;
39016747b715Smrg}
3902