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