dispatch.c revision 0b0d8713
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;
142105b261ecSmrg    }
14226747b715Smrg    return BadAlloc;
142305b261ecSmrg}
142405b261ecSmrg
142505b261ecSmrgint
142605b261ecSmrgProcFreePixmap(ClientPtr client)
142705b261ecSmrg{
142805b261ecSmrg    PixmapPtr pMap;
14294642e01fSmrg    int rc;
143005b261ecSmrg    REQUEST(xResourceReq);
143105b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
14324642e01fSmrg
1433b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client,
14344642e01fSmrg			   DixDestroyAccess);
14354642e01fSmrg    if (rc == Success)
143605b261ecSmrg    {
143705b261ecSmrg	FreeResource(stuff->id, RT_NONE);
14386747b715Smrg	return Success;
143905b261ecSmrg    }
144005b261ecSmrg    else
144105b261ecSmrg    {
144205b261ecSmrg	client->errorValue = stuff->id;
14436747b715Smrg	return rc;
144405b261ecSmrg    }
144505b261ecSmrg}
144605b261ecSmrg
144705b261ecSmrgint
144805b261ecSmrgProcCreateGC(ClientPtr client)
144905b261ecSmrg{
145005b261ecSmrg    int error, rc;
145105b261ecSmrg    GC *pGC;
145205b261ecSmrg    DrawablePtr pDraw;
145305b261ecSmrg    unsigned len;
145405b261ecSmrg    REQUEST(xCreateGCReq);
145505b261ecSmrg
145605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
145705b261ecSmrg    client->errorValue = stuff->gc;
145805b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->gc, client);
14594642e01fSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
14604642e01fSmrg			   DixGetAttrAccess);
146105b261ecSmrg    if (rc != Success)
146205b261ecSmrg	return rc;
146305b261ecSmrg
14646747b715Smrg    len = client->req_len -  bytes_to_int32(sizeof(xCreateGCReq));
146505b261ecSmrg    if (len != Ones(stuff->mask))
146605b261ecSmrg        return BadLength;
14674642e01fSmrg    pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
14684642e01fSmrg			 stuff->gc, client);
146905b261ecSmrg    if (error != Success)
147005b261ecSmrg        return error;
147105b261ecSmrg    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
14726747b715Smrg	return BadAlloc;
14736747b715Smrg    return Success;
147405b261ecSmrg}
147505b261ecSmrg
147605b261ecSmrgint
147705b261ecSmrgProcChangeGC(ClientPtr client)
147805b261ecSmrg{
147905b261ecSmrg    GC *pGC;
148005b261ecSmrg    int result;
148105b261ecSmrg    unsigned len;
148205b261ecSmrg    REQUEST(xChangeGCReq);
148305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
148405b261ecSmrg
14854642e01fSmrg    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
148605b261ecSmrg    if (result != Success)
148705b261ecSmrg	return result;
148805b261ecSmrg
14896747b715Smrg    len = client->req_len -  bytes_to_int32(sizeof(xChangeGCReq));
149005b261ecSmrg    if (len != Ones(stuff->mask))
149105b261ecSmrg        return BadLength;
149205b261ecSmrg
14936747b715Smrg    return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
149405b261ecSmrg}
149505b261ecSmrg
149605b261ecSmrgint
149705b261ecSmrgProcCopyGC(ClientPtr client)
149805b261ecSmrg{
149905b261ecSmrg    GC *dstGC;
150005b261ecSmrg    GC *pGC;
150105b261ecSmrg    int result;
150205b261ecSmrg    REQUEST(xCopyGCReq);
150305b261ecSmrg    REQUEST_SIZE_MATCH(xCopyGCReq);
150405b261ecSmrg
15054642e01fSmrg    result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
150605b261ecSmrg    if (result != Success)
150705b261ecSmrg	return result;
15084642e01fSmrg    result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
150905b261ecSmrg    if (result != Success)
151005b261ecSmrg	return result;
151105b261ecSmrg    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
15126747b715Smrg        return BadMatch;
15136747b715Smrg    if (stuff->mask & ~GCAllBits)
151405b261ecSmrg    {
15156747b715Smrg	client->errorValue = stuff->mask;
15166747b715Smrg	return BadValue;
151705b261ecSmrg    }
15186747b715Smrg    return CopyGC(pGC, dstGC, stuff->mask);
151905b261ecSmrg}
152005b261ecSmrg
152105b261ecSmrgint
152205b261ecSmrgProcSetDashes(ClientPtr client)
152305b261ecSmrg{
152405b261ecSmrg    GC *pGC;
152505b261ecSmrg    int result;
152605b261ecSmrg    REQUEST(xSetDashesReq);
152705b261ecSmrg
152805b261ecSmrg    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
152905b261ecSmrg    if (stuff->nDashes == 0)
153005b261ecSmrg    {
153105b261ecSmrg	 client->errorValue = 0;
153205b261ecSmrg         return BadValue;
153305b261ecSmrg    }
153405b261ecSmrg
15354642e01fSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
153605b261ecSmrg    if (result != Success)
153705b261ecSmrg	return result;
153805b261ecSmrg
15396747b715Smrg    /* If there's an error, either there's no sensible errorValue,
15406747b715Smrg     * or there was a dash segment of 0. */
15416747b715Smrg    client->errorValue = 0;
15426747b715Smrg    return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
154305b261ecSmrg		       (unsigned char *)&stuff[1]);
154405b261ecSmrg}
154505b261ecSmrg
154605b261ecSmrgint
154705b261ecSmrgProcSetClipRectangles(ClientPtr client)
154805b261ecSmrg{
154905b261ecSmrg    int	nr, result;
155005b261ecSmrg    GC *pGC;
155105b261ecSmrg    REQUEST(xSetClipRectanglesReq);
155205b261ecSmrg
155305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
155405b261ecSmrg    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
155505b261ecSmrg	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
155605b261ecSmrg    {
155705b261ecSmrg	client->errorValue = stuff->ordering;
155805b261ecSmrg        return BadValue;
155905b261ecSmrg    }
15604642e01fSmrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
156105b261ecSmrg    if (result != Success)
156205b261ecSmrg	return result;
156305b261ecSmrg
156405b261ecSmrg    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
156505b261ecSmrg    if (nr & 4)
15666747b715Smrg	return BadLength;
156705b261ecSmrg    nr >>= 3;
15686747b715Smrg    return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
156905b261ecSmrg			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
157005b261ecSmrg}
157105b261ecSmrg
157205b261ecSmrgint
157305b261ecSmrgProcFreeGC(ClientPtr client)
157405b261ecSmrg{
157505b261ecSmrg    GC *pGC;
157605b261ecSmrg    int rc;
157705b261ecSmrg    REQUEST(xResourceReq);
157805b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
157905b261ecSmrg
158005b261ecSmrg    rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
158105b261ecSmrg    if (rc != Success)
158205b261ecSmrg	return rc;
158305b261ecSmrg
158405b261ecSmrg    FreeResource(stuff->id, RT_NONE);
15856747b715Smrg    return Success;
158605b261ecSmrg}
158705b261ecSmrg
158805b261ecSmrgint
158905b261ecSmrgProcClearToBackground(ClientPtr client)
159005b261ecSmrg{
159105b261ecSmrg    REQUEST(xClearAreaReq);
159205b261ecSmrg    WindowPtr pWin;
159305b261ecSmrg    int rc;
159405b261ecSmrg
159505b261ecSmrg    REQUEST_SIZE_MATCH(xClearAreaReq);
159605b261ecSmrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
159705b261ecSmrg    if (rc != Success)
159805b261ecSmrg        return rc;
159905b261ecSmrg    if (pWin->drawable.class == InputOnly)
160005b261ecSmrg    {
160105b261ecSmrg	client->errorValue = stuff->window;
16026747b715Smrg	return BadMatch;
160305b261ecSmrg    }
160405b261ecSmrg    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
160505b261ecSmrg    {
160605b261ecSmrg	client->errorValue = stuff->exposures;
16076747b715Smrg        return BadValue;
160805b261ecSmrg    }
160905b261ecSmrg    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
161005b261ecSmrg			       stuff->width, stuff->height,
161105b261ecSmrg			       (Bool)stuff->exposures);
16126747b715Smrg    return Success;
161305b261ecSmrg}
161405b261ecSmrg
161505b261ecSmrgint
161605b261ecSmrgProcCopyArea(ClientPtr client)
161705b261ecSmrg{
161805b261ecSmrg    DrawablePtr pDst;
161905b261ecSmrg    DrawablePtr pSrc;
162005b261ecSmrg    GC *pGC;
162105b261ecSmrg    REQUEST(xCopyAreaReq);
162205b261ecSmrg    RegionPtr pRgn;
162305b261ecSmrg    int rc;
162405b261ecSmrg
162505b261ecSmrg    REQUEST_SIZE_MATCH(xCopyAreaReq);
162605b261ecSmrg
16274642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
162805b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
162905b261ecSmrg    {
163005b261ecSmrg	rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
163105b261ecSmrg				 DixReadAccess);
163205b261ecSmrg	if (rc != Success)
163305b261ecSmrg	    return rc;
163405b261ecSmrg	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
163505b261ecSmrg	{
163605b261ecSmrg	    client->errorValue = stuff->dstDrawable;
16376747b715Smrg	    return BadMatch;
163805b261ecSmrg	}
163905b261ecSmrg    }
164005b261ecSmrg    else
164105b261ecSmrg        pSrc = pDst;
164205b261ecSmrg
164305b261ecSmrg    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
164405b261ecSmrg				 stuff->width, stuff->height,
164505b261ecSmrg				 stuff->dstX, stuff->dstY);
164605b261ecSmrg    if (pGC->graphicsExposures)
164705b261ecSmrg    {
164805b261ecSmrg	(*pDst->pScreen->SendGraphicsExpose)
164905b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
165005b261ecSmrg	if (pRgn)
16516747b715Smrg	    RegionDestroy(pRgn);
165205b261ecSmrg    }
165305b261ecSmrg
16546747b715Smrg    return Success;
165505b261ecSmrg}
165605b261ecSmrg
165705b261ecSmrgint
165805b261ecSmrgProcCopyPlane(ClientPtr client)
165905b261ecSmrg{
166005b261ecSmrg    DrawablePtr psrcDraw, pdstDraw;
166105b261ecSmrg    GC *pGC;
166205b261ecSmrg    REQUEST(xCopyPlaneReq);
166305b261ecSmrg    RegionPtr pRgn;
166405b261ecSmrg    int rc;
166505b261ecSmrg
166605b261ecSmrg    REQUEST_SIZE_MATCH(xCopyPlaneReq);
166705b261ecSmrg
16684642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
166905b261ecSmrg    if (stuff->dstDrawable != stuff->srcDrawable)
167005b261ecSmrg    {
167105b261ecSmrg	rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
167205b261ecSmrg			       DixReadAccess);
167305b261ecSmrg	if (rc != Success)
167405b261ecSmrg	    return rc;
167505b261ecSmrg
167605b261ecSmrg	if (pdstDraw->pScreen != psrcDraw->pScreen)
167705b261ecSmrg	{
167805b261ecSmrg	    client->errorValue = stuff->dstDrawable;
16796747b715Smrg	    return BadMatch;
168005b261ecSmrg	}
168105b261ecSmrg    }
168205b261ecSmrg    else
168305b261ecSmrg        psrcDraw = pdstDraw;
168405b261ecSmrg
168505b261ecSmrg    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
168605b261ecSmrg    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
168705b261ecSmrg       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
168805b261ecSmrg    {
168905b261ecSmrg       client->errorValue = stuff->bitPlane;
16906747b715Smrg       return BadValue;
169105b261ecSmrg    }
169205b261ecSmrg
169305b261ecSmrg    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
169405b261ecSmrg				 stuff->width, stuff->height,
169505b261ecSmrg				 stuff->dstX, stuff->dstY, stuff->bitPlane);
169605b261ecSmrg    if (pGC->graphicsExposures)
169705b261ecSmrg    {
169805b261ecSmrg	(*pdstDraw->pScreen->SendGraphicsExpose)
169905b261ecSmrg 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
170005b261ecSmrg	if (pRgn)
17016747b715Smrg	    RegionDestroy(pRgn);
170205b261ecSmrg    }
17036747b715Smrg    return Success;
170405b261ecSmrg}
170505b261ecSmrg
170605b261ecSmrgint
170705b261ecSmrgProcPolyPoint(ClientPtr client)
170805b261ecSmrg{
170905b261ecSmrg    int npoint;
171005b261ecSmrg    GC *pGC;
171105b261ecSmrg    DrawablePtr pDraw;
171205b261ecSmrg    REQUEST(xPolyPointReq);
171305b261ecSmrg
171405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
171505b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
171605b261ecSmrg	(stuff->coordMode != CoordModePrevious))
171705b261ecSmrg    {
171805b261ecSmrg	client->errorValue = stuff->coordMode;
171905b261ecSmrg        return BadValue;
172005b261ecSmrg    }
17214642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
17226747b715Smrg    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
172305b261ecSmrg    if (npoint)
172405b261ecSmrg        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
172505b261ecSmrg			  (xPoint *) &stuff[1]);
17266747b715Smrg    return Success;
172705b261ecSmrg}
172805b261ecSmrg
172905b261ecSmrgint
173005b261ecSmrgProcPolyLine(ClientPtr client)
173105b261ecSmrg{
173205b261ecSmrg    int npoint;
173305b261ecSmrg    GC *pGC;
173405b261ecSmrg    DrawablePtr pDraw;
173505b261ecSmrg    REQUEST(xPolyLineReq);
173605b261ecSmrg
173705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
173805b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
173905b261ecSmrg	(stuff->coordMode != CoordModePrevious))
174005b261ecSmrg    {
174105b261ecSmrg	client->errorValue = stuff->coordMode;
174205b261ecSmrg        return BadValue;
174305b261ecSmrg    }
17444642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
17456747b715Smrg    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
174605b261ecSmrg    if (npoint > 1)
174705b261ecSmrg	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
174805b261ecSmrg			      (DDXPointPtr) &stuff[1]);
17496747b715Smrg    return Success;
175005b261ecSmrg}
175105b261ecSmrg
175205b261ecSmrgint
175305b261ecSmrgProcPolySegment(ClientPtr client)
175405b261ecSmrg{
175505b261ecSmrg    int nsegs;
175605b261ecSmrg    GC *pGC;
175705b261ecSmrg    DrawablePtr pDraw;
175805b261ecSmrg    REQUEST(xPolySegmentReq);
175905b261ecSmrg
176005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
17614642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
176205b261ecSmrg    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
176305b261ecSmrg    if (nsegs & 4)
17646747b715Smrg	return BadLength;
176505b261ecSmrg    nsegs >>= 3;
176605b261ecSmrg    if (nsegs)
176705b261ecSmrg        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
17686747b715Smrg    return Success;
176905b261ecSmrg}
177005b261ecSmrg
177105b261ecSmrgint
177205b261ecSmrgProcPolyRectangle (ClientPtr client)
177305b261ecSmrg{
177405b261ecSmrg    int nrects;
177505b261ecSmrg    GC *pGC;
177605b261ecSmrg    DrawablePtr pDraw;
177705b261ecSmrg    REQUEST(xPolyRectangleReq);
177805b261ecSmrg
177905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
17804642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
178105b261ecSmrg    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
178205b261ecSmrg    if (nrects & 4)
17836747b715Smrg	return BadLength;
178405b261ecSmrg    nrects >>= 3;
178505b261ecSmrg    if (nrects)
178605b261ecSmrg        (*pGC->ops->PolyRectangle)(pDraw, pGC,
178705b261ecSmrg		    nrects, (xRectangle *) &stuff[1]);
17886747b715Smrg    return Success;
178905b261ecSmrg}
179005b261ecSmrg
179105b261ecSmrgint
179205b261ecSmrgProcPolyArc(ClientPtr client)
179305b261ecSmrg{
179405b261ecSmrg    int		narcs;
179505b261ecSmrg    GC *pGC;
179605b261ecSmrg    DrawablePtr pDraw;
179705b261ecSmrg    REQUEST(xPolyArcReq);
179805b261ecSmrg
179905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
18004642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
180105b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
180205b261ecSmrg    if (narcs % sizeof(xArc))
18036747b715Smrg	return BadLength;
180405b261ecSmrg    narcs /= sizeof(xArc);
180505b261ecSmrg    if (narcs)
180605b261ecSmrg        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
18076747b715Smrg    return Success;
180805b261ecSmrg}
180905b261ecSmrg
181005b261ecSmrgint
181105b261ecSmrgProcFillPoly(ClientPtr client)
181205b261ecSmrg{
181305b261ecSmrg    int          things;
181405b261ecSmrg    GC *pGC;
181505b261ecSmrg    DrawablePtr pDraw;
181605b261ecSmrg    REQUEST(xFillPolyReq);
181705b261ecSmrg
181805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
181905b261ecSmrg    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
182005b261ecSmrg	(stuff->shape != Convex))
182105b261ecSmrg    {
182205b261ecSmrg	client->errorValue = stuff->shape;
182305b261ecSmrg        return BadValue;
182405b261ecSmrg    }
182505b261ecSmrg    if ((stuff->coordMode != CoordModeOrigin) &&
182605b261ecSmrg	(stuff->coordMode != CoordModePrevious))
182705b261ecSmrg    {
182805b261ecSmrg	client->errorValue = stuff->coordMode;
182905b261ecSmrg        return BadValue;
183005b261ecSmrg    }
183105b261ecSmrg
18324642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
18336747b715Smrg    things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
183405b261ecSmrg    if (things)
183505b261ecSmrg        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
183605b261ecSmrg			 stuff->coordMode, things,
183705b261ecSmrg			 (DDXPointPtr) &stuff[1]);
18386747b715Smrg    return Success;
183905b261ecSmrg}
184005b261ecSmrg
184105b261ecSmrgint
184205b261ecSmrgProcPolyFillRectangle(ClientPtr client)
184305b261ecSmrg{
184405b261ecSmrg    int             things;
184505b261ecSmrg    GC *pGC;
184605b261ecSmrg    DrawablePtr pDraw;
184705b261ecSmrg    REQUEST(xPolyFillRectangleReq);
184805b261ecSmrg
184905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
18504642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
185105b261ecSmrg    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
185205b261ecSmrg    if (things & 4)
18536747b715Smrg	return BadLength;
185405b261ecSmrg    things >>= 3;
185505b261ecSmrg
185605b261ecSmrg    if (things)
185705b261ecSmrg        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
185805b261ecSmrg		      (xRectangle *) &stuff[1]);
18596747b715Smrg    return Success;
186005b261ecSmrg}
186105b261ecSmrg
186205b261ecSmrgint
186305b261ecSmrgProcPolyFillArc(ClientPtr client)
186405b261ecSmrg{
186505b261ecSmrg    int		narcs;
186605b261ecSmrg    GC *pGC;
186705b261ecSmrg    DrawablePtr pDraw;
186805b261ecSmrg    REQUEST(xPolyFillArcReq);
186905b261ecSmrg
187005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
18714642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
187205b261ecSmrg    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
187305b261ecSmrg    if (narcs % sizeof(xArc))
18746747b715Smrg	return BadLength;
187505b261ecSmrg    narcs /= sizeof(xArc);
187605b261ecSmrg    if (narcs)
187705b261ecSmrg        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
18786747b715Smrg    return Success;
187905b261ecSmrg}
188005b261ecSmrg
188105b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
188205b261ecSmrg
188305b261ecSmrgint
188405b261ecSmrgServerOrder (void)
188505b261ecSmrg{
188605b261ecSmrg    int	    whichbyte = 1;
188705b261ecSmrg
188805b261ecSmrg    if (*((char *) &whichbyte))
188905b261ecSmrg	return LSBFirst;
189005b261ecSmrg    return MSBFirst;
189105b261ecSmrg}
189205b261ecSmrg
189305b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
189405b261ecSmrg
189505b261ecSmrgvoid
189605b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order)
189705b261ecSmrg{
189805b261ecSmrg    switch (bpp) {
189905b261ecSmrg    case 1:	/* yuck */
190005b261ecSmrg	if (BITMAP_BIT_ORDER != order)
190105b261ecSmrg	    BitOrderInvert ((unsigned char *) base, nbytes);
190205b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
190305b261ecSmrg	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
190405b261ecSmrg#endif
190505b261ecSmrg	break;
190605b261ecSmrg    case 4:
190705b261ecSmrg	break;  /* yuck */
190805b261ecSmrg    case 8:
190905b261ecSmrg	break;
191005b261ecSmrg    case 16:
191105b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
191205b261ecSmrg	    TwoByteSwap ((unsigned char *) base, nbytes);
191305b261ecSmrg	break;
191405b261ecSmrg    case 32:
191505b261ecSmrg	if (IMAGE_BYTE_ORDER != order)
191605b261ecSmrg	    FourByteSwap ((unsigned char *) base, nbytes);
191705b261ecSmrg	break;
191805b261ecSmrg    }
191905b261ecSmrg}
192005b261ecSmrg#else
192105b261ecSmrg#define ReformatImage(b,n,bpp,o)
192205b261ecSmrg#endif
192305b261ecSmrg
192405b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to
192505b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
192605b261ecSmrg * to use internally. Removes need for internal alignment checking.
192705b261ecSmrg * All of the PutImage functions could be changed individually, but
192805b261ecSmrg * as currently written, they call other routines which require things
192905b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here.
193005b261ecSmrg * If an image would be padded differently for 64- versus 32-, then
193105b261ecSmrg * copy each scanline to a 64-bit padded scanline.
193205b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit
193305b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction.
193405b261ecSmrg */
193505b261ecSmrgint
193605b261ecSmrgProcPutImage(ClientPtr client)
193705b261ecSmrg{
193805b261ecSmrg    GC *pGC;
193905b261ecSmrg    DrawablePtr pDraw;
194005b261ecSmrg    long	length; 	/* length of scanline server padded */
194105b261ecSmrg    long 	lengthProto; 	/* length of scanline protocol padded */
194205b261ecSmrg    char	*tmpImage;
194305b261ecSmrg    REQUEST(xPutImageReq);
194405b261ecSmrg
194505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPutImageReq);
19464642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
194705b261ecSmrg    if (stuff->format == XYBitmap)
194805b261ecSmrg    {
194905b261ecSmrg        if ((stuff->depth != 1) ||
195005b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
195105b261ecSmrg            return BadMatch;
195205b261ecSmrg        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
195305b261ecSmrg    }
195405b261ecSmrg    else if (stuff->format == XYPixmap)
195505b261ecSmrg    {
195605b261ecSmrg        if ((pDraw->depth != stuff->depth) ||
195705b261ecSmrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
195805b261ecSmrg            return BadMatch;
195905b261ecSmrg        length      = BitmapBytePad(stuff->width + stuff->leftPad);
196005b261ecSmrg	length      *= stuff->depth;
196105b261ecSmrg    }
196205b261ecSmrg    else if (stuff->format == ZPixmap)
196305b261ecSmrg    {
196405b261ecSmrg        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
196505b261ecSmrg            return BadMatch;
196605b261ecSmrg        length      = PixmapBytePad(stuff->width, stuff->depth);
196705b261ecSmrg    }
196805b261ecSmrg    else
196905b261ecSmrg    {
197005b261ecSmrg	client->errorValue = stuff->format;
197105b261ecSmrg        return BadValue;
197205b261ecSmrg    }
197305b261ecSmrg
197405b261ecSmrg    tmpImage = (char *)&stuff[1];
197505b261ecSmrg    lengthProto = length;
19760b0d8713Smrg
19770b0d8713Smrg    if (lengthProto >= (INT32_MAX / stuff->height))
19780b0d8713Smrg        return BadLength;
197905b261ecSmrg
19806747b715Smrg    if ((bytes_to_int32(lengthProto * stuff->height) +
19816747b715Smrg	bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
198205b261ecSmrg	return BadLength;
198305b261ecSmrg
198405b261ecSmrg    ReformatImage (tmpImage, lengthProto * stuff->height,
198505b261ecSmrg		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
198605b261ecSmrg		   ClientOrder(client));
198705b261ecSmrg
198805b261ecSmrg    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
198905b261ecSmrg		  stuff->width, stuff->height,
199005b261ecSmrg		  stuff->leftPad, stuff->format, tmpImage);
199105b261ecSmrg
19926747b715Smrg     return Success;
199305b261ecSmrg}
199405b261ecSmrg
199505b261ecSmrgstatic int
199605b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable,
199705b261ecSmrg           int x, int y, int width, int height,
199805b261ecSmrg           Mask planemask, xGetImageReply **im_return)
199905b261ecSmrg{
20006747b715Smrg    DrawablePtr		pDraw, pBoundingDraw;
200105b261ecSmrg    int			nlines, linesPerBuf, rc;
20026747b715Smrg    int			linesDone;
20036747b715Smrg    /* coordinates relative to the bounding drawable */
20046747b715Smrg    int			relx, rely;
200505b261ecSmrg    long		widthBytesLine, length;
200605b261ecSmrg    Mask		plane = 0;
200705b261ecSmrg    char		*pBuf;
200805b261ecSmrg    xGetImageReply	xgi;
200905b261ecSmrg    RegionPtr pVisibleRegion = NULL;
201005b261ecSmrg
201105b261ecSmrg    if ((format != XYPixmap) && (format != ZPixmap))
201205b261ecSmrg    {
201305b261ecSmrg	client->errorValue = format;
20146747b715Smrg        return BadValue;
201505b261ecSmrg    }
201605b261ecSmrg    rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
201705b261ecSmrg    if (rc != Success)
201805b261ecSmrg	return rc;
201905b261ecSmrg
20206747b715Smrg    memset(&xgi, 0, sizeof(xGetImageReply));
20216747b715Smrg
20226747b715Smrg    relx = x;
20236747b715Smrg    rely = y;
20246747b715Smrg
202505b261ecSmrg    if(pDraw->type == DRAWABLE_WINDOW)
202605b261ecSmrg    {
20276747b715Smrg	WindowPtr pWin = (WindowPtr)pDraw;
20286747b715Smrg
20296747b715Smrg	/* "If the drawable is a window, the window must be viewable ... or a
20306747b715Smrg	 * BadMatch error results" */
20316747b715Smrg	if (!pWin->viewable)
20326747b715Smrg	    return BadMatch;
20336747b715Smrg
20346747b715Smrg	relx += pDraw->x;
20356747b715Smrg	rely += pDraw->y;
20366747b715Smrg
20376747b715Smrg	if (pDraw->pScreen->GetWindowPixmap) {
20386747b715Smrg	    PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
20396747b715Smrg
20406747b715Smrg	    pBoundingDraw = &pPix->drawable;
20416747b715Smrg#ifdef COMPOSITE
20426747b715Smrg	    relx -= pPix->screen_x;
20436747b715Smrg	    rely -= pPix->screen_y;
20446747b715Smrg#endif
20456747b715Smrg	}
20466747b715Smrg	else
20476747b715Smrg	{
20486747b715Smrg	    pBoundingDraw = (DrawablePtr)pDraw->pScreen->root;
20496747b715Smrg	}
20506747b715Smrg
20516747b715Smrg	xgi.visual = wVisual (pWin);
205205b261ecSmrg    }
205305b261ecSmrg    else
205405b261ecSmrg    {
20556747b715Smrg	pBoundingDraw = pDraw;
205605b261ecSmrg	xgi.visual = None;
205705b261ecSmrg    }
205805b261ecSmrg
20596747b715Smrg    /* "If the drawable is a pixmap, the given rectangle must be wholly
20606747b715Smrg     *  contained within the pixmap, or a BadMatch error results.  If the
20616747b715Smrg     *  drawable is a window [...] it must be the case that if there were no
20626747b715Smrg     *  inferiors or overlapping windows, the specified rectangle of the window
20636747b715Smrg     *  would be fully visible on the screen and wholly contained within the
20646747b715Smrg     *  outside edges of the window, or a BadMatch error results."
20656747b715Smrg     *
20666747b715Smrg     * We relax the window case slightly to mean that the rectangle must exist
20676747b715Smrg     * within the bounds of the window's backing pixmap.  In particular, this
20686747b715Smrg     * means that a GetImage request may succeed or fail with BadMatch depending
20696747b715Smrg     * on whether any of its ancestor windows are redirected.  */
20706747b715Smrg    if(relx < 0 || relx + width > (int)pBoundingDraw->width ||
20716747b715Smrg       rely < 0 || rely + height > (int)pBoundingDraw->height)
20726747b715Smrg	return BadMatch;
20736747b715Smrg
207405b261ecSmrg    xgi.type = X_Reply;
207505b261ecSmrg    xgi.sequenceNumber = client->sequence;
207605b261ecSmrg    xgi.depth = pDraw->depth;
207705b261ecSmrg    if(format == ZPixmap)
207805b261ecSmrg    {
207905b261ecSmrg	widthBytesLine = PixmapBytePad(width, pDraw->depth);
208005b261ecSmrg	length = widthBytesLine * height;
208105b261ecSmrg
208205b261ecSmrg    }
208305b261ecSmrg    else
208405b261ecSmrg    {
208505b261ecSmrg	widthBytesLine = BitmapBytePad(width);
208605b261ecSmrg	plane = ((Mask)1) << (pDraw->depth - 1);
208705b261ecSmrg	/* only planes asked for */
208805b261ecSmrg	length = widthBytesLine * height *
208905b261ecSmrg		 Ones(planemask & (plane | (plane - 1)));
209005b261ecSmrg
209105b261ecSmrg    }
209205b261ecSmrg
209305b261ecSmrg    xgi.length = length;
209405b261ecSmrg
209505b261ecSmrg    if (im_return) {
20966747b715Smrg	pBuf = calloc(1, sz_xGetImageReply + length);
209705b261ecSmrg	if (!pBuf)
20986747b715Smrg	    return BadAlloc;
209905b261ecSmrg	if (widthBytesLine == 0)
210005b261ecSmrg	    linesPerBuf = 0;
210105b261ecSmrg	else
210205b261ecSmrg	    linesPerBuf = height;
210305b261ecSmrg	*im_return = (xGetImageReply *)pBuf;
210405b261ecSmrg	*(xGetImageReply *)pBuf = xgi;
210505b261ecSmrg	pBuf += sz_xGetImageReply;
210605b261ecSmrg    } else {
21076747b715Smrg	xgi.length = bytes_to_int32(xgi.length);
210805b261ecSmrg	if (widthBytesLine == 0 || height == 0)
210905b261ecSmrg	    linesPerBuf = 0;
211005b261ecSmrg	else if (widthBytesLine >= IMAGE_BUFSIZE)
211105b261ecSmrg	    linesPerBuf = 1;
211205b261ecSmrg	else
211305b261ecSmrg	{
211405b261ecSmrg	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
211505b261ecSmrg	    if (linesPerBuf > height)
211605b261ecSmrg		linesPerBuf = height;
211705b261ecSmrg	}
211805b261ecSmrg	length = linesPerBuf * widthBytesLine;
211905b261ecSmrg	if (linesPerBuf < height)
212005b261ecSmrg	{
212105b261ecSmrg	    /* we have to make sure intermediate buffers don't need padding */
212205b261ecSmrg	    while ((linesPerBuf > 1) &&
212305b261ecSmrg		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
212405b261ecSmrg	    {
212505b261ecSmrg		linesPerBuf--;
212605b261ecSmrg		length -= widthBytesLine;
212705b261ecSmrg	    }
212805b261ecSmrg	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
212905b261ecSmrg	    {
213005b261ecSmrg		linesPerBuf++;
213105b261ecSmrg		length += widthBytesLine;
213205b261ecSmrg	    }
213305b261ecSmrg	}
21346747b715Smrg	if(!(pBuf = calloc(1, length)))
21356747b715Smrg	    return BadAlloc;
213605b261ecSmrg	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
213705b261ecSmrg    }
213805b261ecSmrg
21394642e01fSmrg    if (pDraw->type == DRAWABLE_WINDOW)
214005b261ecSmrg    {
214105b261ecSmrg	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
214205b261ecSmrg	if (pVisibleRegion)
214305b261ecSmrg	{
21446747b715Smrg	    RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
214505b261ecSmrg	}
214605b261ecSmrg    }
214705b261ecSmrg
214805b261ecSmrg    if (linesPerBuf == 0)
214905b261ecSmrg    {
215005b261ecSmrg	/* nothing to do */
215105b261ecSmrg    }
215205b261ecSmrg    else if (format == ZPixmap)
215305b261ecSmrg    {
215405b261ecSmrg        linesDone = 0;
215505b261ecSmrg        while (height - linesDone > 0)
215605b261ecSmrg        {
215705b261ecSmrg	    nlines = min(linesPerBuf, height - linesDone);
215805b261ecSmrg	    (*pDraw->pScreen->GetImage) (pDraw,
215905b261ecSmrg	                                 x,
216005b261ecSmrg				         y + linesDone,
216105b261ecSmrg				         width,
216205b261ecSmrg				         nlines,
216305b261ecSmrg				         format,
216405b261ecSmrg				         planemask,
216505b261ecSmrg				         (pointer) pBuf);
216605b261ecSmrg	    if (pVisibleRegion)
216705b261ecSmrg		XaceCensorImage(client, pVisibleRegion, widthBytesLine,
216805b261ecSmrg			pDraw, x, y + linesDone, width,
216905b261ecSmrg			nlines, format, pBuf);
217005b261ecSmrg
217105b261ecSmrg	    /* Note that this is NOT a call to WriteSwappedDataToClient,
217205b261ecSmrg               as we do NOT byte swap */
217305b261ecSmrg	    if (!im_return)
217405b261ecSmrg	    {
217505b261ecSmrg		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
217605b261ecSmrg			       BitsPerPixel (pDraw->depth),
217705b261ecSmrg			       ClientOrder(client));
217805b261ecSmrg
217905b261ecSmrg/* Don't split me, gcc pukes when you do */
218005b261ecSmrg		(void)WriteToClient(client,
218105b261ecSmrg				    (int)(nlines * widthBytesLine),
218205b261ecSmrg				    pBuf);
218305b261ecSmrg	    }
218405b261ecSmrg	    linesDone += nlines;
218505b261ecSmrg        }
218605b261ecSmrg    }
218705b261ecSmrg    else /* XYPixmap */
218805b261ecSmrg    {
218905b261ecSmrg        for (; plane; plane >>= 1)
219005b261ecSmrg	{
219105b261ecSmrg	    if (planemask & plane)
219205b261ecSmrg	    {
219305b261ecSmrg	        linesDone = 0;
219405b261ecSmrg	        while (height - linesDone > 0)
219505b261ecSmrg	        {
219605b261ecSmrg		    nlines = min(linesPerBuf, height - linesDone);
219705b261ecSmrg	            (*pDraw->pScreen->GetImage) (pDraw,
219805b261ecSmrg	                                         x,
219905b261ecSmrg				                 y + linesDone,
220005b261ecSmrg				                 width,
220105b261ecSmrg				                 nlines,
220205b261ecSmrg				                 format,
220305b261ecSmrg				                 plane,
220405b261ecSmrg				                 (pointer)pBuf);
220505b261ecSmrg		    if (pVisibleRegion)
220605b261ecSmrg			XaceCensorImage(client, pVisibleRegion,
220705b261ecSmrg				widthBytesLine,
220805b261ecSmrg				pDraw, x, y + linesDone, width,
220905b261ecSmrg				nlines, format, pBuf);
221005b261ecSmrg
221105b261ecSmrg		    /* Note: NOT a call to WriteSwappedDataToClient,
221205b261ecSmrg		       as we do NOT byte swap */
221305b261ecSmrg		    if (im_return) {
221405b261ecSmrg			pBuf += nlines * widthBytesLine;
221505b261ecSmrg		    } else {
221605b261ecSmrg			ReformatImage (pBuf,
221705b261ecSmrg				       (int)(nlines * widthBytesLine),
221805b261ecSmrg				       1,
221905b261ecSmrg				       ClientOrder (client));
222005b261ecSmrg
222105b261ecSmrg/* Don't split me, gcc pukes when you do */
222205b261ecSmrg			(void)WriteToClient(client,
222305b261ecSmrg					(int)(nlines * widthBytesLine),
222405b261ecSmrg					pBuf);
222505b261ecSmrg		    }
222605b261ecSmrg		    linesDone += nlines;
222705b261ecSmrg		}
222805b261ecSmrg            }
222905b261ecSmrg	}
223005b261ecSmrg    }
223105b261ecSmrg    if (pVisibleRegion)
22326747b715Smrg	RegionDestroy(pVisibleRegion);
223305b261ecSmrg    if (!im_return)
22346747b715Smrg	free(pBuf);
22356747b715Smrg    return Success;
223605b261ecSmrg}
223705b261ecSmrg
223805b261ecSmrgint
223905b261ecSmrgProcGetImage(ClientPtr client)
224005b261ecSmrg{
224105b261ecSmrg    REQUEST(xGetImageReq);
224205b261ecSmrg
224305b261ecSmrg    REQUEST_SIZE_MATCH(xGetImageReq);
224405b261ecSmrg
224505b261ecSmrg    return DoGetImage(client, stuff->format, stuff->drawable,
224605b261ecSmrg		      stuff->x, stuff->y,
224705b261ecSmrg		      (int)stuff->width, (int)stuff->height,
224805b261ecSmrg		      stuff->planeMask, (xGetImageReply **)NULL);
224905b261ecSmrg}
225005b261ecSmrg
225105b261ecSmrgint
225205b261ecSmrgProcPolyText(ClientPtr client)
225305b261ecSmrg{
225405b261ecSmrg    int	err;
225505b261ecSmrg    REQUEST(xPolyTextReq);
225605b261ecSmrg    DrawablePtr pDraw;
225705b261ecSmrg    GC *pGC;
225805b261ecSmrg
225905b261ecSmrg    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
22604642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
226105b261ecSmrg
226205b261ecSmrg    err = PolyText(client,
226305b261ecSmrg		   pDraw,
226405b261ecSmrg		   pGC,
226505b261ecSmrg		   (unsigned char *)&stuff[1],
226605b261ecSmrg		   ((unsigned char *) stuff) + (client->req_len << 2),
226705b261ecSmrg		   stuff->x,
226805b261ecSmrg		   stuff->y,
226905b261ecSmrg		   stuff->reqType,
227005b261ecSmrg		   stuff->drawable);
227105b261ecSmrg
227205b261ecSmrg    if (err == Success)
227305b261ecSmrg    {
22746747b715Smrg	return Success;
227505b261ecSmrg    }
227605b261ecSmrg    else
227705b261ecSmrg	return err;
227805b261ecSmrg}
227905b261ecSmrg
228005b261ecSmrgint
228105b261ecSmrgProcImageText8(ClientPtr client)
228205b261ecSmrg{
228305b261ecSmrg    int	err;
228405b261ecSmrg    DrawablePtr pDraw;
228505b261ecSmrg    GC *pGC;
228605b261ecSmrg
228705b261ecSmrg    REQUEST(xImageTextReq);
228805b261ecSmrg
228905b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
22904642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
229105b261ecSmrg
229205b261ecSmrg    err = ImageText(client,
229305b261ecSmrg		    pDraw,
229405b261ecSmrg		    pGC,
229505b261ecSmrg		    stuff->nChars,
229605b261ecSmrg		    (unsigned char *)&stuff[1],
229705b261ecSmrg		    stuff->x,
229805b261ecSmrg		    stuff->y,
229905b261ecSmrg		    stuff->reqType,
230005b261ecSmrg		    stuff->drawable);
230105b261ecSmrg
230205b261ecSmrg    if (err == Success)
230305b261ecSmrg    {
23046747b715Smrg	return Success;
230505b261ecSmrg    }
230605b261ecSmrg    else
230705b261ecSmrg	return err;
230805b261ecSmrg}
230905b261ecSmrg
231005b261ecSmrgint
231105b261ecSmrgProcImageText16(ClientPtr client)
231205b261ecSmrg{
231305b261ecSmrg    int	err;
231405b261ecSmrg    DrawablePtr pDraw;
231505b261ecSmrg    GC *pGC;
231605b261ecSmrg
231705b261ecSmrg    REQUEST(xImageTextReq);
231805b261ecSmrg
231905b261ecSmrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
23204642e01fSmrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
232105b261ecSmrg
232205b261ecSmrg    err = ImageText(client,
232305b261ecSmrg		    pDraw,
232405b261ecSmrg		    pGC,
232505b261ecSmrg		    stuff->nChars,
232605b261ecSmrg		    (unsigned char *)&stuff[1],
232705b261ecSmrg		    stuff->x,
232805b261ecSmrg		    stuff->y,
232905b261ecSmrg		    stuff->reqType,
233005b261ecSmrg		    stuff->drawable);
233105b261ecSmrg
233205b261ecSmrg    if (err == Success)
233305b261ecSmrg    {
23346747b715Smrg	return Success;
233505b261ecSmrg    }
233605b261ecSmrg    else
233705b261ecSmrg	return err;
233805b261ecSmrg}
233905b261ecSmrg
234005b261ecSmrg
234105b261ecSmrgint
234205b261ecSmrgProcCreateColormap(ClientPtr client)
234305b261ecSmrg{
234405b261ecSmrg    VisualPtr	pVisual;
234505b261ecSmrg    ColormapPtr	pmap;
234605b261ecSmrg    Colormap	mid;
234705b261ecSmrg    WindowPtr   pWin;
234805b261ecSmrg    ScreenPtr pScreen;
234905b261ecSmrg    REQUEST(xCreateColormapReq);
235005b261ecSmrg    int i, result;
235105b261ecSmrg
235205b261ecSmrg    REQUEST_SIZE_MATCH(xCreateColormapReq);
235305b261ecSmrg
235405b261ecSmrg    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
235505b261ecSmrg    {
235605b261ecSmrg	client->errorValue = stuff->alloc;
23576747b715Smrg        return BadValue;
235805b261ecSmrg    }
235905b261ecSmrg    mid = stuff->mid;
236005b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
23614642e01fSmrg    result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
236205b261ecSmrg    if (result != Success)
236305b261ecSmrg        return result;
236405b261ecSmrg
236505b261ecSmrg    pScreen = pWin->drawable.pScreen;
236605b261ecSmrg    for (i = 0, pVisual = pScreen->visuals;
236705b261ecSmrg	 i < pScreen->numVisuals;
236805b261ecSmrg	 i++, pVisual++)
236905b261ecSmrg    {
237005b261ecSmrg	if (pVisual->vid != stuff->visual)
237105b261ecSmrg	    continue;
23726747b715Smrg	return CreateColormap(mid, pScreen, pVisual, &pmap,
237305b261ecSmrg				 (int)stuff->alloc, client->index);
237405b261ecSmrg    }
237505b261ecSmrg    client->errorValue = stuff->visual;
23766747b715Smrg    return BadMatch;
237705b261ecSmrg}
237805b261ecSmrg
237905b261ecSmrgint
238005b261ecSmrgProcFreeColormap(ClientPtr client)
238105b261ecSmrg{
238205b261ecSmrg    ColormapPtr pmap;
23834642e01fSmrg    int rc;
238405b261ecSmrg    REQUEST(xResourceReq);
238505b261ecSmrg
238605b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
2387b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client,
23884642e01fSmrg			   DixDestroyAccess);
23894642e01fSmrg    if (rc == Success)
239005b261ecSmrg    {
239105b261ecSmrg	/* Freeing a default colormap is a no-op */
239205b261ecSmrg	if (!(pmap->flags & IsDefault))
239305b261ecSmrg	    FreeResource(stuff->id, RT_NONE);
23946747b715Smrg	return Success;
239505b261ecSmrg    }
239605b261ecSmrg    else
239705b261ecSmrg    {
239805b261ecSmrg	client->errorValue = stuff->id;
23996747b715Smrg	return rc;
240005b261ecSmrg    }
240105b261ecSmrg}
240205b261ecSmrg
240305b261ecSmrg
240405b261ecSmrgint
240505b261ecSmrgProcCopyColormapAndFree(ClientPtr client)
240605b261ecSmrg{
240705b261ecSmrg    Colormap	mid;
240805b261ecSmrg    ColormapPtr	pSrcMap;
240905b261ecSmrg    REQUEST(xCopyColormapAndFreeReq);
24104642e01fSmrg    int rc;
241105b261ecSmrg
241205b261ecSmrg    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
241305b261ecSmrg    mid = stuff->mid;
241405b261ecSmrg    LEGAL_NEW_RESOURCE(mid, client);
2415b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP,
24164642e01fSmrg			   client, DixReadAccess|DixRemoveAccess);
24174642e01fSmrg    if (rc == Success)
24186747b715Smrg	return CopyColormapAndFree(mid, pSrcMap, client->index);
24196747b715Smrg    client->errorValue = stuff->srcCmap;
24206747b715Smrg    return rc;
242105b261ecSmrg}
242205b261ecSmrg
242305b261ecSmrgint
242405b261ecSmrgProcInstallColormap(ClientPtr client)
242505b261ecSmrg{
242605b261ecSmrg    ColormapPtr pcmp;
24274642e01fSmrg    int rc;
242805b261ecSmrg    REQUEST(xResourceReq);
242905b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
24304642e01fSmrg
2431b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
24324642e01fSmrg			   DixInstallAccess);
24334642e01fSmrg    if (rc != Success)
24344642e01fSmrg	goto out;
24354642e01fSmrg
24364642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
24376747b715Smrg    if (rc != Success) {
24386747b715Smrg	if (rc == BadValue)
24396747b715Smrg	    rc = BadColor;
24404642e01fSmrg	goto out;
24416747b715Smrg    }
24424642e01fSmrg
24434642e01fSmrg    (*(pcmp->pScreen->InstallColormap)) (pcmp);
24446747b715Smrg    return Success;
24454642e01fSmrg
24464642e01fSmrgout:
24474642e01fSmrg    client->errorValue = stuff->id;
24486747b715Smrg    return rc;
244905b261ecSmrg}
245005b261ecSmrg
245105b261ecSmrgint
245205b261ecSmrgProcUninstallColormap(ClientPtr client)
245305b261ecSmrg{
245405b261ecSmrg    ColormapPtr pcmp;
24554642e01fSmrg    int rc;
245605b261ecSmrg    REQUEST(xResourceReq);
245705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
24584642e01fSmrg
2459b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
24604642e01fSmrg			   DixUninstallAccess);
24614642e01fSmrg    if (rc != Success)
24624642e01fSmrg	goto out;
24634642e01fSmrg
24644642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
24656747b715Smrg    if (rc != Success) {
24666747b715Smrg	if (rc == BadValue)
24676747b715Smrg	    rc = BadColor;
24684642e01fSmrg	goto out;
24696747b715Smrg    }
24704642e01fSmrg
24714642e01fSmrg    if(pcmp->mid != pcmp->pScreen->defColormap)
24724642e01fSmrg	(*(pcmp->pScreen->UninstallColormap)) (pcmp);
24736747b715Smrg    return Success;
24744642e01fSmrg
24754642e01fSmrgout:
24764642e01fSmrg    client->errorValue = stuff->id;
24776747b715Smrg    return rc;
247805b261ecSmrg}
247905b261ecSmrg
248005b261ecSmrgint
248105b261ecSmrgProcListInstalledColormaps(ClientPtr client)
248205b261ecSmrg{
248305b261ecSmrg    xListInstalledColormapsReply *preply;
248405b261ecSmrg    int nummaps, rc;
248505b261ecSmrg    WindowPtr pWin;
248605b261ecSmrg    REQUEST(xResourceReq);
248705b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
24884642e01fSmrg
24894642e01fSmrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
249005b261ecSmrg    if (rc != Success)
24916747b715Smrg	return rc;
24924642e01fSmrg
24934642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
24944642e01fSmrg		  DixGetAttrAccess);
24954642e01fSmrg    if (rc != Success)
24966747b715Smrg	return rc;
249705b261ecSmrg
24986747b715Smrg    preply = malloc(sizeof(xListInstalledColormapsReply) +
249905b261ecSmrg		     pWin->drawable.pScreen->maxInstalledCmaps *
250005b261ecSmrg		     sizeof(Colormap));
250105b261ecSmrg    if(!preply)
25026747b715Smrg        return BadAlloc;
250305b261ecSmrg
250405b261ecSmrg    preply->type = X_Reply;
250505b261ecSmrg    preply->sequenceNumber = client->sequence;
250605b261ecSmrg    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
250705b261ecSmrg        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
250805b261ecSmrg    preply->nColormaps = nummaps;
250905b261ecSmrg    preply->length = nummaps;
251005b261ecSmrg    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
251105b261ecSmrg    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
251205b261ecSmrg    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
25136747b715Smrg    free(preply);
25146747b715Smrg    return Success;
251505b261ecSmrg}
251605b261ecSmrg
251705b261ecSmrgint
251805b261ecSmrgProcAllocColor (ClientPtr client)
251905b261ecSmrg{
252005b261ecSmrg    ColormapPtr pmap;
25214642e01fSmrg    int rc;
252205b261ecSmrg    xAllocColorReply acr;
252305b261ecSmrg    REQUEST(xAllocColorReq);
252405b261ecSmrg
252505b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorReq);
2526b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client,
25274642e01fSmrg			   DixAddAccess);
25284642e01fSmrg    if (rc == Success)
252905b261ecSmrg    {
253005b261ecSmrg	acr.type = X_Reply;
253105b261ecSmrg	acr.length = 0;
253205b261ecSmrg	acr.sequenceNumber = client->sequence;
253305b261ecSmrg	acr.red = stuff->red;
253405b261ecSmrg	acr.green = stuff->green;
253505b261ecSmrg	acr.blue = stuff->blue;
253605b261ecSmrg	acr.pixel = 0;
25374642e01fSmrg	if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
253805b261ecSmrg	                       &acr.pixel, client->index)) )
25396747b715Smrg	    return rc;
254005b261ecSmrg#ifdef PANORAMIX
254105b261ecSmrg	if (noPanoramiXExtension || !pmap->pScreen->myNum)
254205b261ecSmrg#endif
254305b261ecSmrg        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
25446747b715Smrg	return Success;
254505b261ecSmrg
254605b261ecSmrg    }
254705b261ecSmrg    else
254805b261ecSmrg    {
254905b261ecSmrg        client->errorValue = stuff->cmap;
25506747b715Smrg        return rc;
255105b261ecSmrg    }
255205b261ecSmrg}
255305b261ecSmrg
255405b261ecSmrgint
255505b261ecSmrgProcAllocNamedColor (ClientPtr client)
255605b261ecSmrg{
255705b261ecSmrg    ColormapPtr pcmp;
25584642e01fSmrg    int rc;
255905b261ecSmrg    REQUEST(xAllocNamedColorReq);
256005b261ecSmrg
256105b261ecSmrg    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2562b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
25634642e01fSmrg			   DixAddAccess);
25644642e01fSmrg    if (rc == Success)
256505b261ecSmrg    {
256605b261ecSmrg	xAllocNamedColorReply ancr;
256705b261ecSmrg
256805b261ecSmrg	ancr.type = X_Reply;
256905b261ecSmrg	ancr.length = 0;
257005b261ecSmrg	ancr.sequenceNumber = client->sequence;
257105b261ecSmrg
257205b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
257305b261ecSmrg	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
257405b261ecSmrg	{
257505b261ecSmrg	    ancr.screenRed = ancr.exactRed;
257605b261ecSmrg	    ancr.screenGreen = ancr.exactGreen;
257705b261ecSmrg	    ancr.screenBlue = ancr.exactBlue;
257805b261ecSmrg	    ancr.pixel = 0;
25794642e01fSmrg	    if( (rc = AllocColor(pcmp,
258005b261ecSmrg	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
258105b261ecSmrg			 &ancr.pixel, client->index)) )
25826747b715Smrg		return rc;
258305b261ecSmrg#ifdef PANORAMIX
258405b261ecSmrg	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
258505b261ecSmrg#endif
258605b261ecSmrg            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
25876747b715Smrg	    return Success;
258805b261ecSmrg	}
258905b261ecSmrg	else
25906747b715Smrg	    return BadName;
259105b261ecSmrg
259205b261ecSmrg    }
259305b261ecSmrg    else
259405b261ecSmrg    {
259505b261ecSmrg        client->errorValue = stuff->cmap;
25966747b715Smrg        return rc;
259705b261ecSmrg    }
259805b261ecSmrg}
259905b261ecSmrg
260005b261ecSmrgint
260105b261ecSmrgProcAllocColorCells (ClientPtr client)
260205b261ecSmrg{
260305b261ecSmrg    ColormapPtr pcmp;
26044642e01fSmrg    int rc;
260505b261ecSmrg    REQUEST(xAllocColorCellsReq);
260605b261ecSmrg
260705b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2608b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
26094642e01fSmrg			   DixAddAccess);
26104642e01fSmrg    if (rc == Success)
261105b261ecSmrg    {
261205b261ecSmrg	xAllocColorCellsReply	accr;
26134642e01fSmrg	int			npixels, nmasks;
261405b261ecSmrg	long			length;
261505b261ecSmrg	Pixel			*ppixels, *pmasks;
261605b261ecSmrg
261705b261ecSmrg	npixels = stuff->colors;
261805b261ecSmrg	if (!npixels)
261905b261ecSmrg	{
262005b261ecSmrg	    client->errorValue = npixels;
26216747b715Smrg	    return BadValue;
262205b261ecSmrg	}
262305b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
262405b261ecSmrg	{
262505b261ecSmrg	    client->errorValue = stuff->contiguous;
26266747b715Smrg	    return BadValue;
262705b261ecSmrg	}
262805b261ecSmrg	nmasks = stuff->planes;
262905b261ecSmrg	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
26306747b715Smrg	ppixels = malloc(length);
263105b261ecSmrg	if(!ppixels)
26326747b715Smrg            return BadAlloc;
263305b261ecSmrg	pmasks = ppixels + npixels;
263405b261ecSmrg
26354642e01fSmrg	if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
263605b261ecSmrg				    (Bool)stuff->contiguous, ppixels, pmasks)) )
263705b261ecSmrg	{
26386747b715Smrg	    free(ppixels);
26396747b715Smrg	    return rc;
264005b261ecSmrg	}
264105b261ecSmrg#ifdef PANORAMIX
264205b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
264305b261ecSmrg#endif
264405b261ecSmrg	{
264505b261ecSmrg	    accr.type = X_Reply;
26466747b715Smrg	    accr.length = bytes_to_int32(length);
264705b261ecSmrg	    accr.sequenceNumber = client->sequence;
264805b261ecSmrg	    accr.nPixels = npixels;
264905b261ecSmrg	    accr.nMasks = nmasks;
265005b261ecSmrg	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
265105b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
265205b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
265305b261ecSmrg	}
26546747b715Smrg	free(ppixels);
26556747b715Smrg        return Success;
265605b261ecSmrg    }
265705b261ecSmrg    else
265805b261ecSmrg    {
265905b261ecSmrg        client->errorValue = stuff->cmap;
26606747b715Smrg        return rc;
266105b261ecSmrg    }
266205b261ecSmrg}
266305b261ecSmrg
266405b261ecSmrgint
266505b261ecSmrgProcAllocColorPlanes(ClientPtr client)
266605b261ecSmrg{
266705b261ecSmrg    ColormapPtr pcmp;
26684642e01fSmrg    int rc;
266905b261ecSmrg    REQUEST(xAllocColorPlanesReq);
267005b261ecSmrg
267105b261ecSmrg    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2672b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
26734642e01fSmrg			   DixAddAccess);
26744642e01fSmrg    if (rc == Success)
267505b261ecSmrg    {
267605b261ecSmrg	xAllocColorPlanesReply	acpr;
26774642e01fSmrg	int			npixels;
267805b261ecSmrg	long			length;
267905b261ecSmrg	Pixel			*ppixels;
268005b261ecSmrg
268105b261ecSmrg	npixels = stuff->colors;
268205b261ecSmrg	if (!npixels)
268305b261ecSmrg	{
268405b261ecSmrg	    client->errorValue = npixels;
26856747b715Smrg	    return BadValue;
268605b261ecSmrg	}
268705b261ecSmrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
268805b261ecSmrg	{
268905b261ecSmrg	    client->errorValue = stuff->contiguous;
26906747b715Smrg	    return BadValue;
269105b261ecSmrg	}
269205b261ecSmrg	acpr.type = X_Reply;
269305b261ecSmrg	acpr.sequenceNumber = client->sequence;
269405b261ecSmrg	acpr.nPixels = npixels;
269505b261ecSmrg	length = (long)npixels * sizeof(Pixel);
26966747b715Smrg	ppixels = malloc(length);
269705b261ecSmrg	if(!ppixels)
26986747b715Smrg            return BadAlloc;
26994642e01fSmrg	if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
270005b261ecSmrg	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
270105b261ecSmrg	    (Bool)stuff->contiguous, ppixels,
270205b261ecSmrg	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
270305b261ecSmrg	{
27046747b715Smrg            free(ppixels);
27056747b715Smrg	    return rc;
270605b261ecSmrg	}
27076747b715Smrg	acpr.length = bytes_to_int32(length);
270805b261ecSmrg#ifdef PANORAMIX
270905b261ecSmrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
271005b261ecSmrg#endif
271105b261ecSmrg	{
271205b261ecSmrg	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
271305b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
271405b261ecSmrg	    WriteSwappedDataToClient(client, length, ppixels);
271505b261ecSmrg	}
27166747b715Smrg	free(ppixels);
27176747b715Smrg        return Success;
271805b261ecSmrg    }
271905b261ecSmrg    else
272005b261ecSmrg    {
272105b261ecSmrg        client->errorValue = stuff->cmap;
27226747b715Smrg        return rc;
272305b261ecSmrg    }
272405b261ecSmrg}
272505b261ecSmrg
272605b261ecSmrgint
272705b261ecSmrgProcFreeColors(ClientPtr client)
272805b261ecSmrg{
272905b261ecSmrg    ColormapPtr pcmp;
27304642e01fSmrg    int rc;
273105b261ecSmrg    REQUEST(xFreeColorsReq);
273205b261ecSmrg
273305b261ecSmrg    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2734b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27354642e01fSmrg			   DixRemoveAccess);
27364642e01fSmrg    if (rc == Success)
273705b261ecSmrg    {
273805b261ecSmrg	int	count;
273905b261ecSmrg
274005b261ecSmrg	if(pcmp->flags & AllAllocated)
27416747b715Smrg	    return BadAccess;
27426747b715Smrg	count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
27436747b715Smrg	return FreeColors(pcmp, client->index, count,
274405b261ecSmrg	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
274505b261ecSmrg    }
274605b261ecSmrg    else
274705b261ecSmrg    {
274805b261ecSmrg        client->errorValue = stuff->cmap;
27496747b715Smrg        return rc;
275005b261ecSmrg    }
275105b261ecSmrg}
275205b261ecSmrg
275305b261ecSmrgint
275405b261ecSmrgProcStoreColors (ClientPtr client)
275505b261ecSmrg{
275605b261ecSmrg    ColormapPtr pcmp;
27574642e01fSmrg    int rc;
275805b261ecSmrg    REQUEST(xStoreColorsReq);
275905b261ecSmrg
276005b261ecSmrg    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2761b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27624642e01fSmrg			   DixWriteAccess);
27634642e01fSmrg    if (rc == Success)
276405b261ecSmrg    {
276505b261ecSmrg	int	count;
276605b261ecSmrg
276705b261ecSmrg        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
276805b261ecSmrg	if (count % sizeof(xColorItem))
27696747b715Smrg	    return BadLength;
277005b261ecSmrg	count /= sizeof(xColorItem);
27716747b715Smrg	return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client);
277205b261ecSmrg    }
277305b261ecSmrg    else
277405b261ecSmrg    {
277505b261ecSmrg        client->errorValue = stuff->cmap;
27766747b715Smrg        return rc;
277705b261ecSmrg    }
277805b261ecSmrg}
277905b261ecSmrg
278005b261ecSmrgint
278105b261ecSmrgProcStoreNamedColor (ClientPtr client)
278205b261ecSmrg{
278305b261ecSmrg    ColormapPtr pcmp;
27844642e01fSmrg    int rc;
278505b261ecSmrg    REQUEST(xStoreNamedColorReq);
278605b261ecSmrg
278705b261ecSmrg    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2788b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
27894642e01fSmrg			   DixWriteAccess);
27904642e01fSmrg    if (rc == Success)
279105b261ecSmrg    {
279205b261ecSmrg	xColorItem	def;
279305b261ecSmrg
279405b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
279505b261ecSmrg	                 stuff->nbytes, &def.red, &def.green, &def.blue))
279605b261ecSmrg	{
279705b261ecSmrg	    def.flags = stuff->flags;
279805b261ecSmrg	    def.pixel = stuff->pixel;
27996747b715Smrg	    return StoreColors(pcmp, 1, &def, client);
280005b261ecSmrg	}
28016747b715Smrg        return BadName;
280205b261ecSmrg    }
280305b261ecSmrg    else
280405b261ecSmrg    {
280505b261ecSmrg        client->errorValue = stuff->cmap;
28066747b715Smrg        return rc;
280705b261ecSmrg    }
280805b261ecSmrg}
280905b261ecSmrg
281005b261ecSmrgint
281105b261ecSmrgProcQueryColors(ClientPtr client)
281205b261ecSmrg{
281305b261ecSmrg    ColormapPtr pcmp;
28144642e01fSmrg    int rc;
281505b261ecSmrg    REQUEST(xQueryColorsReq);
281605b261ecSmrg
281705b261ecSmrg    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2818b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
28194642e01fSmrg			   DixReadAccess);
28204642e01fSmrg    if (rc == Success)
282105b261ecSmrg    {
28224642e01fSmrg	int			count;
282305b261ecSmrg	xrgb 			*prgbs;
282405b261ecSmrg	xQueryColorsReply	qcr;
282505b261ecSmrg
28266747b715Smrg	count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
28276747b715Smrg	prgbs = calloc(1, count * sizeof(xrgb));
282805b261ecSmrg	if(!prgbs && count)
28296747b715Smrg            return BadAlloc;
28306747b715Smrg	if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) )
283105b261ecSmrg	{
28326747b715Smrg	    free(prgbs);
28336747b715Smrg	    return rc;
283405b261ecSmrg	}
28356747b715Smrg	memset(&qcr, 0, sizeof(xQueryColorsReply));
283605b261ecSmrg	qcr.type = X_Reply;
28376747b715Smrg	qcr.length = bytes_to_int32(count * sizeof(xrgb));
283805b261ecSmrg	qcr.sequenceNumber = client->sequence;
283905b261ecSmrg	qcr.nColors = count;
284005b261ecSmrg	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
284105b261ecSmrg	if (count)
284205b261ecSmrg	{
284305b261ecSmrg	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
284405b261ecSmrg	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
284505b261ecSmrg	}
28466747b715Smrg	free(prgbs);
28476747b715Smrg	return Success;
284805b261ecSmrg
284905b261ecSmrg    }
285005b261ecSmrg    else
285105b261ecSmrg    {
285205b261ecSmrg        client->errorValue = stuff->cmap;
28536747b715Smrg        return rc;
285405b261ecSmrg    }
285505b261ecSmrg}
285605b261ecSmrg
285705b261ecSmrgint
285805b261ecSmrgProcLookupColor(ClientPtr client)
285905b261ecSmrg{
286005b261ecSmrg    ColormapPtr pcmp;
28614642e01fSmrg    int rc;
286205b261ecSmrg    REQUEST(xLookupColorReq);
286305b261ecSmrg
286405b261ecSmrg    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2865b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
28664642e01fSmrg			   DixReadAccess);
28674642e01fSmrg    if (rc == Success)
286805b261ecSmrg    {
286905b261ecSmrg	xLookupColorReply lcr;
287005b261ecSmrg
287105b261ecSmrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
287205b261ecSmrg	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
287305b261ecSmrg	{
287405b261ecSmrg	    lcr.type = X_Reply;
287505b261ecSmrg	    lcr.length = 0;
287605b261ecSmrg	    lcr.sequenceNumber = client->sequence;
287705b261ecSmrg	    lcr.screenRed = lcr.exactRed;
287805b261ecSmrg	    lcr.screenGreen = lcr.exactGreen;
287905b261ecSmrg	    lcr.screenBlue = lcr.exactBlue;
288005b261ecSmrg	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
288105b261ecSmrg	                                   &lcr.screenGreen,
288205b261ecSmrg					   &lcr.screenBlue,
288305b261ecSmrg					   pcmp->pVisual);
288405b261ecSmrg	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
28856747b715Smrg	    return Success;
288605b261ecSmrg	}
28876747b715Smrg        return BadName;
288805b261ecSmrg    }
288905b261ecSmrg    else
289005b261ecSmrg    {
289105b261ecSmrg        client->errorValue = stuff->cmap;
28926747b715Smrg        return rc;
289305b261ecSmrg    }
289405b261ecSmrg}
289505b261ecSmrg
289605b261ecSmrgint
289705b261ecSmrgProcCreateCursor (ClientPtr client)
289805b261ecSmrg{
289905b261ecSmrg    CursorPtr		pCursor;
290005b261ecSmrg    PixmapPtr 		src;
290105b261ecSmrg    PixmapPtr 		msk;
290205b261ecSmrg    unsigned char *	srcbits;
290305b261ecSmrg    unsigned char *	mskbits;
290405b261ecSmrg    unsigned short	width, height;
290505b261ecSmrg    long		n;
290605b261ecSmrg    CursorMetricRec 	cm;
29074642e01fSmrg    int rc;
290805b261ecSmrg
290905b261ecSmrg    REQUEST(xCreateCursorReq);
291005b261ecSmrg
291105b261ecSmrg    REQUEST_SIZE_MATCH(xCreateCursorReq);
291205b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
291305b261ecSmrg
2914b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client,
29154642e01fSmrg			   DixReadAccess);
29164642e01fSmrg    if (rc != Success) {
291705b261ecSmrg	client->errorValue = stuff->source;
29186747b715Smrg	return rc;
291905b261ecSmrg    }
29204642e01fSmrg
2921b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
29224642e01fSmrg			   DixReadAccess);
29234642e01fSmrg    if (rc != Success)
292405b261ecSmrg    {
292505b261ecSmrg	if (stuff->mask != None)
292605b261ecSmrg	{
292705b261ecSmrg	    client->errorValue = stuff->mask;
29286747b715Smrg	    return rc;
292905b261ecSmrg	}
293005b261ecSmrg    }
293105b261ecSmrg    else if (  src->drawable.width != msk->drawable.width
293205b261ecSmrg	    || src->drawable.height != msk->drawable.height
293305b261ecSmrg	    || src->drawable.depth != 1
293405b261ecSmrg	    || msk->drawable.depth != 1)
29356747b715Smrg	return BadMatch;
293605b261ecSmrg
293705b261ecSmrg    width = src->drawable.width;
293805b261ecSmrg    height = src->drawable.height;
293905b261ecSmrg
294005b261ecSmrg    if ( stuff->x > width
294105b261ecSmrg      || stuff->y > height )
29426747b715Smrg	return BadMatch;
294305b261ecSmrg
294405b261ecSmrg    n = BitmapBytePad(width)*height;
29456747b715Smrg    srcbits = calloc(1, n);
294605b261ecSmrg    if (!srcbits)
29476747b715Smrg	return BadAlloc;
29486747b715Smrg    mskbits = malloc(n);
294905b261ecSmrg    if (!mskbits)
295005b261ecSmrg    {
29516747b715Smrg	free(srcbits);
29526747b715Smrg	return BadAlloc;
295305b261ecSmrg    }
295405b261ecSmrg
295505b261ecSmrg    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
295605b261ecSmrg					 XYPixmap, 1, (pointer)srcbits);
295705b261ecSmrg    if ( msk == (PixmapPtr)NULL)
295805b261ecSmrg    {
295905b261ecSmrg	unsigned char *bits = mskbits;
296005b261ecSmrg	while (--n >= 0)
296105b261ecSmrg	    *bits++ = ~0;
296205b261ecSmrg    }
296305b261ecSmrg    else
296405b261ecSmrg    {
296505b261ecSmrg	/* zeroing the (pad) bits helps some ddx cursor handling */
29666747b715Smrg	memset((char *)mskbits, 0, n);
296705b261ecSmrg	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
296805b261ecSmrg					height, XYPixmap, 1, (pointer)mskbits);
296905b261ecSmrg    }
297005b261ecSmrg    cm.width = width;
297105b261ecSmrg    cm.height = height;
297205b261ecSmrg    cm.xhot = stuff->x;
297305b261ecSmrg    cm.yhot = stuff->y;
29744642e01fSmrg    rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
29754642e01fSmrg			 stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
29764642e01fSmrg			 stuff->backRed, stuff->backGreen, stuff->backBlue,
29774642e01fSmrg			 &pCursor, client, stuff->cid);
297805b261ecSmrg
29794642e01fSmrg    if (rc != Success)
29804642e01fSmrg	return rc;
29814642e01fSmrg    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
29824642e01fSmrg	return BadAlloc;
29834642e01fSmrg
29846747b715Smrg    return Success;
298505b261ecSmrg}
298605b261ecSmrg
298705b261ecSmrgint
298805b261ecSmrgProcCreateGlyphCursor (ClientPtr client)
298905b261ecSmrg{
299005b261ecSmrg    CursorPtr pCursor;
299105b261ecSmrg    int res;
299205b261ecSmrg
299305b261ecSmrg    REQUEST(xCreateGlyphCursorReq);
299405b261ecSmrg
299505b261ecSmrg    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
299605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
299705b261ecSmrg
299805b261ecSmrg    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
299905b261ecSmrg			   stuff->mask, stuff->maskChar,
300005b261ecSmrg			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
300105b261ecSmrg			   stuff->backRed, stuff->backGreen, stuff->backBlue,
30024642e01fSmrg			   &pCursor, client, stuff->cid);
300305b261ecSmrg    if (res != Success)
300405b261ecSmrg	return res;
300505b261ecSmrg    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
30066747b715Smrg	return Success;
300705b261ecSmrg    return BadAlloc;
300805b261ecSmrg}
300905b261ecSmrg
301005b261ecSmrg
301105b261ecSmrgint
301205b261ecSmrgProcFreeCursor (ClientPtr client)
301305b261ecSmrg{
301405b261ecSmrg    CursorPtr pCursor;
30154642e01fSmrg    int rc;
301605b261ecSmrg    REQUEST(xResourceReq);
301705b261ecSmrg
301805b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
3019b86d567bSmrg    rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client,
30204642e01fSmrg			   DixDestroyAccess);
30214642e01fSmrg    if (rc == Success)
302205b261ecSmrg    {
302305b261ecSmrg	FreeResource(stuff->id, RT_NONE);
30246747b715Smrg	return Success;
302505b261ecSmrg    }
302605b261ecSmrg    else
302705b261ecSmrg    {
302805b261ecSmrg	client->errorValue = stuff->id;
30296747b715Smrg	return rc;
303005b261ecSmrg    }
303105b261ecSmrg}
303205b261ecSmrg
303305b261ecSmrgint
303405b261ecSmrgProcQueryBestSize (ClientPtr client)
303505b261ecSmrg{
303605b261ecSmrg    xQueryBestSizeReply	reply;
303705b261ecSmrg    DrawablePtr pDraw;
303805b261ecSmrg    ScreenPtr pScreen;
303905b261ecSmrg    int rc;
304005b261ecSmrg    REQUEST(xQueryBestSizeReq);
304105b261ecSmrg    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
304205b261ecSmrg
304305b261ecSmrg    if ((stuff->class != CursorShape) &&
304405b261ecSmrg	(stuff->class != TileShape) &&
304505b261ecSmrg	(stuff->class != StippleShape))
304605b261ecSmrg    {
304705b261ecSmrg	client->errorValue = stuff->class;
30486747b715Smrg        return BadValue;
304905b261ecSmrg    }
305005b261ecSmrg
305105b261ecSmrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
30524642e01fSmrg			   DixGetAttrAccess);
305305b261ecSmrg    if (rc != Success)
305405b261ecSmrg	return rc;
305505b261ecSmrg    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
30566747b715Smrg	return BadMatch;
305705b261ecSmrg    pScreen = pDraw->pScreen;
30584642e01fSmrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
30594642e01fSmrg    if (rc != Success)
30604642e01fSmrg	return rc;
306105b261ecSmrg    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
306205b261ecSmrg			       &stuff->height, pScreen);
30636747b715Smrg    memset(&reply, 0, sizeof(xQueryBestSizeReply));
306405b261ecSmrg    reply.type = X_Reply;
306505b261ecSmrg    reply.length = 0;
306605b261ecSmrg    reply.sequenceNumber = client->sequence;
306705b261ecSmrg    reply.width = stuff->width;
306805b261ecSmrg    reply.height = stuff->height;
306905b261ecSmrg    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
30706747b715Smrg    return Success;
307105b261ecSmrg}
307205b261ecSmrg
307305b261ecSmrg
307405b261ecSmrgint
307505b261ecSmrgProcSetScreenSaver (ClientPtr client)
307605b261ecSmrg{
30774642e01fSmrg    int rc, i, blankingOption, exposureOption;
307805b261ecSmrg    REQUEST(xSetScreenSaverReq);
307905b261ecSmrg    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
30804642e01fSmrg
30814642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
30824642e01fSmrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
30834642e01fSmrg		      DixSetAttrAccess);
30844642e01fSmrg	if (rc != Success)
30854642e01fSmrg	    return rc;
30864642e01fSmrg    }
30874642e01fSmrg
308805b261ecSmrg    blankingOption = stuff->preferBlank;
308905b261ecSmrg    if ((blankingOption != DontPreferBlanking) &&
309005b261ecSmrg        (blankingOption != PreferBlanking) &&
309105b261ecSmrg        (blankingOption != DefaultBlanking))
309205b261ecSmrg    {
309305b261ecSmrg	client->errorValue = blankingOption;
309405b261ecSmrg        return BadValue;
309505b261ecSmrg    }
309605b261ecSmrg    exposureOption = stuff->allowExpose;
309705b261ecSmrg    if ((exposureOption != DontAllowExposures) &&
309805b261ecSmrg        (exposureOption != AllowExposures) &&
309905b261ecSmrg        (exposureOption != DefaultExposures))
310005b261ecSmrg    {
310105b261ecSmrg	client->errorValue = exposureOption;
310205b261ecSmrg        return BadValue;
310305b261ecSmrg    }
310405b261ecSmrg    if (stuff->timeout < -1)
310505b261ecSmrg    {
310605b261ecSmrg	client->errorValue = stuff->timeout;
310705b261ecSmrg        return BadValue;
310805b261ecSmrg    }
310905b261ecSmrg    if (stuff->interval < -1)
311005b261ecSmrg    {
311105b261ecSmrg	client->errorValue = stuff->interval;
311205b261ecSmrg        return BadValue;
311305b261ecSmrg    }
311405b261ecSmrg
311505b261ecSmrg    if (blankingOption == DefaultBlanking)
311605b261ecSmrg	ScreenSaverBlanking = defaultScreenSaverBlanking;
311705b261ecSmrg    else
311805b261ecSmrg	ScreenSaverBlanking = blankingOption;
311905b261ecSmrg    if (exposureOption == DefaultExposures)
312005b261ecSmrg	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
312105b261ecSmrg    else
312205b261ecSmrg	ScreenSaverAllowExposures = exposureOption;
312305b261ecSmrg
312405b261ecSmrg    if (stuff->timeout >= 0)
312505b261ecSmrg	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
312605b261ecSmrg    else
312705b261ecSmrg	ScreenSaverTime = defaultScreenSaverTime;
312805b261ecSmrg    if (stuff->interval >= 0)
312905b261ecSmrg	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
313005b261ecSmrg    else
313105b261ecSmrg	ScreenSaverInterval = defaultScreenSaverInterval;
313205b261ecSmrg
313305b261ecSmrg    SetScreenSaverTimer();
31346747b715Smrg    return Success;
313505b261ecSmrg}
313605b261ecSmrg
313705b261ecSmrgint
313805b261ecSmrgProcGetScreenSaver(ClientPtr client)
313905b261ecSmrg{
314005b261ecSmrg    xGetScreenSaverReply rep;
31414642e01fSmrg    int rc, i;
314205b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
31434642e01fSmrg
31444642e01fSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
31454642e01fSmrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
31464642e01fSmrg		      DixGetAttrAccess);
31474642e01fSmrg	if (rc != Success)
31484642e01fSmrg	    return rc;
31494642e01fSmrg    }
31504642e01fSmrg
315105b261ecSmrg    rep.type = X_Reply;
315205b261ecSmrg    rep.length = 0;
315305b261ecSmrg    rep.sequenceNumber = client->sequence;
315405b261ecSmrg    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
315505b261ecSmrg    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
315605b261ecSmrg    rep.preferBlanking = ScreenSaverBlanking;
315705b261ecSmrg    rep.allowExposures = ScreenSaverAllowExposures;
315805b261ecSmrg    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
31596747b715Smrg    return Success;
316005b261ecSmrg}
316105b261ecSmrg
316205b261ecSmrgint
316305b261ecSmrgProcChangeHosts(ClientPtr client)
316405b261ecSmrg{
316505b261ecSmrg    REQUEST(xChangeHostsReq);
316605b261ecSmrg
316705b261ecSmrg    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
316805b261ecSmrg
316905b261ecSmrg    if(stuff->mode == HostInsert)
31706747b715Smrg	return AddHost(client, (int)stuff->hostFamily,
317105b261ecSmrg			 stuff->hostLength, (pointer)&stuff[1]);
31726747b715Smrg    if (stuff->mode == HostDelete)
31736747b715Smrg	return RemoveHost(client, (int)stuff->hostFamily,
317405b261ecSmrg			    stuff->hostLength, (pointer)&stuff[1]);
31756747b715Smrg    client->errorValue = stuff->mode;
31766747b715Smrg    return BadValue;
317705b261ecSmrg}
317805b261ecSmrg
317905b261ecSmrgint
318005b261ecSmrgProcListHosts(ClientPtr client)
318105b261ecSmrg{
318205b261ecSmrg    xListHostsReply reply;
318305b261ecSmrg    int	len, nHosts, result;
318405b261ecSmrg    pointer	pdata;
318505b261ecSmrg    /* REQUEST(xListHostsReq); */
318605b261ecSmrg
318705b261ecSmrg    REQUEST_SIZE_MATCH(xListHostsReq);
318805b261ecSmrg
318905b261ecSmrg    /* untrusted clients can't list hosts */
31904642e01fSmrg    result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
31914642e01fSmrg    if (result != Success)
31924642e01fSmrg	return result;
319305b261ecSmrg
319405b261ecSmrg    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
319505b261ecSmrg    if (result != Success)
31966747b715Smrg	return result;
319705b261ecSmrg    reply.type = X_Reply;
319805b261ecSmrg    reply.sequenceNumber = client->sequence;
319905b261ecSmrg    reply.nHosts = nHosts;
32006747b715Smrg    reply.length = bytes_to_int32(len);
320105b261ecSmrg    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
320205b261ecSmrg    if (nHosts)
320305b261ecSmrg    {
320405b261ecSmrg	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
320505b261ecSmrg	WriteSwappedDataToClient(client, len, pdata);
320605b261ecSmrg    }
32076747b715Smrg    free(pdata);
32086747b715Smrg    return Success;
320905b261ecSmrg}
321005b261ecSmrg
321105b261ecSmrgint
321205b261ecSmrgProcChangeAccessControl(ClientPtr client)
321305b261ecSmrg{
321405b261ecSmrg    REQUEST(xSetAccessControlReq);
321505b261ecSmrg
321605b261ecSmrg    REQUEST_SIZE_MATCH(xSetAccessControlReq);
321705b261ecSmrg    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
321805b261ecSmrg    {
321905b261ecSmrg	client->errorValue = stuff->mode;
322005b261ecSmrg        return BadValue;
322105b261ecSmrg    }
32226747b715Smrg    return ChangeAccessControl(client, stuff->mode == EnableAccess);
322305b261ecSmrg}
322405b261ecSmrg
322505b261ecSmrg/*********************
322605b261ecSmrg * CloseDownRetainedResources
322705b261ecSmrg *
322805b261ecSmrg *    Find all clients that are gone and have terminated in RetainTemporary
322905b261ecSmrg *    and destroy their resources.
323005b261ecSmrg *********************/
323105b261ecSmrg
323205b261ecSmrgstatic void
323305b261ecSmrgCloseDownRetainedResources(void)
323405b261ecSmrg{
323505b261ecSmrg    int i;
323605b261ecSmrg    ClientPtr client;
323705b261ecSmrg
323805b261ecSmrg    for (i=1; i<currentMaxClients; i++)
323905b261ecSmrg    {
324005b261ecSmrg        client = clients[i];
324105b261ecSmrg        if (client && (client->closeDownMode == RetainTemporary)
324205b261ecSmrg	    && (client->clientGone))
324305b261ecSmrg	    CloseDownClient(client);
324405b261ecSmrg    }
324505b261ecSmrg}
324605b261ecSmrg
324705b261ecSmrgint
324805b261ecSmrgProcKillClient(ClientPtr client)
324905b261ecSmrg{
325005b261ecSmrg    REQUEST(xResourceReq);
325105b261ecSmrg    ClientPtr killclient;
325205b261ecSmrg    int rc;
325305b261ecSmrg
325405b261ecSmrg    REQUEST_SIZE_MATCH(xResourceReq);
325505b261ecSmrg    if (stuff->id == AllTemporary)
325605b261ecSmrg    {
325705b261ecSmrg	CloseDownRetainedResources();
32586747b715Smrg        return Success;
325905b261ecSmrg    }
326005b261ecSmrg
326105b261ecSmrg    rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
326205b261ecSmrg    if (rc == Success) {
326305b261ecSmrg	CloseDownClient(killclient);
326405b261ecSmrg	/* if an LBX proxy gets killed, isItTimeToYield will be set */
326505b261ecSmrg	if (isItTimeToYield || (client == killclient))
326605b261ecSmrg	{
326705b261ecSmrg	    /* force yield and return Success, so that Dispatch()
326805b261ecSmrg	     * doesn't try to touch client
326905b261ecSmrg	     */
327005b261ecSmrg	    isItTimeToYield = TRUE;
32716747b715Smrg	    return Success;
327205b261ecSmrg	}
32736747b715Smrg	return Success;
327405b261ecSmrg    }
327505b261ecSmrg    else
327605b261ecSmrg	return rc;
327705b261ecSmrg}
327805b261ecSmrg
327905b261ecSmrgint
328005b261ecSmrgProcSetFontPath(ClientPtr client)
328105b261ecSmrg{
328205b261ecSmrg    unsigned char *ptr;
328305b261ecSmrg    unsigned long nbytes, total;
328405b261ecSmrg    long nfonts;
32856747b715Smrg    int n;
328605b261ecSmrg    REQUEST(xSetFontPathReq);
328705b261ecSmrg
328805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
328905b261ecSmrg
329005b261ecSmrg    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
329105b261ecSmrg    total = nbytes;
329205b261ecSmrg    ptr = (unsigned char *)&stuff[1];
329305b261ecSmrg    nfonts = stuff->nFonts;
329405b261ecSmrg    while (--nfonts >= 0)
329505b261ecSmrg    {
329605b261ecSmrg	if ((total == 0) || (total < (n = (*ptr + 1))))
32976747b715Smrg	    return BadLength;
329805b261ecSmrg	total -= n;
329905b261ecSmrg	ptr += n;
330005b261ecSmrg    }
330105b261ecSmrg    if (total >= 4)
33026747b715Smrg	return BadLength;
33036747b715Smrg    return SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]);
330405b261ecSmrg}
330505b261ecSmrg
330605b261ecSmrgint
330705b261ecSmrgProcGetFontPath(ClientPtr client)
330805b261ecSmrg{
330905b261ecSmrg    xGetFontPathReply reply;
33104642e01fSmrg    int rc, stringLens, numpaths;
331105b261ecSmrg    unsigned char *bufferStart;
331205b261ecSmrg    /* REQUEST (xReq); */
331305b261ecSmrg
331405b261ecSmrg    REQUEST_SIZE_MATCH(xReq);
33154642e01fSmrg    rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
33164642e01fSmrg    if (rc != Success)
33174642e01fSmrg	return rc;
331805b261ecSmrg
331905b261ecSmrg    reply.type = X_Reply;
332005b261ecSmrg    reply.sequenceNumber = client->sequence;
33216747b715Smrg    reply.length = bytes_to_int32(stringLens + numpaths);
332205b261ecSmrg    reply.nPaths = numpaths;
332305b261ecSmrg
332405b261ecSmrg    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
332505b261ecSmrg    if (stringLens || numpaths)
332605b261ecSmrg	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
33276747b715Smrg    return Success;
332805b261ecSmrg}
332905b261ecSmrg
333005b261ecSmrgint
333105b261ecSmrgProcChangeCloseDownMode(ClientPtr client)
333205b261ecSmrg{
33334642e01fSmrg    int rc;
333405b261ecSmrg    REQUEST(xSetCloseDownModeReq);
333505b261ecSmrg    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
33364642e01fSmrg
33374642e01fSmrg    rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
33384642e01fSmrg    if (rc != Success)
33394642e01fSmrg	return rc;
33404642e01fSmrg
334105b261ecSmrg    if ((stuff->mode == AllTemporary) ||
334205b261ecSmrg	(stuff->mode == RetainPermanent) ||
334305b261ecSmrg	(stuff->mode == RetainTemporary))
334405b261ecSmrg    {
334505b261ecSmrg	client->closeDownMode = stuff->mode;
33466747b715Smrg	return Success;
334705b261ecSmrg    }
334805b261ecSmrg    else
334905b261ecSmrg    {
335005b261ecSmrg	client->errorValue = stuff->mode;
33516747b715Smrg	return BadValue;
335205b261ecSmrg    }
335305b261ecSmrg}
335405b261ecSmrg
335505b261ecSmrgint ProcForceScreenSaver(ClientPtr client)
335605b261ecSmrg{
33574642e01fSmrg    int rc;
335805b261ecSmrg    REQUEST(xForceScreenSaverReq);
335905b261ecSmrg
336005b261ecSmrg    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
336105b261ecSmrg
336205b261ecSmrg    if ((stuff->mode != ScreenSaverReset) &&
336305b261ecSmrg	(stuff->mode != ScreenSaverActive))
336405b261ecSmrg    {
336505b261ecSmrg	client->errorValue = stuff->mode;
336605b261ecSmrg        return BadValue;
336705b261ecSmrg    }
33684642e01fSmrg    rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode);
33694642e01fSmrg    if (rc != Success)
33704642e01fSmrg	return rc;
33716747b715Smrg    return Success;
337205b261ecSmrg}
337305b261ecSmrg
337405b261ecSmrgint ProcNoOperation(ClientPtr client)
337505b261ecSmrg{
337605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xReq);
337705b261ecSmrg
337805b261ecSmrg    /* noop -- don't do anything */
33796747b715Smrg    return Success;
338005b261ecSmrg}
338105b261ecSmrg
338205b261ecSmrg/**********************
338305b261ecSmrg * CloseDownClient
338405b261ecSmrg *
338505b261ecSmrg *  Client can either mark his resources destroy or retain.  If retained and
338605b261ecSmrg *  then killed again, the client is really destroyed.
338705b261ecSmrg *********************/
338805b261ecSmrg
338905b261ecSmrgchar dispatchExceptionAtReset = DE_RESET;
339005b261ecSmrg
339105b261ecSmrgvoid
339205b261ecSmrgCloseDownClient(ClientPtr client)
339305b261ecSmrg{
339405b261ecSmrg    Bool really_close_down = client->clientGone ||
339505b261ecSmrg			     client->closeDownMode == DestroyAll;
339605b261ecSmrg
339705b261ecSmrg    if (!client->clientGone)
339805b261ecSmrg    {
339905b261ecSmrg	/* ungrab server if grabbing client dies */
340005b261ecSmrg	if (grabState != GrabNone && grabClient == client)
340105b261ecSmrg	{
340205b261ecSmrg	    UngrabServer(client);
340305b261ecSmrg	}
340405b261ecSmrg	BITCLEAR(grabWaiters, client->index);
340505b261ecSmrg	DeleteClientFromAnySelections(client);
340605b261ecSmrg	ReleaseActiveGrabs(client);
340705b261ecSmrg	DeleteClientFontStuff(client);
340805b261ecSmrg	if (!really_close_down)
340905b261ecSmrg	{
341005b261ecSmrg	    /*  This frees resources that should never be retained
341105b261ecSmrg	     *  no matter what the close down mode is.  Actually we
341205b261ecSmrg	     *  could do this unconditionally, but it's probably
341305b261ecSmrg	     *  better not to traverse all the client's resources
341405b261ecSmrg	     *  twice (once here, once a few lines down in
341505b261ecSmrg	     *  FreeClientResources) in the common case of
341605b261ecSmrg	     *  really_close_down == TRUE.
341705b261ecSmrg	     */
341805b261ecSmrg	    FreeClientNeverRetainResources(client);
341905b261ecSmrg	    client->clientState = ClientStateRetained;
342005b261ecSmrg  	    if (ClientStateCallback)
342105b261ecSmrg            {
342205b261ecSmrg		NewClientInfoRec clientinfo;
342305b261ecSmrg
342405b261ecSmrg		clientinfo.client = client;
342505b261ecSmrg		clientinfo.prefix = (xConnSetupPrefix *)NULL;
342605b261ecSmrg		clientinfo.setup = (xConnSetup *) NULL;
342705b261ecSmrg		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
342805b261ecSmrg            }
342905b261ecSmrg	}
343005b261ecSmrg	client->clientGone = TRUE;  /* so events aren't sent to client */
343105b261ecSmrg	if (ClientIsAsleep(client))
343205b261ecSmrg	    ClientSignal (client);
343305b261ecSmrg	ProcessWorkQueueZombies();
343405b261ecSmrg	CloseDownConnection(client);
343505b261ecSmrg
343605b261ecSmrg	/* If the client made it to the Running stage, nClients has
343705b261ecSmrg	 * been incremented on its behalf, so we need to decrement it
343805b261ecSmrg	 * now.  If it hasn't gotten to Running, nClients has *not*
343905b261ecSmrg	 * been incremented, so *don't* decrement it.
344005b261ecSmrg	 */
344105b261ecSmrg	if (client->clientState != ClientStateInitial &&
344205b261ecSmrg	    client->clientState != ClientStateAuthenticating )
344305b261ecSmrg	{
344405b261ecSmrg	    --nClients;
344505b261ecSmrg	}
344605b261ecSmrg    }
344705b261ecSmrg
344805b261ecSmrg    if (really_close_down)
344905b261ecSmrg    {
345005b261ecSmrg	if (client->clientState == ClientStateRunning && nClients == 0)
345105b261ecSmrg	    dispatchException |= dispatchExceptionAtReset;
345205b261ecSmrg
345305b261ecSmrg	client->clientState = ClientStateGone;
345405b261ecSmrg	if (ClientStateCallback)
345505b261ecSmrg	{
345605b261ecSmrg	    NewClientInfoRec clientinfo;
345705b261ecSmrg
345805b261ecSmrg	    clientinfo.client = client;
345905b261ecSmrg	    clientinfo.prefix = (xConnSetupPrefix *)NULL;
346005b261ecSmrg	    clientinfo.setup = (xConnSetup *) NULL;
346105b261ecSmrg	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
346205b261ecSmrg	}
346305b261ecSmrg	FreeClientResources(client);
346405b261ecSmrg#ifdef XSERVER_DTRACE
346505b261ecSmrg	XSERVER_CLIENT_DISCONNECT(client->index);
346605b261ecSmrg#endif
346705b261ecSmrg	if (client->index < nextFreeClientID)
346805b261ecSmrg	    nextFreeClientID = client->index;
346905b261ecSmrg	clients[client->index] = NullClient;
347005b261ecSmrg	SmartLastClient = NullClient;
34716747b715Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
347205b261ecSmrg
347305b261ecSmrg	while (!clients[currentMaxClients-1])
347405b261ecSmrg	    currentMaxClients--;
347505b261ecSmrg    }
347605b261ecSmrg}
347705b261ecSmrg
347805b261ecSmrgstatic void
347905b261ecSmrgKillAllClients(void)
348005b261ecSmrg{
348105b261ecSmrg    int i;
348205b261ecSmrg    for (i=1; i<currentMaxClients; i++)
348305b261ecSmrg        if (clients[i]) {
348405b261ecSmrg            /* Make sure Retained clients are released. */
348505b261ecSmrg            clients[i]->closeDownMode = DestroyAll;
348605b261ecSmrg            CloseDownClient(clients[i]);
348705b261ecSmrg        }
348805b261ecSmrg}
348905b261ecSmrg
349005b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv)
349105b261ecSmrg{
349205b261ecSmrg    client->index = i;
349305b261ecSmrg    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
34944642e01fSmrg    client->closeDownMode = i ? DestroyAll : RetainPermanent;
349505b261ecSmrg    client->requestVector = InitialVector;
349605b261ecSmrg    client->osPrivate = ospriv;
34976747b715Smrg    QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
349805b261ecSmrg    client->smart_start_tick = SmartScheduleTime;
349905b261ecSmrg    client->smart_stop_tick = SmartScheduleTime;
350005b261ecSmrg    client->smart_check_tick = SmartScheduleTime;
350105b261ecSmrg}
350205b261ecSmrg
350305b261ecSmrg/************************
350405b261ecSmrg * int NextAvailableClient(ospriv)
350505b261ecSmrg *
350605b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes.
350705b261ecSmrg * Returns NULL if there are no free clients.
350805b261ecSmrg *************************/
350905b261ecSmrg
351005b261ecSmrgClientPtr NextAvailableClient(pointer ospriv)
351105b261ecSmrg{
351205b261ecSmrg    int i;
351305b261ecSmrg    ClientPtr client;
351405b261ecSmrg    xReq data;
351505b261ecSmrg
351605b261ecSmrg    i = nextFreeClientID;
351705b261ecSmrg    if (i == MAXCLIENTS)
351805b261ecSmrg	return (ClientPtr)NULL;
35196747b715Smrg    clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
352005b261ecSmrg    if (!client)
352105b261ecSmrg	return (ClientPtr)NULL;
352205b261ecSmrg    InitClient(client, i, ospriv);
352305b261ecSmrg    if (!InitClientResources(client))
352405b261ecSmrg    {
35256747b715Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
352605b261ecSmrg	return (ClientPtr)NULL;
352705b261ecSmrg    }
352805b261ecSmrg    data.reqType = 1;
35296747b715Smrg    data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
353005b261ecSmrg    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
353105b261ecSmrg    {
353205b261ecSmrg	FreeClientResources(client);
35336747b715Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
353405b261ecSmrg	return (ClientPtr)NULL;
353505b261ecSmrg    }
353605b261ecSmrg    if (i == currentMaxClients)
353705b261ecSmrg	currentMaxClients++;
353805b261ecSmrg    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
353905b261ecSmrg	nextFreeClientID++;
354005b261ecSmrg    if (ClientStateCallback)
354105b261ecSmrg    {
354205b261ecSmrg	NewClientInfoRec clientinfo;
354305b261ecSmrg
354405b261ecSmrg        clientinfo.client = client;
354505b261ecSmrg        clientinfo.prefix = (xConnSetupPrefix *)NULL;
354605b261ecSmrg        clientinfo.setup = (xConnSetup *) NULL;
354705b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
354805b261ecSmrg    }
35496747b715Smrg    return client;
355005b261ecSmrg}
355105b261ecSmrg
355205b261ecSmrgint
355305b261ecSmrgProcInitialConnection(ClientPtr client)
355405b261ecSmrg{
355505b261ecSmrg    REQUEST(xReq);
355605b261ecSmrg    xConnClientPrefix *prefix;
355705b261ecSmrg    int whichbyte = 1;
355805b261ecSmrg
355905b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
356005b261ecSmrg    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
35616747b715Smrg	return client->noClientException = -1;
356205b261ecSmrg    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
356305b261ecSmrg	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
356405b261ecSmrg    {
356505b261ecSmrg	client->swapped = TRUE;
356605b261ecSmrg	SwapConnClientPrefix(prefix);
356705b261ecSmrg    }
356805b261ecSmrg    stuff->reqType = 2;
35696747b715Smrg    stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
35706747b715Smrg		     bytes_to_int32(prefix->nbytesAuthString);
357105b261ecSmrg    if (client->swapped)
357205b261ecSmrg    {
357305b261ecSmrg	swaps(&stuff->length, whichbyte);
357405b261ecSmrg    }
357505b261ecSmrg    ResetCurrentRequest(client);
35766747b715Smrg    return Success;
357705b261ecSmrg}
357805b261ecSmrg
35794642e01fSmrgstatic int
358005b261ecSmrgSendConnSetup(ClientPtr client, char *reason)
358105b261ecSmrg{
358205b261ecSmrg    xWindowRoot *root;
358305b261ecSmrg    int i;
358405b261ecSmrg    int numScreens;
358505b261ecSmrg    char* lConnectionInfo;
358605b261ecSmrg    xConnSetupPrefix* lconnSetupPrefix;
358705b261ecSmrg
358805b261ecSmrg    if (reason)
358905b261ecSmrg    {
359005b261ecSmrg	xConnSetupPrefix csp;
359105b261ecSmrg
359205b261ecSmrg	csp.success = xFalse;
359305b261ecSmrg	csp.lengthReason = strlen(reason);
35946747b715Smrg	csp.length = bytes_to_int32(csp.lengthReason);
359505b261ecSmrg	csp.majorVersion = X_PROTOCOL;
359605b261ecSmrg	csp.minorVersion = X_PROTOCOL_REVISION;
359705b261ecSmrg	if (client->swapped)
359805b261ecSmrg	    WriteSConnSetupPrefix(client, &csp);
359905b261ecSmrg	else
360005b261ecSmrg	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
360105b261ecSmrg        (void)WriteToClient(client, (int)csp.lengthReason, reason);
36026747b715Smrg	return client->noClientException = -1;
360305b261ecSmrg    }
360405b261ecSmrg
360505b261ecSmrg    numScreens = screenInfo.numScreens;
360605b261ecSmrg    lConnectionInfo = ConnectionInfo;
360705b261ecSmrg    lconnSetupPrefix = &connSetupPrefix;
360805b261ecSmrg
360905b261ecSmrg    /* We're about to start speaking X protocol back to the client by
361005b261ecSmrg     * sending the connection setup info.  This means the authorization
361105b261ecSmrg     * step is complete, and we can count the client as an
361205b261ecSmrg     * authorized one.
361305b261ecSmrg     */
361405b261ecSmrg    nClients++;
361505b261ecSmrg
361605b261ecSmrg    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
361705b261ecSmrg    client->sequence = 0;
361805b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
361905b261ecSmrg    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
362005b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN
362105b261ecSmrg    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
362205b261ecSmrg    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
362305b261ecSmrg#endif
362405b261ecSmrg    /* fill in the "currentInputMask" */
362505b261ecSmrg    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
362605b261ecSmrg#ifdef PANORAMIX
362705b261ecSmrg    if (noPanoramiXExtension)
362805b261ecSmrg	numScreens = screenInfo.numScreens;
362905b261ecSmrg    else
363005b261ecSmrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
363105b261ecSmrg#endif
363205b261ecSmrg
363305b261ecSmrg    for (i=0; i<numScreens; i++)
363405b261ecSmrg    {
363505b261ecSmrg	unsigned int j;
363605b261ecSmrg	xDepth *pDepth;
36376747b715Smrg	WindowPtr pRoot = screenInfo.screens[i]->root;
363805b261ecSmrg
36396747b715Smrg        root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
364005b261ecSmrg	pDepth = (xDepth *)(root + 1);
364105b261ecSmrg	for (j = 0; j < root->nDepths; j++)
364205b261ecSmrg	{
364305b261ecSmrg	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
364405b261ecSmrg				pDepth->nVisuals * sizeof(xVisualType));
364505b261ecSmrg	}
364605b261ecSmrg	root = (xWindowRoot *)pDepth;
364705b261ecSmrg    }
364805b261ecSmrg
364905b261ecSmrg    if (client->swapped)
365005b261ecSmrg    {
365105b261ecSmrg	WriteSConnSetupPrefix(client, lconnSetupPrefix);
365205b261ecSmrg	WriteSConnectionInfo(client,
365305b261ecSmrg			     (unsigned long)(lconnSetupPrefix->length << 2),
365405b261ecSmrg			     lConnectionInfo);
365505b261ecSmrg    }
365605b261ecSmrg    else
365705b261ecSmrg    {
365805b261ecSmrg	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
365905b261ecSmrg			    (char *) lconnSetupPrefix);
366005b261ecSmrg	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
366105b261ecSmrg			    lConnectionInfo);
366205b261ecSmrg    }
366305b261ecSmrg    client->clientState = ClientStateRunning;
366405b261ecSmrg    if (ClientStateCallback)
366505b261ecSmrg    {
366605b261ecSmrg	NewClientInfoRec clientinfo;
366705b261ecSmrg
366805b261ecSmrg        clientinfo.client = client;
366905b261ecSmrg        clientinfo.prefix = lconnSetupPrefix;
367005b261ecSmrg        clientinfo.setup = (xConnSetup *)lConnectionInfo;
367105b261ecSmrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
367205b261ecSmrg    }
36736747b715Smrg    return Success;
367405b261ecSmrg}
367505b261ecSmrg
367605b261ecSmrgint
367705b261ecSmrgProcEstablishConnection(ClientPtr client)
367805b261ecSmrg{
367905b261ecSmrg    char *reason, *auth_proto, *auth_string;
368005b261ecSmrg    xConnClientPrefix *prefix;
368105b261ecSmrg    REQUEST(xReq);
368205b261ecSmrg
368305b261ecSmrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
368405b261ecSmrg    auth_proto = (char *)prefix + sz_xConnClientPrefix;
36856747b715Smrg    auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
368605b261ecSmrg    if ((prefix->majorVersion != X_PROTOCOL) ||
368705b261ecSmrg	(prefix->minorVersion != X_PROTOCOL_REVISION))
368805b261ecSmrg	reason = "Protocol version mismatch";
368905b261ecSmrg    else
369005b261ecSmrg	reason = ClientAuthorized(client,
369105b261ecSmrg				  (unsigned short)prefix->nbytesAuthProto,
369205b261ecSmrg				  auth_proto,
369305b261ecSmrg				  (unsigned short)prefix->nbytesAuthString,
369405b261ecSmrg				  auth_string);
369505b261ecSmrg    /*
369605b261ecSmrg     * If Kerberos is being used for this client, the clientState
369705b261ecSmrg     * will be set to ClientStateAuthenticating at this point.
369805b261ecSmrg     * More messages need to be exchanged among the X server, Kerberos
369905b261ecSmrg     * server, and client to figure out if everyone is authorized.
370005b261ecSmrg     * So we don't want to send the connection setup info yet, since
370105b261ecSmrg     * the auth step isn't really done.
370205b261ecSmrg     */
370305b261ecSmrg    if (client->clientState == ClientStateCheckingSecurity)
370405b261ecSmrg	client->clientState = ClientStateCheckedSecurity;
370505b261ecSmrg    else if (client->clientState != ClientStateAuthenticating)
370605b261ecSmrg	return(SendConnSetup(client, reason));
37076747b715Smrg    return Success;
370805b261ecSmrg}
370905b261ecSmrg
37106747b715Smrgvoid
371105b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
371205b261ecSmrg                  XID resId, int errorCode)
371305b261ecSmrg{
371405b261ecSmrg    xError rep;
371505b261ecSmrg
37166747b715Smrg    memset(&rep, 0, sizeof(xError));
371705b261ecSmrg    rep.type = X_Error;
371805b261ecSmrg    rep.errorCode = errorCode;
371905b261ecSmrg    rep.majorCode = majorCode;
372005b261ecSmrg    rep.minorCode = minorCode;
372105b261ecSmrg    rep.resourceID = resId;
372205b261ecSmrg
372305b261ecSmrg    WriteEventsToClient (client, 1, (xEvent *)&rep);
372405b261ecSmrg}
372505b261ecSmrg
372605b261ecSmrgvoid
372705b261ecSmrgMarkClientException(ClientPtr client)
372805b261ecSmrg{
372905b261ecSmrg    client->noClientException = -1;
373005b261ecSmrg}
37316747b715Smrg
37326747b715Smrg/*
37336747b715Smrg * This array encodes the answer to the question "what is the log base 2
37346747b715Smrg * of the number of pixels that fit in a scanline pad unit?"
37356747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
37366747b715Smrg */
37376747b715Smrgstatic int answer[6][4] = {
37386747b715Smrg	/* pad   pad   pad     pad*/
37396747b715Smrg	/*  8     16    32    64 */
37406747b715Smrg
37416747b715Smrg	{   3,     4,    5 ,   6 },	/* 1 bit per pixel */
37426747b715Smrg	{   1,     2,    3 ,   4 },	/* 4 bits per pixel */
37436747b715Smrg	{   0,     1,    2 ,   3 },	/* 8 bits per pixel */
37446747b715Smrg	{   ~0,    0,    1 ,   2 },	/* 16 bits per pixel */
37456747b715Smrg	{   ~0,    ~0,   0 ,   1 },	/* 24 bits per pixel */
37466747b715Smrg	{   ~0,    ~0,   0 ,   1 }	/* 32 bits per pixel */
37476747b715Smrg};
37486747b715Smrg
37496747b715Smrg/*
37506747b715Smrg * This array gives the answer to the question "what is the first index for
37516747b715Smrg * the answer array above given the number of bits per pixel?"
37526747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
37536747b715Smrg */
37546747b715Smrgstatic int indexForBitsPerPixel[ 33 ] = {
37556747b715Smrg	~0, 0, ~0, ~0,	/* 1 bit per pixel */
37566747b715Smrg	1, ~0, ~0, ~0,	/* 4 bits per pixel */
37576747b715Smrg	2, ~0, ~0, ~0,	/* 8 bits per pixel */
37586747b715Smrg	~0,~0, ~0, ~0,
37596747b715Smrg	3, ~0, ~0, ~0,	/* 16 bits per pixel */
37606747b715Smrg	~0,~0, ~0, ~0,
37616747b715Smrg	4, ~0, ~0, ~0,	/* 24 bits per pixel */
37626747b715Smrg	~0,~0, ~0, ~0,
37636747b715Smrg	5		/* 32 bits per pixel */
37646747b715Smrg};
37656747b715Smrg
37666747b715Smrg/*
37676747b715Smrg * This array gives the bytesperPixel value for cases where the number
37686747b715Smrg * of bits per pixel is a multiple of 8 but not a power of 2.
37696747b715Smrg */
37706747b715Smrgstatic int answerBytesPerPixel[ 33 ] = {
37716747b715Smrg	~0, 0, ~0, ~0,	/* 1 bit per pixel */
37726747b715Smrg	0, ~0, ~0, ~0,	/* 4 bits per pixel */
37736747b715Smrg	0, ~0, ~0, ~0,	/* 8 bits per pixel */
37746747b715Smrg	~0,~0, ~0, ~0,
37756747b715Smrg	0, ~0, ~0, ~0,	/* 16 bits per pixel */
37766747b715Smrg	~0,~0, ~0, ~0,
37776747b715Smrg	3, ~0, ~0, ~0,	/* 24 bits per pixel */
37786747b715Smrg	~0,~0, ~0, ~0,
37796747b715Smrg	0		/* 32 bits per pixel */
37806747b715Smrg};
37816747b715Smrg
37826747b715Smrg/*
37836747b715Smrg * This array gives the answer to the question "what is the second index for
37846747b715Smrg * the answer array above given the number of bits per scanline pad unit?"
37856747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
37866747b715Smrg */
37876747b715Smrgstatic int indexForScanlinePad[ 65 ] = {
37886747b715Smrg	~0, ~0, ~0, ~0,
37896747b715Smrg	~0, ~0, ~0, ~0,
37906747b715Smrg	 0, ~0, ~0, ~0,	/* 8 bits per scanline pad unit */
37916747b715Smrg	~0, ~0, ~0, ~0,
37926747b715Smrg	 1, ~0, ~0, ~0,	/* 16 bits per scanline pad unit */
37936747b715Smrg	~0, ~0, ~0, ~0,
37946747b715Smrg	~0, ~0, ~0, ~0,
37956747b715Smrg	~0, ~0, ~0, ~0,
37966747b715Smrg	 2, ~0, ~0, ~0,	/* 32 bits per scanline pad unit */
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	~0, ~0, ~0, ~0,
38036747b715Smrg	~0, ~0, ~0, ~0,
38046747b715Smrg	 3		/* 64 bits per scanline pad unit */
38056747b715Smrg};
38066747b715Smrg
38076747b715Smrg/*
38086747b715Smrg	grow the array of screenRecs if necessary.
38096747b715Smrg	call the device-supplied initialization procedure
38106747b715Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv.
38116747b715Smrg	return the number of successfully installed screens.
38126747b715Smrg
38136747b715Smrg*/
38146747b715Smrg
38156747b715Smrgint
38166747b715SmrgAddScreen(
38176747b715Smrg    Bool	(* pfnInit)(
38186747b715Smrg	int /*index*/,
38196747b715Smrg	ScreenPtr /*pScreen*/,
38206747b715Smrg	int /*argc*/,
38216747b715Smrg	char ** /*argv*/
38226747b715Smrg		),
38236747b715Smrg    int argc,
38246747b715Smrg    char **argv)
38256747b715Smrg{
38266747b715Smrg
38276747b715Smrg    int i;
38286747b715Smrg    int scanlinepad, format, depth, bitsPerPixel, j, k;
38296747b715Smrg    ScreenPtr pScreen;
38306747b715Smrg
38316747b715Smrg    i = screenInfo.numScreens;
38326747b715Smrg    if (i == MAXSCREENS)
38336747b715Smrg	return -1;
38346747b715Smrg
38356747b715Smrg    pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
38366747b715Smrg    if (!pScreen)
38376747b715Smrg	return -1;
38386747b715Smrg
38396747b715Smrg    if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
38406747b715Smrg	free (pScreen);
38416747b715Smrg	return -1;
38426747b715Smrg    }
38436747b715Smrg    pScreen->myNum = i;
38446747b715Smrg    pScreen->totalPixmapSize = 0;	/* computed in CreateScratchPixmapForScreen */
38456747b715Smrg    pScreen->ClipNotify = 0;	/* for R4 ddx compatibility */
38466747b715Smrg    pScreen->CreateScreenResources = 0;
38476747b715Smrg
38486747b715Smrg    /*
38496747b715Smrg     * This loop gets run once for every Screen that gets added,
38506747b715Smrg     * but thats ok.  If the ddx layer initializes the formats
38516747b715Smrg     * one at a time calling AddScreen() after each, then each
38526747b715Smrg     * iteration will make it a little more accurate.  Worst case
38536747b715Smrg     * we do this loop N * numPixmapFormats where N is # of screens.
38546747b715Smrg     * Anyway, this must be called after InitOutput and before the
38556747b715Smrg     * screen init routine is called.
38566747b715Smrg     */
38576747b715Smrg    for (format=0; format<screenInfo.numPixmapFormats; format++)
38586747b715Smrg    {
38596747b715Smrg	depth = screenInfo.formats[format].depth;
38606747b715Smrg	bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
38616747b715Smrg	scanlinepad = screenInfo.formats[format].scanlinePad;
38626747b715Smrg	j = indexForBitsPerPixel[ bitsPerPixel ];
38636747b715Smrg	k = indexForScanlinePad[ scanlinepad ];
38646747b715Smrg	PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
38656747b715Smrg	PixmapWidthPaddingInfo[ depth ].padRoundUp =
38666747b715Smrg	    (scanlinepad/bitsPerPixel) - 1;
38676747b715Smrg	j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
38686747b715Smrg	PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
38696747b715Smrg	PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
38706747b715Smrg	if (answerBytesPerPixel[bitsPerPixel])
38716747b715Smrg	{
38726747b715Smrg	    PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
38736747b715Smrg	    PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
38746747b715Smrg		answerBytesPerPixel[bitsPerPixel];
38756747b715Smrg	}
38766747b715Smrg	else
38776747b715Smrg	{
38786747b715Smrg	    PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
38796747b715Smrg	}
38806747b715Smrg    }
38816747b715Smrg
38826747b715Smrg    /* This is where screen specific stuff gets initialized.  Load the
38836747b715Smrg       screen structure, call the hardware, whatever.
38846747b715Smrg       This is also where the default colormap should be allocated and
38856747b715Smrg       also pixel values for blackPixel, whitePixel, and the cursor
38866747b715Smrg       Note that InitScreen is NOT allowed to modify argc, argv, or
38876747b715Smrg       any of the strings pointed to by argv.  They may be passed to
38886747b715Smrg       multiple screens.
38896747b715Smrg    */
38906747b715Smrg    screenInfo.screens[i] = pScreen;
38916747b715Smrg    screenInfo.numScreens++;
38926747b715Smrg    if (!(*pfnInit)(i, pScreen, argc, argv))
38936747b715Smrg    {
38946747b715Smrg	dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
38956747b715Smrg	free(pScreen);
38966747b715Smrg	screenInfo.numScreens--;
38976747b715Smrg	return -1;
38986747b715Smrg    }
38996747b715Smrg
39006747b715Smrg    dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0);
39016747b715Smrg
39026747b715Smrg    return i;
39036747b715Smrg}
3904