1706f2543Smrg/************************************************************
2706f2543Smrg
3706f2543SmrgCopyright 1987, 1989, 1998  The Open Group
4706f2543Smrg
5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that
7706f2543Smrgthe above copyright notice appear in all copies and that both that
8706f2543Smrgcopyright notice and this permission notice appear in supporting
9706f2543Smrgdocumentation.
10706f2543Smrg
11706f2543SmrgThe above copyright notice and this permission notice shall be included in
12706f2543Smrgall copies or substantial portions of the Software.
13706f2543Smrg
14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20706f2543Smrg
21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be
22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings
23706f2543Smrgin this Software without prior written authorization from The Open Group.
24706f2543Smrg
25706f2543Smrg
26706f2543SmrgCopyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
27706f2543Smrg
28706f2543Smrg                        All Rights Reserved
29706f2543Smrg
30706f2543SmrgPermission to use, copy, modify, and distribute this software and its
31706f2543Smrgdocumentation for any purpose and without fee is hereby granted,
32706f2543Smrgprovided that the above copyright notice appear in all copies and that
33706f2543Smrgboth that copyright notice and this permission notice appear in
34706f2543Smrgsupporting documentation, and that the name of Digital not be
35706f2543Smrgused in advertising or publicity pertaining to distribution of the
36706f2543Smrgsoftware without specific, written prior permission.
37706f2543Smrg
38706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44706f2543SmrgSOFTWARE.
45706f2543Smrg
46706f2543Smrg********************************************************/
47706f2543Smrg
48706f2543Smrg/* The panoramix components contained the following notice */
49706f2543Smrg/*****************************************************************
50706f2543Smrg
51706f2543SmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
52706f2543Smrg
53706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy
54706f2543Smrgof this software and associated documentation files (the "Software"), to deal
55706f2543Smrgin the Software without restriction, including without limitation the rights
56706f2543Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57706f2543Smrgcopies of the Software.
58706f2543Smrg
59706f2543SmrgThe above copyright notice and this permission notice shall be included in
60706f2543Smrgall copies or substantial portions of the Software.
61706f2543Smrg
62706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
65706f2543SmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
66706f2543SmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
67706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
68706f2543SmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69706f2543Smrg
70706f2543SmrgExcept as contained in this notice, the name of Digital Equipment Corporation
71706f2543Smrgshall not be used in advertising or otherwise to promote the sale, use or other
72706f2543Smrgdealings in this Software without prior written authorization from Digital
73706f2543SmrgEquipment Corporation.
74706f2543Smrg
75706f2543Smrg******************************************************************/
76706f2543Smrg
77706f2543Smrg/* XSERVER_DTRACE additions:
78706f2543Smrg * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
79706f2543Smrg *
80706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
81706f2543Smrg * copy of this software and associated documentation files (the "Software"),
82706f2543Smrg * to deal in the Software without restriction, including without limitation
83706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
85706f2543Smrg * Software is furnished to do so, subject to the following conditions:
86706f2543Smrg *
87706f2543Smrg * The above copyright notice and this permission notice (including the next
88706f2543Smrg * paragraph) shall be included in all copies or substantial portions of the
89706f2543Smrg * Software.
90706f2543Smrg *
91706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
92706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
93706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
94706f2543Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
95706f2543Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
96706f2543Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
97706f2543Smrg * DEALINGS IN THE SOFTWARE.
98706f2543Smrg */
99706f2543Smrg
100706f2543Smrg
101706f2543Smrg
102706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
103706f2543Smrg#include <dix-config.h>
104706f2543Smrg#include <version-config.h>
105706f2543Smrg#endif
106706f2543Smrg
107706f2543Smrg#ifdef PANORAMIX_DEBUG
108706f2543Smrg#include <stdio.h>
109706f2543Smrgint ProcInitialConnection();
110706f2543Smrg#endif
111706f2543Smrg
112706f2543Smrg#include "windowstr.h"
113706f2543Smrg#include <X11/fonts/fontstruct.h>
114706f2543Smrg#include "dixfontstr.h"
115706f2543Smrg#include "gcstruct.h"
116706f2543Smrg#include "selection.h"
117706f2543Smrg#include "colormapst.h"
118706f2543Smrg#include "cursorstr.h"
119706f2543Smrg#include "scrnintstr.h"
120706f2543Smrg#include "opaque.h"
121706f2543Smrg#include "input.h"
122706f2543Smrg#include "servermd.h"
123706f2543Smrg#include "extnsionst.h"
124706f2543Smrg#include "dixfont.h"
125706f2543Smrg#include "dispatch.h"
126706f2543Smrg#include "swaprep.h"
127706f2543Smrg#include "swapreq.h"
128706f2543Smrg#include "privates.h"
129706f2543Smrg#include "xace.h"
130706f2543Smrg#include "inputstr.h"
131706f2543Smrg#include "xkbsrv.h"
132706f2543Smrg#include "site.h"
133706f2543Smrg
134706f2543Smrg#ifdef XSERVER_DTRACE
135706f2543Smrg#include "registry.h"
136706f2543Smrg#include <sys/types.h>
137706f2543Smrgtypedef const char *string;
138706f2543Smrg#include "Xserver-dtrace.h"
139706f2543Smrg#endif
140706f2543Smrg
141706f2543Smrg#define mskcnt ((MAXCLIENTS + 31) / 32)
142706f2543Smrg#define BITMASK(i) (1U << ((i) & 31))
143706f2543Smrg#define MASKIDX(i) ((i) >> 5)
144706f2543Smrg#define MASKWORD(buf, i) buf[MASKIDX(i)]
145706f2543Smrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
146706f2543Smrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
147706f2543Smrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
148706f2543Smrg
149706f2543SmrgxConnSetupPrefix connSetupPrefix;
150706f2543Smrg
151706f2543SmrgPaddingInfo PixmapWidthPaddingInfo[33];
152706f2543Smrg
153706f2543Smrgstatic ClientPtr grabClient;
154706f2543Smrg#define GrabNone 0
155706f2543Smrg#define GrabActive 1
156706f2543Smrg#define GrabKickout 2
157706f2543Smrgstatic int grabState = GrabNone;
158706f2543Smrgstatic long grabWaiters[mskcnt];
159706f2543SmrgCallbackListPtr ServerGrabCallback = NULL;
160706f2543SmrgHWEventQueuePtr checkForInput[2];
161706f2543Smrgint connBlockScreenStart;
162706f2543Smrg
163706f2543Smrgstatic void KillAllClients(void);
164706f2543Smrg
165706f2543Smrgstatic int nextFreeClientID; /* always MIN free client ID */
166706f2543Smrg
167706f2543Smrgstatic int	nClients;	/* number of authorized clients */
168706f2543Smrg
169706f2543SmrgCallbackListPtr ClientStateCallback;
170706f2543Smrg
171706f2543Smrg/* dispatchException & isItTimeToYield must be declared volatile since they
172706f2543Smrg * are modified by signal handlers - otherwise optimizer may assume it doesn't
173706f2543Smrg * need to actually check value in memory when used and may miss changes from
174706f2543Smrg * signal handlers.
175706f2543Smrg */
176706f2543Smrgvolatile char dispatchException = 0;
177706f2543Smrgvolatile char isItTimeToYield;
178706f2543Smrg
179706f2543Smrg#define SAME_SCREENS(a, b) (\
180706f2543Smrg    (a.pScreen == b.pScreen))
181706f2543Smrg
182706f2543Smrgvoid
183706f2543SmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
184706f2543Smrg{
185706f2543Smrg    checkForInput[0] = c0;
186706f2543Smrg    checkForInput[1] = c1;
187706f2543Smrg}
188706f2543Smrg
189706f2543Smrgvoid
190706f2543SmrgUpdateCurrentTime(void)
191706f2543Smrg{
192706f2543Smrg    TimeStamp systime;
193706f2543Smrg
194706f2543Smrg    /* To avoid time running backwards, we must call GetTimeInMillis before
195706f2543Smrg     * calling ProcessInputEvents.
196706f2543Smrg     */
197706f2543Smrg    systime.months = currentTime.months;
198706f2543Smrg    systime.milliseconds = GetTimeInMillis();
199706f2543Smrg    if (systime.milliseconds < currentTime.milliseconds)
200706f2543Smrg	systime.months++;
201706f2543Smrg    if (*checkForInput[0] != *checkForInput[1])
202706f2543Smrg	ProcessInputEvents();
203706f2543Smrg    if (CompareTimeStamps(systime, currentTime) == LATER)
204706f2543Smrg	currentTime = systime;
205706f2543Smrg}
206706f2543Smrg
207706f2543Smrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
208706f2543Smrgvoid
209706f2543SmrgUpdateCurrentTimeIf(void)
210706f2543Smrg{
211706f2543Smrg    TimeStamp systime;
212706f2543Smrg
213706f2543Smrg    systime.months = currentTime.months;
214706f2543Smrg    systime.milliseconds = GetTimeInMillis();
215706f2543Smrg    if (systime.milliseconds < currentTime.milliseconds)
216706f2543Smrg	systime.months++;
217706f2543Smrg    if (*checkForInput[0] == *checkForInput[1])
218706f2543Smrg	currentTime = systime;
219706f2543Smrg}
220706f2543Smrg
221706f2543Smrg
222706f2543Smrg#undef SMART_DEBUG
223706f2543Smrg
224706f2543Smrg#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
225706f2543Smrg#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
226706f2543Smrg
227706f2543SmrgBool SmartScheduleDisable = FALSE;
228706f2543Smrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
229706f2543Smrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
230706f2543Smrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
231706f2543Smrglong SmartScheduleTime;
232706f2543Smrgint SmartScheduleLatencyLimited = 0;
233706f2543Smrgstatic ClientPtr   SmartLastClient;
234706f2543Smrgstatic int	   SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
235706f2543Smrg
236706f2543Smrg#ifdef SMART_DEBUG
237706f2543Smrglong	    SmartLastPrint;
238706f2543Smrg#endif
239706f2543Smrg
240706f2543Smrgvoid        Dispatch(void);
241706f2543Smrg
242706f2543Smrgstatic int
243706f2543SmrgSmartScheduleClient (int *clientReady, int nready)
244706f2543Smrg{
245706f2543Smrg    ClientPtr	pClient;
246706f2543Smrg    int		i;
247706f2543Smrg    int		client;
248706f2543Smrg    int		bestPrio, best = 0;
249706f2543Smrg    int		bestRobin, robin;
250706f2543Smrg    long	now = SmartScheduleTime;
251706f2543Smrg    long	idle;
252706f2543Smrg
253706f2543Smrg    bestPrio = -0x7fffffff;
254706f2543Smrg    bestRobin = 0;
255706f2543Smrg    idle = 2 * SmartScheduleSlice;
256706f2543Smrg    for (i = 0; i < nready; i++)
257706f2543Smrg    {
258706f2543Smrg	client = clientReady[i];
259706f2543Smrg	pClient = clients[client];
260706f2543Smrg	/* Praise clients which are idle */
261706f2543Smrg	if ((now - pClient->smart_check_tick) >= idle)
262706f2543Smrg	{
263706f2543Smrg	    if (pClient->smart_priority < 0)
264706f2543Smrg		pClient->smart_priority++;
265706f2543Smrg	}
266706f2543Smrg	pClient->smart_check_tick = now;
267706f2543Smrg
268706f2543Smrg	/* check priority to select best client */
269706f2543Smrg	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
270706f2543Smrg	if (pClient->smart_priority > bestPrio ||
271706f2543Smrg	    (pClient->smart_priority == bestPrio && robin > bestRobin))
272706f2543Smrg	{
273706f2543Smrg	    bestPrio = pClient->smart_priority;
274706f2543Smrg	    bestRobin = robin;
275706f2543Smrg	    best = client;
276706f2543Smrg	}
277706f2543Smrg#ifdef SMART_DEBUG
278706f2543Smrg	if ((now - SmartLastPrint) >= 5000)
279706f2543Smrg	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
280706f2543Smrg#endif
281706f2543Smrg    }
282706f2543Smrg#ifdef SMART_DEBUG
283706f2543Smrg    if ((now - SmartLastPrint) >= 5000)
284706f2543Smrg    {
285706f2543Smrg	fprintf (stderr, " use %2d\n", best);
286706f2543Smrg	SmartLastPrint = now;
287706f2543Smrg    }
288706f2543Smrg#endif
289706f2543Smrg    pClient = clients[best];
290706f2543Smrg    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
291706f2543Smrg    /*
292706f2543Smrg     * Set current client pointer
293706f2543Smrg     */
294706f2543Smrg    if (SmartLastClient != pClient)
295706f2543Smrg    {
296706f2543Smrg	pClient->smart_start_tick = now;
297706f2543Smrg	SmartLastClient = pClient;
298706f2543Smrg    }
299706f2543Smrg    /*
300706f2543Smrg     * Adjust slice
301706f2543Smrg     */
302706f2543Smrg    if (nready == 1 && SmartScheduleLatencyLimited == 0)
303706f2543Smrg    {
304706f2543Smrg	/*
305706f2543Smrg	 * If it's been a long time since another client
306706f2543Smrg	 * has run, bump the slice up to get maximal
307706f2543Smrg	 * performance from a single client
308706f2543Smrg	 */
309706f2543Smrg	if ((now - pClient->smart_start_tick) > 1000 &&
310706f2543Smrg	    SmartScheduleSlice < SmartScheduleMaxSlice)
311706f2543Smrg	{
312706f2543Smrg	    SmartScheduleSlice += SmartScheduleInterval;
313706f2543Smrg	}
314706f2543Smrg    }
315706f2543Smrg    else
316706f2543Smrg    {
317706f2543Smrg	SmartScheduleSlice = SmartScheduleInterval;
318706f2543Smrg    }
319706f2543Smrg    return best;
320706f2543Smrg}
321706f2543Smrg
322706f2543Smrgvoid
323706f2543SmrgEnableLimitedSchedulingLatency(void)
324706f2543Smrg{
325706f2543Smrg    ++SmartScheduleLatencyLimited;
326706f2543Smrg    SmartScheduleSlice = SmartScheduleInterval;
327706f2543Smrg}
328706f2543Smrg
329706f2543Smrgvoid
330706f2543SmrgDisableLimitedSchedulingLatency(void)
331706f2543Smrg{
332706f2543Smrg    --SmartScheduleLatencyLimited;
333706f2543Smrg
334706f2543Smrg    /* protect against bugs */
335706f2543Smrg    if (SmartScheduleLatencyLimited < 0)
336706f2543Smrg	SmartScheduleLatencyLimited = 0;
337706f2543Smrg}
338706f2543Smrg
339706f2543Smrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType
340706f2543Smrg
341706f2543Smrgvoid
342706f2543SmrgDispatch(void)
343706f2543Smrg{
344706f2543Smrg    int        *clientReady;     /* array of request ready clients */
345706f2543Smrg    int	result;
346706f2543Smrg    ClientPtr	client;
347706f2543Smrg    int	nready;
348706f2543Smrg    HWEventQueuePtr* icheck = checkForInput;
349706f2543Smrg    long			start_tick;
350706f2543Smrg
351706f2543Smrg    nextFreeClientID = 1;
352706f2543Smrg    nClients = 0;
353706f2543Smrg
354706f2543Smrg    clientReady = malloc(sizeof(int) * MaxClients);
355706f2543Smrg    if (!clientReady)
356706f2543Smrg	return;
357706f2543Smrg
358706f2543Smrg    SmartScheduleSlice = SmartScheduleInterval;
359706f2543Smrg    while (!dispatchException)
360706f2543Smrg    {
361706f2543Smrg        if (*icheck[0] != *icheck[1])
362706f2543Smrg	{
363706f2543Smrg	    ProcessInputEvents();
364706f2543Smrg	    FlushIfCriticalOutputPending();
365706f2543Smrg	}
366706f2543Smrg
367706f2543Smrg	nready = WaitForSomething(clientReady);
368706f2543Smrg
369706f2543Smrg	if (nready && !SmartScheduleDisable)
370706f2543Smrg	{
371706f2543Smrg	    clientReady[0] = SmartScheduleClient (clientReady, nready);
372706f2543Smrg	    nready = 1;
373706f2543Smrg	}
374706f2543Smrg       /*****************
375706f2543Smrg	*  Handle events in round robin fashion, doing input between
376706f2543Smrg	*  each round
377706f2543Smrg	*****************/
378706f2543Smrg
379706f2543Smrg	while (!dispatchException && (--nready >= 0))
380706f2543Smrg	{
381706f2543Smrg	    client = clients[clientReady[nready]];
382706f2543Smrg	    if (! client)
383706f2543Smrg	    {
384706f2543Smrg		/* KillClient can cause this to happen */
385706f2543Smrg		continue;
386706f2543Smrg	    }
387706f2543Smrg	    /* GrabServer activation can cause this to be true */
388706f2543Smrg	    if (grabState == GrabKickout)
389706f2543Smrg	    {
390706f2543Smrg		grabState = GrabActive;
391706f2543Smrg		break;
392706f2543Smrg	    }
393706f2543Smrg	    isItTimeToYield = FALSE;
394706f2543Smrg
395706f2543Smrg	    start_tick = SmartScheduleTime;
396706f2543Smrg	    while (!isItTimeToYield)
397706f2543Smrg	    {
398706f2543Smrg	        if (*icheck[0] != *icheck[1])
399706f2543Smrg		    ProcessInputEvents();
400706f2543Smrg
401706f2543Smrg		FlushIfCriticalOutputPending();
402706f2543Smrg		if (!SmartScheduleDisable &&
403706f2543Smrg		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
404706f2543Smrg		{
405706f2543Smrg		    /* Penalize clients which consume ticks */
406706f2543Smrg		    if (client->smart_priority > SMART_MIN_PRIORITY)
407706f2543Smrg			client->smart_priority--;
408706f2543Smrg		    break;
409706f2543Smrg		}
410706f2543Smrg		/* now, finally, deal with client requests */
411706f2543Smrg
412706f2543Smrg	        result = ReadRequestFromClient(client);
413706f2543Smrg	        if (result <= 0)
414706f2543Smrg	        {
415706f2543Smrg		    if (result < 0)
416706f2543Smrg			CloseDownClient(client);
417706f2543Smrg		    break;
418706f2543Smrg	        }
419706f2543Smrg
420706f2543Smrg		client->sequence++;
421706f2543Smrg#ifdef XSERVER_DTRACE
422706f2543Smrg		XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
423706f2543Smrg			      ((xReq *)client->requestBuffer)->length,
424706f2543Smrg			      client->index, client->requestBuffer);
425706f2543Smrg#endif
426706f2543Smrg		if (result > (maxBigRequestSize << 2))
427706f2543Smrg		    result = BadLength;
428706f2543Smrg		else {
429706f2543Smrg		    result = XaceHookDispatch(client, MAJOROP);
430706f2543Smrg		    if (result == Success)
431706f2543Smrg			result = (* client->requestVector[MAJOROP])(client);
432706f2543Smrg		    XaceHookAuditEnd(client, result);
433706f2543Smrg		}
434706f2543Smrg#ifdef XSERVER_DTRACE
435706f2543Smrg		XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
436706f2543Smrg			      client->sequence, client->index, result);
437706f2543Smrg#endif
438706f2543Smrg
439706f2543Smrg		if (client->noClientException != Success)
440706f2543Smrg		{
441706f2543Smrg		    CloseDownClient(client);
442706f2543Smrg		    break;
443706f2543Smrg		}
444706f2543Smrg		else if (result != Success)
445706f2543Smrg		{
446706f2543Smrg		    SendErrorToClient(client, MAJOROP,
447706f2543Smrg				      MinorOpcodeOfRequest(client),
448706f2543Smrg				      client->errorValue, result);
449706f2543Smrg		    break;
450706f2543Smrg		}
451706f2543Smrg	    }
452706f2543Smrg	    FlushAllOutput();
453706f2543Smrg	    client = clients[clientReady[nready]];
454706f2543Smrg	    if (client)
455706f2543Smrg		client->smart_stop_tick = SmartScheduleTime;
456706f2543Smrg	}
457706f2543Smrg	dispatchException &= ~DE_PRIORITYCHANGE;
458706f2543Smrg    }
459706f2543Smrg#if defined(DDXBEFORERESET)
460706f2543Smrg    ddxBeforeReset ();
461706f2543Smrg#endif
462706f2543Smrg    KillAllClients();
463706f2543Smrg    free(clientReady);
464706f2543Smrg    dispatchException &= ~DE_RESET;
465706f2543Smrg    SmartScheduleLatencyLimited = 0;
466706f2543Smrg}
467706f2543Smrg
468706f2543Smrg#undef MAJOROP
469706f2543Smrg
470706f2543Smrgstatic int  VendorRelease = VENDOR_RELEASE;
471706f2543Smrgstatic char *VendorString = VENDOR_NAME;
472706f2543Smrg
473706f2543Smrgstatic const int padlength[4] = {0, 3, 2, 1};
474706f2543Smrg
475706f2543Smrgvoid
476706f2543SmrgSetVendorRelease(int release)
477706f2543Smrg{
478706f2543Smrg    VendorRelease = release;
479706f2543Smrg}
480706f2543Smrg
481706f2543Smrgvoid
482706f2543SmrgSetVendorString(char *string)
483706f2543Smrg{
484706f2543Smrg    VendorString = string;
485706f2543Smrg}
486706f2543Smrg
487706f2543SmrgBool
488706f2543SmrgCreateConnectionBlock(void)
489706f2543Smrg{
490706f2543Smrg    xConnSetup setup;
491706f2543Smrg    xWindowRoot root;
492706f2543Smrg    xDepth	depth;
493706f2543Smrg    xVisualType visual;
494706f2543Smrg    xPixmapFormat format;
495706f2543Smrg    unsigned long vid;
496706f2543Smrg    int i, j, k,
497706f2543Smrg        lenofblock,
498706f2543Smrg        sizesofar = 0;
499706f2543Smrg    char *pBuf;
500706f2543Smrg
501706f2543Smrg
502706f2543Smrg    memset(&setup, 0, sizeof(xConnSetup));
503706f2543Smrg    /* Leave off the ridBase and ridMask, these must be sent with
504706f2543Smrg       connection */
505706f2543Smrg
506706f2543Smrg    setup.release = VendorRelease;
507706f2543Smrg    /*
508706f2543Smrg     * per-server image and bitmap parameters are defined in Xmd.h
509706f2543Smrg     */
510706f2543Smrg    setup.imageByteOrder = screenInfo.imageByteOrder;
511706f2543Smrg
512706f2543Smrg    setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
513706f2543Smrg    setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
514706f2543Smrg
515706f2543Smrg    setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
516706f2543Smrg    setup.motionBufferSize = NumMotionEvents();
517706f2543Smrg    setup.numRoots = screenInfo.numScreens;
518706f2543Smrg    setup.nbytesVendor = strlen(VendorString);
519706f2543Smrg    setup.numFormats = screenInfo.numPixmapFormats;
520706f2543Smrg    setup.maxRequestSize = MAX_REQUEST_SIZE;
521706f2543Smrg    QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
522706f2543Smrg
523706f2543Smrg    lenofblock = sizeof(xConnSetup) +
524706f2543Smrg            pad_to_int32(setup.nbytesVendor) +
525706f2543Smrg	    (setup.numFormats * sizeof(xPixmapFormat)) +
526706f2543Smrg            (setup.numRoots * sizeof(xWindowRoot));
527706f2543Smrg    ConnectionInfo = malloc(lenofblock);
528706f2543Smrg    if (!ConnectionInfo)
529706f2543Smrg	return FALSE;
530706f2543Smrg
531706f2543Smrg    memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
532706f2543Smrg    sizesofar = sizeof(xConnSetup);
533706f2543Smrg    pBuf = ConnectionInfo + sizeof(xConnSetup);
534706f2543Smrg
535706f2543Smrg    memmove(pBuf, VendorString, (int)setup.nbytesVendor);
536706f2543Smrg    sizesofar += setup.nbytesVendor;
537706f2543Smrg    pBuf += setup.nbytesVendor;
538706f2543Smrg    i = padlength[setup.nbytesVendor & 3];
539706f2543Smrg    sizesofar += i;
540706f2543Smrg    while (--i >= 0)
541706f2543Smrg	*pBuf++ = 0;
542706f2543Smrg
543706f2543Smrg    memset(&format, 0, sizeof(xPixmapFormat));
544706f2543Smrg    for (i=0; i<screenInfo.numPixmapFormats; i++)
545706f2543Smrg    {
546706f2543Smrg	format.depth = screenInfo.formats[i].depth;
547706f2543Smrg	format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
548706f2543Smrg	format.scanLinePad = screenInfo.formats[i].scanlinePad;
549706f2543Smrg	memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
550706f2543Smrg	pBuf += sizeof(xPixmapFormat);
551706f2543Smrg	sizesofar += sizeof(xPixmapFormat);
552706f2543Smrg    }
553706f2543Smrg
554706f2543Smrg    connBlockScreenStart = sizesofar;
555706f2543Smrg    memset(&depth, 0, sizeof(xDepth));
556706f2543Smrg    memset(&visual, 0, sizeof(xVisualType));
557706f2543Smrg    for (i=0; i<screenInfo.numScreens; i++)
558706f2543Smrg    {
559706f2543Smrg	ScreenPtr	pScreen;
560706f2543Smrg	DepthPtr	pDepth;
561706f2543Smrg	VisualPtr	pVisual;
562706f2543Smrg
563706f2543Smrg	pScreen = screenInfo.screens[i];
564706f2543Smrg	root.windowId = pScreen->root->drawable.id;
565706f2543Smrg	root.defaultColormap = pScreen->defColormap;
566706f2543Smrg	root.whitePixel = pScreen->whitePixel;
567706f2543Smrg	root.blackPixel = pScreen->blackPixel;
568706f2543Smrg	root.currentInputMask = 0;    /* filled in when sent */
569706f2543Smrg	root.pixWidth = pScreen->width;
570706f2543Smrg	root.pixHeight = pScreen->height;
571706f2543Smrg	root.mmWidth = pScreen->mmWidth;
572706f2543Smrg	root.mmHeight = pScreen->mmHeight;
573706f2543Smrg	root.minInstalledMaps = pScreen->minInstalledCmaps;
574706f2543Smrg	root.maxInstalledMaps = pScreen->maxInstalledCmaps;
575706f2543Smrg	root.rootVisualID = pScreen->rootVisual;
576706f2543Smrg	root.backingStore = pScreen->backingStoreSupport;
577706f2543Smrg	root.saveUnders = FALSE;
578706f2543Smrg	root.rootDepth = pScreen->rootDepth;
579706f2543Smrg	root.nDepths = pScreen->numDepths;
580706f2543Smrg	memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
581706f2543Smrg	sizesofar += sizeof(xWindowRoot);
582706f2543Smrg	pBuf += sizeof(xWindowRoot);
583706f2543Smrg
584706f2543Smrg	pDepth = pScreen->allowedDepths;
585706f2543Smrg	for(j = 0; j < pScreen->numDepths; j++, pDepth++)
586706f2543Smrg	{
587706f2543Smrg	    lenofblock += sizeof(xDepth) +
588706f2543Smrg		    (pDepth->numVids * sizeof(xVisualType));
589706f2543Smrg	    pBuf = (char *)realloc(ConnectionInfo, lenofblock);
590706f2543Smrg	    if (!pBuf)
591706f2543Smrg	    {
592706f2543Smrg		free(ConnectionInfo);
593706f2543Smrg		return FALSE;
594706f2543Smrg	    }
595706f2543Smrg	    ConnectionInfo = pBuf;
596706f2543Smrg	    pBuf += sizesofar;
597706f2543Smrg	    depth.depth = pDepth->depth;
598706f2543Smrg	    depth.nVisuals = pDepth->numVids;
599706f2543Smrg	    memmove(pBuf, (char *)&depth, sizeof(xDepth));
600706f2543Smrg	    pBuf += sizeof(xDepth);
601706f2543Smrg	    sizesofar += sizeof(xDepth);
602706f2543Smrg	    for(k = 0; k < pDepth->numVids; k++)
603706f2543Smrg	    {
604706f2543Smrg		vid = pDepth->vids[k];
605706f2543Smrg		for (pVisual = pScreen->visuals;
606706f2543Smrg		     pVisual->vid != vid;
607706f2543Smrg		     pVisual++)
608706f2543Smrg		    ;
609706f2543Smrg		visual.visualID = vid;
610706f2543Smrg		visual.class = pVisual->class;
611706f2543Smrg		visual.bitsPerRGB = pVisual->bitsPerRGBValue;
612706f2543Smrg		visual.colormapEntries = pVisual->ColormapEntries;
613706f2543Smrg		visual.redMask = pVisual->redMask;
614706f2543Smrg		visual.greenMask = pVisual->greenMask;
615706f2543Smrg		visual.blueMask = pVisual->blueMask;
616706f2543Smrg		memmove(pBuf, (char *)&visual, sizeof(xVisualType));
617706f2543Smrg		pBuf += sizeof(xVisualType);
618706f2543Smrg		sizesofar += sizeof(xVisualType);
619706f2543Smrg	    }
620706f2543Smrg	}
621706f2543Smrg    }
622706f2543Smrg    connSetupPrefix.success = xTrue;
623706f2543Smrg    connSetupPrefix.length = lenofblock/4;
624706f2543Smrg    connSetupPrefix.majorVersion = X_PROTOCOL;
625706f2543Smrg    connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
626706f2543Smrg    return TRUE;
627706f2543Smrg}
628706f2543Smrg
629706f2543Smrg
630706f2543Smrgint
631706f2543SmrgProcBadRequest(ClientPtr client)
632706f2543Smrg{
633706f2543Smrg    return BadRequest;
634706f2543Smrg}
635706f2543Smrg
636706f2543Smrgint
637706f2543SmrgProcCreateWindow(ClientPtr client)
638706f2543Smrg{
639706f2543Smrg    WindowPtr pParent, pWin;
640706f2543Smrg    REQUEST(xCreateWindowReq);
641706f2543Smrg    int len, rc;
642706f2543Smrg
643706f2543Smrg    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
644706f2543Smrg
645706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->wid, client);
646706f2543Smrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
647706f2543Smrg    if (rc != Success)
648706f2543Smrg        return rc;
649706f2543Smrg    len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
650706f2543Smrg    if (Ones(stuff->mask) != len)
651706f2543Smrg        return BadLength;
652706f2543Smrg    if (!stuff->width || !stuff->height)
653706f2543Smrg    {
654706f2543Smrg	client->errorValue = 0;
655706f2543Smrg        return BadValue;
656706f2543Smrg    }
657706f2543Smrg    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
658706f2543Smrg			      stuff->y, stuff->width, stuff->height,
659706f2543Smrg			      stuff->borderWidth, stuff->class,
660706f2543Smrg			      stuff->mask, (XID *) &stuff[1],
661706f2543Smrg			      (int)stuff->depth,
662706f2543Smrg			      client, stuff->visual, &rc);
663706f2543Smrg    if (pWin)
664706f2543Smrg    {
665706f2543Smrg	Mask mask = pWin->eventMask;
666706f2543Smrg
667706f2543Smrg	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
668706f2543Smrg	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
669706f2543Smrg	    return BadAlloc;
670706f2543Smrg	pWin->eventMask = mask;
671706f2543Smrg    }
672706f2543Smrg    return rc;
673706f2543Smrg}
674706f2543Smrg
675706f2543Smrgint
676706f2543SmrgProcChangeWindowAttributes(ClientPtr client)
677706f2543Smrg{
678706f2543Smrg    WindowPtr pWin;
679706f2543Smrg    REQUEST(xChangeWindowAttributesReq);
680706f2543Smrg    int len, rc;
681706f2543Smrg    Mask access_mode = 0;
682706f2543Smrg
683706f2543Smrg    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
684706f2543Smrg    access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
685706f2543Smrg    access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
686706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
687706f2543Smrg    if (rc != Success)
688706f2543Smrg        return rc;
689706f2543Smrg    len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
690706f2543Smrg    if (len != Ones(stuff->valueMask))
691706f2543Smrg        return BadLength;
692706f2543Smrg    return ChangeWindowAttributes(pWin,
693706f2543Smrg				  stuff->valueMask,
694706f2543Smrg				  (XID *) &stuff[1],
695706f2543Smrg				  client);
696706f2543Smrg}
697706f2543Smrg
698706f2543Smrgint
699706f2543SmrgProcGetWindowAttributes(ClientPtr client)
700706f2543Smrg{
701706f2543Smrg    WindowPtr pWin;
702706f2543Smrg    REQUEST(xResourceReq);
703706f2543Smrg    xGetWindowAttributesReply wa;
704706f2543Smrg    int rc;
705706f2543Smrg
706706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
707706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
708706f2543Smrg    if (rc != Success)
709706f2543Smrg	return rc;
710706f2543Smrg    memset(&wa, 0, sizeof(xGetWindowAttributesReply));
711706f2543Smrg    GetWindowAttributes(pWin, client, &wa);
712706f2543Smrg    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
713706f2543Smrg    return Success;
714706f2543Smrg}
715706f2543Smrg
716706f2543Smrgint
717706f2543SmrgProcDestroyWindow(ClientPtr client)
718706f2543Smrg{
719706f2543Smrg    WindowPtr pWin;
720706f2543Smrg    REQUEST(xResourceReq);
721706f2543Smrg    int rc;
722706f2543Smrg
723706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
724706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
725706f2543Smrg    if (rc != Success)
726706f2543Smrg	return rc;
727706f2543Smrg    if (pWin->parent) {
728706f2543Smrg	rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
729706f2543Smrg			     DixRemoveAccess);
730706f2543Smrg	if (rc != Success)
731706f2543Smrg	    return rc;
732706f2543Smrg	FreeResource(stuff->id, RT_NONE);
733706f2543Smrg    }
734706f2543Smrg    return Success;
735706f2543Smrg}
736706f2543Smrg
737706f2543Smrgint
738706f2543SmrgProcDestroySubwindows(ClientPtr client)
739706f2543Smrg{
740706f2543Smrg    WindowPtr pWin;
741706f2543Smrg    REQUEST(xResourceReq);
742706f2543Smrg    int rc;
743706f2543Smrg
744706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
745706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
746706f2543Smrg    if (rc != Success)
747706f2543Smrg	return rc;
748706f2543Smrg    DestroySubwindows(pWin, client);
749706f2543Smrg    return Success;
750706f2543Smrg}
751706f2543Smrg
752706f2543Smrgint
753706f2543SmrgProcChangeSaveSet(ClientPtr client)
754706f2543Smrg{
755706f2543Smrg    WindowPtr pWin;
756706f2543Smrg    REQUEST(xChangeSaveSetReq);
757706f2543Smrg    int rc;
758706f2543Smrg
759706f2543Smrg    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
760706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
761706f2543Smrg    if (rc != Success)
762706f2543Smrg        return rc;
763706f2543Smrg    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
764706f2543Smrg        return BadMatch;
765706f2543Smrg    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
766706f2543Smrg        return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
767706f2543Smrg    client->errorValue = stuff->mode;
768706f2543Smrg    return BadValue;
769706f2543Smrg}
770706f2543Smrg
771706f2543Smrgint
772706f2543SmrgProcReparentWindow(ClientPtr client)
773706f2543Smrg{
774706f2543Smrg    WindowPtr pWin, pParent;
775706f2543Smrg    REQUEST(xReparentWindowReq);
776706f2543Smrg    int rc;
777706f2543Smrg
778706f2543Smrg    REQUEST_SIZE_MATCH(xReparentWindowReq);
779706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
780706f2543Smrg    if (rc != Success)
781706f2543Smrg        return rc;
782706f2543Smrg    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
783706f2543Smrg    if (rc != Success)
784706f2543Smrg        return rc;
785706f2543Smrg    if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
786706f2543Smrg	return BadMatch;
787706f2543Smrg    if ((pWin->backgroundState == ParentRelative) &&
788706f2543Smrg	(pParent->drawable.depth != pWin->drawable.depth))
789706f2543Smrg	return BadMatch;
790706f2543Smrg    if ((pWin->drawable.class != InputOnly) &&
791706f2543Smrg	(pParent->drawable.class == InputOnly))
792706f2543Smrg	return BadMatch;
793706f2543Smrg    return ReparentWindow(pWin, pParent,
794706f2543Smrg		     (short)stuff->x, (short)stuff->y, client);
795706f2543Smrg}
796706f2543Smrg
797706f2543Smrgint
798706f2543SmrgProcMapWindow(ClientPtr client)
799706f2543Smrg{
800706f2543Smrg    WindowPtr pWin;
801706f2543Smrg    REQUEST(xResourceReq);
802706f2543Smrg    int rc;
803706f2543Smrg
804706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
805706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
806706f2543Smrg    if (rc != Success)
807706f2543Smrg        return rc;
808706f2543Smrg    MapWindow(pWin, client);
809706f2543Smrg           /* update cache to say it is mapped */
810706f2543Smrg    return Success;
811706f2543Smrg}
812706f2543Smrg
813706f2543Smrgint
814706f2543SmrgProcMapSubwindows(ClientPtr client)
815706f2543Smrg{
816706f2543Smrg    WindowPtr pWin;
817706f2543Smrg    REQUEST(xResourceReq);
818706f2543Smrg    int rc;
819706f2543Smrg
820706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
821706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
822706f2543Smrg    if (rc != Success)
823706f2543Smrg        return rc;
824706f2543Smrg    MapSubwindows(pWin, client);
825706f2543Smrg           /* update cache to say it is mapped */
826706f2543Smrg    return Success;
827706f2543Smrg}
828706f2543Smrg
829706f2543Smrgint
830706f2543SmrgProcUnmapWindow(ClientPtr client)
831706f2543Smrg{
832706f2543Smrg    WindowPtr pWin;
833706f2543Smrg    REQUEST(xResourceReq);
834706f2543Smrg    int rc;
835706f2543Smrg
836706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
837706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
838706f2543Smrg    if (rc != Success)
839706f2543Smrg        return rc;
840706f2543Smrg    UnmapWindow(pWin, FALSE);
841706f2543Smrg           /* update cache to say it is mapped */
842706f2543Smrg    return Success;
843706f2543Smrg}
844706f2543Smrg
845706f2543Smrgint
846706f2543SmrgProcUnmapSubwindows(ClientPtr client)
847706f2543Smrg{
848706f2543Smrg    WindowPtr pWin;
849706f2543Smrg    REQUEST(xResourceReq);
850706f2543Smrg    int rc;
851706f2543Smrg
852706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
853706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
854706f2543Smrg    if (rc != Success)
855706f2543Smrg        return rc;
856706f2543Smrg    UnmapSubwindows(pWin);
857706f2543Smrg    return Success;
858706f2543Smrg}
859706f2543Smrg
860706f2543Smrgint
861706f2543SmrgProcConfigureWindow(ClientPtr client)
862706f2543Smrg{
863706f2543Smrg    WindowPtr pWin;
864706f2543Smrg    REQUEST(xConfigureWindowReq);
865706f2543Smrg    int len, rc;
866706f2543Smrg
867706f2543Smrg    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
868706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->window, client,
869706f2543Smrg			 DixManageAccess|DixSetAttrAccess);
870706f2543Smrg    if (rc != Success)
871706f2543Smrg        return rc;
872706f2543Smrg    len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
873706f2543Smrg    if (Ones((Mask)stuff->mask) != len)
874706f2543Smrg        return BadLength;
875706f2543Smrg    return ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], client);
876706f2543Smrg}
877706f2543Smrg
878706f2543Smrgint
879706f2543SmrgProcCirculateWindow(ClientPtr client)
880706f2543Smrg{
881706f2543Smrg    WindowPtr pWin;
882706f2543Smrg    REQUEST(xCirculateWindowReq);
883706f2543Smrg    int rc;
884706f2543Smrg
885706f2543Smrg    REQUEST_SIZE_MATCH(xCirculateWindowReq);
886706f2543Smrg    if ((stuff->direction != RaiseLowest) &&
887706f2543Smrg	(stuff->direction != LowerHighest))
888706f2543Smrg    {
889706f2543Smrg	client->errorValue = stuff->direction;
890706f2543Smrg        return BadValue;
891706f2543Smrg    }
892706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
893706f2543Smrg    if (rc != Success)
894706f2543Smrg        return rc;
895706f2543Smrg    CirculateWindow(pWin, (int)stuff->direction, client);
896706f2543Smrg    return Success;
897706f2543Smrg}
898706f2543Smrg
899706f2543Smrgstatic int
900706f2543SmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep)
901706f2543Smrg{
902706f2543Smrg    DrawablePtr pDraw;
903706f2543Smrg    int rc;
904706f2543Smrg    REQUEST(xResourceReq);
905706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
906706f2543Smrg
907706f2543Smrg    rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
908706f2543Smrg    if (rc != Success)
909706f2543Smrg	return rc;
910706f2543Smrg
911706f2543Smrg    rep->type = X_Reply;
912706f2543Smrg    rep->length = 0;
913706f2543Smrg    rep->sequenceNumber = client->sequence;
914706f2543Smrg    rep->root = pDraw->pScreen->root->drawable.id;
915706f2543Smrg    rep->depth = pDraw->depth;
916706f2543Smrg    rep->width = pDraw->width;
917706f2543Smrg    rep->height = pDraw->height;
918706f2543Smrg
919706f2543Smrg    if (WindowDrawable(pDraw->type))
920706f2543Smrg    {
921706f2543Smrg        WindowPtr pWin = (WindowPtr)pDraw;
922706f2543Smrg	rep->x = pWin->origin.x - wBorderWidth (pWin);
923706f2543Smrg	rep->y = pWin->origin.y - wBorderWidth (pWin);
924706f2543Smrg	rep->borderWidth = pWin->borderWidth;
925706f2543Smrg    }
926706f2543Smrg    else /* DRAWABLE_PIXMAP */
927706f2543Smrg    {
928706f2543Smrg	rep->x = rep->y = rep->borderWidth = 0;
929706f2543Smrg    }
930706f2543Smrg
931706f2543Smrg    return Success;
932706f2543Smrg}
933706f2543Smrg
934706f2543Smrg
935706f2543Smrgint
936706f2543SmrgProcGetGeometry(ClientPtr client)
937706f2543Smrg{
938706f2543Smrg    xGetGeometryReply rep;
939706f2543Smrg    int status;
940706f2543Smrg
941706f2543Smrg    memset(&rep, 0, sizeof(xGetGeometryReply));
942706f2543Smrg    if ((status = GetGeometry(client, &rep)) != Success)
943706f2543Smrg	return status;
944706f2543Smrg
945706f2543Smrg    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
946706f2543Smrg    return Success;
947706f2543Smrg}
948706f2543Smrg
949706f2543Smrg
950706f2543Smrgint
951706f2543SmrgProcQueryTree(ClientPtr client)
952706f2543Smrg{
953706f2543Smrg    xQueryTreeReply reply;
954706f2543Smrg    int rc, numChildren = 0;
955706f2543Smrg    WindowPtr pChild, pWin, pHead;
956706f2543Smrg    Window  *childIDs = (Window *)NULL;
957706f2543Smrg    REQUEST(xResourceReq);
958706f2543Smrg
959706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
960706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
961706f2543Smrg    if (rc != Success)
962706f2543Smrg        return rc;
963706f2543Smrg    memset(&reply, 0, sizeof(xQueryTreeReply));
964706f2543Smrg    reply.type = X_Reply;
965706f2543Smrg    reply.root = pWin->drawable.pScreen->root->drawable.id;
966706f2543Smrg    reply.sequenceNumber = client->sequence;
967706f2543Smrg    if (pWin->parent)
968706f2543Smrg	reply.parent = pWin->parent->drawable.id;
969706f2543Smrg    else
970706f2543Smrg        reply.parent = (Window)None;
971706f2543Smrg    pHead = RealChildHead(pWin);
972706f2543Smrg    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
973706f2543Smrg	numChildren++;
974706f2543Smrg    if (numChildren)
975706f2543Smrg    {
976706f2543Smrg	int curChild = 0;
977706f2543Smrg
978706f2543Smrg	childIDs = malloc(numChildren * sizeof(Window));
979706f2543Smrg	if (!childIDs)
980706f2543Smrg	    return BadAlloc;
981706f2543Smrg	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
982706f2543Smrg	    childIDs[curChild++] = pChild->drawable.id;
983706f2543Smrg    }
984706f2543Smrg
985706f2543Smrg    reply.nChildren = numChildren;
986706f2543Smrg    reply.length = bytes_to_int32(numChildren * sizeof(Window));
987706f2543Smrg
988706f2543Smrg    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
989706f2543Smrg    if (numChildren)
990706f2543Smrg    {
991706f2543Smrg    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
992706f2543Smrg	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
993706f2543Smrg	free(childIDs);
994706f2543Smrg    }
995706f2543Smrg
996706f2543Smrg    return Success;
997706f2543Smrg}
998706f2543Smrg
999706f2543Smrgint
1000706f2543SmrgProcInternAtom(ClientPtr client)
1001706f2543Smrg{
1002706f2543Smrg    Atom atom;
1003706f2543Smrg    char *tchar;
1004706f2543Smrg    REQUEST(xInternAtomReq);
1005706f2543Smrg
1006706f2543Smrg    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
1007706f2543Smrg    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
1008706f2543Smrg    {
1009706f2543Smrg	client->errorValue = stuff->onlyIfExists;
1010706f2543Smrg        return BadValue;
1011706f2543Smrg    }
1012706f2543Smrg    tchar = (char *) &stuff[1];
1013706f2543Smrg    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
1014706f2543Smrg    if (atom != BAD_RESOURCE)
1015706f2543Smrg    {
1016706f2543Smrg	xInternAtomReply reply;
1017706f2543Smrg	memset(&reply, 0, sizeof(xInternAtomReply));
1018706f2543Smrg	reply.type = X_Reply;
1019706f2543Smrg	reply.length = 0;
1020706f2543Smrg	reply.sequenceNumber = client->sequence;
1021706f2543Smrg	reply.atom = atom;
1022706f2543Smrg	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
1023706f2543Smrg	return Success;
1024706f2543Smrg    }
1025706f2543Smrg    else
1026706f2543Smrg	return BadAlloc;
1027706f2543Smrg}
1028706f2543Smrg
1029706f2543Smrgint
1030706f2543SmrgProcGetAtomName(ClientPtr client)
1031706f2543Smrg{
1032706f2543Smrg    const char *str;
1033706f2543Smrg    xGetAtomNameReply reply;
1034706f2543Smrg    int len;
1035706f2543Smrg    REQUEST(xResourceReq);
1036706f2543Smrg
1037706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
1038706f2543Smrg    if ( (str = NameForAtom(stuff->id)) )
1039706f2543Smrg    {
1040706f2543Smrg	len = strlen(str);
1041706f2543Smrg	memset(&reply, 0, sizeof(xGetAtomNameReply));
1042706f2543Smrg	reply.type = X_Reply;
1043706f2543Smrg	reply.length = bytes_to_int32(len);
1044706f2543Smrg	reply.sequenceNumber = client->sequence;
1045706f2543Smrg	reply.nameLength = len;
1046706f2543Smrg	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
1047706f2543Smrg	(void)WriteToClient(client, len, str);
1048706f2543Smrg	return Success;
1049706f2543Smrg    }
1050706f2543Smrg    else
1051706f2543Smrg    {
1052706f2543Smrg	client->errorValue = stuff->id;
1053706f2543Smrg	return BadAtom;
1054706f2543Smrg    }
1055706f2543Smrg}
1056706f2543Smrg
1057706f2543Smrgint
1058706f2543SmrgProcGrabServer(ClientPtr client)
1059706f2543Smrg{
1060706f2543Smrg    int rc;
1061706f2543Smrg    REQUEST_SIZE_MATCH(xReq);
1062706f2543Smrg    if (grabState != GrabNone && client != grabClient)
1063706f2543Smrg    {
1064706f2543Smrg	ResetCurrentRequest(client);
1065706f2543Smrg	client->sequence--;
1066706f2543Smrg	BITSET(grabWaiters, client->index);
1067706f2543Smrg	IgnoreClient(client);
1068706f2543Smrg	return Success;
1069706f2543Smrg    }
1070706f2543Smrg    rc = OnlyListenToOneClient(client);
1071706f2543Smrg    if (rc != Success)
1072706f2543Smrg	return rc;
1073706f2543Smrg    grabState = GrabKickout;
1074706f2543Smrg    grabClient = client;
1075706f2543Smrg
1076706f2543Smrg    if (ServerGrabCallback)
1077706f2543Smrg    {
1078706f2543Smrg	ServerGrabInfoRec grabinfo;
1079706f2543Smrg	grabinfo.client = client;
1080706f2543Smrg	grabinfo.grabstate  = SERVER_GRABBED;
1081706f2543Smrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
1082706f2543Smrg    }
1083706f2543Smrg
1084706f2543Smrg    return Success;
1085706f2543Smrg}
1086706f2543Smrg
1087706f2543Smrgstatic void
1088706f2543SmrgUngrabServer(ClientPtr client)
1089706f2543Smrg{
1090706f2543Smrg    int i;
1091706f2543Smrg
1092706f2543Smrg    grabState = GrabNone;
1093706f2543Smrg    ListenToAllClients();
1094706f2543Smrg    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
1095706f2543Smrg	;
1096706f2543Smrg    if (i >= 0)
1097706f2543Smrg    {
1098706f2543Smrg	i <<= 5;
1099706f2543Smrg	while (!GETBIT(grabWaiters, i))
1100706f2543Smrg	    i++;
1101706f2543Smrg	BITCLEAR(grabWaiters, i);
1102706f2543Smrg	AttendClient(clients[i]);
1103706f2543Smrg    }
1104706f2543Smrg
1105706f2543Smrg    if (ServerGrabCallback)
1106706f2543Smrg    {
1107706f2543Smrg	ServerGrabInfoRec grabinfo;
1108706f2543Smrg	grabinfo.client = client;
1109706f2543Smrg	grabinfo.grabstate  = SERVER_UNGRABBED;
1110706f2543Smrg	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
1111706f2543Smrg    }
1112706f2543Smrg}
1113706f2543Smrg
1114706f2543Smrgint
1115706f2543SmrgProcUngrabServer(ClientPtr client)
1116706f2543Smrg{
1117706f2543Smrg    REQUEST_SIZE_MATCH(xReq);
1118706f2543Smrg    UngrabServer(client);
1119706f2543Smrg    return Success;
1120706f2543Smrg}
1121706f2543Smrg
1122706f2543Smrgint
1123706f2543SmrgProcTranslateCoords(ClientPtr client)
1124706f2543Smrg{
1125706f2543Smrg    REQUEST(xTranslateCoordsReq);
1126706f2543Smrg
1127706f2543Smrg    WindowPtr pWin, pDst;
1128706f2543Smrg    xTranslateCoordsReply rep;
1129706f2543Smrg    int rc;
1130706f2543Smrg
1131706f2543Smrg    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
1132706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
1133706f2543Smrg    if (rc != Success)
1134706f2543Smrg        return rc;
1135706f2543Smrg    rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
1136706f2543Smrg    if (rc != Success)
1137706f2543Smrg        return rc;
1138706f2543Smrg    memset(&rep, 0, sizeof(xTranslateCoordsReply));
1139706f2543Smrg    rep.type = X_Reply;
1140706f2543Smrg    rep.length = 0;
1141706f2543Smrg    rep.sequenceNumber = client->sequence;
1142706f2543Smrg    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
1143706f2543Smrg    {
1144706f2543Smrg	rep.sameScreen = xFalse;
1145706f2543Smrg        rep.child = None;
1146706f2543Smrg	rep.dstX = rep.dstY = 0;
1147706f2543Smrg    }
1148706f2543Smrg    else
1149706f2543Smrg    {
1150706f2543Smrg	INT16 x, y;
1151706f2543Smrg	rep.sameScreen = xTrue;
1152706f2543Smrg	rep.child = None;
1153706f2543Smrg	/* computing absolute coordinates -- adjust to destination later */
1154706f2543Smrg	x = pWin->drawable.x + stuff->srcX;
1155706f2543Smrg	y = pWin->drawable.y + stuff->srcY;
1156706f2543Smrg	pWin = pDst->firstChild;
1157706f2543Smrg	while (pWin)
1158706f2543Smrg	{
1159706f2543Smrg	    BoxRec  box;
1160706f2543Smrg	    if ((pWin->mapped) &&
1161706f2543Smrg		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
1162706f2543Smrg		(x < pWin->drawable.x + (int)pWin->drawable.width +
1163706f2543Smrg		 wBorderWidth (pWin)) &&
1164706f2543Smrg		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
1165706f2543Smrg		(y < pWin->drawable.y + (int)pWin->drawable.height +
1166706f2543Smrg		 wBorderWidth (pWin))
1167706f2543Smrg		/* When a window is shaped, a further check
1168706f2543Smrg		 * is made to see if the point is inside
1169706f2543Smrg		 * borderSize
1170706f2543Smrg		 */
1171706f2543Smrg		&& (!wBoundingShape(pWin) ||
1172706f2543Smrg		    RegionContainsPoint(&pWin->borderSize, x, y, &box))
1173706f2543Smrg
1174706f2543Smrg		&& (!wInputShape(pWin) ||
1175706f2543Smrg		    RegionContainsPoint(wInputShape(pWin),
1176706f2543Smrg					x - pWin->drawable.x,
1177706f2543Smrg					y - pWin->drawable.y, &box))
1178706f2543Smrg		)
1179706f2543Smrg            {
1180706f2543Smrg		rep.child = pWin->drawable.id;
1181706f2543Smrg		pWin = (WindowPtr) NULL;
1182706f2543Smrg	    }
1183706f2543Smrg	    else
1184706f2543Smrg		pWin = pWin->nextSib;
1185706f2543Smrg	}
1186706f2543Smrg	/* adjust to destination coordinates */
1187706f2543Smrg	rep.dstX = x - pDst->drawable.x;
1188706f2543Smrg	rep.dstY = y - pDst->drawable.y;
1189706f2543Smrg    }
1190706f2543Smrg    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
1191706f2543Smrg    return Success;
1192706f2543Smrg}
1193706f2543Smrg
1194706f2543Smrgint
1195706f2543SmrgProcOpenFont(ClientPtr client)
1196706f2543Smrg{
1197706f2543Smrg    int	err;
1198706f2543Smrg    REQUEST(xOpenFontReq);
1199706f2543Smrg
1200706f2543Smrg    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
1201706f2543Smrg    client->errorValue = stuff->fid;
1202706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->fid, client);
1203706f2543Smrg    err = OpenFont(client, stuff->fid, (Mask) 0,
1204706f2543Smrg		stuff->nbytes, (char *)&stuff[1]);
1205706f2543Smrg    if (err == Success)
1206706f2543Smrg    {
1207706f2543Smrg	return Success;
1208706f2543Smrg    }
1209706f2543Smrg    else
1210706f2543Smrg	return err;
1211706f2543Smrg}
1212706f2543Smrg
1213706f2543Smrgint
1214706f2543SmrgProcCloseFont(ClientPtr client)
1215706f2543Smrg{
1216706f2543Smrg    FontPtr pFont;
1217706f2543Smrg    int rc;
1218706f2543Smrg    REQUEST(xResourceReq);
1219706f2543Smrg
1220706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
1221706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT,
1222706f2543Smrg				 client, DixDestroyAccess);
1223706f2543Smrg    if (rc == Success)
1224706f2543Smrg    {
1225706f2543Smrg        FreeResource(stuff->id, RT_NONE);
1226706f2543Smrg	return Success;
1227706f2543Smrg    }
1228706f2543Smrg    else
1229706f2543Smrg    {
1230706f2543Smrg	client->errorValue = stuff->id;
1231706f2543Smrg        return rc;
1232706f2543Smrg    }
1233706f2543Smrg}
1234706f2543Smrg
1235706f2543Smrgint
1236706f2543SmrgProcQueryFont(ClientPtr client)
1237706f2543Smrg{
1238706f2543Smrg    xQueryFontReply	*reply;
1239706f2543Smrg    FontPtr pFont;
1240706f2543Smrg    int rc;
1241706f2543Smrg    REQUEST(xResourceReq);
1242706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
1243706f2543Smrg
1244706f2543Smrg    rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
1245706f2543Smrg    if (rc != Success)
1246706f2543Smrg	return rc;
1247706f2543Smrg
1248706f2543Smrg    {
1249706f2543Smrg	xCharInfo	*pmax = FONTINKMAX(pFont);
1250706f2543Smrg	xCharInfo	*pmin = FONTINKMIN(pFont);
1251706f2543Smrg	int		nprotoxcistructs;
1252706f2543Smrg	int		rlength;
1253706f2543Smrg
1254706f2543Smrg	nprotoxcistructs = (
1255706f2543Smrg	   pmax->rightSideBearing == pmin->rightSideBearing &&
1256706f2543Smrg	   pmax->leftSideBearing == pmin->leftSideBearing &&
1257706f2543Smrg	   pmax->descent == pmin->descent &&
1258706f2543Smrg	   pmax->ascent == pmin->ascent &&
1259706f2543Smrg	   pmax->characterWidth == pmin->characterWidth) ?
1260706f2543Smrg		0 : N2dChars(pFont);
1261706f2543Smrg
1262706f2543Smrg	rlength = sizeof(xQueryFontReply) +
1263706f2543Smrg	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
1264706f2543Smrg		     nprotoxcistructs * sizeof(xCharInfo);
1265706f2543Smrg	reply = calloc(1, rlength);
1266706f2543Smrg	if(!reply)
1267706f2543Smrg	{
1268706f2543Smrg	    return BadAlloc;
1269706f2543Smrg	}
1270706f2543Smrg
1271706f2543Smrg	reply->type = X_Reply;
1272706f2543Smrg	reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
1273706f2543Smrg	reply->sequenceNumber = client->sequence;
1274706f2543Smrg	QueryFont( pFont, reply, nprotoxcistructs);
1275706f2543Smrg
1276706f2543Smrg        WriteReplyToClient(client, rlength, reply);
1277706f2543Smrg	free(reply);
1278706f2543Smrg	return Success;
1279706f2543Smrg    }
1280706f2543Smrg}
1281706f2543Smrg
1282706f2543Smrgint
1283706f2543SmrgProcQueryTextExtents(ClientPtr client)
1284706f2543Smrg{
1285706f2543Smrg    xQueryTextExtentsReply reply;
1286706f2543Smrg    FontPtr pFont;
1287706f2543Smrg    ExtentInfoRec info;
1288706f2543Smrg    unsigned long length;
1289706f2543Smrg    int rc;
1290706f2543Smrg    REQUEST(xQueryTextExtentsReq);
1291706f2543Smrg    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
1292706f2543Smrg
1293706f2543Smrg    rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
1294706f2543Smrg    if (rc != Success)
1295706f2543Smrg	return rc;
1296706f2543Smrg
1297706f2543Smrg    length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
1298706f2543Smrg    length = length << 1;
1299706f2543Smrg    if (stuff->oddLength)
1300706f2543Smrg    {
1301706f2543Smrg	if (length == 0)
1302706f2543Smrg	    return BadLength;
1303706f2543Smrg        length--;
1304706f2543Smrg    }
1305706f2543Smrg    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
1306706f2543Smrg	return BadAlloc;
1307706f2543Smrg    reply.type = X_Reply;
1308706f2543Smrg    reply.length = 0;
1309706f2543Smrg    reply.sequenceNumber = client->sequence;
1310706f2543Smrg    reply.drawDirection = info.drawDirection;
1311706f2543Smrg    reply.fontAscent = info.fontAscent;
1312706f2543Smrg    reply.fontDescent = info.fontDescent;
1313706f2543Smrg    reply.overallAscent = info.overallAscent;
1314706f2543Smrg    reply.overallDescent = info.overallDescent;
1315706f2543Smrg    reply.overallWidth = info.overallWidth;
1316706f2543Smrg    reply.overallLeft = info.overallLeft;
1317706f2543Smrg    reply.overallRight = info.overallRight;
1318706f2543Smrg    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
1319706f2543Smrg    return Success;
1320706f2543Smrg}
1321706f2543Smrg
1322706f2543Smrgint
1323706f2543SmrgProcListFonts(ClientPtr client)
1324706f2543Smrg{
1325706f2543Smrg    REQUEST(xListFontsReq);
1326706f2543Smrg
1327706f2543Smrg    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
1328706f2543Smrg
1329706f2543Smrg    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
1330706f2543Smrg	stuff->maxNames);
1331706f2543Smrg}
1332706f2543Smrg
1333706f2543Smrgint
1334706f2543SmrgProcListFontsWithInfo(ClientPtr client)
1335706f2543Smrg{
1336706f2543Smrg    REQUEST(xListFontsWithInfoReq);
1337706f2543Smrg
1338706f2543Smrg    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
1339706f2543Smrg
1340706f2543Smrg    return StartListFontsWithInfo(client, stuff->nbytes,
1341706f2543Smrg				  (unsigned char *) &stuff[1], stuff->maxNames);
1342706f2543Smrg}
1343706f2543Smrg
1344706f2543Smrg/**
1345706f2543Smrg *
1346706f2543Smrg *  \param value must conform to DeleteType
1347706f2543Smrg */
1348706f2543Smrgint
1349706f2543SmrgdixDestroyPixmap(pointer value, XID pid)
1350706f2543Smrg{
1351706f2543Smrg    PixmapPtr pPixmap = (PixmapPtr)value;
1352706f2543Smrg    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
1353706f2543Smrg}
1354706f2543Smrg
1355706f2543Smrgint
1356706f2543SmrgProcCreatePixmap(ClientPtr client)
1357706f2543Smrg{
1358706f2543Smrg    PixmapPtr pMap;
1359706f2543Smrg    DrawablePtr pDraw;
1360706f2543Smrg    REQUEST(xCreatePixmapReq);
1361706f2543Smrg    DepthPtr pDepth;
1362706f2543Smrg    int i, rc;
1363706f2543Smrg
1364706f2543Smrg    REQUEST_SIZE_MATCH(xCreatePixmapReq);
1365706f2543Smrg    client->errorValue = stuff->pid;
1366706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->pid, client);
1367706f2543Smrg
1368706f2543Smrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
1369706f2543Smrg			   DixGetAttrAccess);
1370706f2543Smrg    if (rc != Success)
1371706f2543Smrg	return rc;
1372706f2543Smrg
1373706f2543Smrg    if (!stuff->width || !stuff->height)
1374706f2543Smrg    {
1375706f2543Smrg	client->errorValue = 0;
1376706f2543Smrg        return BadValue;
1377706f2543Smrg    }
1378706f2543Smrg    if (stuff->width > 32767 || stuff->height > 32767)
1379706f2543Smrg    {
1380706f2543Smrg	/* It is allowed to try and allocate a pixmap which is larger than
1381706f2543Smrg	 * 32767 in either dimension. However, all of the framebuffer code
1382706f2543Smrg	 * is buggy and does not reliably draw to such big pixmaps, basically
1383706f2543Smrg	 * because the Region data structure operates with signed shorts
1384706f2543Smrg	 * for the rectangles in it.
1385706f2543Smrg	 *
1386706f2543Smrg	 * Furthermore, several places in the X server computes the
1387706f2543Smrg	 * size in bytes of the pixmap and tries to store it in an
1388706f2543Smrg	 * integer. This integer can overflow and cause the allocated size
1389706f2543Smrg	 * to be much smaller.
1390706f2543Smrg	 *
1391706f2543Smrg	 * So, such big pixmaps are rejected here with a BadAlloc
1392706f2543Smrg	 */
1393706f2543Smrg	return BadAlloc;
1394706f2543Smrg    }
1395706f2543Smrg    if (stuff->depth != 1)
1396706f2543Smrg    {
1397706f2543Smrg        pDepth = pDraw->pScreen->allowedDepths;
1398706f2543Smrg        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
1399706f2543Smrg	   if (pDepth->depth == stuff->depth)
1400706f2543Smrg               goto CreatePmap;
1401706f2543Smrg	client->errorValue = stuff->depth;
1402706f2543Smrg        return BadValue;
1403706f2543Smrg    }
1404706f2543SmrgCreatePmap:
1405706f2543Smrg    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
1406706f2543Smrg		(pDraw->pScreen, stuff->width,
1407706f2543Smrg		 stuff->height, stuff->depth, 0);
1408706f2543Smrg    if (pMap)
1409706f2543Smrg    {
1410706f2543Smrg	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
1411706f2543Smrg	pMap->drawable.id = stuff->pid;
1412706f2543Smrg	/* security creation/labeling check */
1413706f2543Smrg	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
1414706f2543Smrg		      pMap, RT_NONE, NULL, DixCreateAccess);
1415706f2543Smrg	if (rc != Success) {
1416706f2543Smrg	    (*pDraw->pScreen->DestroyPixmap)(pMap);
1417706f2543Smrg	    return rc;
1418706f2543Smrg	}
1419706f2543Smrg	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
1420706f2543Smrg	    return Success;
1421706f2543Smrg    }
1422706f2543Smrg    return BadAlloc;
1423706f2543Smrg}
1424706f2543Smrg
1425706f2543Smrgint
1426706f2543SmrgProcFreePixmap(ClientPtr client)
1427706f2543Smrg{
1428706f2543Smrg    PixmapPtr pMap;
1429706f2543Smrg    int rc;
1430706f2543Smrg    REQUEST(xResourceReq);
1431706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
1432706f2543Smrg
1433706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client,
1434706f2543Smrg			   DixDestroyAccess);
1435706f2543Smrg    if (rc == Success)
1436706f2543Smrg    {
1437706f2543Smrg	FreeResource(stuff->id, RT_NONE);
1438706f2543Smrg	return Success;
1439706f2543Smrg    }
1440706f2543Smrg    else
1441706f2543Smrg    {
1442706f2543Smrg	client->errorValue = stuff->id;
1443706f2543Smrg	return rc;
1444706f2543Smrg    }
1445706f2543Smrg}
1446706f2543Smrg
1447706f2543Smrgint
1448706f2543SmrgProcCreateGC(ClientPtr client)
1449706f2543Smrg{
1450706f2543Smrg    int error, rc;
1451706f2543Smrg    GC *pGC;
1452706f2543Smrg    DrawablePtr pDraw;
1453706f2543Smrg    unsigned len;
1454706f2543Smrg    REQUEST(xCreateGCReq);
1455706f2543Smrg
1456706f2543Smrg    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
1457706f2543Smrg    client->errorValue = stuff->gc;
1458706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->gc, client);
1459706f2543Smrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
1460706f2543Smrg			   DixGetAttrAccess);
1461706f2543Smrg    if (rc != Success)
1462706f2543Smrg	return rc;
1463706f2543Smrg
1464706f2543Smrg    len = client->req_len -  bytes_to_int32(sizeof(xCreateGCReq));
1465706f2543Smrg    if (len != Ones(stuff->mask))
1466706f2543Smrg        return BadLength;
1467706f2543Smrg    pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
1468706f2543Smrg			 stuff->gc, client);
1469706f2543Smrg    if (error != Success)
1470706f2543Smrg        return error;
1471706f2543Smrg    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
1472706f2543Smrg	return BadAlloc;
1473706f2543Smrg    return Success;
1474706f2543Smrg}
1475706f2543Smrg
1476706f2543Smrgint
1477706f2543SmrgProcChangeGC(ClientPtr client)
1478706f2543Smrg{
1479706f2543Smrg    GC *pGC;
1480706f2543Smrg    int result;
1481706f2543Smrg    unsigned len;
1482706f2543Smrg    REQUEST(xChangeGCReq);
1483706f2543Smrg    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
1484706f2543Smrg
1485706f2543Smrg    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1486706f2543Smrg    if (result != Success)
1487706f2543Smrg	return result;
1488706f2543Smrg
1489706f2543Smrg    len = client->req_len -  bytes_to_int32(sizeof(xChangeGCReq));
1490706f2543Smrg    if (len != Ones(stuff->mask))
1491706f2543Smrg        return BadLength;
1492706f2543Smrg
1493706f2543Smrg    return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
1494706f2543Smrg}
1495706f2543Smrg
1496706f2543Smrgint
1497706f2543SmrgProcCopyGC(ClientPtr client)
1498706f2543Smrg{
1499706f2543Smrg    GC *dstGC;
1500706f2543Smrg    GC *pGC;
1501706f2543Smrg    int result;
1502706f2543Smrg    REQUEST(xCopyGCReq);
1503706f2543Smrg    REQUEST_SIZE_MATCH(xCopyGCReq);
1504706f2543Smrg
1505706f2543Smrg    result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
1506706f2543Smrg    if (result != Success)
1507706f2543Smrg	return result;
1508706f2543Smrg    result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
1509706f2543Smrg    if (result != Success)
1510706f2543Smrg	return result;
1511706f2543Smrg    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
1512706f2543Smrg        return BadMatch;
1513706f2543Smrg    if (stuff->mask & ~GCAllBits)
1514706f2543Smrg    {
1515706f2543Smrg	client->errorValue = stuff->mask;
1516706f2543Smrg	return BadValue;
1517706f2543Smrg    }
1518706f2543Smrg    return CopyGC(pGC, dstGC, stuff->mask);
1519706f2543Smrg}
1520706f2543Smrg
1521706f2543Smrgint
1522706f2543SmrgProcSetDashes(ClientPtr client)
1523706f2543Smrg{
1524706f2543Smrg    GC *pGC;
1525706f2543Smrg    int result;
1526706f2543Smrg    REQUEST(xSetDashesReq);
1527706f2543Smrg
1528706f2543Smrg    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
1529706f2543Smrg    if (stuff->nDashes == 0)
1530706f2543Smrg    {
1531706f2543Smrg	 client->errorValue = 0;
1532706f2543Smrg         return BadValue;
1533706f2543Smrg    }
1534706f2543Smrg
1535706f2543Smrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
1536706f2543Smrg    if (result != Success)
1537706f2543Smrg	return result;
1538706f2543Smrg
1539706f2543Smrg    /* If there's an error, either there's no sensible errorValue,
1540706f2543Smrg     * or there was a dash segment of 0. */
1541706f2543Smrg    client->errorValue = 0;
1542706f2543Smrg    return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
1543706f2543Smrg		       (unsigned char *)&stuff[1]);
1544706f2543Smrg}
1545706f2543Smrg
1546706f2543Smrgint
1547706f2543SmrgProcSetClipRectangles(ClientPtr client)
1548706f2543Smrg{
1549706f2543Smrg    int	nr, result;
1550706f2543Smrg    GC *pGC;
1551706f2543Smrg    REQUEST(xSetClipRectanglesReq);
1552706f2543Smrg
1553706f2543Smrg    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
1554706f2543Smrg    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
1555706f2543Smrg	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
1556706f2543Smrg    {
1557706f2543Smrg	client->errorValue = stuff->ordering;
1558706f2543Smrg        return BadValue;
1559706f2543Smrg    }
1560706f2543Smrg    result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
1561706f2543Smrg    if (result != Success)
1562706f2543Smrg	return result;
1563706f2543Smrg
1564706f2543Smrg    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
1565706f2543Smrg    if (nr & 4)
1566706f2543Smrg	return BadLength;
1567706f2543Smrg    nr >>= 3;
1568706f2543Smrg    return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
1569706f2543Smrg			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
1570706f2543Smrg}
1571706f2543Smrg
1572706f2543Smrgint
1573706f2543SmrgProcFreeGC(ClientPtr client)
1574706f2543Smrg{
1575706f2543Smrg    GC *pGC;
1576706f2543Smrg    int rc;
1577706f2543Smrg    REQUEST(xResourceReq);
1578706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
1579706f2543Smrg
1580706f2543Smrg    rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
1581706f2543Smrg    if (rc != Success)
1582706f2543Smrg	return rc;
1583706f2543Smrg
1584706f2543Smrg    FreeResource(stuff->id, RT_NONE);
1585706f2543Smrg    return Success;
1586706f2543Smrg}
1587706f2543Smrg
1588706f2543Smrgint
1589706f2543SmrgProcClearToBackground(ClientPtr client)
1590706f2543Smrg{
1591706f2543Smrg    REQUEST(xClearAreaReq);
1592706f2543Smrg    WindowPtr pWin;
1593706f2543Smrg    int rc;
1594706f2543Smrg
1595706f2543Smrg    REQUEST_SIZE_MATCH(xClearAreaReq);
1596706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
1597706f2543Smrg    if (rc != Success)
1598706f2543Smrg        return rc;
1599706f2543Smrg    if (pWin->drawable.class == InputOnly)
1600706f2543Smrg    {
1601706f2543Smrg	client->errorValue = stuff->window;
1602706f2543Smrg	return BadMatch;
1603706f2543Smrg    }
1604706f2543Smrg    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
1605706f2543Smrg    {
1606706f2543Smrg	client->errorValue = stuff->exposures;
1607706f2543Smrg        return BadValue;
1608706f2543Smrg    }
1609706f2543Smrg    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
1610706f2543Smrg			       stuff->width, stuff->height,
1611706f2543Smrg			       (Bool)stuff->exposures);
1612706f2543Smrg    return Success;
1613706f2543Smrg}
1614706f2543Smrg
1615706f2543Smrgint
1616706f2543SmrgProcCopyArea(ClientPtr client)
1617706f2543Smrg{
1618706f2543Smrg    DrawablePtr pDst;
1619706f2543Smrg    DrawablePtr pSrc;
1620706f2543Smrg    GC *pGC;
1621706f2543Smrg    REQUEST(xCopyAreaReq);
1622706f2543Smrg    RegionPtr pRgn;
1623706f2543Smrg    int rc;
1624706f2543Smrg
1625706f2543Smrg    REQUEST_SIZE_MATCH(xCopyAreaReq);
1626706f2543Smrg
1627706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
1628706f2543Smrg    if (stuff->dstDrawable != stuff->srcDrawable)
1629706f2543Smrg    {
1630706f2543Smrg	rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
1631706f2543Smrg				 DixReadAccess);
1632706f2543Smrg	if (rc != Success)
1633706f2543Smrg	    return rc;
1634706f2543Smrg	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
1635706f2543Smrg	{
1636706f2543Smrg	    client->errorValue = stuff->dstDrawable;
1637706f2543Smrg	    return BadMatch;
1638706f2543Smrg	}
1639706f2543Smrg    }
1640706f2543Smrg    else
1641706f2543Smrg        pSrc = pDst;
1642706f2543Smrg
1643706f2543Smrg    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
1644706f2543Smrg				 stuff->width, stuff->height,
1645706f2543Smrg				 stuff->dstX, stuff->dstY);
1646706f2543Smrg    if (pGC->graphicsExposures)
1647706f2543Smrg    {
1648706f2543Smrg	(*pDst->pScreen->SendGraphicsExpose)
1649706f2543Smrg 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
1650706f2543Smrg	if (pRgn)
1651706f2543Smrg	    RegionDestroy(pRgn);
1652706f2543Smrg    }
1653706f2543Smrg
1654706f2543Smrg    return Success;
1655706f2543Smrg}
1656706f2543Smrg
1657706f2543Smrgint
1658706f2543SmrgProcCopyPlane(ClientPtr client)
1659706f2543Smrg{
1660706f2543Smrg    DrawablePtr psrcDraw, pdstDraw;
1661706f2543Smrg    GC *pGC;
1662706f2543Smrg    REQUEST(xCopyPlaneReq);
1663706f2543Smrg    RegionPtr pRgn;
1664706f2543Smrg    int rc;
1665706f2543Smrg
1666706f2543Smrg    REQUEST_SIZE_MATCH(xCopyPlaneReq);
1667706f2543Smrg
1668706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
1669706f2543Smrg    if (stuff->dstDrawable != stuff->srcDrawable)
1670706f2543Smrg    {
1671706f2543Smrg	rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
1672706f2543Smrg			       DixReadAccess);
1673706f2543Smrg	if (rc != Success)
1674706f2543Smrg	    return rc;
1675706f2543Smrg
1676706f2543Smrg	if (pdstDraw->pScreen != psrcDraw->pScreen)
1677706f2543Smrg	{
1678706f2543Smrg	    client->errorValue = stuff->dstDrawable;
1679706f2543Smrg	    return BadMatch;
1680706f2543Smrg	}
1681706f2543Smrg    }
1682706f2543Smrg    else
1683706f2543Smrg        psrcDraw = pdstDraw;
1684706f2543Smrg
1685706f2543Smrg    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
1686706f2543Smrg    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
1687706f2543Smrg       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
1688706f2543Smrg    {
1689706f2543Smrg       client->errorValue = stuff->bitPlane;
1690706f2543Smrg       return BadValue;
1691706f2543Smrg    }
1692706f2543Smrg
1693706f2543Smrg    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
1694706f2543Smrg				 stuff->width, stuff->height,
1695706f2543Smrg				 stuff->dstX, stuff->dstY, stuff->bitPlane);
1696706f2543Smrg    if (pGC->graphicsExposures)
1697706f2543Smrg    {
1698706f2543Smrg	(*pdstDraw->pScreen->SendGraphicsExpose)
1699706f2543Smrg 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
1700706f2543Smrg	if (pRgn)
1701706f2543Smrg	    RegionDestroy(pRgn);
1702706f2543Smrg    }
1703706f2543Smrg    return Success;
1704706f2543Smrg}
1705706f2543Smrg
1706706f2543Smrgint
1707706f2543SmrgProcPolyPoint(ClientPtr client)
1708706f2543Smrg{
1709706f2543Smrg    int npoint;
1710706f2543Smrg    GC *pGC;
1711706f2543Smrg    DrawablePtr pDraw;
1712706f2543Smrg    REQUEST(xPolyPointReq);
1713706f2543Smrg
1714706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1715706f2543Smrg    if ((stuff->coordMode != CoordModeOrigin) &&
1716706f2543Smrg	(stuff->coordMode != CoordModePrevious))
1717706f2543Smrg    {
1718706f2543Smrg	client->errorValue = stuff->coordMode;
1719706f2543Smrg        return BadValue;
1720706f2543Smrg    }
1721706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1722706f2543Smrg    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
1723706f2543Smrg    if (npoint)
1724706f2543Smrg        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
1725706f2543Smrg			  (xPoint *) &stuff[1]);
1726706f2543Smrg    return Success;
1727706f2543Smrg}
1728706f2543Smrg
1729706f2543Smrgint
1730706f2543SmrgProcPolyLine(ClientPtr client)
1731706f2543Smrg{
1732706f2543Smrg    int npoint;
1733706f2543Smrg    GC *pGC;
1734706f2543Smrg    DrawablePtr pDraw;
1735706f2543Smrg    REQUEST(xPolyLineReq);
1736706f2543Smrg
1737706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1738706f2543Smrg    if ((stuff->coordMode != CoordModeOrigin) &&
1739706f2543Smrg	(stuff->coordMode != CoordModePrevious))
1740706f2543Smrg    {
1741706f2543Smrg	client->errorValue = stuff->coordMode;
1742706f2543Smrg        return BadValue;
1743706f2543Smrg    }
1744706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1745706f2543Smrg    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
1746706f2543Smrg    if (npoint > 1)
1747706f2543Smrg	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
1748706f2543Smrg			      (DDXPointPtr) &stuff[1]);
1749706f2543Smrg    return Success;
1750706f2543Smrg}
1751706f2543Smrg
1752706f2543Smrgint
1753706f2543SmrgProcPolySegment(ClientPtr client)
1754706f2543Smrg{
1755706f2543Smrg    int nsegs;
1756706f2543Smrg    GC *pGC;
1757706f2543Smrg    DrawablePtr pDraw;
1758706f2543Smrg    REQUEST(xPolySegmentReq);
1759706f2543Smrg
1760706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
1761706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1762706f2543Smrg    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
1763706f2543Smrg    if (nsegs & 4)
1764706f2543Smrg	return BadLength;
1765706f2543Smrg    nsegs >>= 3;
1766706f2543Smrg    if (nsegs)
1767706f2543Smrg        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
1768706f2543Smrg    return Success;
1769706f2543Smrg}
1770706f2543Smrg
1771706f2543Smrgint
1772706f2543SmrgProcPolyRectangle (ClientPtr client)
1773706f2543Smrg{
1774706f2543Smrg    int nrects;
1775706f2543Smrg    GC *pGC;
1776706f2543Smrg    DrawablePtr pDraw;
1777706f2543Smrg    REQUEST(xPolyRectangleReq);
1778706f2543Smrg
1779706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
1780706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1781706f2543Smrg    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
1782706f2543Smrg    if (nrects & 4)
1783706f2543Smrg	return BadLength;
1784706f2543Smrg    nrects >>= 3;
1785706f2543Smrg    if (nrects)
1786706f2543Smrg        (*pGC->ops->PolyRectangle)(pDraw, pGC,
1787706f2543Smrg		    nrects, (xRectangle *) &stuff[1]);
1788706f2543Smrg    return Success;
1789706f2543Smrg}
1790706f2543Smrg
1791706f2543Smrgint
1792706f2543SmrgProcPolyArc(ClientPtr client)
1793706f2543Smrg{
1794706f2543Smrg    int		narcs;
1795706f2543Smrg    GC *pGC;
1796706f2543Smrg    DrawablePtr pDraw;
1797706f2543Smrg    REQUEST(xPolyArcReq);
1798706f2543Smrg
1799706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
1800706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1801706f2543Smrg    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
1802706f2543Smrg    if (narcs % sizeof(xArc))
1803706f2543Smrg	return BadLength;
1804706f2543Smrg    narcs /= sizeof(xArc);
1805706f2543Smrg    if (narcs)
1806706f2543Smrg        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
1807706f2543Smrg    return Success;
1808706f2543Smrg}
1809706f2543Smrg
1810706f2543Smrgint
1811706f2543SmrgProcFillPoly(ClientPtr client)
1812706f2543Smrg{
1813706f2543Smrg    int          things;
1814706f2543Smrg    GC *pGC;
1815706f2543Smrg    DrawablePtr pDraw;
1816706f2543Smrg    REQUEST(xFillPolyReq);
1817706f2543Smrg
1818706f2543Smrg    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
1819706f2543Smrg    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
1820706f2543Smrg	(stuff->shape != Convex))
1821706f2543Smrg    {
1822706f2543Smrg	client->errorValue = stuff->shape;
1823706f2543Smrg        return BadValue;
1824706f2543Smrg    }
1825706f2543Smrg    if ((stuff->coordMode != CoordModeOrigin) &&
1826706f2543Smrg	(stuff->coordMode != CoordModePrevious))
1827706f2543Smrg    {
1828706f2543Smrg	client->errorValue = stuff->coordMode;
1829706f2543Smrg        return BadValue;
1830706f2543Smrg    }
1831706f2543Smrg
1832706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1833706f2543Smrg    things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
1834706f2543Smrg    if (things)
1835706f2543Smrg        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
1836706f2543Smrg			 stuff->coordMode, things,
1837706f2543Smrg			 (DDXPointPtr) &stuff[1]);
1838706f2543Smrg    return Success;
1839706f2543Smrg}
1840706f2543Smrg
1841706f2543Smrgint
1842706f2543SmrgProcPolyFillRectangle(ClientPtr client)
1843706f2543Smrg{
1844706f2543Smrg    int             things;
1845706f2543Smrg    GC *pGC;
1846706f2543Smrg    DrawablePtr pDraw;
1847706f2543Smrg    REQUEST(xPolyFillRectangleReq);
1848706f2543Smrg
1849706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
1850706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1851706f2543Smrg    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
1852706f2543Smrg    if (things & 4)
1853706f2543Smrg	return BadLength;
1854706f2543Smrg    things >>= 3;
1855706f2543Smrg
1856706f2543Smrg    if (things)
1857706f2543Smrg        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
1858706f2543Smrg		      (xRectangle *) &stuff[1]);
1859706f2543Smrg    return Success;
1860706f2543Smrg}
1861706f2543Smrg
1862706f2543Smrgint
1863706f2543SmrgProcPolyFillArc(ClientPtr client)
1864706f2543Smrg{
1865706f2543Smrg    int		narcs;
1866706f2543Smrg    GC *pGC;
1867706f2543Smrg    DrawablePtr pDraw;
1868706f2543Smrg    REQUEST(xPolyFillArcReq);
1869706f2543Smrg
1870706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
1871706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1872706f2543Smrg    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
1873706f2543Smrg    if (narcs % sizeof(xArc))
1874706f2543Smrg	return BadLength;
1875706f2543Smrg    narcs /= sizeof(xArc);
1876706f2543Smrg    if (narcs)
1877706f2543Smrg        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
1878706f2543Smrg    return Success;
1879706f2543Smrg}
1880706f2543Smrg
1881706f2543Smrg#ifdef MATCH_CLIENT_ENDIAN
1882706f2543Smrg
1883706f2543Smrgint
1884706f2543SmrgServerOrder (void)
1885706f2543Smrg{
1886706f2543Smrg    int	    whichbyte = 1;
1887706f2543Smrg
1888706f2543Smrg    if (*((char *) &whichbyte))
1889706f2543Smrg	return LSBFirst;
1890706f2543Smrg    return MSBFirst;
1891706f2543Smrg}
1892706f2543Smrg
1893706f2543Smrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
1894706f2543Smrg
1895706f2543Smrgvoid
1896706f2543SmrgReformatImage (char *base, int nbytes, int bpp, int order)
1897706f2543Smrg{
1898706f2543Smrg    switch (bpp) {
1899706f2543Smrg    case 1:	/* yuck */
1900706f2543Smrg	if (BITMAP_BIT_ORDER != order)
1901706f2543Smrg	    BitOrderInvert ((unsigned char *) base, nbytes);
1902706f2543Smrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
1903706f2543Smrg	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
1904706f2543Smrg#endif
1905706f2543Smrg	break;
1906706f2543Smrg    case 4:
1907706f2543Smrg	break;  /* yuck */
1908706f2543Smrg    case 8:
1909706f2543Smrg	break;
1910706f2543Smrg    case 16:
1911706f2543Smrg	if (IMAGE_BYTE_ORDER != order)
1912706f2543Smrg	    TwoByteSwap ((unsigned char *) base, nbytes);
1913706f2543Smrg	break;
1914706f2543Smrg    case 32:
1915706f2543Smrg	if (IMAGE_BYTE_ORDER != order)
1916706f2543Smrg	    FourByteSwap ((unsigned char *) base, nbytes);
1917706f2543Smrg	break;
1918706f2543Smrg    }
1919706f2543Smrg}
1920706f2543Smrg#else
1921706f2543Smrg#define ReformatImage(b,n,bpp,o)
1922706f2543Smrg#endif
1923706f2543Smrg
1924706f2543Smrg/* 64-bit server notes: the protocol restricts padding of images to
1925706f2543Smrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
1926706f2543Smrg * to use internally. Removes need for internal alignment checking.
1927706f2543Smrg * All of the PutImage functions could be changed individually, but
1928706f2543Smrg * as currently written, they call other routines which require things
1929706f2543Smrg * to be 64-bit padded on scanlines, so we changed things here.
1930706f2543Smrg * If an image would be padded differently for 64- versus 32-, then
1931706f2543Smrg * copy each scanline to a 64-bit padded scanline.
1932706f2543Smrg * Also, we need to make sure that the image is aligned on a 64-bit
1933706f2543Smrg * boundary, even if the scanlines are padded to our satisfaction.
1934706f2543Smrg */
1935706f2543Smrgint
1936706f2543SmrgProcPutImage(ClientPtr client)
1937706f2543Smrg{
1938706f2543Smrg    GC *pGC;
1939706f2543Smrg    DrawablePtr pDraw;
1940706f2543Smrg    long	length; 	/* length of scanline server padded */
1941706f2543Smrg    long 	lengthProto; 	/* length of scanline protocol padded */
1942706f2543Smrg    char	*tmpImage;
1943706f2543Smrg    REQUEST(xPutImageReq);
1944706f2543Smrg
1945706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPutImageReq);
1946706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1947706f2543Smrg    if (stuff->format == XYBitmap)
1948706f2543Smrg    {
1949706f2543Smrg        if ((stuff->depth != 1) ||
1950706f2543Smrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
1951706f2543Smrg            return BadMatch;
1952706f2543Smrg        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
1953706f2543Smrg    }
1954706f2543Smrg    else if (stuff->format == XYPixmap)
1955706f2543Smrg    {
1956706f2543Smrg        if ((pDraw->depth != stuff->depth) ||
1957706f2543Smrg	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
1958706f2543Smrg            return BadMatch;
1959706f2543Smrg        length      = BitmapBytePad(stuff->width + stuff->leftPad);
1960706f2543Smrg	length      *= stuff->depth;
1961706f2543Smrg    }
1962706f2543Smrg    else if (stuff->format == ZPixmap)
1963706f2543Smrg    {
1964706f2543Smrg        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
1965706f2543Smrg            return BadMatch;
1966706f2543Smrg        length      = PixmapBytePad(stuff->width, stuff->depth);
1967706f2543Smrg    }
1968706f2543Smrg    else
1969706f2543Smrg    {
1970706f2543Smrg	client->errorValue = stuff->format;
1971706f2543Smrg        return BadValue;
1972706f2543Smrg    }
1973706f2543Smrg
1974706f2543Smrg    tmpImage = (char *)&stuff[1];
1975706f2543Smrg    lengthProto = length;
1976706f2543Smrg
1977706f2543Smrg    if (lengthProto >= (INT32_MAX / stuff->height))
1978706f2543Smrg        return BadLength;
1979706f2543Smrg
1980706f2543Smrg    if ((bytes_to_int32(lengthProto * stuff->height) +
1981706f2543Smrg	bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
1982706f2543Smrg	return BadLength;
1983706f2543Smrg
1984706f2543Smrg    ReformatImage (tmpImage, lengthProto * stuff->height,
1985706f2543Smrg		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
1986706f2543Smrg		   ClientOrder(client));
1987706f2543Smrg
1988706f2543Smrg    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
1989706f2543Smrg		  stuff->width, stuff->height,
1990706f2543Smrg		  stuff->leftPad, stuff->format, tmpImage);
1991706f2543Smrg
1992706f2543Smrg     return Success;
1993706f2543Smrg}
1994706f2543Smrg
1995706f2543Smrgstatic int
1996706f2543SmrgDoGetImage(ClientPtr client, int format, Drawable drawable,
1997706f2543Smrg           int x, int y, int width, int height,
1998706f2543Smrg           Mask planemask, xGetImageReply **im_return)
1999706f2543Smrg{
2000706f2543Smrg    DrawablePtr		pDraw, pBoundingDraw;
2001706f2543Smrg    int			nlines, linesPerBuf, rc;
2002706f2543Smrg    int			linesDone;
2003706f2543Smrg    /* coordinates relative to the bounding drawable */
2004706f2543Smrg    int			relx, rely;
2005706f2543Smrg    long		widthBytesLine, length;
2006706f2543Smrg    Mask		plane = 0;
2007706f2543Smrg    char		*pBuf;
2008706f2543Smrg    xGetImageReply	xgi;
2009706f2543Smrg    RegionPtr pVisibleRegion = NULL;
2010706f2543Smrg
2011706f2543Smrg    if ((format != XYPixmap) && (format != ZPixmap))
2012706f2543Smrg    {
2013706f2543Smrg	client->errorValue = format;
2014706f2543Smrg        return BadValue;
2015706f2543Smrg    }
2016706f2543Smrg    rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
2017706f2543Smrg    if (rc != Success)
2018706f2543Smrg	return rc;
2019706f2543Smrg
2020706f2543Smrg    memset(&xgi, 0, sizeof(xGetImageReply));
2021706f2543Smrg
2022706f2543Smrg    relx = x;
2023706f2543Smrg    rely = y;
2024706f2543Smrg
2025706f2543Smrg    if(pDraw->type == DRAWABLE_WINDOW)
2026706f2543Smrg    {
2027706f2543Smrg	WindowPtr pWin = (WindowPtr)pDraw;
2028706f2543Smrg
2029706f2543Smrg	/* "If the drawable is a window, the window must be viewable ... or a
2030706f2543Smrg	 * BadMatch error results" */
2031706f2543Smrg	if (!pWin->viewable)
2032706f2543Smrg	    return BadMatch;
2033706f2543Smrg
2034706f2543Smrg	relx += pDraw->x;
2035706f2543Smrg	rely += pDraw->y;
2036706f2543Smrg
2037706f2543Smrg	if (pDraw->pScreen->GetWindowPixmap) {
2038706f2543Smrg	    PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
2039706f2543Smrg
2040706f2543Smrg	    pBoundingDraw = &pPix->drawable;
2041706f2543Smrg#ifdef COMPOSITE
2042706f2543Smrg	    relx -= pPix->screen_x;
2043706f2543Smrg	    rely -= pPix->screen_y;
2044706f2543Smrg#endif
2045706f2543Smrg	}
2046706f2543Smrg	else
2047706f2543Smrg	{
2048706f2543Smrg	    pBoundingDraw = (DrawablePtr)pDraw->pScreen->root;
2049706f2543Smrg	}
2050706f2543Smrg
2051706f2543Smrg	xgi.visual = wVisual (pWin);
2052706f2543Smrg    }
2053706f2543Smrg    else
2054706f2543Smrg    {
2055706f2543Smrg	pBoundingDraw = pDraw;
2056706f2543Smrg	xgi.visual = None;
2057706f2543Smrg    }
2058706f2543Smrg
2059706f2543Smrg    /* "If the drawable is a pixmap, the given rectangle must be wholly
2060706f2543Smrg     *  contained within the pixmap, or a BadMatch error results.  If the
2061706f2543Smrg     *  drawable is a window [...] it must be the case that if there were no
2062706f2543Smrg     *  inferiors or overlapping windows, the specified rectangle of the window
2063706f2543Smrg     *  would be fully visible on the screen and wholly contained within the
2064706f2543Smrg     *  outside edges of the window, or a BadMatch error results."
2065706f2543Smrg     *
2066706f2543Smrg     * We relax the window case slightly to mean that the rectangle must exist
2067706f2543Smrg     * within the bounds of the window's backing pixmap.  In particular, this
2068706f2543Smrg     * means that a GetImage request may succeed or fail with BadMatch depending
2069706f2543Smrg     * on whether any of its ancestor windows are redirected.  */
2070706f2543Smrg    if(relx < 0 || relx + width > (int)pBoundingDraw->width ||
2071706f2543Smrg       rely < 0 || rely + height > (int)pBoundingDraw->height)
2072706f2543Smrg	return BadMatch;
2073706f2543Smrg
2074706f2543Smrg    xgi.type = X_Reply;
2075706f2543Smrg    xgi.sequenceNumber = client->sequence;
2076706f2543Smrg    xgi.depth = pDraw->depth;
2077706f2543Smrg    if(format == ZPixmap)
2078706f2543Smrg    {
2079706f2543Smrg	widthBytesLine = PixmapBytePad(width, pDraw->depth);
2080706f2543Smrg	length = widthBytesLine * height;
2081706f2543Smrg
2082706f2543Smrg    }
2083706f2543Smrg    else
2084706f2543Smrg    {
2085706f2543Smrg	widthBytesLine = BitmapBytePad(width);
2086706f2543Smrg	plane = ((Mask)1) << (pDraw->depth - 1);
2087706f2543Smrg	/* only planes asked for */
2088706f2543Smrg	length = widthBytesLine * height *
2089706f2543Smrg		 Ones(planemask & (plane | (plane - 1)));
2090706f2543Smrg
2091706f2543Smrg    }
2092706f2543Smrg
2093706f2543Smrg    xgi.length = length;
2094706f2543Smrg
2095706f2543Smrg    if (im_return) {
2096706f2543Smrg	pBuf = calloc(1, sz_xGetImageReply + length);
2097706f2543Smrg	if (!pBuf)
2098706f2543Smrg	    return BadAlloc;
2099706f2543Smrg	if (widthBytesLine == 0)
2100706f2543Smrg	    linesPerBuf = 0;
2101706f2543Smrg	else
2102706f2543Smrg	    linesPerBuf = height;
2103706f2543Smrg	*im_return = (xGetImageReply *)pBuf;
2104706f2543Smrg	*(xGetImageReply *)pBuf = xgi;
2105706f2543Smrg	pBuf += sz_xGetImageReply;
2106706f2543Smrg    } else {
2107706f2543Smrg	xgi.length = bytes_to_int32(xgi.length);
2108706f2543Smrg	if (widthBytesLine == 0 || height == 0)
2109706f2543Smrg	    linesPerBuf = 0;
2110706f2543Smrg	else if (widthBytesLine >= IMAGE_BUFSIZE)
2111706f2543Smrg	    linesPerBuf = 1;
2112706f2543Smrg	else
2113706f2543Smrg	{
2114706f2543Smrg	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
2115706f2543Smrg	    if (linesPerBuf > height)
2116706f2543Smrg		linesPerBuf = height;
2117706f2543Smrg	}
2118706f2543Smrg	length = linesPerBuf * widthBytesLine;
2119706f2543Smrg	if (linesPerBuf < height)
2120706f2543Smrg	{
2121706f2543Smrg	    /* we have to make sure intermediate buffers don't need padding */
2122706f2543Smrg	    while ((linesPerBuf > 1) &&
2123706f2543Smrg		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
2124706f2543Smrg	    {
2125706f2543Smrg		linesPerBuf--;
2126706f2543Smrg		length -= widthBytesLine;
2127706f2543Smrg	    }
2128706f2543Smrg	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
2129706f2543Smrg	    {
2130706f2543Smrg		linesPerBuf++;
2131706f2543Smrg		length += widthBytesLine;
2132706f2543Smrg	    }
2133706f2543Smrg	}
2134706f2543Smrg	if(!(pBuf = calloc(1, length)))
2135706f2543Smrg	    return BadAlloc;
2136706f2543Smrg	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
2137706f2543Smrg    }
2138706f2543Smrg
2139706f2543Smrg    if (pDraw->type == DRAWABLE_WINDOW)
2140706f2543Smrg    {
2141706f2543Smrg	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
2142706f2543Smrg	if (pVisibleRegion)
2143706f2543Smrg	{
2144706f2543Smrg	    RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
2145706f2543Smrg	}
2146706f2543Smrg    }
2147706f2543Smrg
2148706f2543Smrg    if (linesPerBuf == 0)
2149706f2543Smrg    {
2150706f2543Smrg	/* nothing to do */
2151706f2543Smrg    }
2152706f2543Smrg    else if (format == ZPixmap)
2153706f2543Smrg    {
2154706f2543Smrg        linesDone = 0;
2155706f2543Smrg        while (height - linesDone > 0)
2156706f2543Smrg        {
2157706f2543Smrg	    nlines = min(linesPerBuf, height - linesDone);
2158706f2543Smrg	    (*pDraw->pScreen->GetImage) (pDraw,
2159706f2543Smrg	                                 x,
2160706f2543Smrg				         y + linesDone,
2161706f2543Smrg				         width,
2162706f2543Smrg				         nlines,
2163706f2543Smrg				         format,
2164706f2543Smrg				         planemask,
2165706f2543Smrg				         (pointer) pBuf);
2166706f2543Smrg	    if (pVisibleRegion)
2167706f2543Smrg		XaceCensorImage(client, pVisibleRegion, widthBytesLine,
2168706f2543Smrg			pDraw, x, y + linesDone, width,
2169706f2543Smrg			nlines, format, pBuf);
2170706f2543Smrg
2171706f2543Smrg	    /* Note that this is NOT a call to WriteSwappedDataToClient,
2172706f2543Smrg               as we do NOT byte swap */
2173706f2543Smrg	    if (!im_return)
2174706f2543Smrg	    {
2175706f2543Smrg		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
2176706f2543Smrg			       BitsPerPixel (pDraw->depth),
2177706f2543Smrg			       ClientOrder(client));
2178706f2543Smrg
2179706f2543Smrg/* Don't split me, gcc pukes when you do */
2180706f2543Smrg		(void)WriteToClient(client,
2181706f2543Smrg				    (int)(nlines * widthBytesLine),
2182706f2543Smrg				    pBuf);
2183706f2543Smrg	    }
2184706f2543Smrg	    linesDone += nlines;
2185706f2543Smrg        }
2186706f2543Smrg    }
2187706f2543Smrg    else /* XYPixmap */
2188706f2543Smrg    {
2189706f2543Smrg        for (; plane; plane >>= 1)
2190706f2543Smrg	{
2191706f2543Smrg	    if (planemask & plane)
2192706f2543Smrg	    {
2193706f2543Smrg	        linesDone = 0;
2194706f2543Smrg	        while (height - linesDone > 0)
2195706f2543Smrg	        {
2196706f2543Smrg		    nlines = min(linesPerBuf, height - linesDone);
2197706f2543Smrg	            (*pDraw->pScreen->GetImage) (pDraw,
2198706f2543Smrg	                                         x,
2199706f2543Smrg				                 y + linesDone,
2200706f2543Smrg				                 width,
2201706f2543Smrg				                 nlines,
2202706f2543Smrg				                 format,
2203706f2543Smrg				                 plane,
2204706f2543Smrg				                 (pointer)pBuf);
2205706f2543Smrg		    if (pVisibleRegion)
2206706f2543Smrg			XaceCensorImage(client, pVisibleRegion,
2207706f2543Smrg				widthBytesLine,
2208706f2543Smrg				pDraw, x, y + linesDone, width,
2209706f2543Smrg				nlines, format, pBuf);
2210706f2543Smrg
2211706f2543Smrg		    /* Note: NOT a call to WriteSwappedDataToClient,
2212706f2543Smrg		       as we do NOT byte swap */
2213706f2543Smrg		    if (im_return) {
2214706f2543Smrg			pBuf += nlines * widthBytesLine;
2215706f2543Smrg		    } else {
2216706f2543Smrg			ReformatImage (pBuf,
2217706f2543Smrg				       (int)(nlines * widthBytesLine),
2218706f2543Smrg				       1,
2219706f2543Smrg				       ClientOrder (client));
2220706f2543Smrg
2221706f2543Smrg/* Don't split me, gcc pukes when you do */
2222706f2543Smrg			(void)WriteToClient(client,
2223706f2543Smrg					(int)(nlines * widthBytesLine),
2224706f2543Smrg					pBuf);
2225706f2543Smrg		    }
2226706f2543Smrg		    linesDone += nlines;
2227706f2543Smrg		}
2228706f2543Smrg            }
2229706f2543Smrg	}
2230706f2543Smrg    }
2231706f2543Smrg    if (pVisibleRegion)
2232706f2543Smrg	RegionDestroy(pVisibleRegion);
2233706f2543Smrg    if (!im_return)
2234706f2543Smrg	free(pBuf);
2235706f2543Smrg    return Success;
2236706f2543Smrg}
2237706f2543Smrg
2238706f2543Smrgint
2239706f2543SmrgProcGetImage(ClientPtr client)
2240706f2543Smrg{
2241706f2543Smrg    REQUEST(xGetImageReq);
2242706f2543Smrg
2243706f2543Smrg    REQUEST_SIZE_MATCH(xGetImageReq);
2244706f2543Smrg
2245706f2543Smrg    return DoGetImage(client, stuff->format, stuff->drawable,
2246706f2543Smrg		      stuff->x, stuff->y,
2247706f2543Smrg		      (int)stuff->width, (int)stuff->height,
2248706f2543Smrg		      stuff->planeMask, (xGetImageReply **)NULL);
2249706f2543Smrg}
2250706f2543Smrg
2251706f2543Smrgint
2252706f2543SmrgProcPolyText(ClientPtr client)
2253706f2543Smrg{
2254706f2543Smrg    int	err;
2255706f2543Smrg    REQUEST(xPolyTextReq);
2256706f2543Smrg    DrawablePtr pDraw;
2257706f2543Smrg    GC *pGC;
2258706f2543Smrg
2259706f2543Smrg    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2260706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2261706f2543Smrg
2262706f2543Smrg    err = PolyText(client,
2263706f2543Smrg		   pDraw,
2264706f2543Smrg		   pGC,
2265706f2543Smrg		   (unsigned char *)&stuff[1],
2266706f2543Smrg		   ((unsigned char *) stuff) + (client->req_len << 2),
2267706f2543Smrg		   stuff->x,
2268706f2543Smrg		   stuff->y,
2269706f2543Smrg		   stuff->reqType,
2270706f2543Smrg		   stuff->drawable);
2271706f2543Smrg
2272706f2543Smrg    if (err == Success)
2273706f2543Smrg    {
2274706f2543Smrg	return Success;
2275706f2543Smrg    }
2276706f2543Smrg    else
2277706f2543Smrg	return err;
2278706f2543Smrg}
2279706f2543Smrg
2280706f2543Smrgint
2281706f2543SmrgProcImageText8(ClientPtr client)
2282706f2543Smrg{
2283706f2543Smrg    int	err;
2284706f2543Smrg    DrawablePtr pDraw;
2285706f2543Smrg    GC *pGC;
2286706f2543Smrg
2287706f2543Smrg    REQUEST(xImageTextReq);
2288706f2543Smrg
2289706f2543Smrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2290706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2291706f2543Smrg
2292706f2543Smrg    err = ImageText(client,
2293706f2543Smrg		    pDraw,
2294706f2543Smrg		    pGC,
2295706f2543Smrg		    stuff->nChars,
2296706f2543Smrg		    (unsigned char *)&stuff[1],
2297706f2543Smrg		    stuff->x,
2298706f2543Smrg		    stuff->y,
2299706f2543Smrg		    stuff->reqType,
2300706f2543Smrg		    stuff->drawable);
2301706f2543Smrg
2302706f2543Smrg    if (err == Success)
2303706f2543Smrg    {
2304706f2543Smrg	return Success;
2305706f2543Smrg    }
2306706f2543Smrg    else
2307706f2543Smrg	return err;
2308706f2543Smrg}
2309706f2543Smrg
2310706f2543Smrgint
2311706f2543SmrgProcImageText16(ClientPtr client)
2312706f2543Smrg{
2313706f2543Smrg    int	err;
2314706f2543Smrg    DrawablePtr pDraw;
2315706f2543Smrg    GC *pGC;
2316706f2543Smrg
2317706f2543Smrg    REQUEST(xImageTextReq);
2318706f2543Smrg
2319706f2543Smrg    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
2320706f2543Smrg    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2321706f2543Smrg
2322706f2543Smrg    err = ImageText(client,
2323706f2543Smrg		    pDraw,
2324706f2543Smrg		    pGC,
2325706f2543Smrg		    stuff->nChars,
2326706f2543Smrg		    (unsigned char *)&stuff[1],
2327706f2543Smrg		    stuff->x,
2328706f2543Smrg		    stuff->y,
2329706f2543Smrg		    stuff->reqType,
2330706f2543Smrg		    stuff->drawable);
2331706f2543Smrg
2332706f2543Smrg    if (err == Success)
2333706f2543Smrg    {
2334706f2543Smrg	return Success;
2335706f2543Smrg    }
2336706f2543Smrg    else
2337706f2543Smrg	return err;
2338706f2543Smrg}
2339706f2543Smrg
2340706f2543Smrg
2341706f2543Smrgint
2342706f2543SmrgProcCreateColormap(ClientPtr client)
2343706f2543Smrg{
2344706f2543Smrg    VisualPtr	pVisual;
2345706f2543Smrg    ColormapPtr	pmap;
2346706f2543Smrg    Colormap	mid;
2347706f2543Smrg    WindowPtr   pWin;
2348706f2543Smrg    ScreenPtr pScreen;
2349706f2543Smrg    REQUEST(xCreateColormapReq);
2350706f2543Smrg    int i, result;
2351706f2543Smrg
2352706f2543Smrg    REQUEST_SIZE_MATCH(xCreateColormapReq);
2353706f2543Smrg
2354706f2543Smrg    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
2355706f2543Smrg    {
2356706f2543Smrg	client->errorValue = stuff->alloc;
2357706f2543Smrg        return BadValue;
2358706f2543Smrg    }
2359706f2543Smrg    mid = stuff->mid;
2360706f2543Smrg    LEGAL_NEW_RESOURCE(mid, client);
2361706f2543Smrg    result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2362706f2543Smrg    if (result != Success)
2363706f2543Smrg        return result;
2364706f2543Smrg
2365706f2543Smrg    pScreen = pWin->drawable.pScreen;
2366706f2543Smrg    for (i = 0, pVisual = pScreen->visuals;
2367706f2543Smrg	 i < pScreen->numVisuals;
2368706f2543Smrg	 i++, pVisual++)
2369706f2543Smrg    {
2370706f2543Smrg	if (pVisual->vid != stuff->visual)
2371706f2543Smrg	    continue;
2372706f2543Smrg	return CreateColormap(mid, pScreen, pVisual, &pmap,
2373706f2543Smrg				 (int)stuff->alloc, client->index);
2374706f2543Smrg    }
2375706f2543Smrg    client->errorValue = stuff->visual;
2376706f2543Smrg    return BadMatch;
2377706f2543Smrg}
2378706f2543Smrg
2379706f2543Smrgint
2380706f2543SmrgProcFreeColormap(ClientPtr client)
2381706f2543Smrg{
2382706f2543Smrg    ColormapPtr pmap;
2383706f2543Smrg    int rc;
2384706f2543Smrg    REQUEST(xResourceReq);
2385706f2543Smrg
2386706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
2387706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client,
2388706f2543Smrg			   DixDestroyAccess);
2389706f2543Smrg    if (rc == Success)
2390706f2543Smrg    {
2391706f2543Smrg	/* Freeing a default colormap is a no-op */
2392706f2543Smrg	if (!(pmap->flags & IsDefault))
2393706f2543Smrg	    FreeResource(stuff->id, RT_NONE);
2394706f2543Smrg	return Success;
2395706f2543Smrg    }
2396706f2543Smrg    else
2397706f2543Smrg    {
2398706f2543Smrg	client->errorValue = stuff->id;
2399706f2543Smrg	return rc;
2400706f2543Smrg    }
2401706f2543Smrg}
2402706f2543Smrg
2403706f2543Smrg
2404706f2543Smrgint
2405706f2543SmrgProcCopyColormapAndFree(ClientPtr client)
2406706f2543Smrg{
2407706f2543Smrg    Colormap	mid;
2408706f2543Smrg    ColormapPtr	pSrcMap;
2409706f2543Smrg    REQUEST(xCopyColormapAndFreeReq);
2410706f2543Smrg    int rc;
2411706f2543Smrg
2412706f2543Smrg    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2413706f2543Smrg    mid = stuff->mid;
2414706f2543Smrg    LEGAL_NEW_RESOURCE(mid, client);
2415706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP,
2416706f2543Smrg			   client, DixReadAccess|DixRemoveAccess);
2417706f2543Smrg    if (rc == Success)
2418706f2543Smrg	return CopyColormapAndFree(mid, pSrcMap, client->index);
2419706f2543Smrg    client->errorValue = stuff->srcCmap;
2420706f2543Smrg    return rc;
2421706f2543Smrg}
2422706f2543Smrg
2423706f2543Smrgint
2424706f2543SmrgProcInstallColormap(ClientPtr client)
2425706f2543Smrg{
2426706f2543Smrg    ColormapPtr pcmp;
2427706f2543Smrg    int rc;
2428706f2543Smrg    REQUEST(xResourceReq);
2429706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
2430706f2543Smrg
2431706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
2432706f2543Smrg			   DixInstallAccess);
2433706f2543Smrg    if (rc != Success)
2434706f2543Smrg	goto out;
2435706f2543Smrg
2436706f2543Smrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2437706f2543Smrg    if (rc != Success) {
2438706f2543Smrg	if (rc == BadValue)
2439706f2543Smrg	    rc = BadColor;
2440706f2543Smrg	goto out;
2441706f2543Smrg    }
2442706f2543Smrg
2443706f2543Smrg    (*(pcmp->pScreen->InstallColormap)) (pcmp);
2444706f2543Smrg    return Success;
2445706f2543Smrg
2446706f2543Smrgout:
2447706f2543Smrg    client->errorValue = stuff->id;
2448706f2543Smrg    return rc;
2449706f2543Smrg}
2450706f2543Smrg
2451706f2543Smrgint
2452706f2543SmrgProcUninstallColormap(ClientPtr client)
2453706f2543Smrg{
2454706f2543Smrg    ColormapPtr pcmp;
2455706f2543Smrg    int rc;
2456706f2543Smrg    REQUEST(xResourceReq);
2457706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
2458706f2543Smrg
2459706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
2460706f2543Smrg			   DixUninstallAccess);
2461706f2543Smrg    if (rc != Success)
2462706f2543Smrg	goto out;
2463706f2543Smrg
2464706f2543Smrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2465706f2543Smrg    if (rc != Success) {
2466706f2543Smrg	if (rc == BadValue)
2467706f2543Smrg	    rc = BadColor;
2468706f2543Smrg	goto out;
2469706f2543Smrg    }
2470706f2543Smrg
2471706f2543Smrg    if(pcmp->mid != pcmp->pScreen->defColormap)
2472706f2543Smrg	(*(pcmp->pScreen->UninstallColormap)) (pcmp);
2473706f2543Smrg    return Success;
2474706f2543Smrg
2475706f2543Smrgout:
2476706f2543Smrg    client->errorValue = stuff->id;
2477706f2543Smrg    return rc;
2478706f2543Smrg}
2479706f2543Smrg
2480706f2543Smrgint
2481706f2543SmrgProcListInstalledColormaps(ClientPtr client)
2482706f2543Smrg{
2483706f2543Smrg    xListInstalledColormapsReply *preply;
2484706f2543Smrg    int nummaps, rc;
2485706f2543Smrg    WindowPtr pWin;
2486706f2543Smrg    REQUEST(xResourceReq);
2487706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
2488706f2543Smrg
2489706f2543Smrg    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
2490706f2543Smrg    if (rc != Success)
2491706f2543Smrg	return rc;
2492706f2543Smrg
2493706f2543Smrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
2494706f2543Smrg		  DixGetAttrAccess);
2495706f2543Smrg    if (rc != Success)
2496706f2543Smrg	return rc;
2497706f2543Smrg
2498706f2543Smrg    preply = malloc(sizeof(xListInstalledColormapsReply) +
2499706f2543Smrg		     pWin->drawable.pScreen->maxInstalledCmaps *
2500706f2543Smrg		     sizeof(Colormap));
2501706f2543Smrg    if(!preply)
2502706f2543Smrg        return BadAlloc;
2503706f2543Smrg
2504706f2543Smrg    preply->type = X_Reply;
2505706f2543Smrg    preply->sequenceNumber = client->sequence;
2506706f2543Smrg    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
2507706f2543Smrg        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
2508706f2543Smrg    preply->nColormaps = nummaps;
2509706f2543Smrg    preply->length = nummaps;
2510706f2543Smrg    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
2511706f2543Smrg    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2512706f2543Smrg    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
2513706f2543Smrg    free(preply);
2514706f2543Smrg    return Success;
2515706f2543Smrg}
2516706f2543Smrg
2517706f2543Smrgint
2518706f2543SmrgProcAllocColor (ClientPtr client)
2519706f2543Smrg{
2520706f2543Smrg    ColormapPtr pmap;
2521706f2543Smrg    int rc;
2522706f2543Smrg    xAllocColorReply acr;
2523706f2543Smrg    REQUEST(xAllocColorReq);
2524706f2543Smrg
2525706f2543Smrg    REQUEST_SIZE_MATCH(xAllocColorReq);
2526706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client,
2527706f2543Smrg			   DixAddAccess);
2528706f2543Smrg    if (rc == Success)
2529706f2543Smrg    {
2530706f2543Smrg	acr.type = X_Reply;
2531706f2543Smrg	acr.length = 0;
2532706f2543Smrg	acr.sequenceNumber = client->sequence;
2533706f2543Smrg	acr.red = stuff->red;
2534706f2543Smrg	acr.green = stuff->green;
2535706f2543Smrg	acr.blue = stuff->blue;
2536706f2543Smrg	acr.pixel = 0;
2537706f2543Smrg	if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
2538706f2543Smrg	                       &acr.pixel, client->index)) )
2539706f2543Smrg	    return rc;
2540706f2543Smrg#ifdef PANORAMIX
2541706f2543Smrg	if (noPanoramiXExtension || !pmap->pScreen->myNum)
2542706f2543Smrg#endif
2543706f2543Smrg        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
2544706f2543Smrg	return Success;
2545706f2543Smrg
2546706f2543Smrg    }
2547706f2543Smrg    else
2548706f2543Smrg    {
2549706f2543Smrg        client->errorValue = stuff->cmap;
2550706f2543Smrg        return rc;
2551706f2543Smrg    }
2552706f2543Smrg}
2553706f2543Smrg
2554706f2543Smrgint
2555706f2543SmrgProcAllocNamedColor (ClientPtr client)
2556706f2543Smrg{
2557706f2543Smrg    ColormapPtr pcmp;
2558706f2543Smrg    int rc;
2559706f2543Smrg    REQUEST(xAllocNamedColorReq);
2560706f2543Smrg
2561706f2543Smrg    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2562706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2563706f2543Smrg			   DixAddAccess);
2564706f2543Smrg    if (rc == Success)
2565706f2543Smrg    {
2566706f2543Smrg	xAllocNamedColorReply ancr;
2567706f2543Smrg
2568706f2543Smrg	ancr.type = X_Reply;
2569706f2543Smrg	ancr.length = 0;
2570706f2543Smrg	ancr.sequenceNumber = client->sequence;
2571706f2543Smrg
2572706f2543Smrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
2573706f2543Smrg	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
2574706f2543Smrg	{
2575706f2543Smrg	    ancr.screenRed = ancr.exactRed;
2576706f2543Smrg	    ancr.screenGreen = ancr.exactGreen;
2577706f2543Smrg	    ancr.screenBlue = ancr.exactBlue;
2578706f2543Smrg	    ancr.pixel = 0;
2579706f2543Smrg	    if( (rc = AllocColor(pcmp,
2580706f2543Smrg	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
2581706f2543Smrg			 &ancr.pixel, client->index)) )
2582706f2543Smrg		return rc;
2583706f2543Smrg#ifdef PANORAMIX
2584706f2543Smrg	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2585706f2543Smrg#endif
2586706f2543Smrg            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
2587706f2543Smrg	    return Success;
2588706f2543Smrg	}
2589706f2543Smrg	else
2590706f2543Smrg	    return BadName;
2591706f2543Smrg
2592706f2543Smrg    }
2593706f2543Smrg    else
2594706f2543Smrg    {
2595706f2543Smrg        client->errorValue = stuff->cmap;
2596706f2543Smrg        return rc;
2597706f2543Smrg    }
2598706f2543Smrg}
2599706f2543Smrg
2600706f2543Smrgint
2601706f2543SmrgProcAllocColorCells (ClientPtr client)
2602706f2543Smrg{
2603706f2543Smrg    ColormapPtr pcmp;
2604706f2543Smrg    int rc;
2605706f2543Smrg    REQUEST(xAllocColorCellsReq);
2606706f2543Smrg
2607706f2543Smrg    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2608706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2609706f2543Smrg			   DixAddAccess);
2610706f2543Smrg    if (rc == Success)
2611706f2543Smrg    {
2612706f2543Smrg	xAllocColorCellsReply	accr;
2613706f2543Smrg	int			npixels, nmasks;
2614706f2543Smrg	long			length;
2615706f2543Smrg	Pixel			*ppixels, *pmasks;
2616706f2543Smrg
2617706f2543Smrg	npixels = stuff->colors;
2618706f2543Smrg	if (!npixels)
2619706f2543Smrg	{
2620706f2543Smrg	    client->errorValue = npixels;
2621706f2543Smrg	    return BadValue;
2622706f2543Smrg	}
2623706f2543Smrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
2624706f2543Smrg	{
2625706f2543Smrg	    client->errorValue = stuff->contiguous;
2626706f2543Smrg	    return BadValue;
2627706f2543Smrg	}
2628706f2543Smrg	nmasks = stuff->planes;
2629706f2543Smrg	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
2630706f2543Smrg	ppixels = malloc(length);
2631706f2543Smrg	if(!ppixels)
2632706f2543Smrg            return BadAlloc;
2633706f2543Smrg	pmasks = ppixels + npixels;
2634706f2543Smrg
2635706f2543Smrg	if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
2636706f2543Smrg				    (Bool)stuff->contiguous, ppixels, pmasks)) )
2637706f2543Smrg	{
2638706f2543Smrg	    free(ppixels);
2639706f2543Smrg	    return rc;
2640706f2543Smrg	}
2641706f2543Smrg#ifdef PANORAMIX
2642706f2543Smrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2643706f2543Smrg#endif
2644706f2543Smrg	{
2645706f2543Smrg	    accr.type = X_Reply;
2646706f2543Smrg	    accr.length = bytes_to_int32(length);
2647706f2543Smrg	    accr.sequenceNumber = client->sequence;
2648706f2543Smrg	    accr.nPixels = npixels;
2649706f2543Smrg	    accr.nMasks = nmasks;
2650706f2543Smrg	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
2651706f2543Smrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2652706f2543Smrg	    WriteSwappedDataToClient(client, length, ppixels);
2653706f2543Smrg	}
2654706f2543Smrg	free(ppixels);
2655706f2543Smrg        return Success;
2656706f2543Smrg    }
2657706f2543Smrg    else
2658706f2543Smrg    {
2659706f2543Smrg        client->errorValue = stuff->cmap;
2660706f2543Smrg        return rc;
2661706f2543Smrg    }
2662706f2543Smrg}
2663706f2543Smrg
2664706f2543Smrgint
2665706f2543SmrgProcAllocColorPlanes(ClientPtr client)
2666706f2543Smrg{
2667706f2543Smrg    ColormapPtr pcmp;
2668706f2543Smrg    int rc;
2669706f2543Smrg    REQUEST(xAllocColorPlanesReq);
2670706f2543Smrg
2671706f2543Smrg    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2672706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2673706f2543Smrg			   DixAddAccess);
2674706f2543Smrg    if (rc == Success)
2675706f2543Smrg    {
2676706f2543Smrg	xAllocColorPlanesReply	acpr;
2677706f2543Smrg	int			npixels;
2678706f2543Smrg	long			length;
2679706f2543Smrg	Pixel			*ppixels;
2680706f2543Smrg
2681706f2543Smrg	npixels = stuff->colors;
2682706f2543Smrg	if (!npixels)
2683706f2543Smrg	{
2684706f2543Smrg	    client->errorValue = npixels;
2685706f2543Smrg	    return BadValue;
2686706f2543Smrg	}
2687706f2543Smrg	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
2688706f2543Smrg	{
2689706f2543Smrg	    client->errorValue = stuff->contiguous;
2690706f2543Smrg	    return BadValue;
2691706f2543Smrg	}
2692706f2543Smrg	acpr.type = X_Reply;
2693706f2543Smrg	acpr.sequenceNumber = client->sequence;
2694706f2543Smrg	acpr.nPixels = npixels;
2695706f2543Smrg	length = (long)npixels * sizeof(Pixel);
2696706f2543Smrg	ppixels = malloc(length);
2697706f2543Smrg	if(!ppixels)
2698706f2543Smrg            return BadAlloc;
2699706f2543Smrg	if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
2700706f2543Smrg	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
2701706f2543Smrg	    (Bool)stuff->contiguous, ppixels,
2702706f2543Smrg	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
2703706f2543Smrg	{
2704706f2543Smrg            free(ppixels);
2705706f2543Smrg	    return rc;
2706706f2543Smrg	}
2707706f2543Smrg	acpr.length = bytes_to_int32(length);
2708706f2543Smrg#ifdef PANORAMIX
2709706f2543Smrg	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2710706f2543Smrg#endif
2711706f2543Smrg	{
2712706f2543Smrg	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
2713706f2543Smrg	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2714706f2543Smrg	    WriteSwappedDataToClient(client, length, ppixels);
2715706f2543Smrg	}
2716706f2543Smrg	free(ppixels);
2717706f2543Smrg        return Success;
2718706f2543Smrg    }
2719706f2543Smrg    else
2720706f2543Smrg    {
2721706f2543Smrg        client->errorValue = stuff->cmap;
2722706f2543Smrg        return rc;
2723706f2543Smrg    }
2724706f2543Smrg}
2725706f2543Smrg
2726706f2543Smrgint
2727706f2543SmrgProcFreeColors(ClientPtr client)
2728706f2543Smrg{
2729706f2543Smrg    ColormapPtr pcmp;
2730706f2543Smrg    int rc;
2731706f2543Smrg    REQUEST(xFreeColorsReq);
2732706f2543Smrg
2733706f2543Smrg    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2734706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2735706f2543Smrg			   DixRemoveAccess);
2736706f2543Smrg    if (rc == Success)
2737706f2543Smrg    {
2738706f2543Smrg	int	count;
2739706f2543Smrg
2740706f2543Smrg	if(pcmp->flags & AllAllocated)
2741706f2543Smrg	    return BadAccess;
2742706f2543Smrg	count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
2743706f2543Smrg	return FreeColors(pcmp, client->index, count,
2744706f2543Smrg	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
2745706f2543Smrg    }
2746706f2543Smrg    else
2747706f2543Smrg    {
2748706f2543Smrg        client->errorValue = stuff->cmap;
2749706f2543Smrg        return rc;
2750706f2543Smrg    }
2751706f2543Smrg}
2752706f2543Smrg
2753706f2543Smrgint
2754706f2543SmrgProcStoreColors (ClientPtr client)
2755706f2543Smrg{
2756706f2543Smrg    ColormapPtr pcmp;
2757706f2543Smrg    int rc;
2758706f2543Smrg    REQUEST(xStoreColorsReq);
2759706f2543Smrg
2760706f2543Smrg    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2761706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2762706f2543Smrg			   DixWriteAccess);
2763706f2543Smrg    if (rc == Success)
2764706f2543Smrg    {
2765706f2543Smrg	int	count;
2766706f2543Smrg
2767706f2543Smrg        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
2768706f2543Smrg	if (count % sizeof(xColorItem))
2769706f2543Smrg	    return BadLength;
2770706f2543Smrg	count /= sizeof(xColorItem);
2771706f2543Smrg	return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client);
2772706f2543Smrg    }
2773706f2543Smrg    else
2774706f2543Smrg    {
2775706f2543Smrg        client->errorValue = stuff->cmap;
2776706f2543Smrg        return rc;
2777706f2543Smrg    }
2778706f2543Smrg}
2779706f2543Smrg
2780706f2543Smrgint
2781706f2543SmrgProcStoreNamedColor (ClientPtr client)
2782706f2543Smrg{
2783706f2543Smrg    ColormapPtr pcmp;
2784706f2543Smrg    int rc;
2785706f2543Smrg    REQUEST(xStoreNamedColorReq);
2786706f2543Smrg
2787706f2543Smrg    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2788706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2789706f2543Smrg			   DixWriteAccess);
2790706f2543Smrg    if (rc == Success)
2791706f2543Smrg    {
2792706f2543Smrg	xColorItem	def;
2793706f2543Smrg
2794706f2543Smrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
2795706f2543Smrg	                 stuff->nbytes, &def.red, &def.green, &def.blue))
2796706f2543Smrg	{
2797706f2543Smrg	    def.flags = stuff->flags;
2798706f2543Smrg	    def.pixel = stuff->pixel;
2799706f2543Smrg	    return StoreColors(pcmp, 1, &def, client);
2800706f2543Smrg	}
2801706f2543Smrg        return BadName;
2802706f2543Smrg    }
2803706f2543Smrg    else
2804706f2543Smrg    {
2805706f2543Smrg        client->errorValue = stuff->cmap;
2806706f2543Smrg        return rc;
2807706f2543Smrg    }
2808706f2543Smrg}
2809706f2543Smrg
2810706f2543Smrgint
2811706f2543SmrgProcQueryColors(ClientPtr client)
2812706f2543Smrg{
2813706f2543Smrg    ColormapPtr pcmp;
2814706f2543Smrg    int rc;
2815706f2543Smrg    REQUEST(xQueryColorsReq);
2816706f2543Smrg
2817706f2543Smrg    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2818706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2819706f2543Smrg			   DixReadAccess);
2820706f2543Smrg    if (rc == Success)
2821706f2543Smrg    {
2822706f2543Smrg	int			count;
2823706f2543Smrg	xrgb 			*prgbs;
2824706f2543Smrg	xQueryColorsReply	qcr;
2825706f2543Smrg
2826706f2543Smrg	count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
2827706f2543Smrg	prgbs = calloc(1, count * sizeof(xrgb));
2828706f2543Smrg	if(!prgbs && count)
2829706f2543Smrg            return BadAlloc;
2830706f2543Smrg	if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) )
2831706f2543Smrg	{
2832706f2543Smrg	    free(prgbs);
2833706f2543Smrg	    return rc;
2834706f2543Smrg	}
2835706f2543Smrg	memset(&qcr, 0, sizeof(xQueryColorsReply));
2836706f2543Smrg	qcr.type = X_Reply;
2837706f2543Smrg	qcr.length = bytes_to_int32(count * sizeof(xrgb));
2838706f2543Smrg	qcr.sequenceNumber = client->sequence;
2839706f2543Smrg	qcr.nColors = count;
2840706f2543Smrg	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
2841706f2543Smrg	if (count)
2842706f2543Smrg	{
2843706f2543Smrg	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
2844706f2543Smrg	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
2845706f2543Smrg	}
2846706f2543Smrg	free(prgbs);
2847706f2543Smrg	return Success;
2848706f2543Smrg
2849706f2543Smrg    }
2850706f2543Smrg    else
2851706f2543Smrg    {
2852706f2543Smrg        client->errorValue = stuff->cmap;
2853706f2543Smrg        return rc;
2854706f2543Smrg    }
2855706f2543Smrg}
2856706f2543Smrg
2857706f2543Smrgint
2858706f2543SmrgProcLookupColor(ClientPtr client)
2859706f2543Smrg{
2860706f2543Smrg    ColormapPtr pcmp;
2861706f2543Smrg    int rc;
2862706f2543Smrg    REQUEST(xLookupColorReq);
2863706f2543Smrg
2864706f2543Smrg    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2865706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
2866706f2543Smrg			   DixReadAccess);
2867706f2543Smrg    if (rc == Success)
2868706f2543Smrg    {
2869706f2543Smrg	xLookupColorReply lcr;
2870706f2543Smrg
2871706f2543Smrg	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
2872706f2543Smrg	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
2873706f2543Smrg	{
2874706f2543Smrg	    lcr.type = X_Reply;
2875706f2543Smrg	    lcr.length = 0;
2876706f2543Smrg	    lcr.sequenceNumber = client->sequence;
2877706f2543Smrg	    lcr.screenRed = lcr.exactRed;
2878706f2543Smrg	    lcr.screenGreen = lcr.exactGreen;
2879706f2543Smrg	    lcr.screenBlue = lcr.exactBlue;
2880706f2543Smrg	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
2881706f2543Smrg	                                   &lcr.screenGreen,
2882706f2543Smrg					   &lcr.screenBlue,
2883706f2543Smrg					   pcmp->pVisual);
2884706f2543Smrg	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
2885706f2543Smrg	    return Success;
2886706f2543Smrg	}
2887706f2543Smrg        return BadName;
2888706f2543Smrg    }
2889706f2543Smrg    else
2890706f2543Smrg    {
2891706f2543Smrg        client->errorValue = stuff->cmap;
2892706f2543Smrg        return rc;
2893706f2543Smrg    }
2894706f2543Smrg}
2895706f2543Smrg
2896706f2543Smrgint
2897706f2543SmrgProcCreateCursor (ClientPtr client)
2898706f2543Smrg{
2899706f2543Smrg    CursorPtr		pCursor;
2900706f2543Smrg    PixmapPtr 		src;
2901706f2543Smrg    PixmapPtr 		msk;
2902706f2543Smrg    unsigned char *	srcbits;
2903706f2543Smrg    unsigned char *	mskbits;
2904706f2543Smrg    unsigned short	width, height;
2905706f2543Smrg    long		n;
2906706f2543Smrg    CursorMetricRec 	cm;
2907706f2543Smrg    int rc;
2908706f2543Smrg
2909706f2543Smrg    REQUEST(xCreateCursorReq);
2910706f2543Smrg
2911706f2543Smrg    REQUEST_SIZE_MATCH(xCreateCursorReq);
2912706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
2913706f2543Smrg
2914706f2543Smrg    rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client,
2915706f2543Smrg			   DixReadAccess);
2916706f2543Smrg    if (rc != Success) {
2917706f2543Smrg	client->errorValue = stuff->source;
2918706f2543Smrg	return rc;
2919706f2543Smrg    }
2920706f2543Smrg
2921706f2543Smrg    rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
2922706f2543Smrg			   DixReadAccess);
2923706f2543Smrg    if (rc != Success)
2924706f2543Smrg    {
2925706f2543Smrg	if (stuff->mask != None)
2926706f2543Smrg	{
2927706f2543Smrg	    client->errorValue = stuff->mask;
2928706f2543Smrg	    return rc;
2929706f2543Smrg	}
2930706f2543Smrg    }
2931706f2543Smrg    else if (  src->drawable.width != msk->drawable.width
2932706f2543Smrg	    || src->drawable.height != msk->drawable.height
2933706f2543Smrg	    || src->drawable.depth != 1
2934706f2543Smrg	    || msk->drawable.depth != 1)
2935706f2543Smrg	return BadMatch;
2936706f2543Smrg
2937706f2543Smrg    width = src->drawable.width;
2938706f2543Smrg    height = src->drawable.height;
2939706f2543Smrg
2940706f2543Smrg    if ( stuff->x > width
2941706f2543Smrg      || stuff->y > height )
2942706f2543Smrg	return BadMatch;
2943706f2543Smrg
2944706f2543Smrg    n = BitmapBytePad(width)*height;
2945706f2543Smrg    srcbits = calloc(1, n);
2946706f2543Smrg    if (!srcbits)
2947706f2543Smrg	return BadAlloc;
2948706f2543Smrg    mskbits = malloc(n);
2949706f2543Smrg    if (!mskbits)
2950706f2543Smrg    {
2951706f2543Smrg	free(srcbits);
2952706f2543Smrg	return BadAlloc;
2953706f2543Smrg    }
2954706f2543Smrg
2955706f2543Smrg    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
2956706f2543Smrg					 XYPixmap, 1, (pointer)srcbits);
2957706f2543Smrg    if ( msk == (PixmapPtr)NULL)
2958706f2543Smrg    {
2959706f2543Smrg	unsigned char *bits = mskbits;
2960706f2543Smrg	while (--n >= 0)
2961706f2543Smrg	    *bits++ = ~0;
2962706f2543Smrg    }
2963706f2543Smrg    else
2964706f2543Smrg    {
2965706f2543Smrg	/* zeroing the (pad) bits helps some ddx cursor handling */
2966706f2543Smrg	memset((char *)mskbits, 0, n);
2967706f2543Smrg	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
2968706f2543Smrg					height, XYPixmap, 1, (pointer)mskbits);
2969706f2543Smrg    }
2970706f2543Smrg    cm.width = width;
2971706f2543Smrg    cm.height = height;
2972706f2543Smrg    cm.xhot = stuff->x;
2973706f2543Smrg    cm.yhot = stuff->y;
2974706f2543Smrg    rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
2975706f2543Smrg			 stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
2976706f2543Smrg			 stuff->backRed, stuff->backGreen, stuff->backBlue,
2977706f2543Smrg			 &pCursor, client, stuff->cid);
2978706f2543Smrg
2979706f2543Smrg    if (rc != Success)
2980706f2543Smrg	return rc;
2981706f2543Smrg    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
2982706f2543Smrg	return BadAlloc;
2983706f2543Smrg
2984706f2543Smrg    return Success;
2985706f2543Smrg}
2986706f2543Smrg
2987706f2543Smrgint
2988706f2543SmrgProcCreateGlyphCursor (ClientPtr client)
2989706f2543Smrg{
2990706f2543Smrg    CursorPtr pCursor;
2991706f2543Smrg    int res;
2992706f2543Smrg
2993706f2543Smrg    REQUEST(xCreateGlyphCursorReq);
2994706f2543Smrg
2995706f2543Smrg    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
2996706f2543Smrg    LEGAL_NEW_RESOURCE(stuff->cid, client);
2997706f2543Smrg
2998706f2543Smrg    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
2999706f2543Smrg			   stuff->mask, stuff->maskChar,
3000706f2543Smrg			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
3001706f2543Smrg			   stuff->backRed, stuff->backGreen, stuff->backBlue,
3002706f2543Smrg			   &pCursor, client, stuff->cid);
3003706f2543Smrg    if (res != Success)
3004706f2543Smrg	return res;
3005706f2543Smrg    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
3006706f2543Smrg	return Success;
3007706f2543Smrg    return BadAlloc;
3008706f2543Smrg}
3009706f2543Smrg
3010706f2543Smrg
3011706f2543Smrgint
3012706f2543SmrgProcFreeCursor (ClientPtr client)
3013706f2543Smrg{
3014706f2543Smrg    CursorPtr pCursor;
3015706f2543Smrg    int rc;
3016706f2543Smrg    REQUEST(xResourceReq);
3017706f2543Smrg
3018706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
3019706f2543Smrg    rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client,
3020706f2543Smrg			   DixDestroyAccess);
3021706f2543Smrg    if (rc == Success)
3022706f2543Smrg    {
3023706f2543Smrg	FreeResource(stuff->id, RT_NONE);
3024706f2543Smrg	return Success;
3025706f2543Smrg    }
3026706f2543Smrg    else
3027706f2543Smrg    {
3028706f2543Smrg	client->errorValue = stuff->id;
3029706f2543Smrg	return rc;
3030706f2543Smrg    }
3031706f2543Smrg}
3032706f2543Smrg
3033706f2543Smrgint
3034706f2543SmrgProcQueryBestSize (ClientPtr client)
3035706f2543Smrg{
3036706f2543Smrg    xQueryBestSizeReply	reply;
3037706f2543Smrg    DrawablePtr pDraw;
3038706f2543Smrg    ScreenPtr pScreen;
3039706f2543Smrg    int rc;
3040706f2543Smrg    REQUEST(xQueryBestSizeReq);
3041706f2543Smrg    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
3042706f2543Smrg
3043706f2543Smrg    if ((stuff->class != CursorShape) &&
3044706f2543Smrg	(stuff->class != TileShape) &&
3045706f2543Smrg	(stuff->class != StippleShape))
3046706f2543Smrg    {
3047706f2543Smrg	client->errorValue = stuff->class;
3048706f2543Smrg        return BadValue;
3049706f2543Smrg    }
3050706f2543Smrg
3051706f2543Smrg    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
3052706f2543Smrg			   DixGetAttrAccess);
3053706f2543Smrg    if (rc != Success)
3054706f2543Smrg	return rc;
3055706f2543Smrg    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
3056706f2543Smrg	return BadMatch;
3057706f2543Smrg    pScreen = pDraw->pScreen;
3058706f2543Smrg    rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
3059706f2543Smrg    if (rc != Success)
3060706f2543Smrg	return rc;
3061706f2543Smrg    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
3062706f2543Smrg			       &stuff->height, pScreen);
3063706f2543Smrg    memset(&reply, 0, sizeof(xQueryBestSizeReply));
3064706f2543Smrg    reply.type = X_Reply;
3065706f2543Smrg    reply.length = 0;
3066706f2543Smrg    reply.sequenceNumber = client->sequence;
3067706f2543Smrg    reply.width = stuff->width;
3068706f2543Smrg    reply.height = stuff->height;
3069706f2543Smrg    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
3070706f2543Smrg    return Success;
3071706f2543Smrg}
3072706f2543Smrg
3073706f2543Smrg
3074706f2543Smrgint
3075706f2543SmrgProcSetScreenSaver (ClientPtr client)
3076706f2543Smrg{
3077706f2543Smrg    int rc, i, blankingOption, exposureOption;
3078706f2543Smrg    REQUEST(xSetScreenSaverReq);
3079706f2543Smrg    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
3080706f2543Smrg
3081706f2543Smrg    for (i = 0; i < screenInfo.numScreens; i++) {
3082706f2543Smrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3083706f2543Smrg		      DixSetAttrAccess);
3084706f2543Smrg	if (rc != Success)
3085706f2543Smrg	    return rc;
3086706f2543Smrg    }
3087706f2543Smrg
3088706f2543Smrg    blankingOption = stuff->preferBlank;
3089706f2543Smrg    if ((blankingOption != DontPreferBlanking) &&
3090706f2543Smrg        (blankingOption != PreferBlanking) &&
3091706f2543Smrg        (blankingOption != DefaultBlanking))
3092706f2543Smrg    {
3093706f2543Smrg	client->errorValue = blankingOption;
3094706f2543Smrg        return BadValue;
3095706f2543Smrg    }
3096706f2543Smrg    exposureOption = stuff->allowExpose;
3097706f2543Smrg    if ((exposureOption != DontAllowExposures) &&
3098706f2543Smrg        (exposureOption != AllowExposures) &&
3099706f2543Smrg        (exposureOption != DefaultExposures))
3100706f2543Smrg    {
3101706f2543Smrg	client->errorValue = exposureOption;
3102706f2543Smrg        return BadValue;
3103706f2543Smrg    }
3104706f2543Smrg    if (stuff->timeout < -1)
3105706f2543Smrg    {
3106706f2543Smrg	client->errorValue = stuff->timeout;
3107706f2543Smrg        return BadValue;
3108706f2543Smrg    }
3109706f2543Smrg    if (stuff->interval < -1)
3110706f2543Smrg    {
3111706f2543Smrg	client->errorValue = stuff->interval;
3112706f2543Smrg        return BadValue;
3113706f2543Smrg    }
3114706f2543Smrg
3115706f2543Smrg    if (blankingOption == DefaultBlanking)
3116706f2543Smrg	ScreenSaverBlanking = defaultScreenSaverBlanking;
3117706f2543Smrg    else
3118706f2543Smrg	ScreenSaverBlanking = blankingOption;
3119706f2543Smrg    if (exposureOption == DefaultExposures)
3120706f2543Smrg	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
3121706f2543Smrg    else
3122706f2543Smrg	ScreenSaverAllowExposures = exposureOption;
3123706f2543Smrg
3124706f2543Smrg    if (stuff->timeout >= 0)
3125706f2543Smrg	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
3126706f2543Smrg    else
3127706f2543Smrg	ScreenSaverTime = defaultScreenSaverTime;
3128706f2543Smrg    if (stuff->interval >= 0)
3129706f2543Smrg	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
3130706f2543Smrg    else
3131706f2543Smrg	ScreenSaverInterval = defaultScreenSaverInterval;
3132706f2543Smrg
3133706f2543Smrg    SetScreenSaverTimer();
3134706f2543Smrg    return Success;
3135706f2543Smrg}
3136706f2543Smrg
3137706f2543Smrgint
3138706f2543SmrgProcGetScreenSaver(ClientPtr client)
3139706f2543Smrg{
3140706f2543Smrg    xGetScreenSaverReply rep;
3141706f2543Smrg    int rc, i;
3142706f2543Smrg    REQUEST_SIZE_MATCH(xReq);
3143706f2543Smrg
3144706f2543Smrg    for (i = 0; i < screenInfo.numScreens; i++) {
3145706f2543Smrg	rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3146706f2543Smrg		      DixGetAttrAccess);
3147706f2543Smrg	if (rc != Success)
3148706f2543Smrg	    return rc;
3149706f2543Smrg    }
3150706f2543Smrg
3151706f2543Smrg    rep.type = X_Reply;
3152706f2543Smrg    rep.length = 0;
3153706f2543Smrg    rep.sequenceNumber = client->sequence;
3154706f2543Smrg    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
3155706f2543Smrg    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
3156706f2543Smrg    rep.preferBlanking = ScreenSaverBlanking;
3157706f2543Smrg    rep.allowExposures = ScreenSaverAllowExposures;
3158706f2543Smrg    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
3159706f2543Smrg    return Success;
3160706f2543Smrg}
3161706f2543Smrg
3162706f2543Smrgint
3163706f2543SmrgProcChangeHosts(ClientPtr client)
3164706f2543Smrg{
3165706f2543Smrg    REQUEST(xChangeHostsReq);
3166706f2543Smrg
3167706f2543Smrg    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
3168706f2543Smrg
3169706f2543Smrg    if(stuff->mode == HostInsert)
3170706f2543Smrg	return AddHost(client, (int)stuff->hostFamily,
3171706f2543Smrg			 stuff->hostLength, (pointer)&stuff[1]);
3172706f2543Smrg    if (stuff->mode == HostDelete)
3173706f2543Smrg	return RemoveHost(client, (int)stuff->hostFamily,
3174706f2543Smrg			    stuff->hostLength, (pointer)&stuff[1]);
3175706f2543Smrg    client->errorValue = stuff->mode;
3176706f2543Smrg    return BadValue;
3177706f2543Smrg}
3178706f2543Smrg
3179706f2543Smrgint
3180706f2543SmrgProcListHosts(ClientPtr client)
3181706f2543Smrg{
3182706f2543Smrg    xListHostsReply reply;
3183706f2543Smrg    int	len, nHosts, result;
3184706f2543Smrg    pointer	pdata;
3185706f2543Smrg    /* REQUEST(xListHostsReq); */
3186706f2543Smrg
3187706f2543Smrg    REQUEST_SIZE_MATCH(xListHostsReq);
3188706f2543Smrg
3189706f2543Smrg    /* untrusted clients can't list hosts */
3190706f2543Smrg    result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
3191706f2543Smrg    if (result != Success)
3192706f2543Smrg	return result;
3193706f2543Smrg
3194706f2543Smrg    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
3195706f2543Smrg    if (result != Success)
3196706f2543Smrg	return result;
3197706f2543Smrg    reply.type = X_Reply;
3198706f2543Smrg    reply.sequenceNumber = client->sequence;
3199706f2543Smrg    reply.nHosts = nHosts;
3200706f2543Smrg    reply.length = bytes_to_int32(len);
3201706f2543Smrg    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
3202706f2543Smrg    if (nHosts)
3203706f2543Smrg    {
3204706f2543Smrg	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
3205706f2543Smrg	WriteSwappedDataToClient(client, len, pdata);
3206706f2543Smrg    }
3207706f2543Smrg    free(pdata);
3208706f2543Smrg    return Success;
3209706f2543Smrg}
3210706f2543Smrg
3211706f2543Smrgint
3212706f2543SmrgProcChangeAccessControl(ClientPtr client)
3213706f2543Smrg{
3214706f2543Smrg    REQUEST(xSetAccessControlReq);
3215706f2543Smrg
3216706f2543Smrg    REQUEST_SIZE_MATCH(xSetAccessControlReq);
3217706f2543Smrg    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
3218706f2543Smrg    {
3219706f2543Smrg	client->errorValue = stuff->mode;
3220706f2543Smrg        return BadValue;
3221706f2543Smrg    }
3222706f2543Smrg    return ChangeAccessControl(client, stuff->mode == EnableAccess);
3223706f2543Smrg}
3224706f2543Smrg
3225706f2543Smrg/*********************
3226706f2543Smrg * CloseDownRetainedResources
3227706f2543Smrg *
3228706f2543Smrg *    Find all clients that are gone and have terminated in RetainTemporary
3229706f2543Smrg *    and destroy their resources.
3230706f2543Smrg *********************/
3231706f2543Smrg
3232706f2543Smrgstatic void
3233706f2543SmrgCloseDownRetainedResources(void)
3234706f2543Smrg{
3235706f2543Smrg    int i;
3236706f2543Smrg    ClientPtr client;
3237706f2543Smrg
3238706f2543Smrg    for (i=1; i<currentMaxClients; i++)
3239706f2543Smrg    {
3240706f2543Smrg        client = clients[i];
3241706f2543Smrg        if (client && (client->closeDownMode == RetainTemporary)
3242706f2543Smrg	    && (client->clientGone))
3243706f2543Smrg	    CloseDownClient(client);
3244706f2543Smrg    }
3245706f2543Smrg}
3246706f2543Smrg
3247706f2543Smrgint
3248706f2543SmrgProcKillClient(ClientPtr client)
3249706f2543Smrg{
3250706f2543Smrg    REQUEST(xResourceReq);
3251706f2543Smrg    ClientPtr killclient;
3252706f2543Smrg    int rc;
3253706f2543Smrg
3254706f2543Smrg    REQUEST_SIZE_MATCH(xResourceReq);
3255706f2543Smrg    if (stuff->id == AllTemporary)
3256706f2543Smrg    {
3257706f2543Smrg	CloseDownRetainedResources();
3258706f2543Smrg        return Success;
3259706f2543Smrg    }
3260706f2543Smrg
3261706f2543Smrg    rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
3262706f2543Smrg    if (rc == Success) {
3263706f2543Smrg	CloseDownClient(killclient);
3264706f2543Smrg	/* if an LBX proxy gets killed, isItTimeToYield will be set */
3265706f2543Smrg	if (isItTimeToYield || (client == killclient))
3266706f2543Smrg	{
3267706f2543Smrg	    /* force yield and return Success, so that Dispatch()
3268706f2543Smrg	     * doesn't try to touch client
3269706f2543Smrg	     */
3270706f2543Smrg	    isItTimeToYield = TRUE;
3271706f2543Smrg	    return Success;
3272706f2543Smrg	}
3273706f2543Smrg	return Success;
3274706f2543Smrg    }
3275706f2543Smrg    else
3276706f2543Smrg	return rc;
3277706f2543Smrg}
3278706f2543Smrg
3279706f2543Smrgint
3280706f2543SmrgProcSetFontPath(ClientPtr client)
3281706f2543Smrg{
3282706f2543Smrg    unsigned char *ptr;
3283706f2543Smrg    unsigned long nbytes, total;
3284706f2543Smrg    long nfonts;
3285706f2543Smrg    int n;
3286706f2543Smrg    REQUEST(xSetFontPathReq);
3287706f2543Smrg
3288706f2543Smrg    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
3289706f2543Smrg
3290706f2543Smrg    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
3291706f2543Smrg    total = nbytes;
3292706f2543Smrg    ptr = (unsigned char *)&stuff[1];
3293706f2543Smrg    nfonts = stuff->nFonts;
3294706f2543Smrg    while (--nfonts >= 0)
3295706f2543Smrg    {
3296706f2543Smrg	if ((total == 0) || (total < (n = (*ptr + 1))))
3297706f2543Smrg	    return BadLength;
3298706f2543Smrg	total -= n;
3299706f2543Smrg	ptr += n;
3300706f2543Smrg    }
3301706f2543Smrg    if (total >= 4)
3302706f2543Smrg	return BadLength;
3303706f2543Smrg    return SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]);
3304706f2543Smrg}
3305706f2543Smrg
3306706f2543Smrgint
3307706f2543SmrgProcGetFontPath(ClientPtr client)
3308706f2543Smrg{
3309706f2543Smrg    xGetFontPathReply reply;
3310706f2543Smrg    int rc, stringLens, numpaths;
3311706f2543Smrg    unsigned char *bufferStart;
3312706f2543Smrg    /* REQUEST (xReq); */
3313706f2543Smrg
3314706f2543Smrg    REQUEST_SIZE_MATCH(xReq);
3315706f2543Smrg    rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
3316706f2543Smrg    if (rc != Success)
3317706f2543Smrg	return rc;
3318706f2543Smrg
3319706f2543Smrg    reply.type = X_Reply;
3320706f2543Smrg    reply.sequenceNumber = client->sequence;
3321706f2543Smrg    reply.length = bytes_to_int32(stringLens + numpaths);
3322706f2543Smrg    reply.nPaths = numpaths;
3323706f2543Smrg
3324706f2543Smrg    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
3325706f2543Smrg    if (stringLens || numpaths)
3326706f2543Smrg	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
3327706f2543Smrg    return Success;
3328706f2543Smrg}
3329706f2543Smrg
3330706f2543Smrgint
3331706f2543SmrgProcChangeCloseDownMode(ClientPtr client)
3332706f2543Smrg{
3333706f2543Smrg    int rc;
3334706f2543Smrg    REQUEST(xSetCloseDownModeReq);
3335706f2543Smrg    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
3336706f2543Smrg
3337706f2543Smrg    rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
3338706f2543Smrg    if (rc != Success)
3339706f2543Smrg	return rc;
3340706f2543Smrg
3341706f2543Smrg    if ((stuff->mode == AllTemporary) ||
3342706f2543Smrg	(stuff->mode == RetainPermanent) ||
3343706f2543Smrg	(stuff->mode == RetainTemporary))
3344706f2543Smrg    {
3345706f2543Smrg	client->closeDownMode = stuff->mode;
3346706f2543Smrg	return Success;
3347706f2543Smrg    }
3348706f2543Smrg    else
3349706f2543Smrg    {
3350706f2543Smrg	client->errorValue = stuff->mode;
3351706f2543Smrg	return BadValue;
3352706f2543Smrg    }
3353706f2543Smrg}
3354706f2543Smrg
3355706f2543Smrgint ProcForceScreenSaver(ClientPtr client)
3356706f2543Smrg{
3357706f2543Smrg    int rc;
3358706f2543Smrg    REQUEST(xForceScreenSaverReq);
3359706f2543Smrg
3360706f2543Smrg    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
3361706f2543Smrg
3362706f2543Smrg    if ((stuff->mode != ScreenSaverReset) &&
3363706f2543Smrg	(stuff->mode != ScreenSaverActive))
3364706f2543Smrg    {
3365706f2543Smrg	client->errorValue = stuff->mode;
3366706f2543Smrg        return BadValue;
3367706f2543Smrg    }
3368706f2543Smrg    rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode);
3369706f2543Smrg    if (rc != Success)
3370706f2543Smrg	return rc;
3371706f2543Smrg    return Success;
3372706f2543Smrg}
3373706f2543Smrg
3374706f2543Smrgint ProcNoOperation(ClientPtr client)
3375706f2543Smrg{
3376706f2543Smrg    REQUEST_AT_LEAST_SIZE(xReq);
3377706f2543Smrg
3378706f2543Smrg    /* noop -- don't do anything */
3379706f2543Smrg    return Success;
3380706f2543Smrg}
3381706f2543Smrg
3382706f2543Smrg/**********************
3383706f2543Smrg * CloseDownClient
3384706f2543Smrg *
3385706f2543Smrg *  Client can either mark his resources destroy or retain.  If retained and
3386706f2543Smrg *  then killed again, the client is really destroyed.
3387706f2543Smrg *********************/
3388706f2543Smrg
3389706f2543Smrgchar dispatchExceptionAtReset = DE_RESET;
3390706f2543Smrg
3391706f2543Smrgvoid
3392706f2543SmrgCloseDownClient(ClientPtr client)
3393706f2543Smrg{
3394706f2543Smrg    Bool really_close_down = client->clientGone ||
3395706f2543Smrg			     client->closeDownMode == DestroyAll;
3396706f2543Smrg
3397706f2543Smrg    if (!client->clientGone)
3398706f2543Smrg    {
3399706f2543Smrg	/* ungrab server if grabbing client dies */
3400706f2543Smrg	if (grabState != GrabNone && grabClient == client)
3401706f2543Smrg	{
3402706f2543Smrg	    UngrabServer(client);
3403706f2543Smrg	}
3404706f2543Smrg	BITCLEAR(grabWaiters, client->index);
3405706f2543Smrg	DeleteClientFromAnySelections(client);
3406706f2543Smrg	ReleaseActiveGrabs(client);
3407706f2543Smrg	DeleteClientFontStuff(client);
3408706f2543Smrg	if (!really_close_down)
3409706f2543Smrg	{
3410706f2543Smrg	    /*  This frees resources that should never be retained
3411706f2543Smrg	     *  no matter what the close down mode is.  Actually we
3412706f2543Smrg	     *  could do this unconditionally, but it's probably
3413706f2543Smrg	     *  better not to traverse all the client's resources
3414706f2543Smrg	     *  twice (once here, once a few lines down in
3415706f2543Smrg	     *  FreeClientResources) in the common case of
3416706f2543Smrg	     *  really_close_down == TRUE.
3417706f2543Smrg	     */
3418706f2543Smrg	    FreeClientNeverRetainResources(client);
3419706f2543Smrg	    client->clientState = ClientStateRetained;
3420706f2543Smrg  	    if (ClientStateCallback)
3421706f2543Smrg            {
3422706f2543Smrg		NewClientInfoRec clientinfo;
3423706f2543Smrg
3424706f2543Smrg		clientinfo.client = client;
3425706f2543Smrg		clientinfo.prefix = (xConnSetupPrefix *)NULL;
3426706f2543Smrg		clientinfo.setup = (xConnSetup *) NULL;
3427706f2543Smrg		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
3428706f2543Smrg            }
3429706f2543Smrg	}
3430706f2543Smrg	client->clientGone = TRUE;  /* so events aren't sent to client */
3431706f2543Smrg	if (ClientIsAsleep(client))
3432706f2543Smrg	    ClientSignal (client);
3433706f2543Smrg	ProcessWorkQueueZombies();
3434706f2543Smrg	CloseDownConnection(client);
3435706f2543Smrg
3436706f2543Smrg	/* If the client made it to the Running stage, nClients has
3437706f2543Smrg	 * been incremented on its behalf, so we need to decrement it
3438706f2543Smrg	 * now.  If it hasn't gotten to Running, nClients has *not*
3439706f2543Smrg	 * been incremented, so *don't* decrement it.
3440706f2543Smrg	 */
3441706f2543Smrg	if (client->clientState != ClientStateInitial &&
3442706f2543Smrg	    client->clientState != ClientStateAuthenticating )
3443706f2543Smrg	{
3444706f2543Smrg	    --nClients;
3445706f2543Smrg	}
3446706f2543Smrg    }
3447706f2543Smrg
3448706f2543Smrg    if (really_close_down)
3449706f2543Smrg    {
3450706f2543Smrg	if (client->clientState == ClientStateRunning && nClients == 0)
3451706f2543Smrg	    dispatchException |= dispatchExceptionAtReset;
3452706f2543Smrg
3453706f2543Smrg	client->clientState = ClientStateGone;
3454706f2543Smrg	if (ClientStateCallback)
3455706f2543Smrg	{
3456706f2543Smrg	    NewClientInfoRec clientinfo;
3457706f2543Smrg
3458706f2543Smrg	    clientinfo.client = client;
3459706f2543Smrg	    clientinfo.prefix = (xConnSetupPrefix *)NULL;
3460706f2543Smrg	    clientinfo.setup = (xConnSetup *) NULL;
3461706f2543Smrg	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
3462706f2543Smrg	}
3463706f2543Smrg	FreeClientResources(client);
3464706f2543Smrg#ifdef XSERVER_DTRACE
3465706f2543Smrg	XSERVER_CLIENT_DISCONNECT(client->index);
3466706f2543Smrg#endif
3467706f2543Smrg	if (client->index < nextFreeClientID)
3468706f2543Smrg	    nextFreeClientID = client->index;
3469706f2543Smrg	clients[client->index] = NullClient;
3470706f2543Smrg	SmartLastClient = NullClient;
3471706f2543Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3472706f2543Smrg
3473706f2543Smrg	while (!clients[currentMaxClients-1])
3474706f2543Smrg	    currentMaxClients--;
3475706f2543Smrg    }
3476706f2543Smrg}
3477706f2543Smrg
3478706f2543Smrgstatic void
3479706f2543SmrgKillAllClients(void)
3480706f2543Smrg{
3481706f2543Smrg    int i;
3482706f2543Smrg    for (i=1; i<currentMaxClients; i++)
3483706f2543Smrg        if (clients[i]) {
3484706f2543Smrg            /* Make sure Retained clients are released. */
3485706f2543Smrg            clients[i]->closeDownMode = DestroyAll;
3486706f2543Smrg            CloseDownClient(clients[i]);
3487706f2543Smrg        }
3488706f2543Smrg}
3489706f2543Smrg
3490706f2543Smrgvoid InitClient(ClientPtr client, int i, pointer ospriv)
3491706f2543Smrg{
3492706f2543Smrg    client->index = i;
3493706f2543Smrg    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
3494706f2543Smrg    client->closeDownMode = i ? DestroyAll : RetainPermanent;
3495706f2543Smrg    client->requestVector = InitialVector;
3496706f2543Smrg    client->osPrivate = ospriv;
3497706f2543Smrg    QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
3498706f2543Smrg    client->smart_start_tick = SmartScheduleTime;
3499706f2543Smrg    client->smart_stop_tick = SmartScheduleTime;
3500706f2543Smrg    client->smart_check_tick = SmartScheduleTime;
3501706f2543Smrg}
3502706f2543Smrg
3503706f2543Smrg/************************
3504706f2543Smrg * int NextAvailableClient(ospriv)
3505706f2543Smrg *
3506706f2543Smrg * OS dependent portion can't assign client id's because of CloseDownModes.
3507706f2543Smrg * Returns NULL if there are no free clients.
3508706f2543Smrg *************************/
3509706f2543Smrg
3510706f2543SmrgClientPtr NextAvailableClient(pointer ospriv)
3511706f2543Smrg{
3512706f2543Smrg    int i;
3513706f2543Smrg    ClientPtr client;
3514706f2543Smrg    xReq data;
3515706f2543Smrg
3516706f2543Smrg    i = nextFreeClientID;
3517706f2543Smrg    if (i == MAXCLIENTS)
3518706f2543Smrg	return (ClientPtr)NULL;
3519706f2543Smrg    clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
3520706f2543Smrg    if (!client)
3521706f2543Smrg	return (ClientPtr)NULL;
3522706f2543Smrg    InitClient(client, i, ospriv);
3523706f2543Smrg    if (!InitClientResources(client))
3524706f2543Smrg    {
3525706f2543Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3526706f2543Smrg	return (ClientPtr)NULL;
3527706f2543Smrg    }
3528706f2543Smrg    data.reqType = 1;
3529706f2543Smrg    data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
3530706f2543Smrg    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
3531706f2543Smrg    {
3532706f2543Smrg	FreeClientResources(client);
3533706f2543Smrg	dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3534706f2543Smrg	return (ClientPtr)NULL;
3535706f2543Smrg    }
3536706f2543Smrg    if (i == currentMaxClients)
3537706f2543Smrg	currentMaxClients++;
3538706f2543Smrg    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
3539706f2543Smrg	nextFreeClientID++;
3540706f2543Smrg    if (ClientStateCallback)
3541706f2543Smrg    {
3542706f2543Smrg	NewClientInfoRec clientinfo;
3543706f2543Smrg
3544706f2543Smrg        clientinfo.client = client;
3545706f2543Smrg        clientinfo.prefix = (xConnSetupPrefix *)NULL;
3546706f2543Smrg        clientinfo.setup = (xConnSetup *) NULL;
3547706f2543Smrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
3548706f2543Smrg    }
3549706f2543Smrg    return client;
3550706f2543Smrg}
3551706f2543Smrg
3552706f2543Smrgint
3553706f2543SmrgProcInitialConnection(ClientPtr client)
3554706f2543Smrg{
3555706f2543Smrg    REQUEST(xReq);
3556706f2543Smrg    xConnClientPrefix *prefix;
3557706f2543Smrg    int whichbyte = 1;
3558706f2543Smrg
3559706f2543Smrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
3560706f2543Smrg    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
3561706f2543Smrg	return client->noClientException = -1;
3562706f2543Smrg    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
3563706f2543Smrg	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
3564706f2543Smrg    {
3565706f2543Smrg	client->swapped = TRUE;
3566706f2543Smrg	SwapConnClientPrefix(prefix);
3567706f2543Smrg    }
3568706f2543Smrg    stuff->reqType = 2;
3569706f2543Smrg    stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
3570706f2543Smrg		     bytes_to_int32(prefix->nbytesAuthString);
3571706f2543Smrg    if (client->swapped)
3572706f2543Smrg    {
3573706f2543Smrg	swaps(&stuff->length, whichbyte);
3574706f2543Smrg    }
3575706f2543Smrg    ResetCurrentRequest(client);
3576706f2543Smrg    return Success;
3577706f2543Smrg}
3578706f2543Smrg
3579706f2543Smrgstatic int
3580706f2543SmrgSendConnSetup(ClientPtr client, char *reason)
3581706f2543Smrg{
3582706f2543Smrg    xWindowRoot *root;
3583706f2543Smrg    int i;
3584706f2543Smrg    int numScreens;
3585706f2543Smrg    char* lConnectionInfo;
3586706f2543Smrg    xConnSetupPrefix* lconnSetupPrefix;
3587706f2543Smrg
3588706f2543Smrg    if (reason)
3589706f2543Smrg    {
3590706f2543Smrg	xConnSetupPrefix csp;
3591706f2543Smrg
3592706f2543Smrg	csp.success = xFalse;
3593706f2543Smrg	csp.lengthReason = strlen(reason);
3594706f2543Smrg	csp.length = bytes_to_int32(csp.lengthReason);
3595706f2543Smrg	csp.majorVersion = X_PROTOCOL;
3596706f2543Smrg	csp.minorVersion = X_PROTOCOL_REVISION;
3597706f2543Smrg	if (client->swapped)
3598706f2543Smrg	    WriteSConnSetupPrefix(client, &csp);
3599706f2543Smrg	else
3600706f2543Smrg	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
3601706f2543Smrg        (void)WriteToClient(client, (int)csp.lengthReason, reason);
3602706f2543Smrg	return client->noClientException = -1;
3603706f2543Smrg    }
3604706f2543Smrg
3605706f2543Smrg    numScreens = screenInfo.numScreens;
3606706f2543Smrg    lConnectionInfo = ConnectionInfo;
3607706f2543Smrg    lconnSetupPrefix = &connSetupPrefix;
3608706f2543Smrg
3609706f2543Smrg    /* We're about to start speaking X protocol back to the client by
3610706f2543Smrg     * sending the connection setup info.  This means the authorization
3611706f2543Smrg     * step is complete, and we can count the client as an
3612706f2543Smrg     * authorized one.
3613706f2543Smrg     */
3614706f2543Smrg    nClients++;
3615706f2543Smrg
3616706f2543Smrg    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
3617706f2543Smrg    client->sequence = 0;
3618706f2543Smrg    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
3619706f2543Smrg    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
3620706f2543Smrg#ifdef MATCH_CLIENT_ENDIAN
3621706f2543Smrg    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
3622706f2543Smrg    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
3623706f2543Smrg#endif
3624706f2543Smrg    /* fill in the "currentInputMask" */
3625706f2543Smrg    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
3626706f2543Smrg#ifdef PANORAMIX
3627706f2543Smrg    if (noPanoramiXExtension)
3628706f2543Smrg	numScreens = screenInfo.numScreens;
3629706f2543Smrg    else
3630706f2543Smrg        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
3631706f2543Smrg#endif
3632706f2543Smrg
3633706f2543Smrg    for (i=0; i<numScreens; i++)
3634706f2543Smrg    {
3635706f2543Smrg	unsigned int j;
3636706f2543Smrg	xDepth *pDepth;
3637706f2543Smrg	WindowPtr pRoot = screenInfo.screens[i]->root;
3638706f2543Smrg
3639706f2543Smrg        root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
3640706f2543Smrg	pDepth = (xDepth *)(root + 1);
3641706f2543Smrg	for (j = 0; j < root->nDepths; j++)
3642706f2543Smrg	{
3643706f2543Smrg	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
3644706f2543Smrg				pDepth->nVisuals * sizeof(xVisualType));
3645706f2543Smrg	}
3646706f2543Smrg	root = (xWindowRoot *)pDepth;
3647706f2543Smrg    }
3648706f2543Smrg
3649706f2543Smrg    if (client->swapped)
3650706f2543Smrg    {
3651706f2543Smrg	WriteSConnSetupPrefix(client, lconnSetupPrefix);
3652706f2543Smrg	WriteSConnectionInfo(client,
3653706f2543Smrg			     (unsigned long)(lconnSetupPrefix->length << 2),
3654706f2543Smrg			     lConnectionInfo);
3655706f2543Smrg    }
3656706f2543Smrg    else
3657706f2543Smrg    {
3658706f2543Smrg	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
3659706f2543Smrg			    (char *) lconnSetupPrefix);
3660706f2543Smrg	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
3661706f2543Smrg			    lConnectionInfo);
3662706f2543Smrg    }
3663706f2543Smrg    client->clientState = ClientStateRunning;
3664706f2543Smrg    if (ClientStateCallback)
3665706f2543Smrg    {
3666706f2543Smrg	NewClientInfoRec clientinfo;
3667706f2543Smrg
3668706f2543Smrg        clientinfo.client = client;
3669706f2543Smrg        clientinfo.prefix = lconnSetupPrefix;
3670706f2543Smrg        clientinfo.setup = (xConnSetup *)lConnectionInfo;
3671706f2543Smrg	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
3672706f2543Smrg    }
3673706f2543Smrg    return Success;
3674706f2543Smrg}
3675706f2543Smrg
3676706f2543Smrgint
3677706f2543SmrgProcEstablishConnection(ClientPtr client)
3678706f2543Smrg{
3679706f2543Smrg    char *reason, *auth_proto, *auth_string;
3680706f2543Smrg    xConnClientPrefix *prefix;
3681706f2543Smrg    REQUEST(xReq);
3682706f2543Smrg
3683706f2543Smrg    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
3684706f2543Smrg    auth_proto = (char *)prefix + sz_xConnClientPrefix;
3685706f2543Smrg    auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
368648a68b89Smrg
368748a68b89Smrg    if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
368848a68b89Smrg       pad_to_int32(prefix->nbytesAuthProto) +
368948a68b89Smrg       pad_to_int32(prefix->nbytesAuthString))
369048a68b89Smrg        reason = "Bad length";
369148a68b89Smrg    else if ((prefix->majorVersion != X_PROTOCOL) ||
3692706f2543Smrg	(prefix->minorVersion != X_PROTOCOL_REVISION))
3693706f2543Smrg	reason = "Protocol version mismatch";
3694706f2543Smrg    else
3695706f2543Smrg	reason = ClientAuthorized(client,
3696706f2543Smrg				  (unsigned short)prefix->nbytesAuthProto,
3697706f2543Smrg				  auth_proto,
3698706f2543Smrg				  (unsigned short)prefix->nbytesAuthString,
3699706f2543Smrg				  auth_string);
3700706f2543Smrg    /*
3701706f2543Smrg     * If Kerberos is being used for this client, the clientState
3702706f2543Smrg     * will be set to ClientStateAuthenticating at this point.
3703706f2543Smrg     * More messages need to be exchanged among the X server, Kerberos
3704706f2543Smrg     * server, and client to figure out if everyone is authorized.
3705706f2543Smrg     * So we don't want to send the connection setup info yet, since
3706706f2543Smrg     * the auth step isn't really done.
3707706f2543Smrg     */
3708706f2543Smrg    if (client->clientState == ClientStateCheckingSecurity)
3709706f2543Smrg	client->clientState = ClientStateCheckedSecurity;
3710706f2543Smrg    else if (client->clientState != ClientStateAuthenticating)
3711706f2543Smrg	return(SendConnSetup(client, reason));
3712706f2543Smrg    return Success;
3713706f2543Smrg}
3714706f2543Smrg
3715706f2543Smrgvoid
3716706f2543SmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
3717706f2543Smrg                  XID resId, int errorCode)
3718706f2543Smrg{
3719706f2543Smrg    xError rep;
3720706f2543Smrg
3721706f2543Smrg    memset(&rep, 0, sizeof(xError));
3722706f2543Smrg    rep.type = X_Error;
3723706f2543Smrg    rep.errorCode = errorCode;
3724706f2543Smrg    rep.majorCode = majorCode;
3725706f2543Smrg    rep.minorCode = minorCode;
3726706f2543Smrg    rep.resourceID = resId;
3727706f2543Smrg
3728706f2543Smrg    WriteEventsToClient (client, 1, (xEvent *)&rep);
3729706f2543Smrg}
3730706f2543Smrg
3731706f2543Smrgvoid
3732706f2543SmrgMarkClientException(ClientPtr client)
3733706f2543Smrg{
3734706f2543Smrg    client->noClientException = -1;
3735706f2543Smrg}
3736706f2543Smrg
3737706f2543Smrg/*
3738706f2543Smrg * This array encodes the answer to the question "what is the log base 2
3739706f2543Smrg * of the number of pixels that fit in a scanline pad unit?"
3740706f2543Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3741706f2543Smrg */
3742706f2543Smrgstatic int answer[6][4] = {
3743706f2543Smrg	/* pad   pad   pad     pad*/
3744706f2543Smrg	/*  8     16    32    64 */
3745706f2543Smrg
3746706f2543Smrg	{   3,     4,    5 ,   6 },	/* 1 bit per pixel */
3747706f2543Smrg	{   1,     2,    3 ,   4 },	/* 4 bits per pixel */
3748706f2543Smrg	{   0,     1,    2 ,   3 },	/* 8 bits per pixel */
3749706f2543Smrg	{   ~0,    0,    1 ,   2 },	/* 16 bits per pixel */
3750706f2543Smrg	{   ~0,    ~0,   0 ,   1 },	/* 24 bits per pixel */
3751706f2543Smrg	{   ~0,    ~0,   0 ,   1 }	/* 32 bits per pixel */
3752706f2543Smrg};
3753706f2543Smrg
3754706f2543Smrg/*
3755706f2543Smrg * This array gives the answer to the question "what is the first index for
3756706f2543Smrg * the answer array above given the number of bits per pixel?"
3757706f2543Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3758706f2543Smrg */
3759706f2543Smrgstatic int indexForBitsPerPixel[ 33 ] = {
3760706f2543Smrg	~0, 0, ~0, ~0,	/* 1 bit per pixel */
3761706f2543Smrg	1, ~0, ~0, ~0,	/* 4 bits per pixel */
3762706f2543Smrg	2, ~0, ~0, ~0,	/* 8 bits per pixel */
3763706f2543Smrg	~0,~0, ~0, ~0,
3764706f2543Smrg	3, ~0, ~0, ~0,	/* 16 bits per pixel */
3765706f2543Smrg	~0,~0, ~0, ~0,
3766706f2543Smrg	4, ~0, ~0, ~0,	/* 24 bits per pixel */
3767706f2543Smrg	~0,~0, ~0, ~0,
3768706f2543Smrg	5		/* 32 bits per pixel */
3769706f2543Smrg};
3770706f2543Smrg
3771706f2543Smrg/*
3772706f2543Smrg * This array gives the bytesperPixel value for cases where the number
3773706f2543Smrg * of bits per pixel is a multiple of 8 but not a power of 2.
3774706f2543Smrg */
3775706f2543Smrgstatic int answerBytesPerPixel[ 33 ] = {
3776706f2543Smrg	~0, 0, ~0, ~0,	/* 1 bit per pixel */
3777706f2543Smrg	0, ~0, ~0, ~0,	/* 4 bits per pixel */
3778706f2543Smrg	0, ~0, ~0, ~0,	/* 8 bits per pixel */
3779706f2543Smrg	~0,~0, ~0, ~0,
3780706f2543Smrg	0, ~0, ~0, ~0,	/* 16 bits per pixel */
3781706f2543Smrg	~0,~0, ~0, ~0,
3782706f2543Smrg	3, ~0, ~0, ~0,	/* 24 bits per pixel */
3783706f2543Smrg	~0,~0, ~0, ~0,
3784706f2543Smrg	0		/* 32 bits per pixel */
3785706f2543Smrg};
3786706f2543Smrg
3787706f2543Smrg/*
3788706f2543Smrg * This array gives the answer to the question "what is the second index for
3789706f2543Smrg * the answer array above given the number of bits per scanline pad unit?"
3790706f2543Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3791706f2543Smrg */
3792706f2543Smrgstatic int indexForScanlinePad[ 65 ] = {
3793706f2543Smrg	~0, ~0, ~0, ~0,
3794706f2543Smrg	~0, ~0, ~0, ~0,
3795706f2543Smrg	 0, ~0, ~0, ~0,	/* 8 bits per scanline pad unit */
3796706f2543Smrg	~0, ~0, ~0, ~0,
3797706f2543Smrg	 1, ~0, ~0, ~0,	/* 16 bits per scanline pad unit */
3798706f2543Smrg	~0, ~0, ~0, ~0,
3799706f2543Smrg	~0, ~0, ~0, ~0,
3800706f2543Smrg	~0, ~0, ~0, ~0,
3801706f2543Smrg	 2, ~0, ~0, ~0,	/* 32 bits per scanline pad unit */
3802706f2543Smrg	~0, ~0, ~0, ~0,
3803706f2543Smrg	~0, ~0, ~0, ~0,
3804706f2543Smrg	~0, ~0, ~0, ~0,
3805706f2543Smrg	~0, ~0, ~0, ~0,
3806706f2543Smrg	~0, ~0, ~0, ~0,
3807706f2543Smrg	~0, ~0, ~0, ~0,
3808706f2543Smrg	~0, ~0, ~0, ~0,
3809706f2543Smrg	 3		/* 64 bits per scanline pad unit */
3810706f2543Smrg};
3811706f2543Smrg
3812706f2543Smrg/*
3813706f2543Smrg	grow the array of screenRecs if necessary.
3814706f2543Smrg	call the device-supplied initialization procedure
3815706f2543Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv.
3816706f2543Smrg	return the number of successfully installed screens.
3817706f2543Smrg
3818706f2543Smrg*/
3819706f2543Smrg
3820706f2543Smrgint
3821706f2543SmrgAddScreen(
3822706f2543Smrg    Bool	(* pfnInit)(
3823706f2543Smrg	int /*index*/,
3824706f2543Smrg	ScreenPtr /*pScreen*/,
3825706f2543Smrg	int /*argc*/,
3826706f2543Smrg	char ** /*argv*/
3827706f2543Smrg		),
3828706f2543Smrg    int argc,
3829706f2543Smrg    char **argv)
3830706f2543Smrg{
3831706f2543Smrg
3832706f2543Smrg    int i;
3833706f2543Smrg    int scanlinepad, format, depth, bitsPerPixel, j, k;
3834706f2543Smrg    ScreenPtr pScreen;
3835706f2543Smrg
3836706f2543Smrg    i = screenInfo.numScreens;
3837706f2543Smrg    if (i == MAXSCREENS)
3838706f2543Smrg	return -1;
3839706f2543Smrg
3840706f2543Smrg    pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
3841706f2543Smrg    if (!pScreen)
3842706f2543Smrg	return -1;
3843706f2543Smrg
3844706f2543Smrg    if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
3845706f2543Smrg	free (pScreen);
3846706f2543Smrg	return -1;
3847706f2543Smrg    }
3848706f2543Smrg    pScreen->myNum = i;
3849706f2543Smrg    pScreen->totalPixmapSize = 0;	/* computed in CreateScratchPixmapForScreen */
3850706f2543Smrg    pScreen->ClipNotify = 0;	/* for R4 ddx compatibility */
3851706f2543Smrg    pScreen->CreateScreenResources = 0;
3852706f2543Smrg
3853706f2543Smrg    /*
3854706f2543Smrg     * This loop gets run once for every Screen that gets added,
3855706f2543Smrg     * but thats ok.  If the ddx layer initializes the formats
3856706f2543Smrg     * one at a time calling AddScreen() after each, then each
3857706f2543Smrg     * iteration will make it a little more accurate.  Worst case
3858706f2543Smrg     * we do this loop N * numPixmapFormats where N is # of screens.
3859706f2543Smrg     * Anyway, this must be called after InitOutput and before the
3860706f2543Smrg     * screen init routine is called.
3861706f2543Smrg     */
3862706f2543Smrg    for (format=0; format<screenInfo.numPixmapFormats; format++)
3863706f2543Smrg    {
3864706f2543Smrg	depth = screenInfo.formats[format].depth;
3865706f2543Smrg	bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
3866706f2543Smrg	scanlinepad = screenInfo.formats[format].scanlinePad;
3867706f2543Smrg	j = indexForBitsPerPixel[ bitsPerPixel ];
3868706f2543Smrg	k = indexForScanlinePad[ scanlinepad ];
3869706f2543Smrg	PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
3870706f2543Smrg	PixmapWidthPaddingInfo[ depth ].padRoundUp =
3871706f2543Smrg	    (scanlinepad/bitsPerPixel) - 1;
3872706f2543Smrg	j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
3873706f2543Smrg	PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
3874706f2543Smrg	PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
3875706f2543Smrg	if (answerBytesPerPixel[bitsPerPixel])
3876706f2543Smrg	{
3877706f2543Smrg	    PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
3878706f2543Smrg	    PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
3879706f2543Smrg		answerBytesPerPixel[bitsPerPixel];
3880706f2543Smrg	}
3881706f2543Smrg	else
3882706f2543Smrg	{
3883706f2543Smrg	    PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
3884706f2543Smrg	}
3885706f2543Smrg    }
3886706f2543Smrg
3887706f2543Smrg    /* This is where screen specific stuff gets initialized.  Load the
3888706f2543Smrg       screen structure, call the hardware, whatever.
3889706f2543Smrg       This is also where the default colormap should be allocated and
3890706f2543Smrg       also pixel values for blackPixel, whitePixel, and the cursor
3891706f2543Smrg       Note that InitScreen is NOT allowed to modify argc, argv, or
3892706f2543Smrg       any of the strings pointed to by argv.  They may be passed to
3893706f2543Smrg       multiple screens.
3894706f2543Smrg    */
3895706f2543Smrg    screenInfo.screens[i] = pScreen;
3896706f2543Smrg    screenInfo.numScreens++;
3897706f2543Smrg    if (!(*pfnInit)(i, pScreen, argc, argv))
3898706f2543Smrg    {
3899706f2543Smrg	dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
3900706f2543Smrg	free(pScreen);
3901706f2543Smrg	screenInfo.numScreens--;
3902706f2543Smrg	return -1;
3903706f2543Smrg    }
3904706f2543Smrg
3905706f2543Smrg    dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0);
3906706f2543Smrg
3907706f2543Smrg    return i;
3908706f2543Smrg}
3909