3953 lines
		
	
	
		
			114 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			3953 lines
		
	
	
		
			114 KiB
		
	
	
	
		
			C
		
	
	
	
/************************************************************
 | 
						|
 | 
						|
Copyright 1987, 1989, 1998  The Open Group
 | 
						|
 | 
						|
Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
documentation for any purpose is hereby granted without fee, provided that
 | 
						|
the above copyright notice appear in all copies and that both that
 | 
						|
copyright notice and this permission notice appear in supporting
 | 
						|
documentation.
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be included in
 | 
						|
all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | 
						|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 | 
						|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
						|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
Except as contained in this notice, the name of The Open Group shall not be
 | 
						|
used in advertising or otherwise to promote the sale, use or other dealings
 | 
						|
in this Software without prior written authorization from The Open Group.
 | 
						|
 | 
						|
Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
 | 
						|
 | 
						|
                        All Rights Reserved
 | 
						|
 | 
						|
Permission to use, copy, modify, and distribute this software and its 
 | 
						|
documentation for any purpose and without fee is hereby granted, 
 | 
						|
provided that the above copyright notice appear in all copies and that
 | 
						|
both that copyright notice and this permission notice appear in 
 | 
						|
supporting documentation, and that the name of Digital not be
 | 
						|
used in advertising or publicity pertaining to distribution of the
 | 
						|
software without specific, written prior permission.  
 | 
						|
 | 
						|
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 | 
						|
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 | 
						|
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 | 
						|
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 | 
						|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 | 
						|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 | 
						|
SOFTWARE.
 | 
						|
 | 
						|
********************************************************/
 | 
						|
 | 
						|
/* The panoramix components contained the following notice */
 | 
						|
/*****************************************************************
 | 
						|
 | 
						|
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
 | 
						|
 | 
						|
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
						|
of this software and associated documentation files (the "Software"), to deal
 | 
						|
in the Software without restriction, including without limitation the rights
 | 
						|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
						|
copies of the Software.
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be included in
 | 
						|
all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
						|
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
 | 
						|
BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
 | 
						|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 | 
						|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
Except as contained in this notice, the name of Digital Equipment Corporation
 | 
						|
shall not be used in advertising or otherwise to promote the sale, use or other
 | 
						|
dealings in this Software without prior written authorization from Digital
 | 
						|
Equipment Corporation.
 | 
						|
 | 
						|
******************************************************************/
 | 
						|
 | 
						|
/* XSERVER_DTRACE additions:
 | 
						|
 * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
 | 
						|
 *
 | 
						|
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
						|
 * copy of this software and associated documentation files (the "Software"),
 | 
						|
 * to deal in the Software without restriction, including without limitation
 | 
						|
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
						|
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
						|
 * Software is furnished to do so, subject to the following conditions:
 | 
						|
 *
 | 
						|
 * The above copyright notice and this permission notice (including the next
 | 
						|
 * paragraph) shall be included in all copies or substantial portions of the
 | 
						|
 * Software.
 | 
						|
 *
 | 
						|
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
						|
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
						|
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
						|
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
						|
 * DEALINGS IN THE SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#include <version-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef PANORAMIX_DEBUG
 | 
						|
#include <stdio.h>
 | 
						|
int ProcInitialConnection();
 | 
						|
#endif
 | 
						|
 | 
						|
#include "windowstr.h"
 | 
						|
#include <X11/fonts/fontstruct.h>
 | 
						|
#include "dixfontstr.h"
 | 
						|
#include "gcstruct.h"
 | 
						|
#include "selection.h"
 | 
						|
#include "colormapst.h"
 | 
						|
#include "cursorstr.h"
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "opaque.h"
 | 
						|
#include "input.h"
 | 
						|
#include "servermd.h"
 | 
						|
#include "extnsionst.h"
 | 
						|
#include "dixfont.h"
 | 
						|
#include "dispatch.h"
 | 
						|
#include "swaprep.h"
 | 
						|
#include "swapreq.h"
 | 
						|
#include "privates.h"
 | 
						|
#include "xace.h"
 | 
						|
#include "inputstr.h"
 | 
						|
#include "xkbsrv.h"
 | 
						|
#include "site.h"
 | 
						|
#include "client.h"
 | 
						|
 | 
						|
#ifdef XSERVER_DTRACE
 | 
						|
#include "registry.h"
 | 
						|
#include <sys/types.h>
 | 
						|
typedef const char *string;
 | 
						|
 | 
						|
#include "Xserver-dtrace.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#define mskcnt ((MAXCLIENTS + 31) / 32)
 | 
						|
#define BITMASK(i) (1U << ((i) & 31))
 | 
						|
#define MASKIDX(i) ((i) >> 5)
 | 
						|
#define MASKWORD(buf, i) buf[MASKIDX(i)]
 | 
						|
#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
 | 
						|
#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
 | 
						|
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
 | 
						|
 | 
						|
xConnSetupPrefix connSetupPrefix;
 | 
						|
 | 
						|
PaddingInfo PixmapWidthPaddingInfo[33];
 | 
						|
 | 
						|
static ClientPtr grabClient;
 | 
						|
 | 
						|
#define GrabNone 0
 | 
						|
#define GrabActive 1
 | 
						|
#define GrabKickout 2
 | 
						|
static int grabState = GrabNone;
 | 
						|
static long grabWaiters[mskcnt];
 | 
						|
CallbackListPtr ServerGrabCallback = NULL;
 | 
						|
HWEventQueuePtr checkForInput[2];
 | 
						|
int connBlockScreenStart;
 | 
						|
 | 
						|
static void KillAllClients(void);
 | 
						|
 | 
						|
static int nextFreeClientID;    /* always MIN free client ID */
 | 
						|
 | 
						|
static int nClients;            /* number of authorized clients */
 | 
						|
 | 
						|
CallbackListPtr ClientStateCallback;
 | 
						|
 | 
						|
/* dispatchException & isItTimeToYield must be declared volatile since they
 | 
						|
 * are modified by signal handlers - otherwise optimizer may assume it doesn't
 | 
						|
 * need to actually check value in memory when used and may miss changes from
 | 
						|
 * signal handlers.
 | 
						|
 */
 | 
						|
volatile char dispatchException = 0;
 | 
						|
volatile char isItTimeToYield;
 | 
						|
 | 
						|
#define SAME_SCREENS(a, b) (\
 | 
						|
    (a.pScreen == b.pScreen))
 | 
						|
 | 
						|
void
 | 
						|
SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
 | 
						|
{
 | 
						|
    checkForInput[0] = c0;
 | 
						|
    checkForInput[1] = c1;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
UpdateCurrentTime(void)
 | 
						|
{
 | 
						|
    TimeStamp systime;
 | 
						|
 | 
						|
    /* To avoid time running backwards, we must call GetTimeInMillis before
 | 
						|
     * calling ProcessInputEvents.
 | 
						|
     */
 | 
						|
    systime.months = currentTime.months;
 | 
						|
    systime.milliseconds = GetTimeInMillis();
 | 
						|
    if (systime.milliseconds < currentTime.milliseconds)
 | 
						|
        systime.months++;
 | 
						|
    if (*checkForInput[0] != *checkForInput[1])
 | 
						|
        ProcessInputEvents();
 | 
						|
    if (CompareTimeStamps(systime, currentTime) == LATER)
 | 
						|
        currentTime = systime;
 | 
						|
}
 | 
						|
 | 
						|
/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
 | 
						|
void
 | 
						|
UpdateCurrentTimeIf(void)
 | 
						|
{
 | 
						|
    TimeStamp systime;
 | 
						|
 | 
						|
    systime.months = currentTime.months;
 | 
						|
    systime.milliseconds = GetTimeInMillis();
 | 
						|
    if (systime.milliseconds < currentTime.milliseconds)
 | 
						|
        systime.months++;
 | 
						|
    if (CompareTimeStamps(systime, currentTime) == LATER)
 | 
						|
        currentTime = systime;
 | 
						|
}
 | 
						|
 | 
						|
#undef SMART_DEBUG
 | 
						|
 | 
						|
/* in milliseconds */
 | 
						|
#define SMART_SCHEDULE_DEFAULT_INTERVAL	5
 | 
						|
#define SMART_SCHEDULE_MAX_SLICE	15
 | 
						|
 | 
						|
#if defined(WIN32) && !defined(__CYGWIN__)
 | 
						|
Bool SmartScheduleDisable = TRUE;
 | 
						|
#else
 | 
						|
Bool SmartScheduleDisable = FALSE;
 | 
						|
#endif
 | 
						|
long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
 | 
						|
long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
 | 
						|
long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
 | 
						|
long SmartScheduleTime;
 | 
						|
int SmartScheduleLatencyLimited = 0;
 | 
						|
static ClientPtr SmartLastClient;
 | 
						|
static int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1];
 | 
						|
 | 
						|
#ifdef SMART_DEBUG
 | 
						|
long SmartLastPrint;
 | 
						|
#endif
 | 
						|
 | 
						|
void Dispatch(void);
 | 
						|
 | 
						|
static int
 | 
						|
SmartScheduleClient(int *clientReady, int nready)
 | 
						|
{
 | 
						|
    ClientPtr pClient;
 | 
						|
    int i;
 | 
						|
    int client;
 | 
						|
    int bestPrio, best = 0;
 | 
						|
    int bestRobin, robin;
 | 
						|
    long now = SmartScheduleTime;
 | 
						|
    long idle;
 | 
						|
 | 
						|
    bestPrio = -0x7fffffff;
 | 
						|
    bestRobin = 0;
 | 
						|
    idle = 2 * SmartScheduleSlice;
 | 
						|
    for (i = 0; i < nready; i++) {
 | 
						|
        client = clientReady[i];
 | 
						|
        pClient = clients[client];
 | 
						|
        /* Praise clients which haven't run in a while */
 | 
						|
        if ((now - pClient->smart_stop_tick) >= idle) {
 | 
						|
            if (pClient->smart_priority < 0)
 | 
						|
                pClient->smart_priority++;
 | 
						|
        }
 | 
						|
 | 
						|
        /* check priority to select best client */
 | 
						|
        robin =
 | 
						|
            (pClient->index -
 | 
						|
             SmartLastIndex[pClient->smart_priority -
 | 
						|
                            SMART_MIN_PRIORITY]) & 0xff;
 | 
						|
        if (pClient->smart_priority > bestPrio ||
 | 
						|
            (pClient->smart_priority == bestPrio && robin > bestRobin)) {
 | 
						|
            bestPrio = pClient->smart_priority;
 | 
						|
            bestRobin = robin;
 | 
						|
            best = client;
 | 
						|
        }
 | 
						|
#ifdef SMART_DEBUG
 | 
						|
        if ((now - SmartLastPrint) >= 5000)
 | 
						|
            fprintf(stderr, " %2d: %3d", client, pClient->smart_priority);
 | 
						|
#endif
 | 
						|
    }
 | 
						|
#ifdef SMART_DEBUG
 | 
						|
    if ((now - SmartLastPrint) >= 5000) {
 | 
						|
        fprintf(stderr, " use %2d\n", best);
 | 
						|
        SmartLastPrint = now;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    pClient = clients[best];
 | 
						|
    SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index;
 | 
						|
    /*
 | 
						|
     * Set current client pointer
 | 
						|
     */
 | 
						|
    if (SmartLastClient != pClient) {
 | 
						|
        pClient->smart_start_tick = now;
 | 
						|
        SmartLastClient = pClient;
 | 
						|
    }
 | 
						|
    /*
 | 
						|
     * Adjust slice
 | 
						|
     */
 | 
						|
    if (nready == 1 && SmartScheduleLatencyLimited == 0) {
 | 
						|
        /*
 | 
						|
         * If it's been a long time since another client
 | 
						|
         * has run, bump the slice up to get maximal
 | 
						|
         * performance from a single client
 | 
						|
         */
 | 
						|
        if ((now - pClient->smart_start_tick) > 1000 &&
 | 
						|
            SmartScheduleSlice < SmartScheduleMaxSlice) {
 | 
						|
            SmartScheduleSlice += SmartScheduleInterval;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        SmartScheduleSlice = SmartScheduleInterval;
 | 
						|
    }
 | 
						|
    return best;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
EnableLimitedSchedulingLatency(void)
 | 
						|
{
 | 
						|
    ++SmartScheduleLatencyLimited;
 | 
						|
    SmartScheduleSlice = SmartScheduleInterval;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DisableLimitedSchedulingLatency(void)
 | 
						|
{
 | 
						|
    --SmartScheduleLatencyLimited;
 | 
						|
 | 
						|
    /* protect against bugs */
 | 
						|
    if (SmartScheduleLatencyLimited < 0)
 | 
						|
        SmartScheduleLatencyLimited = 0;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
Dispatch(void)
 | 
						|
{
 | 
						|
    int *clientReady;           /* array of request ready clients */
 | 
						|
    int result;
 | 
						|
    ClientPtr client;
 | 
						|
    int nready;
 | 
						|
    HWEventQueuePtr *icheck = checkForInput;
 | 
						|
    long start_tick;
 | 
						|
 | 
						|
    nextFreeClientID = 1;
 | 
						|
    nClients = 0;
 | 
						|
 | 
						|
    clientReady = malloc(sizeof(int) * MaxClients);
 | 
						|
    if (!clientReady)
 | 
						|
        return;
 | 
						|
 | 
						|
    SmartScheduleSlice = SmartScheduleInterval;
 | 
						|
    while (!dispatchException) {
 | 
						|
        if (*icheck[0] != *icheck[1]) {
 | 
						|
            ProcessInputEvents();
 | 
						|
            FlushIfCriticalOutputPending();
 | 
						|
        }
 | 
						|
 | 
						|
        nready = WaitForSomething(clientReady);
 | 
						|
 | 
						|
        if (nready && !SmartScheduleDisable) {
 | 
						|
            clientReady[0] = SmartScheduleClient(clientReady, nready);
 | 
						|
            nready = 1;
 | 
						|
        }
 | 
						|
       /***************** 
 | 
						|
	*  Handle events in round robin fashion, doing input between 
 | 
						|
	*  each round 
 | 
						|
	*****************/
 | 
						|
 | 
						|
        while (!dispatchException && (--nready >= 0)) {
 | 
						|
            client = clients[clientReady[nready]];
 | 
						|
            if (!client) {
 | 
						|
                /* KillClient can cause this to happen */
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            /* GrabServer activation can cause this to be true */
 | 
						|
            if (grabState == GrabKickout) {
 | 
						|
                grabState = GrabActive;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            isItTimeToYield = FALSE;
 | 
						|
 | 
						|
            start_tick = SmartScheduleTime;
 | 
						|
            while (!isItTimeToYield) {
 | 
						|
                if (*icheck[0] != *icheck[1])
 | 
						|
                    ProcessInputEvents();
 | 
						|
 | 
						|
                FlushIfCriticalOutputPending();
 | 
						|
                if (!SmartScheduleDisable &&
 | 
						|
                    (SmartScheduleTime - start_tick) >= SmartScheduleSlice) {
 | 
						|
                    /* Penalize clients which consume ticks */
 | 
						|
                    if (client->smart_priority > SMART_MIN_PRIORITY)
 | 
						|
                        client->smart_priority--;
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
                /* now, finally, deal with client requests */
 | 
						|
 | 
						|
                /* Update currentTime so request time checks, such as for input
 | 
						|
                 * device grabs, are calculated correctly */
 | 
						|
                UpdateCurrentTimeIf();
 | 
						|
                result = ReadRequestFromClient(client);
 | 
						|
                if (result <= 0) {
 | 
						|
                    if (result < 0)
 | 
						|
                        CloseDownClient(client);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                client->sequence++;
 | 
						|
                client->majorOp = ((xReq *) client->requestBuffer)->reqType;
 | 
						|
                client->minorOp = 0;
 | 
						|
                if (client->majorOp >= EXTENSION_BASE) {
 | 
						|
                    ExtensionEntry *ext = GetExtensionEntry(client->majorOp);
 | 
						|
 | 
						|
                    if (ext)
 | 
						|
                        client->minorOp = ext->MinorOpcode(client);
 | 
						|
                }
 | 
						|
#ifdef XSERVER_DTRACE
 | 
						|
                if (XSERVER_REQUEST_START_ENABLED())
 | 
						|
                    XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
 | 
						|
                                          client->majorOp,
 | 
						|
                                          ((xReq *) client->requestBuffer)->length,
 | 
						|
                                          client->index,
 | 
						|
                                          client->requestBuffer);
 | 
						|
#endif
 | 
						|
                if (result > (maxBigRequestSize << 2))
 | 
						|
                    result = BadLength;
 | 
						|
                else {
 | 
						|
                    result = XaceHookDispatch(client, client->majorOp);
 | 
						|
                    if (result == Success)
 | 
						|
                        result =
 | 
						|
                            (*client->requestVector[client->majorOp]) (client);
 | 
						|
                    XaceHookAuditEnd(client, result);
 | 
						|
                }
 | 
						|
#ifdef XSERVER_DTRACE
 | 
						|
                if (XSERVER_REQUEST_DONE_ENABLED())
 | 
						|
                    XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
 | 
						|
                                         client->majorOp, client->sequence,
 | 
						|
                                         client->index, result);
 | 
						|
#endif
 | 
						|
 | 
						|
                if (client->noClientException != Success) {
 | 
						|
                    CloseDownClient(client);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
                else if (result != Success) {
 | 
						|
                    SendErrorToClient(client, client->majorOp,
 | 
						|
                                      client->minorOp,
 | 
						|
                                      client->errorValue, result);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            FlushAllOutput();
 | 
						|
            client = clients[clientReady[nready]];
 | 
						|
            if (client)
 | 
						|
                client->smart_stop_tick = SmartScheduleTime;
 | 
						|
        }
 | 
						|
        dispatchException &= ~DE_PRIORITYCHANGE;
 | 
						|
    }
 | 
						|
#if defined(DDXBEFORERESET)
 | 
						|
    ddxBeforeReset();
 | 
						|
#endif
 | 
						|
    KillAllClients();
 | 
						|
    free(clientReady);
 | 
						|
    dispatchException &= ~DE_RESET;
 | 
						|
    SmartScheduleLatencyLimited = 0;
 | 
						|
    ResetOsBuffers();
 | 
						|
}
 | 
						|
 | 
						|
static int VendorRelease = VENDOR_RELEASE;
 | 
						|
static const char *VendorString = VENDOR_NAME;
 | 
						|
 | 
						|
void
 | 
						|
SetVendorRelease(int release)
 | 
						|
{
 | 
						|
    VendorRelease = release;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
SetVendorString(const char *vendor)
 | 
						|
{
 | 
						|
    VendorString = vendor;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
CreateConnectionBlock(void)
 | 
						|
{
 | 
						|
    xConnSetup setup;
 | 
						|
    xWindowRoot root;
 | 
						|
    xDepth depth;
 | 
						|
    xVisualType visual;
 | 
						|
    xPixmapFormat format;
 | 
						|
    unsigned long vid;
 | 
						|
    int i, j, k, lenofblock, sizesofar = 0;
 | 
						|
    char *pBuf;
 | 
						|
 | 
						|
    memset(&setup, 0, sizeof(xConnSetup));
 | 
						|
    /* Leave off the ridBase and ridMask, these must be sent with
 | 
						|
       connection */
 | 
						|
 | 
						|
    setup.release = VendorRelease;
 | 
						|
    /*
 | 
						|
     * per-server image and bitmap parameters are defined in Xmd.h
 | 
						|
     */
 | 
						|
    setup.imageByteOrder = screenInfo.imageByteOrder;
 | 
						|
 | 
						|
    setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
 | 
						|
    setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
 | 
						|
 | 
						|
    setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
 | 
						|
    setup.motionBufferSize = NumMotionEvents();
 | 
						|
    setup.numRoots = screenInfo.numScreens;
 | 
						|
    setup.nbytesVendor = strlen(VendorString);
 | 
						|
    setup.numFormats = screenInfo.numPixmapFormats;
 | 
						|
    setup.maxRequestSize = MAX_REQUEST_SIZE;
 | 
						|
    QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
 | 
						|
 | 
						|
    lenofblock = sizeof(xConnSetup) +
 | 
						|
        pad_to_int32(setup.nbytesVendor) +
 | 
						|
        (setup.numFormats * sizeof(xPixmapFormat)) +
 | 
						|
        (setup.numRoots * sizeof(xWindowRoot));
 | 
						|
    ConnectionInfo = malloc(lenofblock);
 | 
						|
    if (!ConnectionInfo)
 | 
						|
        return FALSE;
 | 
						|
 | 
						|
    memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup));
 | 
						|
    sizesofar = sizeof(xConnSetup);
 | 
						|
    pBuf = ConnectionInfo + sizeof(xConnSetup);
 | 
						|
 | 
						|
    memmove(pBuf, VendorString, (int) setup.nbytesVendor);
 | 
						|
    sizesofar += setup.nbytesVendor;
 | 
						|
    pBuf += setup.nbytesVendor;
 | 
						|
    i = padding_for_int32(setup.nbytesVendor);
 | 
						|
    sizesofar += i;
 | 
						|
    while (--i >= 0)
 | 
						|
        *pBuf++ = 0;
 | 
						|
 | 
						|
    memset(&format, 0, sizeof(xPixmapFormat));
 | 
						|
    for (i = 0; i < screenInfo.numPixmapFormats; i++) {
 | 
						|
        format.depth = screenInfo.formats[i].depth;
 | 
						|
        format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
 | 
						|
        format.scanLinePad = screenInfo.formats[i].scanlinePad;
 | 
						|
        memmove(pBuf, (char *) &format, sizeof(xPixmapFormat));
 | 
						|
        pBuf += sizeof(xPixmapFormat);
 | 
						|
        sizesofar += sizeof(xPixmapFormat);
 | 
						|
    }
 | 
						|
 | 
						|
    connBlockScreenStart = sizesofar;
 | 
						|
    memset(&depth, 0, sizeof(xDepth));
 | 
						|
    memset(&visual, 0, sizeof(xVisualType));
 | 
						|
    for (i = 0; i < screenInfo.numScreens; i++) {
 | 
						|
        ScreenPtr pScreen;
 | 
						|
        DepthPtr pDepth;
 | 
						|
        VisualPtr pVisual;
 | 
						|
 | 
						|
        pScreen = screenInfo.screens[i];
 | 
						|
        root.windowId = pScreen->root->drawable.id;
 | 
						|
        root.defaultColormap = pScreen->defColormap;
 | 
						|
        root.whitePixel = pScreen->whitePixel;
 | 
						|
        root.blackPixel = pScreen->blackPixel;
 | 
						|
        root.currentInputMask = 0;      /* filled in when sent */
 | 
						|
        root.pixWidth = pScreen->width;
 | 
						|
        root.pixHeight = pScreen->height;
 | 
						|
        root.mmWidth = pScreen->mmWidth;
 | 
						|
        root.mmHeight = pScreen->mmHeight;
 | 
						|
        root.minInstalledMaps = pScreen->minInstalledCmaps;
 | 
						|
        root.maxInstalledMaps = pScreen->maxInstalledCmaps;
 | 
						|
        root.rootVisualID = pScreen->rootVisual;
 | 
						|
        root.backingStore = pScreen->backingStoreSupport;
 | 
						|
        root.saveUnders = FALSE;
 | 
						|
        root.rootDepth = pScreen->rootDepth;
 | 
						|
        root.nDepths = pScreen->numDepths;
 | 
						|
        memmove(pBuf, (char *) &root, sizeof(xWindowRoot));
 | 
						|
        sizesofar += sizeof(xWindowRoot);
 | 
						|
        pBuf += sizeof(xWindowRoot);
 | 
						|
 | 
						|
        pDepth = pScreen->allowedDepths;
 | 
						|
        for (j = 0; j < pScreen->numDepths; j++, pDepth++) {
 | 
						|
            lenofblock += sizeof(xDepth) +
 | 
						|
                (pDepth->numVids * sizeof(xVisualType));
 | 
						|
            pBuf = (char *) realloc(ConnectionInfo, lenofblock);
 | 
						|
            if (!pBuf) {
 | 
						|
                free(ConnectionInfo);
 | 
						|
                return FALSE;
 | 
						|
            }
 | 
						|
            ConnectionInfo = pBuf;
 | 
						|
            pBuf += sizesofar;
 | 
						|
            depth.depth = pDepth->depth;
 | 
						|
            depth.nVisuals = pDepth->numVids;
 | 
						|
            memmove(pBuf, (char *) &depth, sizeof(xDepth));
 | 
						|
            pBuf += sizeof(xDepth);
 | 
						|
            sizesofar += sizeof(xDepth);
 | 
						|
            for (k = 0; k < pDepth->numVids; k++) {
 | 
						|
                vid = pDepth->vids[k];
 | 
						|
                for (pVisual = pScreen->visuals;
 | 
						|
                     pVisual->vid != vid; pVisual++);
 | 
						|
                visual.visualID = vid;
 | 
						|
                visual.class = pVisual->class;
 | 
						|
                visual.bitsPerRGB = pVisual->bitsPerRGBValue;
 | 
						|
                visual.colormapEntries = pVisual->ColormapEntries;
 | 
						|
                visual.redMask = pVisual->redMask;
 | 
						|
                visual.greenMask = pVisual->greenMask;
 | 
						|
                visual.blueMask = pVisual->blueMask;
 | 
						|
                memmove(pBuf, (char *) &visual, sizeof(xVisualType));
 | 
						|
                pBuf += sizeof(xVisualType);
 | 
						|
                sizesofar += sizeof(xVisualType);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    connSetupPrefix.success = xTrue;
 | 
						|
    connSetupPrefix.length = lenofblock / 4;
 | 
						|
    connSetupPrefix.majorVersion = X_PROTOCOL;
 | 
						|
    connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcBadRequest(ClientPtr client)
 | 
						|
{
 | 
						|
    return BadRequest;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCreateWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pParent, pWin;
 | 
						|
 | 
						|
    REQUEST(xCreateWindowReq);
 | 
						|
    int len, rc;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
 | 
						|
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->wid, client);
 | 
						|
    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
 | 
						|
    if (Ones(stuff->mask) != len)
 | 
						|
        return BadLength;
 | 
						|
    if (!stuff->width || !stuff->height) {
 | 
						|
        client->errorValue = 0;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
 | 
						|
                        stuff->y, stuff->width, stuff->height,
 | 
						|
                        stuff->borderWidth, stuff->class,
 | 
						|
                        stuff->mask, (XID *) &stuff[1],
 | 
						|
                        (int) stuff->depth, client, stuff->visual, &rc);
 | 
						|
    if (pWin) {
 | 
						|
        Mask mask = pWin->eventMask;
 | 
						|
 | 
						|
        pWin->eventMask = 0;    /* subterfuge in case AddResource fails */
 | 
						|
        if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin))
 | 
						|
            return BadAlloc;
 | 
						|
        pWin->eventMask = mask;
 | 
						|
    }
 | 
						|
    return rc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcChangeWindowAttributes(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xChangeWindowAttributesReq);
 | 
						|
    int len, rc;
 | 
						|
    Mask access_mode = 0;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
 | 
						|
    access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
 | 
						|
    access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
 | 
						|
    if (len != Ones(stuff->valueMask))
 | 
						|
        return BadLength;
 | 
						|
    return ChangeWindowAttributes(pWin,
 | 
						|
                                  stuff->valueMask, (XID *) &stuff[1], client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGetWindowAttributes(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    xGetWindowAttributesReply wa;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    memset(&wa, 0, sizeof(xGetWindowAttributesReply));
 | 
						|
    GetWindowAttributes(pWin, client, &wa);
 | 
						|
    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcDestroyWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    if (pWin->parent) {
 | 
						|
        rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
 | 
						|
                             DixRemoveAccess);
 | 
						|
        if (rc != Success)
 | 
						|
            return rc;
 | 
						|
        FreeResource(stuff->id, RT_NONE);
 | 
						|
    }
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcDestroySubwindows(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    DestroySubwindows(pWin, client);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcChangeSaveSet(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xChangeSaveSetReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
 | 
						|
        return BadMatch;
 | 
						|
    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
 | 
						|
        return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
 | 
						|
    client->errorValue = stuff->mode;
 | 
						|
    return BadValue;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcReparentWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin, pParent;
 | 
						|
 | 
						|
    REQUEST(xReparentWindowReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xReparentWindowReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
 | 
						|
        return BadMatch;
 | 
						|
    if ((pWin->backgroundState == ParentRelative) &&
 | 
						|
        (pParent->drawable.depth != pWin->drawable.depth))
 | 
						|
        return BadMatch;
 | 
						|
    if ((pWin->drawable.class != InputOnly) &&
 | 
						|
        (pParent->drawable.class == InputOnly))
 | 
						|
        return BadMatch;
 | 
						|
    return ReparentWindow(pWin, pParent,
 | 
						|
                          (short) stuff->x, (short) stuff->y, client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcMapWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    MapWindow(pWin, client);
 | 
						|
    /* update cache to say it is mapped */
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcMapSubwindows(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    MapSubwindows(pWin, client);
 | 
						|
    /* update cache to say it is mapped */
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcUnmapWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    UnmapWindow(pWin, FALSE);
 | 
						|
    /* update cache to say it is mapped */
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcUnmapSubwindows(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    UnmapSubwindows(pWin);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcConfigureWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xConfigureWindowReq);
 | 
						|
    int len, rc;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->window, client,
 | 
						|
                         DixManageAccess | DixSetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
 | 
						|
    if (Ones((Mask) stuff->mask) != len)
 | 
						|
        return BadLength;
 | 
						|
    return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCirculateWindow(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xCirculateWindowReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCirculateWindowReq);
 | 
						|
    if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) {
 | 
						|
        client->errorValue = stuff->direction;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    CirculateWindow(pWin, (int) stuff->direction, client);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
GetGeometry(ClientPtr client, xGetGeometryReply * rep)
 | 
						|
{
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    rep->type = X_Reply;
 | 
						|
    rep->length = 0;
 | 
						|
    rep->sequenceNumber = client->sequence;
 | 
						|
    rep->root = pDraw->pScreen->root->drawable.id;
 | 
						|
    rep->depth = pDraw->depth;
 | 
						|
    rep->width = pDraw->width;
 | 
						|
    rep->height = pDraw->height;
 | 
						|
 | 
						|
    if (WindowDrawable(pDraw->type)) {
 | 
						|
        WindowPtr pWin = (WindowPtr) pDraw;
 | 
						|
 | 
						|
        rep->x = pWin->origin.x - wBorderWidth(pWin);
 | 
						|
        rep->y = pWin->origin.y - wBorderWidth(pWin);
 | 
						|
        rep->borderWidth = pWin->borderWidth;
 | 
						|
    }
 | 
						|
    else {                      /* DRAWABLE_PIXMAP */
 | 
						|
 | 
						|
        rep->x = rep->y = rep->borderWidth = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGetGeometry(ClientPtr client)
 | 
						|
{
 | 
						|
    xGetGeometryReply rep = { .type = X_Reply };
 | 
						|
    int status;
 | 
						|
 | 
						|
    if ((status = GetGeometry(client, &rep)) != Success)
 | 
						|
        return status;
 | 
						|
 | 
						|
    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcQueryTree(ClientPtr client)
 | 
						|
{
 | 
						|
    xQueryTreeReply reply;
 | 
						|
    int rc, numChildren = 0;
 | 
						|
    WindowPtr pChild, pWin, pHead;
 | 
						|
    Window *childIDs = (Window *) NULL;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    reply = (xQueryTreeReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .root = pWin->drawable.pScreen->root->drawable.id,
 | 
						|
        .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None
 | 
						|
    };
 | 
						|
    pHead = RealChildHead(pWin);
 | 
						|
    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
 | 
						|
        numChildren++;
 | 
						|
    if (numChildren) {
 | 
						|
        int curChild = 0;
 | 
						|
 | 
						|
        childIDs = malloc(numChildren * sizeof(Window));
 | 
						|
        if (!childIDs)
 | 
						|
            return BadAlloc;
 | 
						|
        for (pChild = pWin->lastChild; pChild != pHead;
 | 
						|
             pChild = pChild->prevSib)
 | 
						|
            childIDs[curChild++] = pChild->drawable.id;
 | 
						|
    }
 | 
						|
 | 
						|
    reply.nChildren = numChildren;
 | 
						|
    reply.length = bytes_to_int32(numChildren * sizeof(Window));
 | 
						|
 | 
						|
    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
 | 
						|
    if (numChildren) {
 | 
						|
        client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 | 
						|
        WriteSwappedDataToClient(client, numChildren * sizeof(Window),
 | 
						|
                                 childIDs);
 | 
						|
        free(childIDs);
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcInternAtom(ClientPtr client)
 | 
						|
{
 | 
						|
    Atom atom;
 | 
						|
    char *tchar;
 | 
						|
 | 
						|
    REQUEST(xInternAtomReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
 | 
						|
    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) {
 | 
						|
        client->errorValue = stuff->onlyIfExists;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    tchar = (char *) &stuff[1];
 | 
						|
    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
 | 
						|
    if (atom != BAD_RESOURCE) {
 | 
						|
        xInternAtomReply reply = {
 | 
						|
            .type = X_Reply,
 | 
						|
            .sequenceNumber = client->sequence,
 | 
						|
            .length = 0,
 | 
						|
            .atom = atom
 | 
						|
        };
 | 
						|
        WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return BadAlloc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGetAtomName(ClientPtr client)
 | 
						|
{
 | 
						|
    const char *str;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    if ((str = NameForAtom(stuff->id))) {
 | 
						|
        int len = strlen(str);
 | 
						|
        xGetAtomNameReply reply = {
 | 
						|
            .type = X_Reply,
 | 
						|
            .sequenceNumber = client->sequence,
 | 
						|
            .length = bytes_to_int32(len),
 | 
						|
            .nameLength = len
 | 
						|
        };
 | 
						|
 | 
						|
        WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
 | 
						|
        WriteToClient(client, len, str);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->id;
 | 
						|
        return BadAtom;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGrabServer(ClientPtr client)
 | 
						|
{
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xReq);
 | 
						|
    if (grabState != GrabNone && client != grabClient) {
 | 
						|
        ResetCurrentRequest(client);
 | 
						|
        client->sequence--;
 | 
						|
        BITSET(grabWaiters, client->index);
 | 
						|
        IgnoreClient(client);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    rc = OnlyListenToOneClient(client);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    grabState = GrabKickout;
 | 
						|
    grabClient = client;
 | 
						|
 | 
						|
    if (ServerGrabCallback) {
 | 
						|
        ServerGrabInfoRec grabinfo;
 | 
						|
 | 
						|
        grabinfo.client = client;
 | 
						|
        grabinfo.grabstate = SERVER_GRABBED;
 | 
						|
        CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
UngrabServer(ClientPtr client)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    grabState = GrabNone;
 | 
						|
    ListenToAllClients();
 | 
						|
    for (i = mskcnt; --i >= 0 && !grabWaiters[i];);
 | 
						|
    if (i >= 0) {
 | 
						|
        i <<= 5;
 | 
						|
        while (!GETBIT(grabWaiters, i))
 | 
						|
            i++;
 | 
						|
        BITCLEAR(grabWaiters, i);
 | 
						|
        AttendClient(clients[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    if (ServerGrabCallback) {
 | 
						|
        ServerGrabInfoRec grabinfo;
 | 
						|
 | 
						|
        grabinfo.client = client;
 | 
						|
        grabinfo.grabstate = SERVER_UNGRABBED;
 | 
						|
        CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcUngrabServer(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST_SIZE_MATCH(xReq);
 | 
						|
    UngrabServer(client);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcTranslateCoords(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xTranslateCoordsReq);
 | 
						|
 | 
						|
    WindowPtr pWin, pDst;
 | 
						|
    xTranslateCoordsReply rep;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    rep = (xTranslateCoordsReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0
 | 
						|
    };
 | 
						|
    if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) {
 | 
						|
        rep.sameScreen = xFalse;
 | 
						|
        rep.child = None;
 | 
						|
        rep.dstX = rep.dstY = 0;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        INT16 x, y;
 | 
						|
 | 
						|
        rep.sameScreen = xTrue;
 | 
						|
        rep.child = None;
 | 
						|
        /* computing absolute coordinates -- adjust to destination later */
 | 
						|
        x = pWin->drawable.x + stuff->srcX;
 | 
						|
        y = pWin->drawable.y + stuff->srcY;
 | 
						|
        pWin = pDst->firstChild;
 | 
						|
        while (pWin) {
 | 
						|
            BoxRec box;
 | 
						|
 | 
						|
            if ((pWin->mapped) &&
 | 
						|
                (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
 | 
						|
                (x < pWin->drawable.x + (int) pWin->drawable.width +
 | 
						|
                 wBorderWidth(pWin)) &&
 | 
						|
                (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
 | 
						|
                (y < pWin->drawable.y + (int) pWin->drawable.height +
 | 
						|
                 wBorderWidth(pWin))
 | 
						|
                /* When a window is shaped, a further check
 | 
						|
                 * is made to see if the point is inside
 | 
						|
                 * borderSize
 | 
						|
                 */
 | 
						|
                && (!wBoundingShape(pWin) ||
 | 
						|
                    RegionContainsPoint(&pWin->borderSize, x, y, &box))
 | 
						|
 | 
						|
                && (!wInputShape(pWin) ||
 | 
						|
                    RegionContainsPoint(wInputShape(pWin),
 | 
						|
                                        x - pWin->drawable.x,
 | 
						|
                                        y - pWin->drawable.y, &box))
 | 
						|
                ) {
 | 
						|
                rep.child = pWin->drawable.id;
 | 
						|
                pWin = (WindowPtr) NULL;
 | 
						|
            }
 | 
						|
            else
 | 
						|
                pWin = pWin->nextSib;
 | 
						|
        }
 | 
						|
        /* adjust to destination coordinates */
 | 
						|
        rep.dstX = x - pDst->drawable.x;
 | 
						|
        rep.dstY = y - pDst->drawable.y;
 | 
						|
    }
 | 
						|
    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcOpenFont(ClientPtr client)
 | 
						|
{
 | 
						|
    int err;
 | 
						|
 | 
						|
    REQUEST(xOpenFontReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
 | 
						|
    client->errorValue = stuff->fid;
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->fid, client);
 | 
						|
    err = OpenFont(client, stuff->fid, (Mask) 0,
 | 
						|
                   stuff->nbytes, (char *) &stuff[1]);
 | 
						|
    if (err == Success) {
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return err;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCloseFont(ClientPtr client)
 | 
						|
{
 | 
						|
    FontPtr pFont;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT,
 | 
						|
                                 client, DixDestroyAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        FreeResource(stuff->id, RT_NONE);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->id;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcQueryFont(ClientPtr client)
 | 
						|
{
 | 
						|
    xQueryFontReply *reply;
 | 
						|
    FontPtr pFont;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    {
 | 
						|
        xCharInfo *pmax = FONTINKMAX(pFont);
 | 
						|
        xCharInfo *pmin = FONTINKMIN(pFont);
 | 
						|
        int nprotoxcistructs;
 | 
						|
        int rlength;
 | 
						|
 | 
						|
        nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing &&
 | 
						|
                            pmax->leftSideBearing == pmin->leftSideBearing &&
 | 
						|
                            pmax->descent == pmin->descent &&
 | 
						|
                            pmax->ascent == pmin->ascent &&
 | 
						|
                            pmax->characterWidth == pmin->characterWidth) ?
 | 
						|
            0 : N2dChars(pFont);
 | 
						|
 | 
						|
        rlength = sizeof(xQueryFontReply) +
 | 
						|
            FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
 | 
						|
            nprotoxcistructs * sizeof(xCharInfo);
 | 
						|
        reply = calloc(1, rlength);
 | 
						|
        if (!reply) {
 | 
						|
            return BadAlloc;
 | 
						|
        }
 | 
						|
 | 
						|
        reply->type = X_Reply;
 | 
						|
        reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
 | 
						|
        reply->sequenceNumber = client->sequence;
 | 
						|
        QueryFont(pFont, reply, nprotoxcistructs);
 | 
						|
 | 
						|
        WriteReplyToClient(client, rlength, reply);
 | 
						|
        free(reply);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcQueryTextExtents(ClientPtr client)
 | 
						|
{
 | 
						|
    xQueryTextExtentsReply reply;
 | 
						|
    FontPtr pFont;
 | 
						|
    ExtentInfoRec info;
 | 
						|
    unsigned long length;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xQueryTextExtentsReq);
 | 
						|
    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
 | 
						|
 | 
						|
    rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
 | 
						|
    length = length << 1;
 | 
						|
    if (stuff->oddLength) {
 | 
						|
        if (length == 0)
 | 
						|
            return BadLength;
 | 
						|
        length--;
 | 
						|
    }
 | 
						|
    if (!QueryTextExtents(pFont, length, (unsigned char *) &stuff[1], &info))
 | 
						|
        return BadAlloc;
 | 
						|
    reply = (xQueryTextExtentsReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .drawDirection = info.drawDirection,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
        .fontAscent = info.fontAscent,
 | 
						|
        .fontDescent = info.fontDescent,
 | 
						|
        .overallAscent = info.overallAscent,
 | 
						|
        .overallDescent = info.overallDescent,
 | 
						|
        .overallWidth = info.overallWidth,
 | 
						|
        .overallLeft = info.overallLeft,
 | 
						|
        .overallRight = info.overallRight
 | 
						|
    };
 | 
						|
    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcListFonts(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xListFontsReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
 | 
						|
 | 
						|
    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
 | 
						|
                     stuff->maxNames);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcListFontsWithInfo(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xListFontsWithInfoReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
 | 
						|
 | 
						|
    return StartListFontsWithInfo(client, stuff->nbytes,
 | 
						|
                                  (unsigned char *) &stuff[1], stuff->maxNames);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 *
 | 
						|
 *  \param value must conform to DeleteType
 | 
						|
 */
 | 
						|
int
 | 
						|
dixDestroyPixmap(void *value, XID pid)
 | 
						|
{
 | 
						|
    PixmapPtr pPixmap = (PixmapPtr) value;
 | 
						|
 | 
						|
    return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCreatePixmap(ClientPtr client)
 | 
						|
{
 | 
						|
    PixmapPtr pMap;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xCreatePixmapReq);
 | 
						|
    DepthPtr pDepth;
 | 
						|
    int i, rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCreatePixmapReq);
 | 
						|
    client->errorValue = stuff->pid;
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->pid, client);
 | 
						|
 | 
						|
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
 | 
						|
                           DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    if (!stuff->width || !stuff->height) {
 | 
						|
        client->errorValue = 0;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    if (stuff->width > 32767 || stuff->height > 32767) {
 | 
						|
        /* It is allowed to try and allocate a pixmap which is larger than
 | 
						|
         * 32767 in either dimension. However, all of the framebuffer code
 | 
						|
         * is buggy and does not reliably draw to such big pixmaps, basically
 | 
						|
         * because the Region data structure operates with signed shorts
 | 
						|
         * for the rectangles in it.
 | 
						|
         *
 | 
						|
         * Furthermore, several places in the X server computes the
 | 
						|
         * size in bytes of the pixmap and tries to store it in an
 | 
						|
         * integer. This integer can overflow and cause the allocated size
 | 
						|
         * to be much smaller.
 | 
						|
         *
 | 
						|
         * So, such big pixmaps are rejected here with a BadAlloc
 | 
						|
         */
 | 
						|
        return BadAlloc;
 | 
						|
    }
 | 
						|
    if (stuff->depth != 1) {
 | 
						|
        pDepth = pDraw->pScreen->allowedDepths;
 | 
						|
        for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
 | 
						|
            if (pDepth->depth == stuff->depth)
 | 
						|
                goto CreatePmap;
 | 
						|
        client->errorValue = stuff->depth;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 CreatePmap:
 | 
						|
    pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap)
 | 
						|
        (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0);
 | 
						|
    if (pMap) {
 | 
						|
        pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
 | 
						|
        pMap->drawable.id = stuff->pid;
 | 
						|
        /* security creation/labeling check */
 | 
						|
        rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
 | 
						|
                      pMap, RT_NONE, NULL, DixCreateAccess);
 | 
						|
        if (rc != Success) {
 | 
						|
            (*pDraw->pScreen->DestroyPixmap) (pMap);
 | 
						|
            return rc;
 | 
						|
        }
 | 
						|
        if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap))
 | 
						|
            return Success;
 | 
						|
    }
 | 
						|
    return BadAlloc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcFreePixmap(ClientPtr client)
 | 
						|
{
 | 
						|
    PixmapPtr pMap;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP,
 | 
						|
                                 client, DixDestroyAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        FreeResource(stuff->id, RT_NONE);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->id;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCreateGC(ClientPtr client)
 | 
						|
{
 | 
						|
    int error, rc;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    unsigned len;
 | 
						|
 | 
						|
    REQUEST(xCreateGCReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
 | 
						|
    client->errorValue = stuff->gc;
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->gc, client);
 | 
						|
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
 | 
						|
                           DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
 | 
						|
    if (len != Ones(stuff->mask))
 | 
						|
        return BadLength;
 | 
						|
    pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
 | 
						|
                          stuff->gc, client);
 | 
						|
    if (error != Success)
 | 
						|
        return error;
 | 
						|
    if (!AddResource(stuff->gc, RT_GC, (void *) pGC))
 | 
						|
        return BadAlloc;
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcChangeGC(ClientPtr client)
 | 
						|
{
 | 
						|
    GC *pGC;
 | 
						|
    int result;
 | 
						|
    unsigned len;
 | 
						|
 | 
						|
    REQUEST(xChangeGCReq);
 | 
						|
    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
 | 
						|
 | 
						|
    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
 | 
						|
    len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
 | 
						|
    if (len != Ones(stuff->mask))
 | 
						|
        return BadLength;
 | 
						|
 | 
						|
    return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCopyGC(ClientPtr client)
 | 
						|
{
 | 
						|
    GC *dstGC;
 | 
						|
    GC *pGC;
 | 
						|
    int result;
 | 
						|
 | 
						|
    REQUEST(xCopyGCReq);
 | 
						|
    REQUEST_SIZE_MATCH(xCopyGCReq);
 | 
						|
 | 
						|
    result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
    result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
 | 
						|
        return BadMatch;
 | 
						|
    if (stuff->mask & ~GCAllBits) {
 | 
						|
        client->errorValue = stuff->mask;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    return CopyGC(pGC, dstGC, stuff->mask);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcSetDashes(ClientPtr client)
 | 
						|
{
 | 
						|
    GC *pGC;
 | 
						|
    int result;
 | 
						|
 | 
						|
    REQUEST(xSetDashesReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
 | 
						|
    if (stuff->nDashes == 0) {
 | 
						|
        client->errorValue = 0;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
 | 
						|
    /* If there's an error, either there's no sensible errorValue,
 | 
						|
     * or there was a dash segment of 0. */
 | 
						|
    client->errorValue = 0;
 | 
						|
    return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
 | 
						|
                     (unsigned char *) &stuff[1]);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcSetClipRectangles(ClientPtr client)
 | 
						|
{
 | 
						|
    int nr, result;
 | 
						|
    GC *pGC;
 | 
						|
 | 
						|
    REQUEST(xSetClipRectanglesReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
 | 
						|
    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
 | 
						|
        (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) {
 | 
						|
        client->errorValue = stuff->ordering;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
 | 
						|
    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
 | 
						|
    if (nr & 4)
 | 
						|
        return BadLength;
 | 
						|
    nr >>= 3;
 | 
						|
    return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
 | 
						|
                        nr, (xRectangle *) &stuff[1], (int) stuff->ordering);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcFreeGC(ClientPtr client)
 | 
						|
{
 | 
						|
    GC *pGC;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    FreeResource(stuff->id, RT_NONE);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcClearToBackground(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xClearAreaReq);
 | 
						|
    WindowPtr pWin;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xClearAreaReq);
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    if (pWin->drawable.class == InputOnly) {
 | 
						|
        client->errorValue = stuff->window;
 | 
						|
        return BadMatch;
 | 
						|
    }
 | 
						|
    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) {
 | 
						|
        client->errorValue = stuff->exposures;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y,
 | 
						|
                                                  stuff->width, stuff->height,
 | 
						|
                                                  (Bool) stuff->exposures);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCopyArea(ClientPtr client)
 | 
						|
{
 | 
						|
    DrawablePtr pDst;
 | 
						|
    DrawablePtr pSrc;
 | 
						|
    GC *pGC;
 | 
						|
 | 
						|
    REQUEST(xCopyAreaReq);
 | 
						|
    RegionPtr pRgn;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCopyAreaReq);
 | 
						|
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
 | 
						|
    if (stuff->dstDrawable != stuff->srcDrawable) {
 | 
						|
        rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
 | 
						|
                               DixReadAccess);
 | 
						|
        if (rc != Success)
 | 
						|
            return rc;
 | 
						|
        if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) {
 | 
						|
            client->errorValue = stuff->dstDrawable;
 | 
						|
            return BadMatch;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
        pSrc = pDst;
 | 
						|
 | 
						|
    pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
 | 
						|
                                  stuff->width, stuff->height,
 | 
						|
                                  stuff->dstX, stuff->dstY);
 | 
						|
    if (pGC->graphicsExposures) {
 | 
						|
        (*pDst->pScreen->SendGraphicsExpose)
 | 
						|
            (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
 | 
						|
        if (pRgn)
 | 
						|
            RegionDestroy(pRgn);
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCopyPlane(ClientPtr client)
 | 
						|
{
 | 
						|
    DrawablePtr psrcDraw, pdstDraw;
 | 
						|
    GC *pGC;
 | 
						|
 | 
						|
    REQUEST(xCopyPlaneReq);
 | 
						|
    RegionPtr pRgn;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCopyPlaneReq);
 | 
						|
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
 | 
						|
    if (stuff->dstDrawable != stuff->srcDrawable) {
 | 
						|
        rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
 | 
						|
                               DixReadAccess);
 | 
						|
        if (rc != Success)
 | 
						|
            return rc;
 | 
						|
 | 
						|
        if (pdstDraw->pScreen != psrcDraw->pScreen) {
 | 
						|
            client->errorValue = stuff->dstDrawable;
 | 
						|
            return BadMatch;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
        psrcDraw = pdstDraw;
 | 
						|
 | 
						|
    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
 | 
						|
    if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
 | 
						|
        (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
 | 
						|
        client->errorValue = stuff->bitPlane;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    pRgn =
 | 
						|
        (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX,
 | 
						|
                                stuff->srcY, stuff->width, stuff->height,
 | 
						|
                                stuff->dstX, stuff->dstY, stuff->bitPlane);
 | 
						|
    if (pGC->graphicsExposures) {
 | 
						|
        (*pdstDraw->pScreen->SendGraphicsExpose)
 | 
						|
            (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
 | 
						|
        if (pRgn)
 | 
						|
            RegionDestroy(pRgn);
 | 
						|
    }
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyPoint(ClientPtr client)
 | 
						|
{
 | 
						|
    int npoint;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolyPointReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
 | 
						|
    if ((stuff->coordMode != CoordModeOrigin) &&
 | 
						|
        (stuff->coordMode != CoordModePrevious)) {
 | 
						|
        client->errorValue = stuff->coordMode;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
 | 
						|
    if (npoint)
 | 
						|
        (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint,
 | 
						|
                                (xPoint *) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyLine(ClientPtr client)
 | 
						|
{
 | 
						|
    int npoint;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolyLineReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
 | 
						|
    if ((stuff->coordMode != CoordModeOrigin) &&
 | 
						|
        (stuff->coordMode != CoordModePrevious)) {
 | 
						|
        client->errorValue = stuff->coordMode;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
 | 
						|
    if (npoint > 1)
 | 
						|
        (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint,
 | 
						|
                                (DDXPointPtr) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolySegment(ClientPtr client)
 | 
						|
{
 | 
						|
    int nsegs;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolySegmentReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
 | 
						|
    if (nsegs & 4)
 | 
						|
        return BadLength;
 | 
						|
    nsegs >>= 3;
 | 
						|
    if (nsegs)
 | 
						|
        (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyRectangle(ClientPtr client)
 | 
						|
{
 | 
						|
    int nrects;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolyRectangleReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
 | 
						|
    if (nrects & 4)
 | 
						|
        return BadLength;
 | 
						|
    nrects >>= 3;
 | 
						|
    if (nrects)
 | 
						|
        (*pGC->ops->PolyRectangle) (pDraw, pGC,
 | 
						|
                                    nrects, (xRectangle *) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyArc(ClientPtr client)
 | 
						|
{
 | 
						|
    int narcs;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolyArcReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
 | 
						|
    if (narcs % sizeof(xArc))
 | 
						|
        return BadLength;
 | 
						|
    narcs /= sizeof(xArc);
 | 
						|
    if (narcs)
 | 
						|
        (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcFillPoly(ClientPtr client)
 | 
						|
{
 | 
						|
    int things;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xFillPolyReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
 | 
						|
    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
 | 
						|
        (stuff->shape != Convex)) {
 | 
						|
        client->errorValue = stuff->shape;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    if ((stuff->coordMode != CoordModeOrigin) &&
 | 
						|
        (stuff->coordMode != CoordModePrevious)) {
 | 
						|
        client->errorValue = stuff->coordMode;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
 | 
						|
    if (things)
 | 
						|
        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
 | 
						|
                                  stuff->coordMode, things,
 | 
						|
                                  (DDXPointPtr) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyFillRectangle(ClientPtr client)
 | 
						|
{
 | 
						|
    int things;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolyFillRectangleReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
 | 
						|
    if (things & 4)
 | 
						|
        return BadLength;
 | 
						|
    things >>= 3;
 | 
						|
 | 
						|
    if (things)
 | 
						|
        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
 | 
						|
                                   (xRectangle *) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyFillArc(ClientPtr client)
 | 
						|
{
 | 
						|
    int narcs;
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
 | 
						|
    REQUEST(xPolyFillArcReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
 | 
						|
    if (narcs % sizeof(xArc))
 | 
						|
        return BadLength;
 | 
						|
    narcs /= sizeof(xArc);
 | 
						|
    if (narcs)
 | 
						|
        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef MATCH_CLIENT_ENDIAN
 | 
						|
 | 
						|
int
 | 
						|
ServerOrder(void)
 | 
						|
{
 | 
						|
    int whichbyte = 1;
 | 
						|
 | 
						|
    if (*((char *) &whichbyte))
 | 
						|
        return LSBFirst;
 | 
						|
    return MSBFirst;
 | 
						|
}
 | 
						|
 | 
						|
#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
 | 
						|
 | 
						|
void
 | 
						|
ReformatImage(char *base, int nbytes, int bpp, int order)
 | 
						|
{
 | 
						|
    switch (bpp) {
 | 
						|
    case 1:                    /* yuck */
 | 
						|
        if (BITMAP_BIT_ORDER != order)
 | 
						|
            BitOrderInvert((unsigned char *) base, nbytes);
 | 
						|
#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
 | 
						|
        ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order);
 | 
						|
#endif
 | 
						|
        break;
 | 
						|
    case 4:
 | 
						|
        break;                  /* yuck */
 | 
						|
    case 8:
 | 
						|
        break;
 | 
						|
    case 16:
 | 
						|
        if (IMAGE_BYTE_ORDER != order)
 | 
						|
            TwoByteSwap((unsigned char *) base, nbytes);
 | 
						|
        break;
 | 
						|
    case 32:
 | 
						|
        if (IMAGE_BYTE_ORDER != order)
 | 
						|
            FourByteSwap((unsigned char *) base, nbytes);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
#else
 | 
						|
#define ReformatImage(b,n,bpp,o)
 | 
						|
#endif
 | 
						|
 | 
						|
/* 64-bit server notes: the protocol restricts padding of images to
 | 
						|
 * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
 | 
						|
 * to use internally. Removes need for internal alignment checking.
 | 
						|
 * All of the PutImage functions could be changed individually, but
 | 
						|
 * as currently written, they call other routines which require things
 | 
						|
 * to be 64-bit padded on scanlines, so we changed things here.
 | 
						|
 * If an image would be padded differently for 64- versus 32-, then
 | 
						|
 * copy each scanline to a 64-bit padded scanline.
 | 
						|
 * Also, we need to make sure that the image is aligned on a 64-bit
 | 
						|
 * boundary, even if the scanlines are padded to our satisfaction.
 | 
						|
 */
 | 
						|
int
 | 
						|
ProcPutImage(ClientPtr client)
 | 
						|
{
 | 
						|
    GC *pGC;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    long length;                /* length of scanline server padded */
 | 
						|
    long lengthProto;           /* length of scanline protocol padded */
 | 
						|
    char *tmpImage;
 | 
						|
 | 
						|
    REQUEST(xPutImageReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPutImageReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
    if (stuff->format == XYBitmap) {
 | 
						|
        if ((stuff->depth != 1) ||
 | 
						|
            (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
 | 
						|
            return BadMatch;
 | 
						|
        length = BitmapBytePad(stuff->width + stuff->leftPad);
 | 
						|
    }
 | 
						|
    else if (stuff->format == XYPixmap) {
 | 
						|
        if ((pDraw->depth != stuff->depth) ||
 | 
						|
            (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
 | 
						|
            return BadMatch;
 | 
						|
        length = BitmapBytePad(stuff->width + stuff->leftPad);
 | 
						|
        length *= stuff->depth;
 | 
						|
    }
 | 
						|
    else if (stuff->format == ZPixmap) {
 | 
						|
        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
 | 
						|
            return BadMatch;
 | 
						|
        length = PixmapBytePad(stuff->width, stuff->depth);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->format;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    tmpImage = (char *) &stuff[1];
 | 
						|
    lengthProto = length;
 | 
						|
 | 
						|
    if ((bytes_to_int32(lengthProto * stuff->height) +
 | 
						|
         bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
 | 
						|
        return BadLength;
 | 
						|
 | 
						|
    ReformatImage(tmpImage, lengthProto * stuff->height,
 | 
						|
                  stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1,
 | 
						|
                  ClientOrder(client));
 | 
						|
 | 
						|
    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
 | 
						|
                           stuff->width, stuff->height,
 | 
						|
                           stuff->leftPad, stuff->format, tmpImage);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
DoGetImage(ClientPtr client, int format, Drawable drawable,
 | 
						|
           int x, int y, int width, int height,
 | 
						|
           Mask planemask)
 | 
						|
{
 | 
						|
    DrawablePtr pDraw, pBoundingDraw;
 | 
						|
    int nlines, linesPerBuf, rc;
 | 
						|
    int linesDone;
 | 
						|
 | 
						|
    /* coordinates relative to the bounding drawable */
 | 
						|
    int relx, rely;
 | 
						|
    long widthBytesLine, length;
 | 
						|
    Mask plane = 0;
 | 
						|
    char *pBuf;
 | 
						|
    xGetImageReply xgi;
 | 
						|
    RegionPtr pVisibleRegion = NULL;
 | 
						|
 | 
						|
    if ((format != XYPixmap) && (format != ZPixmap)) {
 | 
						|
        client->errorValue = format;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    memset(&xgi, 0, sizeof(xGetImageReply));
 | 
						|
 | 
						|
    relx = x;
 | 
						|
    rely = y;
 | 
						|
 | 
						|
    if (pDraw->type == DRAWABLE_WINDOW) {
 | 
						|
        WindowPtr pWin = (WindowPtr) pDraw;
 | 
						|
 | 
						|
        /* "If the drawable is a window, the window must be viewable ... or a
 | 
						|
         * BadMatch error results" */
 | 
						|
        if (!pWin->viewable)
 | 
						|
            return BadMatch;
 | 
						|
 | 
						|
        /* If the drawable is a window, the rectangle must be contained within
 | 
						|
         * its bounds (including the border). */
 | 
						|
        if (x < -wBorderWidth(pWin) ||
 | 
						|
            x + width > wBorderWidth(pWin) + (int) pDraw->width ||
 | 
						|
            y < -wBorderWidth(pWin) ||
 | 
						|
            y + height > wBorderWidth(pWin) + (int) pDraw->height)
 | 
						|
            return BadMatch;
 | 
						|
 | 
						|
        relx += pDraw->x;
 | 
						|
        rely += pDraw->y;
 | 
						|
 | 
						|
        if (pDraw->pScreen->GetWindowPixmap) {
 | 
						|
            PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
 | 
						|
 | 
						|
            pBoundingDraw = &pPix->drawable;
 | 
						|
#ifdef COMPOSITE
 | 
						|
            relx -= pPix->screen_x;
 | 
						|
            rely -= pPix->screen_y;
 | 
						|
#endif
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            pBoundingDraw = (DrawablePtr) pDraw->pScreen->root;
 | 
						|
        }
 | 
						|
 | 
						|
        xgi.visual = wVisual(pWin);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        pBoundingDraw = pDraw;
 | 
						|
        xgi.visual = None;
 | 
						|
    }
 | 
						|
 | 
						|
    /* "If the drawable is a pixmap, the given rectangle must be wholly
 | 
						|
     *  contained within the pixmap, or a BadMatch error results.  If the
 | 
						|
     *  drawable is a window [...] it must be the case that if there were no
 | 
						|
     *  inferiors or overlapping windows, the specified rectangle of the window
 | 
						|
     *  would be fully visible on the screen and wholly contained within the
 | 
						|
     *  outside edges of the window, or a BadMatch error results."
 | 
						|
     *
 | 
						|
     * We relax the window case slightly to mean that the rectangle must exist
 | 
						|
     * within the bounds of the window's backing pixmap.  In particular, this
 | 
						|
     * means that a GetImage request may succeed or fail with BadMatch depending
 | 
						|
     * on whether any of its ancestor windows are redirected.  */
 | 
						|
    if (relx < 0 || relx + width > (int) pBoundingDraw->width ||
 | 
						|
        rely < 0 || rely + height > (int) pBoundingDraw->height)
 | 
						|
        return BadMatch;
 | 
						|
 | 
						|
    xgi.type = X_Reply;
 | 
						|
    xgi.sequenceNumber = client->sequence;
 | 
						|
    xgi.depth = pDraw->depth;
 | 
						|
    if (format == ZPixmap) {
 | 
						|
        widthBytesLine = PixmapBytePad(width, pDraw->depth);
 | 
						|
        length = widthBytesLine * height;
 | 
						|
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        widthBytesLine = BitmapBytePad(width);
 | 
						|
        plane = ((Mask) 1) << (pDraw->depth - 1);
 | 
						|
        /* only planes asked for */
 | 
						|
        length = widthBytesLine * height *
 | 
						|
            Ones(planemask & (plane | (plane - 1)));
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    xgi.length = length;
 | 
						|
 | 
						|
    xgi.length = bytes_to_int32(xgi.length);
 | 
						|
    if (widthBytesLine == 0 || height == 0)
 | 
						|
        linesPerBuf = 0;
 | 
						|
    else if (widthBytesLine >= IMAGE_BUFSIZE)
 | 
						|
        linesPerBuf = 1;
 | 
						|
    else {
 | 
						|
        linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
 | 
						|
        if (linesPerBuf > height)
 | 
						|
            linesPerBuf = height;
 | 
						|
    }
 | 
						|
    length = linesPerBuf * widthBytesLine;
 | 
						|
    if (linesPerBuf < height) {
 | 
						|
        /* we have to make sure intermediate buffers don't need padding */
 | 
						|
        while ((linesPerBuf > 1) &&
 | 
						|
               (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) {
 | 
						|
            linesPerBuf--;
 | 
						|
            length -= widthBytesLine;
 | 
						|
        }
 | 
						|
        while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) {
 | 
						|
            linesPerBuf++;
 | 
						|
            length += widthBytesLine;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (!(pBuf = calloc(1, length)))
 | 
						|
        return BadAlloc;
 | 
						|
    WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
 | 
						|
 | 
						|
    if (pDraw->type == DRAWABLE_WINDOW) {
 | 
						|
        pVisibleRegion = NotClippedByChildren((WindowPtr) pDraw);
 | 
						|
        if (pVisibleRegion) {
 | 
						|
            RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (linesPerBuf == 0) {
 | 
						|
        /* nothing to do */
 | 
						|
    }
 | 
						|
    else if (format == ZPixmap) {
 | 
						|
        linesDone = 0;
 | 
						|
        while (height - linesDone > 0) {
 | 
						|
            nlines = min(linesPerBuf, height - linesDone);
 | 
						|
            (*pDraw->pScreen->GetImage) (pDraw,
 | 
						|
                                         x,
 | 
						|
                                         y + linesDone,
 | 
						|
                                         width,
 | 
						|
                                         nlines,
 | 
						|
                                         format, planemask, (void *) pBuf);
 | 
						|
            if (pVisibleRegion)
 | 
						|
                XaceCensorImage(client, pVisibleRegion, widthBytesLine,
 | 
						|
                                pDraw, x, y + linesDone, width,
 | 
						|
                                nlines, format, pBuf);
 | 
						|
 | 
						|
            /* Note that this is NOT a call to WriteSwappedDataToClient,
 | 
						|
               as we do NOT byte swap */
 | 
						|
            ReformatImage(pBuf, (int) (nlines * widthBytesLine),
 | 
						|
                          BitsPerPixel(pDraw->depth), ClientOrder(client));
 | 
						|
 | 
						|
            WriteToClient(client, (int) (nlines * widthBytesLine), pBuf);
 | 
						|
            linesDone += nlines;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {                      /* XYPixmap */
 | 
						|
 | 
						|
        for (; plane; plane >>= 1) {
 | 
						|
            if (planemask & plane) {
 | 
						|
                linesDone = 0;
 | 
						|
                while (height - linesDone > 0) {
 | 
						|
                    nlines = min(linesPerBuf, height - linesDone);
 | 
						|
                    (*pDraw->pScreen->GetImage) (pDraw,
 | 
						|
                                                 x,
 | 
						|
                                                 y + linesDone,
 | 
						|
                                                 width,
 | 
						|
                                                 nlines,
 | 
						|
                                                 format, plane, (void *) pBuf);
 | 
						|
                    if (pVisibleRegion)
 | 
						|
                        XaceCensorImage(client, pVisibleRegion,
 | 
						|
                                        widthBytesLine,
 | 
						|
                                        pDraw, x, y + linesDone, width,
 | 
						|
                                        nlines, format, pBuf);
 | 
						|
 | 
						|
                    /* Note: NOT a call to WriteSwappedDataToClient,
 | 
						|
                       as we do NOT byte swap */
 | 
						|
                    ReformatImage(pBuf, (int) (nlines * widthBytesLine),
 | 
						|
                                  1, ClientOrder(client));
 | 
						|
 | 
						|
                    WriteToClient(client, (int)(nlines * widthBytesLine), pBuf);
 | 
						|
                    linesDone += nlines;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (pVisibleRegion)
 | 
						|
        RegionDestroy(pVisibleRegion);
 | 
						|
    free(pBuf);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGetImage(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xGetImageReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xGetImageReq);
 | 
						|
 | 
						|
    return DoGetImage(client, stuff->format, stuff->drawable,
 | 
						|
                      stuff->x, stuff->y,
 | 
						|
                      (int) stuff->width, (int) stuff->height,
 | 
						|
                      stuff->planeMask);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcPolyText(ClientPtr client)
 | 
						|
{
 | 
						|
    int err;
 | 
						|
 | 
						|
    REQUEST(xPolyTextReq);
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    GC *pGC;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
 | 
						|
    err = PolyText(client,
 | 
						|
                   pDraw,
 | 
						|
                   pGC,
 | 
						|
                   (unsigned char *) &stuff[1],
 | 
						|
                   ((unsigned char *) stuff) + (client->req_len << 2),
 | 
						|
                   stuff->x, stuff->y, stuff->reqType, stuff->drawable);
 | 
						|
 | 
						|
    if (err == Success) {
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return err;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcImageText8(ClientPtr client)
 | 
						|
{
 | 
						|
    int err;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    GC *pGC;
 | 
						|
 | 
						|
    REQUEST(xImageTextReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
 | 
						|
    err = ImageText(client,
 | 
						|
                    pDraw,
 | 
						|
                    pGC,
 | 
						|
                    stuff->nChars,
 | 
						|
                    (unsigned char *) &stuff[1],
 | 
						|
                    stuff->x, stuff->y, stuff->reqType, stuff->drawable);
 | 
						|
 | 
						|
    if (err == Success) {
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return err;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcImageText16(ClientPtr client)
 | 
						|
{
 | 
						|
    int err;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    GC *pGC;
 | 
						|
 | 
						|
    REQUEST(xImageTextReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
 | 
						|
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
 | 
						|
 | 
						|
    err = ImageText(client,
 | 
						|
                    pDraw,
 | 
						|
                    pGC,
 | 
						|
                    stuff->nChars,
 | 
						|
                    (unsigned char *) &stuff[1],
 | 
						|
                    stuff->x, stuff->y, stuff->reqType, stuff->drawable);
 | 
						|
 | 
						|
    if (err == Success) {
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return err;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCreateColormap(ClientPtr client)
 | 
						|
{
 | 
						|
    VisualPtr pVisual;
 | 
						|
    ColormapPtr pmap;
 | 
						|
    Colormap mid;
 | 
						|
    WindowPtr pWin;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
 | 
						|
    REQUEST(xCreateColormapReq);
 | 
						|
    int i, result;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCreateColormapReq);
 | 
						|
 | 
						|
    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) {
 | 
						|
        client->errorValue = stuff->alloc;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    mid = stuff->mid;
 | 
						|
    LEGAL_NEW_RESOURCE(mid, client);
 | 
						|
    result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
 | 
						|
    pScreen = pWin->drawable.pScreen;
 | 
						|
    for (i = 0, pVisual = pScreen->visuals;
 | 
						|
         i < pScreen->numVisuals; i++, pVisual++) {
 | 
						|
        if (pVisual->vid != stuff->visual)
 | 
						|
            continue;
 | 
						|
        return CreateColormap(mid, pScreen, pVisual, &pmap,
 | 
						|
                              (int) stuff->alloc, client->index);
 | 
						|
    }
 | 
						|
    client->errorValue = stuff->visual;
 | 
						|
    return BadMatch;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcFreeColormap(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pmap;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP,
 | 
						|
                                 client, DixDestroyAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        /* Freeing a default colormap is a no-op */
 | 
						|
        if (!(pmap->flags & IsDefault))
 | 
						|
            FreeResource(stuff->id, RT_NONE);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->id;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCopyColormapAndFree(ClientPtr client)
 | 
						|
{
 | 
						|
    Colormap mid;
 | 
						|
    ColormapPtr pSrcMap;
 | 
						|
 | 
						|
    REQUEST(xCopyColormapAndFreeReq);
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
 | 
						|
    mid = stuff->mid;
 | 
						|
    LEGAL_NEW_RESOURCE(mid, client);
 | 
						|
    rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap,
 | 
						|
                                 RT_COLORMAP, client,
 | 
						|
                                 DixReadAccess | DixRemoveAccess);
 | 
						|
    if (rc == Success)
 | 
						|
        return CopyColormapAndFree(mid, pSrcMap, client->index);
 | 
						|
    client->errorValue = stuff->srcCmap;
 | 
						|
    return rc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcInstallColormap(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
 | 
						|
                                 client, DixInstallAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        goto out;
 | 
						|
 | 
						|
    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        if (rc == BadValue)
 | 
						|
            rc = BadColor;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    (*(pcmp->pScreen->InstallColormap)) (pcmp);
 | 
						|
    return Success;
 | 
						|
 | 
						|
 out:
 | 
						|
    client->errorValue = stuff->id;
 | 
						|
    return rc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcUninstallColormap(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
 | 
						|
                                 client, DixUninstallAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        goto out;
 | 
						|
 | 
						|
    rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        if (rc == BadValue)
 | 
						|
            rc = BadColor;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pcmp->mid != pcmp->pScreen->defColormap)
 | 
						|
        (*(pcmp->pScreen->UninstallColormap)) (pcmp);
 | 
						|
    return Success;
 | 
						|
 | 
						|
 out:
 | 
						|
    client->errorValue = stuff->id;
 | 
						|
    return rc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcListInstalledColormaps(ClientPtr client)
 | 
						|
{
 | 
						|
    xListInstalledColormapsReply *preply;
 | 
						|
    int nummaps, rc;
 | 
						|
    WindowPtr pWin;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
 | 
						|
    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
 | 
						|
                  DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    preply = malloc(sizeof(xListInstalledColormapsReply) +
 | 
						|
                    pWin->drawable.pScreen->maxInstalledCmaps *
 | 
						|
                    sizeof(Colormap));
 | 
						|
    if (!preply)
 | 
						|
        return BadAlloc;
 | 
						|
 | 
						|
    preply->type = X_Reply;
 | 
						|
    preply->sequenceNumber = client->sequence;
 | 
						|
    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
 | 
						|
        (pWin->drawable.pScreen, (Colormap *) &preply[1]);
 | 
						|
    preply->nColormaps = nummaps;
 | 
						|
    preply->length = nummaps;
 | 
						|
    WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply);
 | 
						|
    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 | 
						|
    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
 | 
						|
    free(preply);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcAllocColor(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pmap;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xAllocColorReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xAllocColorReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixAddAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        xAllocColorReply acr = {
 | 
						|
            .type = X_Reply,
 | 
						|
            .sequenceNumber = client->sequence,
 | 
						|
            .length = 0,
 | 
						|
            .red = stuff->red,
 | 
						|
            .green = stuff->green,
 | 
						|
            .blue = stuff->blue,
 | 
						|
            .pixel = 0
 | 
						|
        };
 | 
						|
        if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
 | 
						|
                             &acr.pixel, client->index)))
 | 
						|
            return rc;
 | 
						|
#ifdef PANORAMIX
 | 
						|
        if (noPanoramiXExtension || !pmap->pScreen->myNum)
 | 
						|
#endif
 | 
						|
            WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
 | 
						|
        return Success;
 | 
						|
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcAllocNamedColor(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xAllocNamedColorReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixAddAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        xAllocNamedColorReply ancr = {
 | 
						|
            .type = X_Reply,
 | 
						|
            .sequenceNumber = client->sequence,
 | 
						|
            .length = 0
 | 
						|
        };
 | 
						|
        if (OsLookupColor
 | 
						|
            (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
 | 
						|
             &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) {
 | 
						|
            ancr.screenRed = ancr.exactRed;
 | 
						|
            ancr.screenGreen = ancr.exactGreen;
 | 
						|
            ancr.screenBlue = ancr.exactBlue;
 | 
						|
            ancr.pixel = 0;
 | 
						|
            if ((rc = AllocColor(pcmp,
 | 
						|
                                 &ancr.screenRed, &ancr.screenGreen,
 | 
						|
                                 &ancr.screenBlue, &ancr.pixel, client->index)))
 | 
						|
                return rc;
 | 
						|
#ifdef PANORAMIX
 | 
						|
            if (noPanoramiXExtension || !pcmp->pScreen->myNum)
 | 
						|
#endif
 | 
						|
                WriteReplyToClient(client, sizeof(xAllocNamedColorReply),
 | 
						|
                                   &ancr);
 | 
						|
            return Success;
 | 
						|
        }
 | 
						|
        else
 | 
						|
            return BadName;
 | 
						|
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcAllocColorCells(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xAllocColorCellsReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixAddAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        int npixels, nmasks;
 | 
						|
        long length;
 | 
						|
        Pixel *ppixels, *pmasks;
 | 
						|
 | 
						|
        npixels = stuff->colors;
 | 
						|
        if (!npixels) {
 | 
						|
            client->errorValue = npixels;
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
        if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
 | 
						|
            client->errorValue = stuff->contiguous;
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
        nmasks = stuff->planes;
 | 
						|
        length = ((long) npixels + (long) nmasks) * sizeof(Pixel);
 | 
						|
        ppixels = malloc(length);
 | 
						|
        if (!ppixels)
 | 
						|
            return BadAlloc;
 | 
						|
        pmasks = ppixels + npixels;
 | 
						|
 | 
						|
        if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
 | 
						|
                                  (Bool) stuff->contiguous, ppixels, pmasks))) {
 | 
						|
            free(ppixels);
 | 
						|
            return rc;
 | 
						|
        }
 | 
						|
#ifdef PANORAMIX
 | 
						|
        if (noPanoramiXExtension || !pcmp->pScreen->myNum)
 | 
						|
#endif
 | 
						|
        {
 | 
						|
            xAllocColorCellsReply accr = {
 | 
						|
                .type = X_Reply,
 | 
						|
                .sequenceNumber = client->sequence,
 | 
						|
                .length = bytes_to_int32(length),
 | 
						|
                .nPixels = npixels,
 | 
						|
                .nMasks = nmasks
 | 
						|
            };
 | 
						|
            WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr);
 | 
						|
            client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 | 
						|
            WriteSwappedDataToClient(client, length, ppixels);
 | 
						|
        }
 | 
						|
        free(ppixels);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcAllocColorPlanes(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xAllocColorPlanesReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixAddAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        xAllocColorPlanesReply acpr;
 | 
						|
        int npixels;
 | 
						|
        long length;
 | 
						|
        Pixel *ppixels;
 | 
						|
 | 
						|
        npixels = stuff->colors;
 | 
						|
        if (!npixels) {
 | 
						|
            client->errorValue = npixels;
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
        if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
 | 
						|
            client->errorValue = stuff->contiguous;
 | 
						|
            return BadValue;
 | 
						|
        }
 | 
						|
        acpr = (xAllocColorPlanesReply) {
 | 
						|
            .type = X_Reply,
 | 
						|
            .sequenceNumber = client->sequence,
 | 
						|
            .nPixels = npixels
 | 
						|
        };
 | 
						|
        length = (long) npixels *sizeof(Pixel);
 | 
						|
 | 
						|
        ppixels = malloc(length);
 | 
						|
        if (!ppixels)
 | 
						|
            return BadAlloc;
 | 
						|
        if ((rc = AllocColorPlanes(client->index, pcmp, npixels,
 | 
						|
                                   (int) stuff->red, (int) stuff->green,
 | 
						|
                                   (int) stuff->blue, (Bool) stuff->contiguous,
 | 
						|
                                   ppixels, &acpr.redMask, &acpr.greenMask,
 | 
						|
                                   &acpr.blueMask))) {
 | 
						|
            free(ppixels);
 | 
						|
            return rc;
 | 
						|
        }
 | 
						|
        acpr.length = bytes_to_int32(length);
 | 
						|
#ifdef PANORAMIX
 | 
						|
        if (noPanoramiXExtension || !pcmp->pScreen->myNum)
 | 
						|
#endif
 | 
						|
        {
 | 
						|
            WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
 | 
						|
            client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
 | 
						|
            WriteSwappedDataToClient(client, length, ppixels);
 | 
						|
        }
 | 
						|
        free(ppixels);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcFreeColors(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xFreeColorsReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixRemoveAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        int count;
 | 
						|
 | 
						|
        if (pcmp->flags & AllAllocated)
 | 
						|
            return BadAccess;
 | 
						|
        count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
 | 
						|
        return FreeColors(pcmp, client->index, count,
 | 
						|
                          (Pixel *) &stuff[1], (Pixel) stuff->planeMask);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcStoreColors(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xStoreColorsReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixWriteAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        int count;
 | 
						|
 | 
						|
        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
 | 
						|
        if (count % sizeof(xColorItem))
 | 
						|
            return BadLength;
 | 
						|
        count /= sizeof(xColorItem);
 | 
						|
        return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcStoreNamedColor(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xStoreNamedColorReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixWriteAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        xColorItem def;
 | 
						|
 | 
						|
        if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1],
 | 
						|
                          stuff->nbytes, &def.red, &def.green, &def.blue)) {
 | 
						|
            def.flags = stuff->flags;
 | 
						|
            def.pixel = stuff->pixel;
 | 
						|
            return StoreColors(pcmp, 1, &def, client);
 | 
						|
        }
 | 
						|
        return BadName;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcQueryColors(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xQueryColorsReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixReadAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        int count;
 | 
						|
        xrgb *prgbs;
 | 
						|
        xQueryColorsReply qcr;
 | 
						|
 | 
						|
        count =
 | 
						|
            bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
 | 
						|
        prgbs = calloc(1, count * sizeof(xrgb));
 | 
						|
        if (!prgbs && count)
 | 
						|
            return BadAlloc;
 | 
						|
        if ((rc =
 | 
						|
             QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) {
 | 
						|
            free(prgbs);
 | 
						|
            return rc;
 | 
						|
        }
 | 
						|
        qcr = (xQueryColorsReply) {
 | 
						|
            .type = X_Reply,
 | 
						|
            .sequenceNumber = client->sequence,
 | 
						|
            .length = bytes_to_int32(count * sizeof(xrgb)),
 | 
						|
            .nColors = count
 | 
						|
        };
 | 
						|
        WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
 | 
						|
        if (count) {
 | 
						|
            client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
 | 
						|
            WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
 | 
						|
        }
 | 
						|
        free(prgbs);
 | 
						|
        return Success;
 | 
						|
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLookupColor(ClientPtr client)
 | 
						|
{
 | 
						|
    ColormapPtr pcmp;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xLookupColorReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
 | 
						|
    rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
 | 
						|
                                 client, DixReadAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        CARD16 exactRed, exactGreen, exactBlue;
 | 
						|
 | 
						|
        if (OsLookupColor
 | 
						|
            (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
 | 
						|
             &exactRed, &exactGreen, &exactBlue)) {
 | 
						|
            xLookupColorReply lcr = {
 | 
						|
                .type = X_Reply,
 | 
						|
                .sequenceNumber = client->sequence,
 | 
						|
                .length = 0,
 | 
						|
                .exactRed = exactRed,
 | 
						|
                .exactGreen = exactGreen,
 | 
						|
                .exactBlue = exactBlue,
 | 
						|
                .screenRed = exactRed,
 | 
						|
                .screenGreen = exactGreen,
 | 
						|
                .screenBlue = exactBlue
 | 
						|
            };
 | 
						|
            (*pcmp->pScreen->ResolveColor) (&lcr.screenRed,
 | 
						|
                                            &lcr.screenGreen,
 | 
						|
                                            &lcr.screenBlue, pcmp->pVisual);
 | 
						|
            WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
 | 
						|
            return Success;
 | 
						|
        }
 | 
						|
        return BadName;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->cmap;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCreateCursor(ClientPtr client)
 | 
						|
{
 | 
						|
    CursorPtr pCursor;
 | 
						|
    PixmapPtr src;
 | 
						|
    PixmapPtr msk;
 | 
						|
    unsigned char *srcbits;
 | 
						|
    unsigned char *mskbits;
 | 
						|
    unsigned short width, height;
 | 
						|
    long n;
 | 
						|
    CursorMetricRec cm;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xCreateCursorReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCreateCursorReq);
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->cid, client);
 | 
						|
 | 
						|
    rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP,
 | 
						|
                                 client, DixReadAccess);
 | 
						|
    if (rc != Success) {
 | 
						|
        client->errorValue = stuff->source;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
 | 
						|
    if (src->drawable.depth != 1)
 | 
						|
        return (BadMatch);
 | 
						|
 | 
						|
    /* Find and validate cursor mask pixmap, if one is provided */
 | 
						|
    if (stuff->mask != None) {
 | 
						|
        rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP,
 | 
						|
                                     client, DixReadAccess);
 | 
						|
        if (rc != Success) {
 | 
						|
            client->errorValue = stuff->mask;
 | 
						|
            return rc;
 | 
						|
        }
 | 
						|
 | 
						|
        if (src->drawable.width != msk->drawable.width
 | 
						|
            || src->drawable.height != msk->drawable.height
 | 
						|
            || src->drawable.depth != 1 || msk->drawable.depth != 1)
 | 
						|
            return BadMatch;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        msk = NULL;
 | 
						|
 | 
						|
    width = src->drawable.width;
 | 
						|
    height = src->drawable.height;
 | 
						|
 | 
						|
    if (stuff->x > width || stuff->y > height)
 | 
						|
        return BadMatch;
 | 
						|
 | 
						|
    n = BitmapBytePad(width) * height;
 | 
						|
    srcbits = calloc(1, n);
 | 
						|
    if (!srcbits)
 | 
						|
        return BadAlloc;
 | 
						|
    mskbits = malloc(n);
 | 
						|
    if (!mskbits) {
 | 
						|
        free(srcbits);
 | 
						|
        return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height,
 | 
						|
                                        XYPixmap, 1, (void *) srcbits);
 | 
						|
    if (msk == (PixmapPtr) NULL) {
 | 
						|
        unsigned char *bits = mskbits;
 | 
						|
 | 
						|
        while (--n >= 0)
 | 
						|
            *bits++ = ~0;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        /* zeroing the (pad) bits helps some ddx cursor handling */
 | 
						|
        memset((char *) mskbits, 0, n);
 | 
						|
        (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width,
 | 
						|
                                            height, XYPixmap, 1,
 | 
						|
                                            (void *) mskbits);
 | 
						|
    }
 | 
						|
    cm.width = width;
 | 
						|
    cm.height = height;
 | 
						|
    cm.xhot = stuff->x;
 | 
						|
    cm.yhot = stuff->y;
 | 
						|
    rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
 | 
						|
                         stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
 | 
						|
                         stuff->backRed, stuff->backGreen, stuff->backBlue,
 | 
						|
                         &pCursor, client, stuff->cid);
 | 
						|
 | 
						|
    if (rc != Success)
 | 
						|
        goto bail;
 | 
						|
    if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
 | 
						|
        rc = BadAlloc;
 | 
						|
        goto bail;
 | 
						|
    }
 | 
						|
 | 
						|
    return Success;
 | 
						|
 bail:
 | 
						|
    free(srcbits);
 | 
						|
    free(mskbits);
 | 
						|
    return rc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcCreateGlyphCursor(ClientPtr client)
 | 
						|
{
 | 
						|
    CursorPtr pCursor;
 | 
						|
    int res;
 | 
						|
 | 
						|
    REQUEST(xCreateGlyphCursorReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
 | 
						|
    LEGAL_NEW_RESOURCE(stuff->cid, client);
 | 
						|
 | 
						|
    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
 | 
						|
                           stuff->mask, stuff->maskChar,
 | 
						|
                           stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
 | 
						|
                           stuff->backRed, stuff->backGreen, stuff->backBlue,
 | 
						|
                           &pCursor, client, stuff->cid);
 | 
						|
    if (res != Success)
 | 
						|
        return res;
 | 
						|
    if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
 | 
						|
        return Success;
 | 
						|
    return BadAlloc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcFreeCursor(ClientPtr client)
 | 
						|
{
 | 
						|
    CursorPtr pCursor;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR,
 | 
						|
                                 client, DixDestroyAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        FreeResource(stuff->id, RT_NONE);
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->id;
 | 
						|
        return rc;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcQueryBestSize(ClientPtr client)
 | 
						|
{
 | 
						|
    xQueryBestSizeReply reply;
 | 
						|
    DrawablePtr pDraw;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xQueryBestSizeReq);
 | 
						|
    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
 | 
						|
 | 
						|
    if ((stuff->class != CursorShape) &&
 | 
						|
        (stuff->class != TileShape) && (stuff->class != StippleShape)) {
 | 
						|
        client->errorValue = stuff->class;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
 | 
						|
                           DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
 | 
						|
        return BadMatch;
 | 
						|
    pScreen = pDraw->pScreen;
 | 
						|
    rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    (*pScreen->QueryBestSize) (stuff->class, &stuff->width,
 | 
						|
                               &stuff->height, pScreen);
 | 
						|
    reply = (xQueryBestSizeReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
        .width = stuff->width,
 | 
						|
        .height = stuff->height
 | 
						|
    };
 | 
						|
    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcSetScreenSaver(ClientPtr client)
 | 
						|
{
 | 
						|
    int rc, i, blankingOption, exposureOption;
 | 
						|
 | 
						|
    REQUEST(xSetScreenSaverReq);
 | 
						|
    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
 | 
						|
 | 
						|
    for (i = 0; i < screenInfo.numScreens; i++) {
 | 
						|
        rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
 | 
						|
                      DixSetAttrAccess);
 | 
						|
        if (rc != Success)
 | 
						|
            return rc;
 | 
						|
    }
 | 
						|
 | 
						|
    blankingOption = stuff->preferBlank;
 | 
						|
    if ((blankingOption != DontPreferBlanking) &&
 | 
						|
        (blankingOption != PreferBlanking) &&
 | 
						|
        (blankingOption != DefaultBlanking)) {
 | 
						|
        client->errorValue = blankingOption;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    exposureOption = stuff->allowExpose;
 | 
						|
    if ((exposureOption != DontAllowExposures) &&
 | 
						|
        (exposureOption != AllowExposures) &&
 | 
						|
        (exposureOption != DefaultExposures)) {
 | 
						|
        client->errorValue = exposureOption;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    if (stuff->timeout < -1) {
 | 
						|
        client->errorValue = stuff->timeout;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    if (stuff->interval < -1) {
 | 
						|
        client->errorValue = stuff->interval;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (blankingOption == DefaultBlanking)
 | 
						|
        ScreenSaverBlanking = defaultScreenSaverBlanking;
 | 
						|
    else
 | 
						|
        ScreenSaverBlanking = blankingOption;
 | 
						|
    if (exposureOption == DefaultExposures)
 | 
						|
        ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
 | 
						|
    else
 | 
						|
        ScreenSaverAllowExposures = exposureOption;
 | 
						|
 | 
						|
    if (stuff->timeout >= 0)
 | 
						|
        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
 | 
						|
    else
 | 
						|
        ScreenSaverTime = defaultScreenSaverTime;
 | 
						|
    if (stuff->interval >= 0)
 | 
						|
        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
 | 
						|
    else
 | 
						|
        ScreenSaverInterval = defaultScreenSaverInterval;
 | 
						|
 | 
						|
    SetScreenSaverTimer();
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGetScreenSaver(ClientPtr client)
 | 
						|
{
 | 
						|
    xGetScreenSaverReply rep;
 | 
						|
    int rc, i;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xReq);
 | 
						|
 | 
						|
    for (i = 0; i < screenInfo.numScreens; i++) {
 | 
						|
        rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
 | 
						|
                      DixGetAttrAccess);
 | 
						|
        if (rc != Success)
 | 
						|
            return rc;
 | 
						|
    }
 | 
						|
 | 
						|
    rep = (xGetScreenSaverReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = 0,
 | 
						|
        .timeout = ScreenSaverTime / MILLI_PER_SECOND,
 | 
						|
        .interval = ScreenSaverInterval / MILLI_PER_SECOND,
 | 
						|
        .preferBlanking = ScreenSaverBlanking,
 | 
						|
        .allowExposures = ScreenSaverAllowExposures
 | 
						|
    };
 | 
						|
    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcChangeHosts(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xChangeHostsReq);
 | 
						|
 | 
						|
    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
 | 
						|
 | 
						|
    if (stuff->mode == HostInsert)
 | 
						|
        return AddHost(client, (int) stuff->hostFamily,
 | 
						|
                       stuff->hostLength, (void *) &stuff[1]);
 | 
						|
    if (stuff->mode == HostDelete)
 | 
						|
        return RemoveHost(client, (int) stuff->hostFamily,
 | 
						|
                          stuff->hostLength, (void *) &stuff[1]);
 | 
						|
    client->errorValue = stuff->mode;
 | 
						|
    return BadValue;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcListHosts(ClientPtr client)
 | 
						|
{
 | 
						|
    xListHostsReply reply;
 | 
						|
    int len, nHosts, result;
 | 
						|
    BOOL enabled;
 | 
						|
    void *pdata;
 | 
						|
 | 
						|
    /* REQUEST(xListHostsReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xListHostsReq);
 | 
						|
 | 
						|
    /* untrusted clients can't list hosts */
 | 
						|
    result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
 | 
						|
    result = GetHosts(&pdata, &nHosts, &len, &enabled);
 | 
						|
    if (result != Success)
 | 
						|
        return result;
 | 
						|
 | 
						|
    reply = (xListHostsReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .enabled = enabled,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = bytes_to_int32(len),
 | 
						|
        .nHosts = nHosts
 | 
						|
    };
 | 
						|
    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
 | 
						|
    if (nHosts) {
 | 
						|
        client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
 | 
						|
        WriteSwappedDataToClient(client, len, pdata);
 | 
						|
    }
 | 
						|
    free(pdata);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcChangeAccessControl(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xSetAccessControlReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xSetAccessControlReq);
 | 
						|
    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) {
 | 
						|
        client->errorValue = stuff->mode;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    return ChangeAccessControl(client, stuff->mode == EnableAccess);
 | 
						|
}
 | 
						|
 | 
						|
/*********************
 | 
						|
 * CloseDownRetainedResources
 | 
						|
 *
 | 
						|
 *    Find all clients that are gone and have terminated in RetainTemporary 
 | 
						|
 *    and destroy their resources.
 | 
						|
 *********************/
 | 
						|
 | 
						|
static void
 | 
						|
CloseDownRetainedResources(void)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    ClientPtr client;
 | 
						|
 | 
						|
    for (i = 1; i < currentMaxClients; i++) {
 | 
						|
        client = clients[i];
 | 
						|
        if (client && (client->closeDownMode == RetainTemporary)
 | 
						|
            && (client->clientGone))
 | 
						|
            CloseDownClient(client);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcKillClient(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xResourceReq);
 | 
						|
    ClientPtr killclient;
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xResourceReq);
 | 
						|
    if (stuff->id == AllTemporary) {
 | 
						|
        CloseDownRetainedResources();
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
 | 
						|
    rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
 | 
						|
    if (rc == Success) {
 | 
						|
        CloseDownClient(killclient);
 | 
						|
        if (client == killclient) {
 | 
						|
            /* force yield and return Success, so that Dispatch()
 | 
						|
             * doesn't try to touch client
 | 
						|
             */
 | 
						|
            isItTimeToYield = TRUE;
 | 
						|
        }
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else
 | 
						|
        return rc;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcSetFontPath(ClientPtr client)
 | 
						|
{
 | 
						|
    unsigned char *ptr;
 | 
						|
    unsigned long nbytes, total;
 | 
						|
    long nfonts;
 | 
						|
    int n;
 | 
						|
 | 
						|
    REQUEST(xSetFontPathReq);
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
 | 
						|
 | 
						|
    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
 | 
						|
    total = nbytes;
 | 
						|
    ptr = (unsigned char *) &stuff[1];
 | 
						|
    nfonts = stuff->nFonts;
 | 
						|
    while (--nfonts >= 0) {
 | 
						|
        if ((total == 0) || (total < (n = (*ptr + 1))))
 | 
						|
            return BadLength;
 | 
						|
        total -= n;
 | 
						|
        ptr += n;
 | 
						|
    }
 | 
						|
    if (total >= 4)
 | 
						|
        return BadLength;
 | 
						|
    return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcGetFontPath(ClientPtr client)
 | 
						|
{
 | 
						|
    xGetFontPathReply reply;
 | 
						|
    int rc, stringLens, numpaths;
 | 
						|
    unsigned char *bufferStart;
 | 
						|
 | 
						|
    /* REQUEST (xReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xReq);
 | 
						|
    rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    reply = (xGetFontPathReply) {
 | 
						|
        .type = X_Reply,
 | 
						|
        .sequenceNumber = client->sequence,
 | 
						|
        .length = bytes_to_int32(stringLens + numpaths),
 | 
						|
        .nPaths = numpaths
 | 
						|
    };
 | 
						|
 | 
						|
    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
 | 
						|
    if (stringLens || numpaths)
 | 
						|
        WriteToClient(client, stringLens + numpaths, bufferStart);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcChangeCloseDownMode(ClientPtr client)
 | 
						|
{
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xSetCloseDownModeReq);
 | 
						|
    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
 | 
						|
 | 
						|
    rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
 | 
						|
    if ((stuff->mode == AllTemporary) ||
 | 
						|
        (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) {
 | 
						|
        client->closeDownMode = stuff->mode;
 | 
						|
        return Success;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        client->errorValue = stuff->mode;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcForceScreenSaver(ClientPtr client)
 | 
						|
{
 | 
						|
    int rc;
 | 
						|
 | 
						|
    REQUEST(xForceScreenSaverReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
 | 
						|
 | 
						|
    if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) {
 | 
						|
        client->errorValue = stuff->mode;
 | 
						|
        return BadValue;
 | 
						|
    }
 | 
						|
    rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode);
 | 
						|
    if (rc != Success)
 | 
						|
        return rc;
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcNoOperation(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST_AT_LEAST_SIZE(xReq);
 | 
						|
 | 
						|
    /* noop -- don't do anything */
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
/**********************
 | 
						|
 * CloseDownClient
 | 
						|
 *
 | 
						|
 *  Client can either mark his resources destroy or retain.  If retained and
 | 
						|
 *  then killed again, the client is really destroyed.
 | 
						|
 *********************/
 | 
						|
 | 
						|
char dispatchExceptionAtReset = DE_RESET;
 | 
						|
 | 
						|
void
 | 
						|
CloseDownClient(ClientPtr client)
 | 
						|
{
 | 
						|
    Bool really_close_down = client->clientGone ||
 | 
						|
        client->closeDownMode == DestroyAll;
 | 
						|
 | 
						|
    if (!client->clientGone) {
 | 
						|
        /* ungrab server if grabbing client dies */
 | 
						|
        if (grabState != GrabNone && grabClient == client) {
 | 
						|
            UngrabServer(client);
 | 
						|
        }
 | 
						|
        BITCLEAR(grabWaiters, client->index);
 | 
						|
        DeleteClientFromAnySelections(client);
 | 
						|
        ReleaseActiveGrabs(client);
 | 
						|
        DeleteClientFontStuff(client);
 | 
						|
        if (!really_close_down) {
 | 
						|
            /*  This frees resources that should never be retained
 | 
						|
             *  no matter what the close down mode is.  Actually we
 | 
						|
             *  could do this unconditionally, but it's probably
 | 
						|
             *  better not to traverse all the client's resources
 | 
						|
             *  twice (once here, once a few lines down in
 | 
						|
             *  FreeClientResources) in the common case of
 | 
						|
             *  really_close_down == TRUE.
 | 
						|
             */
 | 
						|
            FreeClientNeverRetainResources(client);
 | 
						|
            client->clientState = ClientStateRetained;
 | 
						|
            if (ClientStateCallback) {
 | 
						|
                NewClientInfoRec clientinfo;
 | 
						|
 | 
						|
                clientinfo.client = client;
 | 
						|
                clientinfo.prefix = (xConnSetupPrefix *) NULL;
 | 
						|
                clientinfo.setup = (xConnSetup *) NULL;
 | 
						|
                CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        client->clientGone = TRUE;      /* so events aren't sent to client */
 | 
						|
        if (ClientIsAsleep(client))
 | 
						|
            ClientSignal(client);
 | 
						|
        ProcessWorkQueueZombies();
 | 
						|
        CloseDownConnection(client);
 | 
						|
 | 
						|
        /* If the client made it to the Running stage, nClients has
 | 
						|
         * been incremented on its behalf, so we need to decrement it
 | 
						|
         * now.  If it hasn't gotten to Running, nClients has *not*
 | 
						|
         * been incremented, so *don't* decrement it.
 | 
						|
         */
 | 
						|
        if (client->clientState != ClientStateInitial) {
 | 
						|
            --nClients;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (really_close_down) {
 | 
						|
        if (client->clientState == ClientStateRunning && nClients == 0)
 | 
						|
            dispatchException |= dispatchExceptionAtReset;
 | 
						|
 | 
						|
        client->clientState = ClientStateGone;
 | 
						|
        if (ClientStateCallback) {
 | 
						|
            NewClientInfoRec clientinfo;
 | 
						|
 | 
						|
            clientinfo.client = client;
 | 
						|
            clientinfo.prefix = (xConnSetupPrefix *) NULL;
 | 
						|
            clientinfo.setup = (xConnSetup *) NULL;
 | 
						|
            CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
 | 
						|
        }
 | 
						|
        TouchListenerGone(client->clientAsMask);
 | 
						|
        FreeClientResources(client);
 | 
						|
        /* Disable client ID tracking. This must be done after
 | 
						|
         * ClientStateCallback. */
 | 
						|
        ReleaseClientIds(client);
 | 
						|
#ifdef XSERVER_DTRACE
 | 
						|
        XSERVER_CLIENT_DISCONNECT(client->index);
 | 
						|
#endif
 | 
						|
        if (client->index < nextFreeClientID)
 | 
						|
            nextFreeClientID = client->index;
 | 
						|
        clients[client->index] = NullClient;
 | 
						|
        SmartLastClient = NullClient;
 | 
						|
        dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
 | 
						|
 | 
						|
        while (!clients[currentMaxClients - 1])
 | 
						|
            currentMaxClients--;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
KillAllClients(void)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 1; i < currentMaxClients; i++)
 | 
						|
        if (clients[i]) {
 | 
						|
            /* Make sure Retained clients are released. */
 | 
						|
            clients[i]->closeDownMode = DestroyAll;
 | 
						|
            CloseDownClient(clients[i]);
 | 
						|
        }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
InitClient(ClientPtr client, int i, void *ospriv)
 | 
						|
{
 | 
						|
    client->index = i;
 | 
						|
    client->clientAsMask = ((Mask) i) << CLIENTOFFSET;
 | 
						|
    client->closeDownMode = i ? DestroyAll : RetainPermanent;
 | 
						|
    client->requestVector = InitialVector;
 | 
						|
    client->osPrivate = ospriv;
 | 
						|
    QueryMinMaxKeyCodes(&client->minKC, &client->maxKC);
 | 
						|
    client->smart_start_tick = SmartScheduleTime;
 | 
						|
    client->smart_stop_tick = SmartScheduleTime;
 | 
						|
    client->clientIds = NULL;
 | 
						|
}
 | 
						|
 | 
						|
/************************
 | 
						|
 * int NextAvailableClient(ospriv)
 | 
						|
 *
 | 
						|
 * OS dependent portion can't assign client id's because of CloseDownModes.
 | 
						|
 * Returns NULL if there are no free clients.
 | 
						|
 *************************/
 | 
						|
 | 
						|
ClientPtr
 | 
						|
NextAvailableClient(void *ospriv)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    ClientPtr client;
 | 
						|
    xReq data;
 | 
						|
 | 
						|
    i = nextFreeClientID;
 | 
						|
    if (i == MAXCLIENTS)
 | 
						|
        return (ClientPtr) NULL;
 | 
						|
    clients[i] = client =
 | 
						|
        dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
 | 
						|
    if (!client)
 | 
						|
        return (ClientPtr) NULL;
 | 
						|
    InitClient(client, i, ospriv);
 | 
						|
    if (!InitClientResources(client)) {
 | 
						|
        dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
 | 
						|
        return (ClientPtr) NULL;
 | 
						|
    }
 | 
						|
    data.reqType = 1;
 | 
						|
    data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
 | 
						|
    if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) {
 | 
						|
        FreeClientResources(client);
 | 
						|
        dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
 | 
						|
        return (ClientPtr) NULL;
 | 
						|
    }
 | 
						|
    if (i == currentMaxClients)
 | 
						|
        currentMaxClients++;
 | 
						|
    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
 | 
						|
        nextFreeClientID++;
 | 
						|
 | 
						|
    /* Enable client ID tracking. This must be done before
 | 
						|
     * ClientStateCallback. */
 | 
						|
    ReserveClientIds(client);
 | 
						|
 | 
						|
    if (ClientStateCallback) {
 | 
						|
        NewClientInfoRec clientinfo;
 | 
						|
 | 
						|
        clientinfo.client = client;
 | 
						|
        clientinfo.prefix = (xConnSetupPrefix *) NULL;
 | 
						|
        clientinfo.setup = (xConnSetup *) NULL;
 | 
						|
        CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
 | 
						|
    }
 | 
						|
    return client;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcInitialConnection(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
    xConnClientPrefix *prefix;
 | 
						|
    int whichbyte = 1;
 | 
						|
    char order;
 | 
						|
 | 
						|
    prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq);
 | 
						|
    order = prefix->byteOrder;
 | 
						|
    if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
 | 
						|
	return client->noClientException = -1;
 | 
						|
    if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
 | 
						|
	(!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
 | 
						|
	client->swapped = TRUE;
 | 
						|
	SwapConnClientPrefix(prefix);
 | 
						|
    }
 | 
						|
    stuff->reqType = 2;
 | 
						|
    stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
 | 
						|
        bytes_to_int32(prefix->nbytesAuthString);
 | 
						|
    if (client->swapped) {
 | 
						|
        swaps(&stuff->length);
 | 
						|
    }
 | 
						|
    if (order == 'r' || order == 'R') {
 | 
						|
	client->local = FALSE;
 | 
						|
    }
 | 
						|
    ResetCurrentRequest(client);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
SendConnSetup(ClientPtr client, const char *reason)
 | 
						|
{
 | 
						|
    xWindowRoot *root;
 | 
						|
    int i;
 | 
						|
    int numScreens;
 | 
						|
    char *lConnectionInfo;
 | 
						|
    xConnSetupPrefix *lconnSetupPrefix;
 | 
						|
 | 
						|
    if (reason) {
 | 
						|
        xConnSetupPrefix csp;
 | 
						|
 | 
						|
        csp.success = xFalse;
 | 
						|
        csp.lengthReason = strlen(reason);
 | 
						|
        csp.length = bytes_to_int32(csp.lengthReason);
 | 
						|
        csp.majorVersion = X_PROTOCOL;
 | 
						|
        csp.minorVersion = X_PROTOCOL_REVISION;
 | 
						|
        if (client->swapped)
 | 
						|
            WriteSConnSetupPrefix(client, &csp);
 | 
						|
        else
 | 
						|
            WriteToClient(client, sz_xConnSetupPrefix, &csp);
 | 
						|
        WriteToClient(client, (int) csp.lengthReason, reason);
 | 
						|
        return client->noClientException = -1;
 | 
						|
    }
 | 
						|
 | 
						|
    numScreens = screenInfo.numScreens;
 | 
						|
    lConnectionInfo = ConnectionInfo;
 | 
						|
    lconnSetupPrefix = &connSetupPrefix;
 | 
						|
 | 
						|
    /* We're about to start speaking X protocol back to the client by
 | 
						|
     * sending the connection setup info.  This means the authorization
 | 
						|
     * step is complete, and we can count the client as an
 | 
						|
     * authorized one.
 | 
						|
     */
 | 
						|
    nClients++;
 | 
						|
 | 
						|
    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
 | 
						|
    client->sequence = 0;
 | 
						|
    ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask;
 | 
						|
    ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
 | 
						|
#ifdef MATCH_CLIENT_ENDIAN
 | 
						|
    ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client);
 | 
						|
    ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client);
 | 
						|
#endif
 | 
						|
    /* fill in the "currentInputMask" */
 | 
						|
    root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart);
 | 
						|
#ifdef PANORAMIX
 | 
						|
    if (noPanoramiXExtension)
 | 
						|
        numScreens = screenInfo.numScreens;
 | 
						|
    else
 | 
						|
        numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
 | 
						|
#endif
 | 
						|
 | 
						|
    for (i = 0; i < numScreens; i++) {
 | 
						|
        unsigned int j;
 | 
						|
        xDepth *pDepth;
 | 
						|
        WindowPtr pRoot = screenInfo.screens[i]->root;
 | 
						|
 | 
						|
        root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
 | 
						|
        pDepth = (xDepth *) (root + 1);
 | 
						|
        for (j = 0; j < root->nDepths; j++) {
 | 
						|
            pDepth = (xDepth *) (((char *) (pDepth + 1)) +
 | 
						|
                                 pDepth->nVisuals * sizeof(xVisualType));
 | 
						|
        }
 | 
						|
        root = (xWindowRoot *) pDepth;
 | 
						|
    }
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
        WriteSConnSetupPrefix(client, lconnSetupPrefix);
 | 
						|
        WriteSConnectionInfo(client,
 | 
						|
                             (unsigned long) (lconnSetupPrefix->length << 2),
 | 
						|
                             lConnectionInfo);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix);
 | 
						|
        WriteToClient(client, (int) (lconnSetupPrefix->length << 2),
 | 
						|
		      lConnectionInfo);
 | 
						|
    }
 | 
						|
    client->clientState = ClientStateRunning;
 | 
						|
    if (ClientStateCallback) {
 | 
						|
        NewClientInfoRec clientinfo;
 | 
						|
 | 
						|
        clientinfo.client = client;
 | 
						|
        clientinfo.prefix = lconnSetupPrefix;
 | 
						|
        clientinfo.setup = (xConnSetup *) lConnectionInfo;
 | 
						|
        CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
 | 
						|
    }
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcEstablishConnection(ClientPtr client)
 | 
						|
{
 | 
						|
    const char *reason;
 | 
						|
    char *auth_proto, *auth_string;
 | 
						|
    xConnClientPrefix *prefix;
 | 
						|
 | 
						|
    REQUEST(xReq);
 | 
						|
 | 
						|
    prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
 | 
						|
    auth_proto = (char *) prefix + sz_xConnClientPrefix;
 | 
						|
    auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
 | 
						|
    if ((prefix->majorVersion != X_PROTOCOL) ||
 | 
						|
        (prefix->minorVersion != X_PROTOCOL_REVISION))
 | 
						|
        reason = "Protocol version mismatch";
 | 
						|
    else
 | 
						|
        reason = ClientAuthorized(client,
 | 
						|
                                  (unsigned short) prefix->nbytesAuthProto,
 | 
						|
                                  auth_proto,
 | 
						|
                                  (unsigned short) prefix->nbytesAuthString,
 | 
						|
                                  auth_string);
 | 
						|
 | 
						|
    return (SendConnSetup(client, reason));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
 | 
						|
                  XID resId, int errorCode)
 | 
						|
{
 | 
						|
    xError rep = {
 | 
						|
        .type = X_Error,
 | 
						|
        .errorCode = errorCode,
 | 
						|
        .resourceID = resId,
 | 
						|
        .minorCode = minorCode,
 | 
						|
        .majorCode = majorCode
 | 
						|
    };
 | 
						|
 | 
						|
    WriteEventsToClient(client, 1, (xEvent *) &rep);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
MarkClientException(ClientPtr client)
 | 
						|
{
 | 
						|
    client->noClientException = -1;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * This array encodes the answer to the question "what is the log base 2
 | 
						|
 * of the number of pixels that fit in a scanline pad unit?"
 | 
						|
 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
 | 
						|
 */
 | 
						|
static int answer[6][4] = {
 | 
						|
    /* pad   pad   pad     pad */
 | 
						|
    /*  8     16    32    64 */
 | 
						|
 | 
						|
    {3, 4, 5, 6},               /* 1 bit per pixel */
 | 
						|
    {1, 2, 3, 4},               /* 4 bits per pixel */
 | 
						|
    {0, 1, 2, 3},               /* 8 bits per pixel */
 | 
						|
    {~0, 0, 1, 2},              /* 16 bits per pixel */
 | 
						|
    {~0, ~0, 0, 1},             /* 24 bits per pixel */
 | 
						|
    {~0, ~0, 0, 1}              /* 32 bits per pixel */
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
 * This array gives the answer to the question "what is the first index for
 | 
						|
 * the answer array above given the number of bits per pixel?"
 | 
						|
 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
 | 
						|
 */
 | 
						|
static int indexForBitsPerPixel[33] = {
 | 
						|
    ~0, 0, ~0, ~0,              /* 1 bit per pixel */
 | 
						|
    1, ~0, ~0, ~0,              /* 4 bits per pixel */
 | 
						|
    2, ~0, ~0, ~0,              /* 8 bits per pixel */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    3, ~0, ~0, ~0,              /* 16 bits per pixel */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    4, ~0, ~0, ~0,              /* 24 bits per pixel */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    5                           /* 32 bits per pixel */
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
 * This array gives the bytesperPixel value for cases where the number
 | 
						|
 * of bits per pixel is a multiple of 8 but not a power of 2.
 | 
						|
 */
 | 
						|
static int answerBytesPerPixel[33] = {
 | 
						|
    ~0, 0, ~0, ~0,              /* 1 bit per pixel */
 | 
						|
    0, ~0, ~0, ~0,              /* 4 bits per pixel */
 | 
						|
    0, ~0, ~0, ~0,              /* 8 bits per pixel */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    0, ~0, ~0, ~0,              /* 16 bits per pixel */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    3, ~0, ~0, ~0,              /* 24 bits per pixel */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    0                           /* 32 bits per pixel */
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
 * This array gives the answer to the question "what is the second index for
 | 
						|
 * the answer array above given the number of bits per scanline pad unit?"
 | 
						|
 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
 | 
						|
 */
 | 
						|
static int indexForScanlinePad[65] = {
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    0, ~0, ~0, ~0,              /* 8 bits per scanline pad unit */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    1, ~0, ~0, ~0,              /* 16 bits per scanline pad unit */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    2, ~0, ~0, ~0,              /* 32 bits per scanline pad unit */
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    ~0, ~0, ~0, ~0,
 | 
						|
    3                           /* 64 bits per scanline pad unit */
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
	grow the array of screenRecs if necessary.
 | 
						|
	call the device-supplied initialization procedure
 | 
						|
with its screen number, a pointer to its ScreenRec, argc, and argv.
 | 
						|
	return the number of successfully installed screens.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
 | 
						|
{
 | 
						|
    int scanlinepad, format, depth, bitsPerPixel, j, k;
 | 
						|
 | 
						|
    dixInitScreenSpecificPrivates(pScreen);
 | 
						|
 | 
						|
    if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    pScreen->myNum = i;
 | 
						|
    if (gpu) {
 | 
						|
        pScreen->myNum += GPU_SCREEN_OFFSET;
 | 
						|
        pScreen->isGPU = TRUE;
 | 
						|
    }
 | 
						|
    pScreen->totalPixmapSize = 0;       /* computed in CreateScratchPixmapForScreen */
 | 
						|
    pScreen->ClipNotify = 0;    /* for R4 ddx compatibility */
 | 
						|
    pScreen->CreateScreenResources = 0;
 | 
						|
 | 
						|
    xorg_list_init(&pScreen->pixmap_dirty_list);
 | 
						|
    xorg_list_init(&pScreen->unattached_list);
 | 
						|
    xorg_list_init(&pScreen->output_slave_list);
 | 
						|
    xorg_list_init(&pScreen->offload_slave_list);
 | 
						|
 | 
						|
    /*
 | 
						|
     * This loop gets run once for every Screen that gets added,
 | 
						|
     * but thats ok.  If the ddx layer initializes the formats
 | 
						|
     * one at a time calling AddScreen() after each, then each
 | 
						|
     * iteration will make it a little more accurate.  Worst case
 | 
						|
     * we do this loop N * numPixmapFormats where N is # of screens.
 | 
						|
     * Anyway, this must be called after InitOutput and before the
 | 
						|
     * screen init routine is called.
 | 
						|
     */
 | 
						|
    for (format = 0; format < screenInfo.numPixmapFormats; format++) {
 | 
						|
        depth = screenInfo.formats[format].depth;
 | 
						|
        bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
 | 
						|
        scanlinepad = screenInfo.formats[format].scanlinePad;
 | 
						|
        j = indexForBitsPerPixel[bitsPerPixel];
 | 
						|
        k = indexForScanlinePad[scanlinepad];
 | 
						|
        PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k];
 | 
						|
        PixmapWidthPaddingInfo[depth].padRoundUp =
 | 
						|
            (scanlinepad / bitsPerPixel) - 1;
 | 
						|
        j = indexForBitsPerPixel[8];    /* bits per byte */
 | 
						|
        PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k];
 | 
						|
        PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel;
 | 
						|
        if (answerBytesPerPixel[bitsPerPixel]) {
 | 
						|
            PixmapWidthPaddingInfo[depth].notPower2 = 1;
 | 
						|
            PixmapWidthPaddingInfo[depth].bytesPerPixel =
 | 
						|
                answerBytesPerPixel[bitsPerPixel];
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            PixmapWidthPaddingInfo[depth].notPower2 = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
 | 
						|
                           int /*argc */ ,
 | 
						|
                           char **      /*argv */
 | 
						|
          ), int argc, char **argv)
 | 
						|
{
 | 
						|
 | 
						|
    int i;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
    Bool ret;
 | 
						|
 | 
						|
    i = screenInfo.numScreens;
 | 
						|
    if (i == MAXSCREENS)
 | 
						|
        return -1;
 | 
						|
 | 
						|
    pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
 | 
						|
    if (!pScreen)
 | 
						|
        return -1;
 | 
						|
 | 
						|
    ret = init_screen(pScreen, i, FALSE);
 | 
						|
    if (ret != 0) {
 | 
						|
        free(pScreen);
 | 
						|
        return ret;
 | 
						|
    }
 | 
						|
    /* This is where screen specific stuff gets initialized.  Load the
 | 
						|
       screen structure, call the hardware, whatever.
 | 
						|
       This is also where the default colormap should be allocated and
 | 
						|
       also pixel values for blackPixel, whitePixel, and the cursor
 | 
						|
       Note that InitScreen is NOT allowed to modify argc, argv, or
 | 
						|
       any of the strings pointed to by argv.  They may be passed to
 | 
						|
       multiple screens.
 | 
						|
     */
 | 
						|
    screenInfo.screens[i] = pScreen;
 | 
						|
    screenInfo.numScreens++;
 | 
						|
    if (!(*pfnInit) (pScreen, argc, argv)) {
 | 
						|
        dixFreeScreenSpecificPrivates(pScreen);
 | 
						|
        dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
 | 
						|
        free(pScreen);
 | 
						|
        screenInfo.numScreens--;
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    update_desktop_dimensions();
 | 
						|
 | 
						|
    dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR,
 | 
						|
                                0);
 | 
						|
 | 
						|
    return i;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
 | 
						|
                              int /*argc */ ,
 | 
						|
                              char **      /*argv */
 | 
						|
                              ),
 | 
						|
             int argc, char **argv)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    ScreenPtr pScreen;
 | 
						|
    Bool ret;
 | 
						|
 | 
						|
    i = screenInfo.numGPUScreens;
 | 
						|
    if (i == MAXGPUSCREENS)
 | 
						|
        return -1;
 | 
						|
 | 
						|
    pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
 | 
						|
    if (!pScreen)
 | 
						|
        return -1;
 | 
						|
 | 
						|
    ret = init_screen(pScreen, i, TRUE);
 | 
						|
    if (ret != 0) {
 | 
						|
        free(pScreen);
 | 
						|
        return ret;
 | 
						|
    }
 | 
						|
 | 
						|
    /* This is where screen specific stuff gets initialized.  Load the
 | 
						|
       screen structure, call the hardware, whatever.
 | 
						|
       This is also where the default colormap should be allocated and
 | 
						|
       also pixel values for blackPixel, whitePixel, and the cursor
 | 
						|
       Note that InitScreen is NOT allowed to modify argc, argv, or
 | 
						|
       any of the strings pointed to by argv.  They may be passed to
 | 
						|
       multiple screens.
 | 
						|
     */
 | 
						|
    screenInfo.gpuscreens[i] = pScreen;
 | 
						|
    screenInfo.numGPUScreens++;
 | 
						|
    if (!(*pfnInit) (pScreen, argc, argv)) {
 | 
						|
        dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
 | 
						|
        free(pScreen);
 | 
						|
        screenInfo.numGPUScreens--;
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    update_desktop_dimensions();
 | 
						|
 | 
						|
    return i;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
RemoveGPUScreen(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    int idx, j;
 | 
						|
    if (!pScreen->isGPU)
 | 
						|
        return;
 | 
						|
 | 
						|
    idx = pScreen->myNum - GPU_SCREEN_OFFSET;
 | 
						|
    for (j = idx; j < screenInfo.numGPUScreens - 1; j++) {
 | 
						|
        screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1];
 | 
						|
        screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET;
 | 
						|
    }
 | 
						|
    screenInfo.numGPUScreens--;
 | 
						|
 | 
						|
    /* this gets freed later in the resource list, but without
 | 
						|
     * the screen existing it causes crashes - so remove it here */
 | 
						|
    if (pScreen->defColormap)
 | 
						|
        FreeResource(pScreen->defColormap, RT_COLORMAP);
 | 
						|
    free(pScreen);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new)
 | 
						|
{
 | 
						|
    assert(new->isGPU);
 | 
						|
    assert(!new->current_master);
 | 
						|
    xorg_list_add(&new->unattached_head, &pScreen->unattached_list);
 | 
						|
    new->current_master = pScreen;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DetachUnboundGPU(ScreenPtr slave)
 | 
						|
{
 | 
						|
    assert(slave->isGPU);
 | 
						|
    xorg_list_del(&slave->unattached_head);
 | 
						|
    slave->current_master = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
 | 
						|
{
 | 
						|
    assert(new->isGPU);
 | 
						|
    xorg_list_add(&new->output_head, &pScreen->output_slave_list);
 | 
						|
    new->current_master = pScreen;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DetachOutputGPU(ScreenPtr slave)
 | 
						|
{
 | 
						|
    assert(slave->isGPU);
 | 
						|
    xorg_list_del(&slave->output_head);
 | 
						|
    slave->current_master = NULL;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
 | 
						|
{
 | 
						|
    assert(new->isGPU);
 | 
						|
    xorg_list_add(&new->offload_head, &pScreen->offload_slave_list);
 | 
						|
    new->current_master = pScreen;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DetachOffloadGPU(ScreenPtr slave)
 | 
						|
{
 | 
						|
    assert(slave->isGPU);
 | 
						|
    xorg_list_del(&slave->offload_head);
 | 
						|
    slave->current_master = NULL;
 | 
						|
}
 | 
						|
 |