dispatch.c revision 05b261ec
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 13705b261ecSmrg#include "xace.h" 13805b261ecSmrg#ifdef XAPPGROUP 13905b261ecSmrg#include "appgroup.h" 14005b261ecSmrg#endif 14105b261ecSmrg#ifdef XKB 14205b261ecSmrg#ifndef XKB_IN_SERVER 14305b261ecSmrg#define XKB_IN_SERVER 14405b261ecSmrg#endif 14505b261ecSmrg#include "inputstr.h" 14605b261ecSmrg#include <xkbsrv.h> 14705b261ecSmrg#endif 14805b261ecSmrg 14905b261ecSmrg#ifdef XSERVER_DTRACE 15005b261ecSmrg#include <sys/types.h> 15105b261ecSmrgtypedef const char *string; 15205b261ecSmrg#include "Xserver-dtrace.h" 15305b261ecSmrg 15405b261ecSmrgchar *RequestNames[256]; 15505b261ecSmrgstatic void LoadRequestNames(void); 15605b261ecSmrgstatic void FreeRequestNames(void); 15705b261ecSmrg#define GetRequestName(i) (RequestNames[i]) 15805b261ecSmrg#endif 15905b261ecSmrg 16005b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32) 16105b261ecSmrg#define BITMASK(i) (1U << ((i) & 31)) 16205b261ecSmrg#define MASKIDX(i) ((i) >> 5) 16305b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)] 16405b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) 16505b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) 16605b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) 16705b261ecSmrg 16805b261ecSmrgextern xConnSetupPrefix connSetupPrefix; 16905b261ecSmrgextern char *ConnectionInfo; 17005b261ecSmrg 17105b261ecSmrg_X_EXPORT Selection *CurrentSelections; 17205b261ecSmrg_X_EXPORT int NumCurrentSelections; 17305b261ecSmrgCallbackListPtr SelectionCallback = NULL; 17405b261ecSmrg 17505b261ecSmrgstatic ClientPtr grabClient; 17605b261ecSmrg#define GrabNone 0 17705b261ecSmrg#define GrabActive 1 17805b261ecSmrg#define GrabKickout 2 17905b261ecSmrgstatic int grabState = GrabNone; 18005b261ecSmrgstatic long grabWaiters[mskcnt]; 18105b261ecSmrg_X_EXPORT CallbackListPtr ServerGrabCallback = NULL; 18205b261ecSmrgHWEventQueuePtr checkForInput[2]; 18305b261ecSmrgextern int connBlockScreenStart; 18405b261ecSmrg 18505b261ecSmrgstatic void KillAllClients(void); 18605b261ecSmrg 18705b261ecSmrgstatic void DeleteClientFromAnySelections(ClientPtr client); 18805b261ecSmrg 18905b261ecSmrgstatic int nextFreeClientID; /* always MIN free client ID */ 19005b261ecSmrg 19105b261ecSmrgstatic int nClients; /* number of authorized clients */ 19205b261ecSmrg 19305b261ecSmrg_X_EXPORT CallbackListPtr ClientStateCallback; 19405b261ecSmrg 19505b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they 19605b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't 19705b261ecSmrg * need to actually check value in memory when used and may miss changes from 19805b261ecSmrg * signal handlers. 19905b261ecSmrg */ 20005b261ecSmrg_X_EXPORT volatile char dispatchException = 0; 20105b261ecSmrg_X_EXPORT volatile char isItTimeToYield; 20205b261ecSmrg 20305b261ecSmrg/* Various of the DIX function interfaces were not designed to allow 20405b261ecSmrg * the client->errorValue to be set on BadValue and other errors. 20505b261ecSmrg * Rather than changing interfaces and breaking untold code we introduce 20605b261ecSmrg * a new global that dispatch can use. 20705b261ecSmrg */ 20805b261ecSmrgXID clientErrorValue; /* XXX this is a kludge */ 20905b261ecSmrg 21005b261ecSmrg#define SAME_SCREENS(a, b) (\ 21105b261ecSmrg (a.pScreen == b.pScreen)) 21205b261ecSmrg 21305b261ecSmrg_X_EXPORT void 21405b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) 21505b261ecSmrg{ 21605b261ecSmrg checkForInput[0] = c0; 21705b261ecSmrg checkForInput[1] = c1; 21805b261ecSmrg} 21905b261ecSmrg 22005b261ecSmrg_X_EXPORT void 22105b261ecSmrgUpdateCurrentTime(void) 22205b261ecSmrg{ 22305b261ecSmrg TimeStamp systime; 22405b261ecSmrg 22505b261ecSmrg /* To avoid time running backwards, we must call GetTimeInMillis before 22605b261ecSmrg * calling ProcessInputEvents. 22705b261ecSmrg */ 22805b261ecSmrg systime.months = currentTime.months; 22905b261ecSmrg systime.milliseconds = GetTimeInMillis(); 23005b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 23105b261ecSmrg systime.months++; 23205b261ecSmrg if (*checkForInput[0] != *checkForInput[1]) 23305b261ecSmrg ProcessInputEvents(); 23405b261ecSmrg if (CompareTimeStamps(systime, currentTime) == LATER) 23505b261ecSmrg currentTime = systime; 23605b261ecSmrg} 23705b261ecSmrg 23805b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ 23905b261ecSmrg_X_EXPORT void 24005b261ecSmrgUpdateCurrentTimeIf(void) 24105b261ecSmrg{ 24205b261ecSmrg TimeStamp systime; 24305b261ecSmrg 24405b261ecSmrg systime.months = currentTime.months; 24505b261ecSmrg systime.milliseconds = GetTimeInMillis(); 24605b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 24705b261ecSmrg systime.months++; 24805b261ecSmrg if (*checkForInput[0] == *checkForInput[1]) 24905b261ecSmrg currentTime = systime; 25005b261ecSmrg} 25105b261ecSmrg 25205b261ecSmrgvoid 25305b261ecSmrgInitSelections(void) 25405b261ecSmrg{ 25505b261ecSmrg if (CurrentSelections) 25605b261ecSmrg xfree(CurrentSelections); 25705b261ecSmrg CurrentSelections = (Selection *)NULL; 25805b261ecSmrg NumCurrentSelections = 0; 25905b261ecSmrg} 26005b261ecSmrg 26105b261ecSmrgvoid 26205b261ecSmrgFlushClientCaches(XID id) 26305b261ecSmrg{ 26405b261ecSmrg int i; 26505b261ecSmrg ClientPtr client; 26605b261ecSmrg 26705b261ecSmrg client = clients[CLIENT_ID(id)]; 26805b261ecSmrg if (client == NullClient) 26905b261ecSmrg return ; 27005b261ecSmrg for (i=0; i<currentMaxClients; i++) 27105b261ecSmrg { 27205b261ecSmrg client = clients[i]; 27305b261ecSmrg if (client != NullClient) 27405b261ecSmrg { 27505b261ecSmrg if (client->lastDrawableID == id) 27605b261ecSmrg { 27705b261ecSmrg client->lastDrawableID = WindowTable[0]->drawable.id; 27805b261ecSmrg client->lastDrawable = (DrawablePtr)WindowTable[0]; 27905b261ecSmrg } 28005b261ecSmrg else if (client->lastGCID == id) 28105b261ecSmrg { 28205b261ecSmrg client->lastGCID = INVALID; 28305b261ecSmrg client->lastGC = (GCPtr)NULL; 28405b261ecSmrg } 28505b261ecSmrg } 28605b261ecSmrg } 28705b261ecSmrg} 28805b261ecSmrg#ifdef SMART_SCHEDULE 28905b261ecSmrg 29005b261ecSmrg#undef SMART_DEBUG 29105b261ecSmrg 29205b261ecSmrg#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ 29305b261ecSmrg#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ 29405b261ecSmrg 29505b261ecSmrgBool SmartScheduleDisable = FALSE; 29605b261ecSmrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; 29705b261ecSmrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; 29805b261ecSmrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; 29905b261ecSmrglong SmartScheduleTime; 30005b261ecSmrgstatic ClientPtr SmartLastClient; 30105b261ecSmrgstatic int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; 30205b261ecSmrg 30305b261ecSmrg#ifdef SMART_DEBUG 30405b261ecSmrglong SmartLastPrint; 30505b261ecSmrg#endif 30605b261ecSmrg 30705b261ecSmrgvoid Dispatch(void); 30805b261ecSmrgvoid InitProcVectors(void); 30905b261ecSmrg 31005b261ecSmrgstatic int 31105b261ecSmrgSmartScheduleClient (int *clientReady, int nready) 31205b261ecSmrg{ 31305b261ecSmrg ClientPtr pClient; 31405b261ecSmrg int i; 31505b261ecSmrg int client; 31605b261ecSmrg int bestPrio, best = 0; 31705b261ecSmrg int bestRobin, robin; 31805b261ecSmrg long now = SmartScheduleTime; 31905b261ecSmrg long idle; 32005b261ecSmrg 32105b261ecSmrg bestPrio = -0x7fffffff; 32205b261ecSmrg bestRobin = 0; 32305b261ecSmrg idle = 2 * SmartScheduleSlice; 32405b261ecSmrg for (i = 0; i < nready; i++) 32505b261ecSmrg { 32605b261ecSmrg client = clientReady[i]; 32705b261ecSmrg pClient = clients[client]; 32805b261ecSmrg /* Praise clients which are idle */ 32905b261ecSmrg if ((now - pClient->smart_check_tick) >= idle) 33005b261ecSmrg { 33105b261ecSmrg if (pClient->smart_priority < 0) 33205b261ecSmrg pClient->smart_priority++; 33305b261ecSmrg } 33405b261ecSmrg pClient->smart_check_tick = now; 33505b261ecSmrg 33605b261ecSmrg /* check priority to select best client */ 33705b261ecSmrg robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; 33805b261ecSmrg if (pClient->smart_priority > bestPrio || 33905b261ecSmrg (pClient->smart_priority == bestPrio && robin > bestRobin)) 34005b261ecSmrg { 34105b261ecSmrg bestPrio = pClient->smart_priority; 34205b261ecSmrg bestRobin = robin; 34305b261ecSmrg best = client; 34405b261ecSmrg } 34505b261ecSmrg#ifdef SMART_DEBUG 34605b261ecSmrg if ((now - SmartLastPrint) >= 5000) 34705b261ecSmrg fprintf (stderr, " %2d: %3d", client, pClient->smart_priority); 34805b261ecSmrg#endif 34905b261ecSmrg } 35005b261ecSmrg#ifdef SMART_DEBUG 35105b261ecSmrg if ((now - SmartLastPrint) >= 5000) 35205b261ecSmrg { 35305b261ecSmrg fprintf (stderr, " use %2d\n", best); 35405b261ecSmrg SmartLastPrint = now; 35505b261ecSmrg } 35605b261ecSmrg#endif 35705b261ecSmrg pClient = clients[best]; 35805b261ecSmrg SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index; 35905b261ecSmrg /* 36005b261ecSmrg * Set current client pointer 36105b261ecSmrg */ 36205b261ecSmrg if (SmartLastClient != pClient) 36305b261ecSmrg { 36405b261ecSmrg pClient->smart_start_tick = now; 36505b261ecSmrg SmartLastClient = pClient; 36605b261ecSmrg } 36705b261ecSmrg /* 36805b261ecSmrg * Adjust slice 36905b261ecSmrg */ 37005b261ecSmrg if (nready == 1) 37105b261ecSmrg { 37205b261ecSmrg /* 37305b261ecSmrg * If it's been a long time since another client 37405b261ecSmrg * has run, bump the slice up to get maximal 37505b261ecSmrg * performance from a single client 37605b261ecSmrg */ 37705b261ecSmrg if ((now - pClient->smart_start_tick) > 1000 && 37805b261ecSmrg SmartScheduleSlice < SmartScheduleMaxSlice) 37905b261ecSmrg { 38005b261ecSmrg SmartScheduleSlice += SmartScheduleInterval; 38105b261ecSmrg } 38205b261ecSmrg } 38305b261ecSmrg else 38405b261ecSmrg { 38505b261ecSmrg SmartScheduleSlice = SmartScheduleInterval; 38605b261ecSmrg } 38705b261ecSmrg return best; 38805b261ecSmrg} 38905b261ecSmrg#endif 39005b261ecSmrg 39105b261ecSmrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType 39205b261ecSmrg 39305b261ecSmrgvoid 39405b261ecSmrgDispatch(void) 39505b261ecSmrg{ 39605b261ecSmrg int *clientReady; /* array of request ready clients */ 39705b261ecSmrg int result; 39805b261ecSmrg ClientPtr client; 39905b261ecSmrg int nready; 40005b261ecSmrg HWEventQueuePtr* icheck = checkForInput; 40105b261ecSmrg#ifdef SMART_SCHEDULE 40205b261ecSmrg long start_tick; 40305b261ecSmrg#endif 40405b261ecSmrg 40505b261ecSmrg nextFreeClientID = 1; 40605b261ecSmrg InitSelections(); 40705b261ecSmrg nClients = 0; 40805b261ecSmrg 40905b261ecSmrg clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients); 41005b261ecSmrg if (!clientReady) 41105b261ecSmrg return; 41205b261ecSmrg 41305b261ecSmrg#ifdef XSERVER_DTRACE 41405b261ecSmrg LoadRequestNames(); 41505b261ecSmrg#endif 41605b261ecSmrg 41705b261ecSmrg while (!dispatchException) 41805b261ecSmrg { 41905b261ecSmrg if (*icheck[0] != *icheck[1]) 42005b261ecSmrg { 42105b261ecSmrg ProcessInputEvents(); 42205b261ecSmrg FlushIfCriticalOutputPending(); 42305b261ecSmrg } 42405b261ecSmrg 42505b261ecSmrg nready = WaitForSomething(clientReady); 42605b261ecSmrg 42705b261ecSmrg#ifdef SMART_SCHEDULE 42805b261ecSmrg if (nready && !SmartScheduleDisable) 42905b261ecSmrg { 43005b261ecSmrg clientReady[0] = SmartScheduleClient (clientReady, nready); 43105b261ecSmrg nready = 1; 43205b261ecSmrg } 43305b261ecSmrg#endif 43405b261ecSmrg /***************** 43505b261ecSmrg * Handle events in round robin fashion, doing input between 43605b261ecSmrg * each round 43705b261ecSmrg *****************/ 43805b261ecSmrg 43905b261ecSmrg while (!dispatchException && (--nready >= 0)) 44005b261ecSmrg { 44105b261ecSmrg client = clients[clientReady[nready]]; 44205b261ecSmrg if (! client) 44305b261ecSmrg { 44405b261ecSmrg /* KillClient can cause this to happen */ 44505b261ecSmrg continue; 44605b261ecSmrg } 44705b261ecSmrg /* GrabServer activation can cause this to be true */ 44805b261ecSmrg if (grabState == GrabKickout) 44905b261ecSmrg { 45005b261ecSmrg grabState = GrabActive; 45105b261ecSmrg break; 45205b261ecSmrg } 45305b261ecSmrg isItTimeToYield = FALSE; 45405b261ecSmrg 45505b261ecSmrg requestingClient = client; 45605b261ecSmrg#ifdef SMART_SCHEDULE 45705b261ecSmrg start_tick = SmartScheduleTime; 45805b261ecSmrg#endif 45905b261ecSmrg while (!isItTimeToYield) 46005b261ecSmrg { 46105b261ecSmrg if (*icheck[0] != *icheck[1]) 46205b261ecSmrg { 46305b261ecSmrg ProcessInputEvents(); 46405b261ecSmrg FlushIfCriticalOutputPending(); 46505b261ecSmrg } 46605b261ecSmrg#ifdef SMART_SCHEDULE 46705b261ecSmrg if (!SmartScheduleDisable && 46805b261ecSmrg (SmartScheduleTime - start_tick) >= SmartScheduleSlice) 46905b261ecSmrg { 47005b261ecSmrg /* Penalize clients which consume ticks */ 47105b261ecSmrg if (client->smart_priority > SMART_MIN_PRIORITY) 47205b261ecSmrg client->smart_priority--; 47305b261ecSmrg break; 47405b261ecSmrg } 47505b261ecSmrg#endif 47605b261ecSmrg /* now, finally, deal with client requests */ 47705b261ecSmrg 47805b261ecSmrg result = ReadRequestFromClient(client); 47905b261ecSmrg if (result <= 0) 48005b261ecSmrg { 48105b261ecSmrg if (result < 0) 48205b261ecSmrg CloseDownClient(client); 48305b261ecSmrg break; 48405b261ecSmrg } 48505b261ecSmrg 48605b261ecSmrg client->sequence++; 48705b261ecSmrg#ifdef DEBUG 48805b261ecSmrg if (client->requestLogIndex == MAX_REQUEST_LOG) 48905b261ecSmrg client->requestLogIndex = 0; 49005b261ecSmrg client->requestLog[client->requestLogIndex] = MAJOROP; 49105b261ecSmrg client->requestLogIndex++; 49205b261ecSmrg#endif 49305b261ecSmrg#ifdef XSERVER_DTRACE 49405b261ecSmrg XSERVER_REQUEST_START(GetRequestName(MAJOROP), MAJOROP, 49505b261ecSmrg ((xReq *)client->requestBuffer)->length, 49605b261ecSmrg client->index, client->requestBuffer); 49705b261ecSmrg#endif 49805b261ecSmrg if (result > (maxBigRequestSize << 2)) 49905b261ecSmrg result = BadLength; 50005b261ecSmrg else { 50105b261ecSmrg XaceHook(XACE_AUDIT_BEGIN, client); 50205b261ecSmrg result = (* client->requestVector[MAJOROP])(client); 50305b261ecSmrg XaceHook(XACE_AUDIT_END, client, result); 50405b261ecSmrg } 50505b261ecSmrg#ifdef XSERVER_DTRACE 50605b261ecSmrg XSERVER_REQUEST_DONE(GetRequestName(MAJOROP), MAJOROP, 50705b261ecSmrg client->sequence, client->index, result); 50805b261ecSmrg#endif 50905b261ecSmrg 51005b261ecSmrg if (result != Success) 51105b261ecSmrg { 51205b261ecSmrg if (client->noClientException != Success) 51305b261ecSmrg CloseDownClient(client); 51405b261ecSmrg else 51505b261ecSmrg SendErrorToClient(client, MAJOROP, 51605b261ecSmrg MinorOpcodeOfRequest(client), 51705b261ecSmrg client->errorValue, result); 51805b261ecSmrg break; 51905b261ecSmrg } 52005b261ecSmrg#ifdef DAMAGEEXT 52105b261ecSmrg FlushIfCriticalOutputPending (); 52205b261ecSmrg#endif 52305b261ecSmrg } 52405b261ecSmrg FlushAllOutput(); 52505b261ecSmrg#ifdef SMART_SCHEDULE 52605b261ecSmrg client = clients[clientReady[nready]]; 52705b261ecSmrg if (client) 52805b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 52905b261ecSmrg#endif 53005b261ecSmrg requestingClient = NULL; 53105b261ecSmrg } 53205b261ecSmrg dispatchException &= ~DE_PRIORITYCHANGE; 53305b261ecSmrg } 53405b261ecSmrg#if defined(DDXBEFORERESET) 53505b261ecSmrg ddxBeforeReset (); 53605b261ecSmrg#endif 53705b261ecSmrg KillAllClients(); 53805b261ecSmrg DEALLOCATE_LOCAL(clientReady); 53905b261ecSmrg dispatchException &= ~DE_RESET; 54005b261ecSmrg#ifdef XSERVER_DTRACE 54105b261ecSmrg FreeRequestNames(); 54205b261ecSmrg#endif 54305b261ecSmrg} 54405b261ecSmrg 54505b261ecSmrg#undef MAJOROP 54605b261ecSmrg 54705b261ecSmrg_X_EXPORT int 54805b261ecSmrgProcBadRequest(ClientPtr client) 54905b261ecSmrg{ 55005b261ecSmrg return (BadRequest); 55105b261ecSmrg} 55205b261ecSmrg 55305b261ecSmrgint 55405b261ecSmrgProcCreateWindow(ClientPtr client) 55505b261ecSmrg{ 55605b261ecSmrg WindowPtr pParent, pWin; 55705b261ecSmrg REQUEST(xCreateWindowReq); 55805b261ecSmrg int result, len, rc; 55905b261ecSmrg 56005b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateWindowReq); 56105b261ecSmrg 56205b261ecSmrg LEGAL_NEW_RESOURCE(stuff->wid, client); 56305b261ecSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess); 56405b261ecSmrg if (rc != Success) 56505b261ecSmrg return rc; 56605b261ecSmrg len = client->req_len - (sizeof(xCreateWindowReq) >> 2); 56705b261ecSmrg if (Ones(stuff->mask) != len) 56805b261ecSmrg return BadLength; 56905b261ecSmrg if (!stuff->width || !stuff->height) 57005b261ecSmrg { 57105b261ecSmrg client->errorValue = 0; 57205b261ecSmrg return BadValue; 57305b261ecSmrg } 57405b261ecSmrg pWin = CreateWindow(stuff->wid, pParent, stuff->x, 57505b261ecSmrg stuff->y, stuff->width, stuff->height, 57605b261ecSmrg stuff->borderWidth, stuff->class, 57705b261ecSmrg stuff->mask, (XID *) &stuff[1], 57805b261ecSmrg (int)stuff->depth, 57905b261ecSmrg client, stuff->visual, &result); 58005b261ecSmrg if (pWin) 58105b261ecSmrg { 58205b261ecSmrg Mask mask = pWin->eventMask; 58305b261ecSmrg 58405b261ecSmrg pWin->eventMask = 0; /* subterfuge in case AddResource fails */ 58505b261ecSmrg if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin)) 58605b261ecSmrg return BadAlloc; 58705b261ecSmrg pWin->eventMask = mask; 58805b261ecSmrg } 58905b261ecSmrg if (client->noClientException != Success) 59005b261ecSmrg return(client->noClientException); 59105b261ecSmrg else 59205b261ecSmrg return(result); 59305b261ecSmrg} 59405b261ecSmrg 59505b261ecSmrgint 59605b261ecSmrgProcChangeWindowAttributes(ClientPtr client) 59705b261ecSmrg{ 59805b261ecSmrg WindowPtr pWin; 59905b261ecSmrg REQUEST(xChangeWindowAttributesReq); 60005b261ecSmrg int result; 60105b261ecSmrg int len, rc; 60205b261ecSmrg 60305b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); 60405b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 60505b261ecSmrg if (rc != Success) 60605b261ecSmrg return rc; 60705b261ecSmrg len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2); 60805b261ecSmrg if (len != Ones(stuff->valueMask)) 60905b261ecSmrg return BadLength; 61005b261ecSmrg result = ChangeWindowAttributes(pWin, 61105b261ecSmrg stuff->valueMask, 61205b261ecSmrg (XID *) &stuff[1], 61305b261ecSmrg client); 61405b261ecSmrg if (client->noClientException != Success) 61505b261ecSmrg return(client->noClientException); 61605b261ecSmrg else 61705b261ecSmrg return(result); 61805b261ecSmrg} 61905b261ecSmrg 62005b261ecSmrgint 62105b261ecSmrgProcGetWindowAttributes(ClientPtr client) 62205b261ecSmrg{ 62305b261ecSmrg WindowPtr pWin; 62405b261ecSmrg REQUEST(xResourceReq); 62505b261ecSmrg xGetWindowAttributesReply wa; 62605b261ecSmrg int rc; 62705b261ecSmrg 62805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 62905b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 63005b261ecSmrg if (rc != Success) 63105b261ecSmrg return rc; 63205b261ecSmrg GetWindowAttributes(pWin, client, &wa); 63305b261ecSmrg WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); 63405b261ecSmrg return(client->noClientException); 63505b261ecSmrg} 63605b261ecSmrg 63705b261ecSmrgint 63805b261ecSmrgProcDestroyWindow(ClientPtr client) 63905b261ecSmrg{ 64005b261ecSmrg WindowPtr pWin; 64105b261ecSmrg REQUEST(xResourceReq); 64205b261ecSmrg int rc; 64305b261ecSmrg 64405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 64505b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 64605b261ecSmrg if (rc != Success) 64705b261ecSmrg return rc; 64805b261ecSmrg if (pWin->parent) 64905b261ecSmrg FreeResource(stuff->id, RT_NONE); 65005b261ecSmrg return(client->noClientException); 65105b261ecSmrg} 65205b261ecSmrg 65305b261ecSmrgint 65405b261ecSmrgProcDestroySubwindows(ClientPtr client) 65505b261ecSmrg{ 65605b261ecSmrg WindowPtr pWin; 65705b261ecSmrg REQUEST(xResourceReq); 65805b261ecSmrg int rc; 65905b261ecSmrg 66005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 66105b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 66205b261ecSmrg if (rc != Success) 66305b261ecSmrg return rc; 66405b261ecSmrg DestroySubwindows(pWin, client); 66505b261ecSmrg return(client->noClientException); 66605b261ecSmrg} 66705b261ecSmrg 66805b261ecSmrgint 66905b261ecSmrgProcChangeSaveSet(ClientPtr client) 67005b261ecSmrg{ 67105b261ecSmrg WindowPtr pWin; 67205b261ecSmrg REQUEST(xChangeSaveSetReq); 67305b261ecSmrg int result, rc; 67405b261ecSmrg 67505b261ecSmrg REQUEST_SIZE_MATCH(xChangeSaveSetReq); 67605b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); 67705b261ecSmrg if (rc != Success) 67805b261ecSmrg return rc; 67905b261ecSmrg if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) 68005b261ecSmrg return BadMatch; 68105b261ecSmrg if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) 68205b261ecSmrg { 68305b261ecSmrg result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); 68405b261ecSmrg if (client->noClientException != Success) 68505b261ecSmrg return(client->noClientException); 68605b261ecSmrg else 68705b261ecSmrg return(result); 68805b261ecSmrg } 68905b261ecSmrg else 69005b261ecSmrg { 69105b261ecSmrg client->errorValue = stuff->mode; 69205b261ecSmrg return( BadValue ); 69305b261ecSmrg } 69405b261ecSmrg} 69505b261ecSmrg 69605b261ecSmrgint 69705b261ecSmrgProcReparentWindow(ClientPtr client) 69805b261ecSmrg{ 69905b261ecSmrg WindowPtr pWin, pParent; 70005b261ecSmrg REQUEST(xReparentWindowReq); 70105b261ecSmrg int result, rc; 70205b261ecSmrg 70305b261ecSmrg REQUEST_SIZE_MATCH(xReparentWindowReq); 70405b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 70505b261ecSmrg if (rc != Success) 70605b261ecSmrg return rc; 70705b261ecSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess); 70805b261ecSmrg if (rc != Success) 70905b261ecSmrg return rc; 71005b261ecSmrg if (SAME_SCREENS(pWin->drawable, pParent->drawable)) 71105b261ecSmrg { 71205b261ecSmrg if ((pWin->backgroundState == ParentRelative) && 71305b261ecSmrg (pParent->drawable.depth != pWin->drawable.depth)) 71405b261ecSmrg return BadMatch; 71505b261ecSmrg if ((pWin->drawable.class != InputOnly) && 71605b261ecSmrg (pParent->drawable.class == InputOnly)) 71705b261ecSmrg return BadMatch; 71805b261ecSmrg result = ReparentWindow(pWin, pParent, 71905b261ecSmrg (short)stuff->x, (short)stuff->y, client); 72005b261ecSmrg if (client->noClientException != Success) 72105b261ecSmrg return(client->noClientException); 72205b261ecSmrg else 72305b261ecSmrg return(result); 72405b261ecSmrg } 72505b261ecSmrg else 72605b261ecSmrg return (BadMatch); 72705b261ecSmrg} 72805b261ecSmrg 72905b261ecSmrgint 73005b261ecSmrgProcMapWindow(ClientPtr client) 73105b261ecSmrg{ 73205b261ecSmrg WindowPtr pWin; 73305b261ecSmrg REQUEST(xResourceReq); 73405b261ecSmrg int rc; 73505b261ecSmrg 73605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 73705b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 73805b261ecSmrg if (rc != Success) 73905b261ecSmrg return rc; 74005b261ecSmrg MapWindow(pWin, client); 74105b261ecSmrg /* update cache to say it is mapped */ 74205b261ecSmrg return(client->noClientException); 74305b261ecSmrg} 74405b261ecSmrg 74505b261ecSmrgint 74605b261ecSmrgProcMapSubwindows(ClientPtr client) 74705b261ecSmrg{ 74805b261ecSmrg WindowPtr pWin; 74905b261ecSmrg REQUEST(xResourceReq); 75005b261ecSmrg int rc; 75105b261ecSmrg 75205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 75305b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 75405b261ecSmrg if (rc != Success) 75505b261ecSmrg return rc; 75605b261ecSmrg MapSubwindows(pWin, client); 75705b261ecSmrg /* update cache to say it is mapped */ 75805b261ecSmrg return(client->noClientException); 75905b261ecSmrg} 76005b261ecSmrg 76105b261ecSmrgint 76205b261ecSmrgProcUnmapWindow(ClientPtr client) 76305b261ecSmrg{ 76405b261ecSmrg WindowPtr pWin; 76505b261ecSmrg REQUEST(xResourceReq); 76605b261ecSmrg int rc; 76705b261ecSmrg 76805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 76905b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 77005b261ecSmrg if (rc != Success) 77105b261ecSmrg return rc; 77205b261ecSmrg UnmapWindow(pWin, FALSE); 77305b261ecSmrg /* update cache to say it is mapped */ 77405b261ecSmrg return(client->noClientException); 77505b261ecSmrg} 77605b261ecSmrg 77705b261ecSmrgint 77805b261ecSmrgProcUnmapSubwindows(ClientPtr client) 77905b261ecSmrg{ 78005b261ecSmrg WindowPtr pWin; 78105b261ecSmrg REQUEST(xResourceReq); 78205b261ecSmrg int rc; 78305b261ecSmrg 78405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 78505b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 78605b261ecSmrg if (rc != Success) 78705b261ecSmrg return rc; 78805b261ecSmrg UnmapSubwindows(pWin); 78905b261ecSmrg return(client->noClientException); 79005b261ecSmrg} 79105b261ecSmrg 79205b261ecSmrgint 79305b261ecSmrgProcConfigureWindow(ClientPtr client) 79405b261ecSmrg{ 79505b261ecSmrg WindowPtr pWin; 79605b261ecSmrg REQUEST(xConfigureWindowReq); 79705b261ecSmrg int result; 79805b261ecSmrg int len, rc; 79905b261ecSmrg 80005b261ecSmrg REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); 80105b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 80205b261ecSmrg if (rc != Success) 80305b261ecSmrg return rc; 80405b261ecSmrg len = client->req_len - (sizeof(xConfigureWindowReq) >> 2); 80505b261ecSmrg if (Ones((Mask)stuff->mask) != len) 80605b261ecSmrg return BadLength; 80705b261ecSmrg result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 80805b261ecSmrg client); 80905b261ecSmrg if (client->noClientException != Success) 81005b261ecSmrg return(client->noClientException); 81105b261ecSmrg else 81205b261ecSmrg return(result); 81305b261ecSmrg} 81405b261ecSmrg 81505b261ecSmrgint 81605b261ecSmrgProcCirculateWindow(ClientPtr client) 81705b261ecSmrg{ 81805b261ecSmrg WindowPtr pWin; 81905b261ecSmrg REQUEST(xCirculateWindowReq); 82005b261ecSmrg int rc; 82105b261ecSmrg 82205b261ecSmrg REQUEST_SIZE_MATCH(xCirculateWindowReq); 82305b261ecSmrg if ((stuff->direction != RaiseLowest) && 82405b261ecSmrg (stuff->direction != LowerHighest)) 82505b261ecSmrg { 82605b261ecSmrg client->errorValue = stuff->direction; 82705b261ecSmrg return BadValue; 82805b261ecSmrg } 82905b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 83005b261ecSmrg if (rc != Success) 83105b261ecSmrg return rc; 83205b261ecSmrg CirculateWindow(pWin, (int)stuff->direction, client); 83305b261ecSmrg return(client->noClientException); 83405b261ecSmrg} 83505b261ecSmrg 83605b261ecSmrgstatic int 83705b261ecSmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep) 83805b261ecSmrg{ 83905b261ecSmrg DrawablePtr pDraw; 84005b261ecSmrg int rc; 84105b261ecSmrg REQUEST(xResourceReq); 84205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 84305b261ecSmrg 84405b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixReadAccess); 84505b261ecSmrg if (rc != Success) 84605b261ecSmrg return rc; 84705b261ecSmrg 84805b261ecSmrg rep->type = X_Reply; 84905b261ecSmrg rep->length = 0; 85005b261ecSmrg rep->sequenceNumber = client->sequence; 85105b261ecSmrg rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id; 85205b261ecSmrg rep->depth = pDraw->depth; 85305b261ecSmrg rep->width = pDraw->width; 85405b261ecSmrg rep->height = pDraw->height; 85505b261ecSmrg 85605b261ecSmrg /* XXX - Because the pixmap-implementation of the multibuffer extension 85705b261ecSmrg * may have the buffer-id's drawable resource value be a pointer 85805b261ecSmrg * to the buffer's window instead of the buffer itself 85905b261ecSmrg * (this happens if the buffer is the displayed buffer), 86005b261ecSmrg * we also have to check that the id matches before we can 86105b261ecSmrg * truly say that it is a DRAWABLE_WINDOW. 86205b261ecSmrg */ 86305b261ecSmrg 86405b261ecSmrg if ((pDraw->type == UNDRAWABLE_WINDOW) || 86505b261ecSmrg ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id))) 86605b261ecSmrg { 86705b261ecSmrg WindowPtr pWin = (WindowPtr)pDraw; 86805b261ecSmrg rep->x = pWin->origin.x - wBorderWidth (pWin); 86905b261ecSmrg rep->y = pWin->origin.y - wBorderWidth (pWin); 87005b261ecSmrg rep->borderWidth = pWin->borderWidth; 87105b261ecSmrg } 87205b261ecSmrg else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */ 87305b261ecSmrg { 87405b261ecSmrg rep->x = rep->y = rep->borderWidth = 0; 87505b261ecSmrg } 87605b261ecSmrg 87705b261ecSmrg return Success; 87805b261ecSmrg} 87905b261ecSmrg 88005b261ecSmrg 88105b261ecSmrgint 88205b261ecSmrgProcGetGeometry(ClientPtr client) 88305b261ecSmrg{ 88405b261ecSmrg xGetGeometryReply rep; 88505b261ecSmrg int status; 88605b261ecSmrg 88705b261ecSmrg if ((status = GetGeometry(client, &rep)) != Success) 88805b261ecSmrg return status; 88905b261ecSmrg 89005b261ecSmrg WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); 89105b261ecSmrg return(client->noClientException); 89205b261ecSmrg} 89305b261ecSmrg 89405b261ecSmrg 89505b261ecSmrgint 89605b261ecSmrgProcQueryTree(ClientPtr client) 89705b261ecSmrg{ 89805b261ecSmrg xQueryTreeReply reply; 89905b261ecSmrg int rc, numChildren = 0; 90005b261ecSmrg WindowPtr pChild, pWin, pHead; 90105b261ecSmrg Window *childIDs = (Window *)NULL; 90205b261ecSmrg REQUEST(xResourceReq); 90305b261ecSmrg 90405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 90505b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 90605b261ecSmrg if (rc != Success) 90705b261ecSmrg return rc; 90805b261ecSmrg reply.type = X_Reply; 90905b261ecSmrg reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; 91005b261ecSmrg reply.sequenceNumber = client->sequence; 91105b261ecSmrg if (pWin->parent) 91205b261ecSmrg reply.parent = pWin->parent->drawable.id; 91305b261ecSmrg else 91405b261ecSmrg reply.parent = (Window)None; 91505b261ecSmrg pHead = RealChildHead(pWin); 91605b261ecSmrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 91705b261ecSmrg numChildren++; 91805b261ecSmrg if (numChildren) 91905b261ecSmrg { 92005b261ecSmrg int curChild = 0; 92105b261ecSmrg 92205b261ecSmrg childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window)); 92305b261ecSmrg if (!childIDs) 92405b261ecSmrg return BadAlloc; 92505b261ecSmrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 92605b261ecSmrg childIDs[curChild++] = pChild->drawable.id; 92705b261ecSmrg } 92805b261ecSmrg 92905b261ecSmrg reply.nChildren = numChildren; 93005b261ecSmrg reply.length = (numChildren * sizeof(Window)) >> 2; 93105b261ecSmrg 93205b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); 93305b261ecSmrg if (numChildren) 93405b261ecSmrg { 93505b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 93605b261ecSmrg WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs); 93705b261ecSmrg DEALLOCATE_LOCAL(childIDs); 93805b261ecSmrg } 93905b261ecSmrg 94005b261ecSmrg return(client->noClientException); 94105b261ecSmrg} 94205b261ecSmrg 94305b261ecSmrgint 94405b261ecSmrgProcInternAtom(ClientPtr client) 94505b261ecSmrg{ 94605b261ecSmrg Atom atom; 94705b261ecSmrg char *tchar; 94805b261ecSmrg REQUEST(xInternAtomReq); 94905b261ecSmrg 95005b261ecSmrg REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); 95105b261ecSmrg if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) 95205b261ecSmrg { 95305b261ecSmrg client->errorValue = stuff->onlyIfExists; 95405b261ecSmrg return(BadValue); 95505b261ecSmrg } 95605b261ecSmrg tchar = (char *) &stuff[1]; 95705b261ecSmrg atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); 95805b261ecSmrg if (atom != BAD_RESOURCE) 95905b261ecSmrg { 96005b261ecSmrg xInternAtomReply reply; 96105b261ecSmrg reply.type = X_Reply; 96205b261ecSmrg reply.length = 0; 96305b261ecSmrg reply.sequenceNumber = client->sequence; 96405b261ecSmrg reply.atom = atom; 96505b261ecSmrg WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); 96605b261ecSmrg return(client->noClientException); 96705b261ecSmrg } 96805b261ecSmrg else 96905b261ecSmrg return (BadAlloc); 97005b261ecSmrg} 97105b261ecSmrg 97205b261ecSmrgint 97305b261ecSmrgProcGetAtomName(ClientPtr client) 97405b261ecSmrg{ 97505b261ecSmrg char *str; 97605b261ecSmrg xGetAtomNameReply reply; 97705b261ecSmrg int len; 97805b261ecSmrg REQUEST(xResourceReq); 97905b261ecSmrg 98005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 98105b261ecSmrg if ( (str = NameForAtom(stuff->id)) ) 98205b261ecSmrg { 98305b261ecSmrg len = strlen(str); 98405b261ecSmrg reply.type = X_Reply; 98505b261ecSmrg reply.length = (len + 3) >> 2; 98605b261ecSmrg reply.sequenceNumber = client->sequence; 98705b261ecSmrg reply.nameLength = len; 98805b261ecSmrg WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); 98905b261ecSmrg (void)WriteToClient(client, len, str); 99005b261ecSmrg return(client->noClientException); 99105b261ecSmrg } 99205b261ecSmrg else 99305b261ecSmrg { 99405b261ecSmrg client->errorValue = stuff->id; 99505b261ecSmrg return (BadAtom); 99605b261ecSmrg } 99705b261ecSmrg} 99805b261ecSmrg 99905b261ecSmrgint 100005b261ecSmrgProcSetSelectionOwner(ClientPtr client) 100105b261ecSmrg{ 100205b261ecSmrg WindowPtr pWin; 100305b261ecSmrg TimeStamp time; 100405b261ecSmrg REQUEST(xSetSelectionOwnerReq); 100505b261ecSmrg 100605b261ecSmrg REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); 100705b261ecSmrg UpdateCurrentTime(); 100805b261ecSmrg time = ClientTimeToServerTime(stuff->time); 100905b261ecSmrg 101005b261ecSmrg /* If the client's time stamp is in the future relative to the server's 101105b261ecSmrg time stamp, do not set the selection, just return success. */ 101205b261ecSmrg if (CompareTimeStamps(time, currentTime) == LATER) 101305b261ecSmrg return Success; 101405b261ecSmrg if (stuff->window != None) 101505b261ecSmrg { 101605b261ecSmrg int rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); 101705b261ecSmrg if (rc != Success) 101805b261ecSmrg return rc; 101905b261ecSmrg } 102005b261ecSmrg else 102105b261ecSmrg pWin = (WindowPtr)None; 102205b261ecSmrg if (ValidAtom(stuff->selection)) 102305b261ecSmrg { 102405b261ecSmrg int i = 0; 102505b261ecSmrg 102605b261ecSmrg /* 102705b261ecSmrg * First, see if the selection is already set... 102805b261ecSmrg */ 102905b261ecSmrg while ((i < NumCurrentSelections) && 103005b261ecSmrg CurrentSelections[i].selection != stuff->selection) 103105b261ecSmrg i++; 103205b261ecSmrg if (i < NumCurrentSelections) 103305b261ecSmrg { 103405b261ecSmrg xEvent event; 103505b261ecSmrg 103605b261ecSmrg /* If the timestamp in client's request is in the past relative 103705b261ecSmrg to the time stamp indicating the last time the owner of the 103805b261ecSmrg selection was set, do not set the selection, just return 103905b261ecSmrg success. */ 104005b261ecSmrg if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged) 104105b261ecSmrg == EARLIER) 104205b261ecSmrg return Success; 104305b261ecSmrg if (CurrentSelections[i].client && 104405b261ecSmrg (!pWin || (CurrentSelections[i].client != client))) 104505b261ecSmrg { 104605b261ecSmrg event.u.u.type = SelectionClear; 104705b261ecSmrg event.u.selectionClear.time = time.milliseconds; 104805b261ecSmrg event.u.selectionClear.window = CurrentSelections[i].window; 104905b261ecSmrg event.u.selectionClear.atom = CurrentSelections[i].selection; 105005b261ecSmrg (void) TryClientEvents (CurrentSelections[i].client, &event, 1, 105105b261ecSmrg NoEventMask, NoEventMask /* CantBeFiltered */, 105205b261ecSmrg NullGrab); 105305b261ecSmrg } 105405b261ecSmrg } 105505b261ecSmrg else 105605b261ecSmrg { 105705b261ecSmrg /* 105805b261ecSmrg * It doesn't exist, so add it... 105905b261ecSmrg */ 106005b261ecSmrg Selection *newsels; 106105b261ecSmrg 106205b261ecSmrg if (i == 0) 106305b261ecSmrg newsels = (Selection *)xalloc(sizeof(Selection)); 106405b261ecSmrg else 106505b261ecSmrg newsels = (Selection *)xrealloc(CurrentSelections, 106605b261ecSmrg (NumCurrentSelections + 1) * sizeof(Selection)); 106705b261ecSmrg if (!newsels) 106805b261ecSmrg return BadAlloc; 106905b261ecSmrg NumCurrentSelections++; 107005b261ecSmrg CurrentSelections = newsels; 107105b261ecSmrg CurrentSelections[i].selection = stuff->selection; 107205b261ecSmrg } 107305b261ecSmrg CurrentSelections[i].lastTimeChanged = time; 107405b261ecSmrg CurrentSelections[i].window = stuff->window; 107505b261ecSmrg CurrentSelections[i].pWin = pWin; 107605b261ecSmrg CurrentSelections[i].client = (pWin ? client : NullClient); 107705b261ecSmrg if (SelectionCallback) 107805b261ecSmrg { 107905b261ecSmrg SelectionInfoRec info; 108005b261ecSmrg 108105b261ecSmrg info.selection = &CurrentSelections[i]; 108205b261ecSmrg info.kind= SelectionSetOwner; 108305b261ecSmrg CallCallbacks(&SelectionCallback, &info); 108405b261ecSmrg } 108505b261ecSmrg return (client->noClientException); 108605b261ecSmrg } 108705b261ecSmrg else 108805b261ecSmrg { 108905b261ecSmrg client->errorValue = stuff->selection; 109005b261ecSmrg return (BadAtom); 109105b261ecSmrg } 109205b261ecSmrg} 109305b261ecSmrg 109405b261ecSmrgint 109505b261ecSmrgProcGetSelectionOwner(ClientPtr client) 109605b261ecSmrg{ 109705b261ecSmrg REQUEST(xResourceReq); 109805b261ecSmrg 109905b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 110005b261ecSmrg if (ValidAtom(stuff->id)) 110105b261ecSmrg { 110205b261ecSmrg int i; 110305b261ecSmrg xGetSelectionOwnerReply reply; 110405b261ecSmrg 110505b261ecSmrg i = 0; 110605b261ecSmrg while ((i < NumCurrentSelections) && 110705b261ecSmrg CurrentSelections[i].selection != stuff->id) i++; 110805b261ecSmrg reply.type = X_Reply; 110905b261ecSmrg reply.length = 0; 111005b261ecSmrg reply.sequenceNumber = client->sequence; 111105b261ecSmrg if (i < NumCurrentSelections) 111205b261ecSmrg reply.owner = CurrentSelections[i].window; 111305b261ecSmrg else 111405b261ecSmrg reply.owner = None; 111505b261ecSmrg WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply); 111605b261ecSmrg return(client->noClientException); 111705b261ecSmrg } 111805b261ecSmrg else 111905b261ecSmrg { 112005b261ecSmrg client->errorValue = stuff->id; 112105b261ecSmrg return (BadAtom); 112205b261ecSmrg } 112305b261ecSmrg} 112405b261ecSmrg 112505b261ecSmrgint 112605b261ecSmrgProcConvertSelection(ClientPtr client) 112705b261ecSmrg{ 112805b261ecSmrg Bool paramsOkay; 112905b261ecSmrg xEvent event; 113005b261ecSmrg WindowPtr pWin; 113105b261ecSmrg REQUEST(xConvertSelectionReq); 113205b261ecSmrg int rc; 113305b261ecSmrg 113405b261ecSmrg REQUEST_SIZE_MATCH(xConvertSelectionReq); 113505b261ecSmrg rc = dixLookupWindow(&pWin, stuff->requestor, client, DixReadAccess); 113605b261ecSmrg if (rc != Success) 113705b261ecSmrg return rc; 113805b261ecSmrg 113905b261ecSmrg paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target)); 114005b261ecSmrg if (stuff->property != None) 114105b261ecSmrg paramsOkay &= ValidAtom(stuff->property); 114205b261ecSmrg if (paramsOkay) 114305b261ecSmrg { 114405b261ecSmrg int i; 114505b261ecSmrg 114605b261ecSmrg i = 0; 114705b261ecSmrg while ((i < NumCurrentSelections) && 114805b261ecSmrg CurrentSelections[i].selection != stuff->selection) i++; 114905b261ecSmrg if ((i < NumCurrentSelections) && 115005b261ecSmrg (CurrentSelections[i].window != None) && 115105b261ecSmrg XaceHook(XACE_RESOURCE_ACCESS, client, 115205b261ecSmrg CurrentSelections[i].window, RT_WINDOW, 115305b261ecSmrg DixReadAccess, CurrentSelections[i].pWin)) 115405b261ecSmrg { 115505b261ecSmrg event.u.u.type = SelectionRequest; 115605b261ecSmrg event.u.selectionRequest.time = stuff->time; 115705b261ecSmrg event.u.selectionRequest.owner = 115805b261ecSmrg CurrentSelections[i].window; 115905b261ecSmrg event.u.selectionRequest.requestor = stuff->requestor; 116005b261ecSmrg event.u.selectionRequest.selection = stuff->selection; 116105b261ecSmrg event.u.selectionRequest.target = stuff->target; 116205b261ecSmrg event.u.selectionRequest.property = stuff->property; 116305b261ecSmrg if (TryClientEvents( 116405b261ecSmrg CurrentSelections[i].client, &event, 1, NoEventMask, 116505b261ecSmrg NoEventMask /* CantBeFiltered */, NullGrab)) 116605b261ecSmrg return (client->noClientException); 116705b261ecSmrg } 116805b261ecSmrg event.u.u.type = SelectionNotify; 116905b261ecSmrg event.u.selectionNotify.time = stuff->time; 117005b261ecSmrg event.u.selectionNotify.requestor = stuff->requestor; 117105b261ecSmrg event.u.selectionNotify.selection = stuff->selection; 117205b261ecSmrg event.u.selectionNotify.target = stuff->target; 117305b261ecSmrg event.u.selectionNotify.property = None; 117405b261ecSmrg (void) TryClientEvents(client, &event, 1, NoEventMask, 117505b261ecSmrg NoEventMask /* CantBeFiltered */, NullGrab); 117605b261ecSmrg return (client->noClientException); 117705b261ecSmrg } 117805b261ecSmrg else 117905b261ecSmrg { 118005b261ecSmrg client->errorValue = stuff->property; 118105b261ecSmrg return (BadAtom); 118205b261ecSmrg } 118305b261ecSmrg} 118405b261ecSmrg 118505b261ecSmrgint 118605b261ecSmrgProcGrabServer(ClientPtr client) 118705b261ecSmrg{ 118805b261ecSmrg REQUEST_SIZE_MATCH(xReq); 118905b261ecSmrg if (grabState != GrabNone && client != grabClient) 119005b261ecSmrg { 119105b261ecSmrg ResetCurrentRequest(client); 119205b261ecSmrg client->sequence--; 119305b261ecSmrg BITSET(grabWaiters, client->index); 119405b261ecSmrg IgnoreClient(client); 119505b261ecSmrg return(client->noClientException); 119605b261ecSmrg } 119705b261ecSmrg OnlyListenToOneClient(client); 119805b261ecSmrg grabState = GrabKickout; 119905b261ecSmrg grabClient = client; 120005b261ecSmrg 120105b261ecSmrg if (ServerGrabCallback) 120205b261ecSmrg { 120305b261ecSmrg ServerGrabInfoRec grabinfo; 120405b261ecSmrg grabinfo.client = client; 120505b261ecSmrg grabinfo.grabstate = SERVER_GRABBED; 120605b261ecSmrg CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 120705b261ecSmrg } 120805b261ecSmrg 120905b261ecSmrg return(client->noClientException); 121005b261ecSmrg} 121105b261ecSmrg 121205b261ecSmrgstatic void 121305b261ecSmrgUngrabServer(ClientPtr client) 121405b261ecSmrg{ 121505b261ecSmrg int i; 121605b261ecSmrg 121705b261ecSmrg grabState = GrabNone; 121805b261ecSmrg ListenToAllClients(); 121905b261ecSmrg for (i = mskcnt; --i >= 0 && !grabWaiters[i]; ) 122005b261ecSmrg ; 122105b261ecSmrg if (i >= 0) 122205b261ecSmrg { 122305b261ecSmrg i <<= 5; 122405b261ecSmrg while (!GETBIT(grabWaiters, i)) 122505b261ecSmrg i++; 122605b261ecSmrg BITCLEAR(grabWaiters, i); 122705b261ecSmrg AttendClient(clients[i]); 122805b261ecSmrg } 122905b261ecSmrg 123005b261ecSmrg if (ServerGrabCallback) 123105b261ecSmrg { 123205b261ecSmrg ServerGrabInfoRec grabinfo; 123305b261ecSmrg grabinfo.client = client; 123405b261ecSmrg grabinfo.grabstate = SERVER_UNGRABBED; 123505b261ecSmrg CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 123605b261ecSmrg } 123705b261ecSmrg} 123805b261ecSmrg 123905b261ecSmrgint 124005b261ecSmrgProcUngrabServer(ClientPtr client) 124105b261ecSmrg{ 124205b261ecSmrg REQUEST_SIZE_MATCH(xReq); 124305b261ecSmrg UngrabServer(client); 124405b261ecSmrg return(client->noClientException); 124505b261ecSmrg} 124605b261ecSmrg 124705b261ecSmrgint 124805b261ecSmrgProcTranslateCoords(ClientPtr client) 124905b261ecSmrg{ 125005b261ecSmrg REQUEST(xTranslateCoordsReq); 125105b261ecSmrg 125205b261ecSmrg WindowPtr pWin, pDst; 125305b261ecSmrg xTranslateCoordsReply rep; 125405b261ecSmrg int rc; 125505b261ecSmrg 125605b261ecSmrg REQUEST_SIZE_MATCH(xTranslateCoordsReq); 125705b261ecSmrg rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess); 125805b261ecSmrg if (rc != Success) 125905b261ecSmrg return rc; 126005b261ecSmrg rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess); 126105b261ecSmrg if (rc != Success) 126205b261ecSmrg return rc; 126305b261ecSmrg rep.type = X_Reply; 126405b261ecSmrg rep.length = 0; 126505b261ecSmrg rep.sequenceNumber = client->sequence; 126605b261ecSmrg if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) 126705b261ecSmrg { 126805b261ecSmrg rep.sameScreen = xFalse; 126905b261ecSmrg rep.child = None; 127005b261ecSmrg rep.dstX = rep.dstY = 0; 127105b261ecSmrg } 127205b261ecSmrg else 127305b261ecSmrg { 127405b261ecSmrg INT16 x, y; 127505b261ecSmrg rep.sameScreen = xTrue; 127605b261ecSmrg rep.child = None; 127705b261ecSmrg /* computing absolute coordinates -- adjust to destination later */ 127805b261ecSmrg x = pWin->drawable.x + stuff->srcX; 127905b261ecSmrg y = pWin->drawable.y + stuff->srcY; 128005b261ecSmrg pWin = pDst->firstChild; 128105b261ecSmrg while (pWin) 128205b261ecSmrg { 128305b261ecSmrg#ifdef SHAPE 128405b261ecSmrg BoxRec box; 128505b261ecSmrg#endif 128605b261ecSmrg if ((pWin->mapped) && 128705b261ecSmrg (x >= pWin->drawable.x - wBorderWidth (pWin)) && 128805b261ecSmrg (x < pWin->drawable.x + (int)pWin->drawable.width + 128905b261ecSmrg wBorderWidth (pWin)) && 129005b261ecSmrg (y >= pWin->drawable.y - wBorderWidth (pWin)) && 129105b261ecSmrg (y < pWin->drawable.y + (int)pWin->drawable.height + 129205b261ecSmrg wBorderWidth (pWin)) 129305b261ecSmrg#ifdef SHAPE 129405b261ecSmrg /* When a window is shaped, a further check 129505b261ecSmrg * is made to see if the point is inside 129605b261ecSmrg * borderSize 129705b261ecSmrg */ 129805b261ecSmrg && (!wBoundingShape(pWin) || 129905b261ecSmrg POINT_IN_REGION(pWin->drawable.pScreen, 130005b261ecSmrg &pWin->borderSize, x, y, &box)) 130105b261ecSmrg 130205b261ecSmrg && (!wInputShape(pWin) || 130305b261ecSmrg POINT_IN_REGION(pWin->drawable.pScreen, 130405b261ecSmrg wInputShape(pWin), 130505b261ecSmrg x - pWin->drawable.x, 130605b261ecSmrg y - pWin->drawable.y, &box)) 130705b261ecSmrg#endif 130805b261ecSmrg ) 130905b261ecSmrg { 131005b261ecSmrg rep.child = pWin->drawable.id; 131105b261ecSmrg pWin = (WindowPtr) NULL; 131205b261ecSmrg } 131305b261ecSmrg else 131405b261ecSmrg pWin = pWin->nextSib; 131505b261ecSmrg } 131605b261ecSmrg /* adjust to destination coordinates */ 131705b261ecSmrg rep.dstX = x - pDst->drawable.x; 131805b261ecSmrg rep.dstY = y - pDst->drawable.y; 131905b261ecSmrg } 132005b261ecSmrg WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); 132105b261ecSmrg return(client->noClientException); 132205b261ecSmrg} 132305b261ecSmrg 132405b261ecSmrgint 132505b261ecSmrgProcOpenFont(ClientPtr client) 132605b261ecSmrg{ 132705b261ecSmrg int err; 132805b261ecSmrg REQUEST(xOpenFontReq); 132905b261ecSmrg 133005b261ecSmrg REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); 133105b261ecSmrg client->errorValue = stuff->fid; 133205b261ecSmrg LEGAL_NEW_RESOURCE(stuff->fid, client); 133305b261ecSmrg err = OpenFont(client, stuff->fid, (Mask) 0, 133405b261ecSmrg stuff->nbytes, (char *)&stuff[1]); 133505b261ecSmrg if (err == Success) 133605b261ecSmrg { 133705b261ecSmrg return(client->noClientException); 133805b261ecSmrg } 133905b261ecSmrg else 134005b261ecSmrg return err; 134105b261ecSmrg} 134205b261ecSmrg 134305b261ecSmrgint 134405b261ecSmrgProcCloseFont(ClientPtr client) 134505b261ecSmrg{ 134605b261ecSmrg FontPtr pFont; 134705b261ecSmrg REQUEST(xResourceReq); 134805b261ecSmrg 134905b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 135005b261ecSmrg pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT, 135105b261ecSmrg DixDestroyAccess); 135205b261ecSmrg if ( pFont != (FontPtr)NULL) /* id was valid */ 135305b261ecSmrg { 135405b261ecSmrg FreeResource(stuff->id, RT_NONE); 135505b261ecSmrg return(client->noClientException); 135605b261ecSmrg } 135705b261ecSmrg else 135805b261ecSmrg { 135905b261ecSmrg client->errorValue = stuff->id; 136005b261ecSmrg return (BadFont); 136105b261ecSmrg } 136205b261ecSmrg} 136305b261ecSmrg 136405b261ecSmrgint 136505b261ecSmrgProcQueryFont(ClientPtr client) 136605b261ecSmrg{ 136705b261ecSmrg xQueryFontReply *reply; 136805b261ecSmrg FontPtr pFont; 136905b261ecSmrg GC *pGC; 137005b261ecSmrg REQUEST(xResourceReq); 137105b261ecSmrg 137205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 137305b261ecSmrg client->errorValue = stuff->id; /* EITHER font or gc */ 137405b261ecSmrg pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT, 137505b261ecSmrg DixReadAccess); 137605b261ecSmrg if (!pFont) 137705b261ecSmrg { 137805b261ecSmrg pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC, 137905b261ecSmrg DixReadAccess); 138005b261ecSmrg if (!pGC) 138105b261ecSmrg { 138205b261ecSmrg client->errorValue = stuff->id; 138305b261ecSmrg return(BadFont); /* procotol spec says only error is BadFont */ 138405b261ecSmrg } 138505b261ecSmrg pFont = pGC->font; 138605b261ecSmrg } 138705b261ecSmrg 138805b261ecSmrg { 138905b261ecSmrg xCharInfo *pmax = FONTINKMAX(pFont); 139005b261ecSmrg xCharInfo *pmin = FONTINKMIN(pFont); 139105b261ecSmrg int nprotoxcistructs; 139205b261ecSmrg int rlength; 139305b261ecSmrg 139405b261ecSmrg nprotoxcistructs = ( 139505b261ecSmrg pmax->rightSideBearing == pmin->rightSideBearing && 139605b261ecSmrg pmax->leftSideBearing == pmin->leftSideBearing && 139705b261ecSmrg pmax->descent == pmin->descent && 139805b261ecSmrg pmax->ascent == pmin->ascent && 139905b261ecSmrg pmax->characterWidth == pmin->characterWidth) ? 140005b261ecSmrg 0 : N2dChars(pFont); 140105b261ecSmrg 140205b261ecSmrg rlength = sizeof(xQueryFontReply) + 140305b261ecSmrg FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + 140405b261ecSmrg nprotoxcistructs * sizeof(xCharInfo); 140505b261ecSmrg reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength); 140605b261ecSmrg if(!reply) 140705b261ecSmrg { 140805b261ecSmrg return(BadAlloc); 140905b261ecSmrg } 141005b261ecSmrg 141105b261ecSmrg reply->type = X_Reply; 141205b261ecSmrg reply->length = (rlength - sizeof(xGenericReply)) >> 2; 141305b261ecSmrg reply->sequenceNumber = client->sequence; 141405b261ecSmrg QueryFont( pFont, reply, nprotoxcistructs); 141505b261ecSmrg 141605b261ecSmrg WriteReplyToClient(client, rlength, reply); 141705b261ecSmrg DEALLOCATE_LOCAL(reply); 141805b261ecSmrg return(client->noClientException); 141905b261ecSmrg } 142005b261ecSmrg} 142105b261ecSmrg 142205b261ecSmrgint 142305b261ecSmrgProcQueryTextExtents(ClientPtr client) 142405b261ecSmrg{ 142505b261ecSmrg REQUEST(xQueryTextExtentsReq); 142605b261ecSmrg xQueryTextExtentsReply reply; 142705b261ecSmrg FontPtr pFont; 142805b261ecSmrg GC *pGC; 142905b261ecSmrg ExtentInfoRec info; 143005b261ecSmrg unsigned long length; 143105b261ecSmrg 143205b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); 143305b261ecSmrg 143405b261ecSmrg pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT, 143505b261ecSmrg DixReadAccess); 143605b261ecSmrg if (!pFont) 143705b261ecSmrg { 143805b261ecSmrg pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC, 143905b261ecSmrg DixReadAccess); 144005b261ecSmrg if (!pGC) 144105b261ecSmrg { 144205b261ecSmrg client->errorValue = stuff->fid; 144305b261ecSmrg return(BadFont); 144405b261ecSmrg } 144505b261ecSmrg pFont = pGC->font; 144605b261ecSmrg } 144705b261ecSmrg length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2); 144805b261ecSmrg length = length << 1; 144905b261ecSmrg if (stuff->oddLength) 145005b261ecSmrg { 145105b261ecSmrg if (length == 0) 145205b261ecSmrg return(BadLength); 145305b261ecSmrg length--; 145405b261ecSmrg } 145505b261ecSmrg if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info)) 145605b261ecSmrg return(BadAlloc); 145705b261ecSmrg reply.type = X_Reply; 145805b261ecSmrg reply.length = 0; 145905b261ecSmrg reply.sequenceNumber = client->sequence; 146005b261ecSmrg reply.drawDirection = info.drawDirection; 146105b261ecSmrg reply.fontAscent = info.fontAscent; 146205b261ecSmrg reply.fontDescent = info.fontDescent; 146305b261ecSmrg reply.overallAscent = info.overallAscent; 146405b261ecSmrg reply.overallDescent = info.overallDescent; 146505b261ecSmrg reply.overallWidth = info.overallWidth; 146605b261ecSmrg reply.overallLeft = info.overallLeft; 146705b261ecSmrg reply.overallRight = info.overallRight; 146805b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); 146905b261ecSmrg return(client->noClientException); 147005b261ecSmrg} 147105b261ecSmrg 147205b261ecSmrgint 147305b261ecSmrgProcListFonts(ClientPtr client) 147405b261ecSmrg{ 147505b261ecSmrg REQUEST(xListFontsReq); 147605b261ecSmrg 147705b261ecSmrg REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); 147805b261ecSmrg 147905b261ecSmrg return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 148005b261ecSmrg stuff->maxNames); 148105b261ecSmrg} 148205b261ecSmrg 148305b261ecSmrgint 148405b261ecSmrgProcListFontsWithInfo(ClientPtr client) 148505b261ecSmrg{ 148605b261ecSmrg REQUEST(xListFontsWithInfoReq); 148705b261ecSmrg 148805b261ecSmrg REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); 148905b261ecSmrg 149005b261ecSmrg return StartListFontsWithInfo(client, stuff->nbytes, 149105b261ecSmrg (unsigned char *) &stuff[1], stuff->maxNames); 149205b261ecSmrg} 149305b261ecSmrg 149405b261ecSmrg/** 149505b261ecSmrg * 149605b261ecSmrg * \param value must conform to DeleteType 149705b261ecSmrg */ 149805b261ecSmrgint 149905b261ecSmrgdixDestroyPixmap(pointer value, XID pid) 150005b261ecSmrg{ 150105b261ecSmrg PixmapPtr pPixmap = (PixmapPtr)value; 150205b261ecSmrg return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 150305b261ecSmrg} 150405b261ecSmrg 150505b261ecSmrgint 150605b261ecSmrgProcCreatePixmap(ClientPtr client) 150705b261ecSmrg{ 150805b261ecSmrg PixmapPtr pMap; 150905b261ecSmrg DrawablePtr pDraw; 151005b261ecSmrg REQUEST(xCreatePixmapReq); 151105b261ecSmrg DepthPtr pDepth; 151205b261ecSmrg int i, rc; 151305b261ecSmrg 151405b261ecSmrg REQUEST_SIZE_MATCH(xCreatePixmapReq); 151505b261ecSmrg client->errorValue = stuff->pid; 151605b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 151705b261ecSmrg 151805b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 151905b261ecSmrg DixReadAccess); 152005b261ecSmrg if (rc != Success) 152105b261ecSmrg return rc; 152205b261ecSmrg 152305b261ecSmrg if (!stuff->width || !stuff->height) 152405b261ecSmrg { 152505b261ecSmrg client->errorValue = 0; 152605b261ecSmrg return BadValue; 152705b261ecSmrg } 152805b261ecSmrg if (stuff->width > 32767 || stuff->height > 32767) 152905b261ecSmrg { 153005b261ecSmrg /* It is allowed to try and allocate a pixmap which is larger than 153105b261ecSmrg * 32767 in either dimension. However, all of the framebuffer code 153205b261ecSmrg * is buggy and does not reliably draw to such big pixmaps, basically 153305b261ecSmrg * because the Region data structure operates with signed shorts 153405b261ecSmrg * for the rectangles in it. 153505b261ecSmrg * 153605b261ecSmrg * Furthermore, several places in the X server computes the 153705b261ecSmrg * size in bytes of the pixmap and tries to store it in an 153805b261ecSmrg * integer. This integer can overflow and cause the allocated size 153905b261ecSmrg * to be much smaller. 154005b261ecSmrg * 154105b261ecSmrg * So, such big pixmaps are rejected here with a BadAlloc 154205b261ecSmrg */ 154305b261ecSmrg return BadAlloc; 154405b261ecSmrg } 154505b261ecSmrg if (stuff->depth != 1) 154605b261ecSmrg { 154705b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 154805b261ecSmrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 154905b261ecSmrg if (pDepth->depth == stuff->depth) 155005b261ecSmrg goto CreatePmap; 155105b261ecSmrg client->errorValue = stuff->depth; 155205b261ecSmrg return BadValue; 155305b261ecSmrg } 155405b261ecSmrgCreatePmap: 155505b261ecSmrg pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) 155605b261ecSmrg (pDraw->pScreen, stuff->width, 155705b261ecSmrg stuff->height, stuff->depth); 155805b261ecSmrg if (pMap) 155905b261ecSmrg { 156005b261ecSmrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 156105b261ecSmrg pMap->drawable.id = stuff->pid; 156205b261ecSmrg if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) 156305b261ecSmrg return(client->noClientException); 156405b261ecSmrg } 156505b261ecSmrg return (BadAlloc); 156605b261ecSmrg} 156705b261ecSmrg 156805b261ecSmrgint 156905b261ecSmrgProcFreePixmap(ClientPtr client) 157005b261ecSmrg{ 157105b261ecSmrg PixmapPtr pMap; 157205b261ecSmrg 157305b261ecSmrg REQUEST(xResourceReq); 157405b261ecSmrg 157505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 157605b261ecSmrg pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP, 157705b261ecSmrg DixDestroyAccess); 157805b261ecSmrg if (pMap) 157905b261ecSmrg { 158005b261ecSmrg FreeResource(stuff->id, RT_NONE); 158105b261ecSmrg return(client->noClientException); 158205b261ecSmrg } 158305b261ecSmrg else 158405b261ecSmrg { 158505b261ecSmrg client->errorValue = stuff->id; 158605b261ecSmrg return (BadPixmap); 158705b261ecSmrg } 158805b261ecSmrg} 158905b261ecSmrg 159005b261ecSmrgint 159105b261ecSmrgProcCreateGC(ClientPtr client) 159205b261ecSmrg{ 159305b261ecSmrg int error, rc; 159405b261ecSmrg GC *pGC; 159505b261ecSmrg DrawablePtr pDraw; 159605b261ecSmrg unsigned len; 159705b261ecSmrg REQUEST(xCreateGCReq); 159805b261ecSmrg 159905b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateGCReq); 160005b261ecSmrg client->errorValue = stuff->gc; 160105b261ecSmrg LEGAL_NEW_RESOURCE(stuff->gc, client); 160205b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess); 160305b261ecSmrg if (rc != Success) 160405b261ecSmrg return rc; 160505b261ecSmrg 160605b261ecSmrg len = client->req_len - (sizeof(xCreateGCReq) >> 2); 160705b261ecSmrg if (len != Ones(stuff->mask)) 160805b261ecSmrg return BadLength; 160905b261ecSmrg pGC = (GC *)CreateGC(pDraw, stuff->mask, 161005b261ecSmrg (XID *) &stuff[1], &error); 161105b261ecSmrg if (error != Success) 161205b261ecSmrg return error; 161305b261ecSmrg if (!AddResource(stuff->gc, RT_GC, (pointer)pGC)) 161405b261ecSmrg return (BadAlloc); 161505b261ecSmrg return(client->noClientException); 161605b261ecSmrg} 161705b261ecSmrg 161805b261ecSmrgint 161905b261ecSmrgProcChangeGC(ClientPtr client) 162005b261ecSmrg{ 162105b261ecSmrg GC *pGC; 162205b261ecSmrg int result; 162305b261ecSmrg unsigned len; 162405b261ecSmrg REQUEST(xChangeGCReq); 162505b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeGCReq); 162605b261ecSmrg 162705b261ecSmrg result = dixLookupGC(&pGC, stuff->gc, client, DixWriteAccess); 162805b261ecSmrg if (result != Success) 162905b261ecSmrg return result; 163005b261ecSmrg 163105b261ecSmrg len = client->req_len - (sizeof(xChangeGCReq) >> 2); 163205b261ecSmrg if (len != Ones(stuff->mask)) 163305b261ecSmrg return BadLength; 163405b261ecSmrg 163505b261ecSmrg result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0); 163605b261ecSmrg if (client->noClientException != Success) 163705b261ecSmrg return(client->noClientException); 163805b261ecSmrg else 163905b261ecSmrg { 164005b261ecSmrg client->errorValue = clientErrorValue; 164105b261ecSmrg return(result); 164205b261ecSmrg } 164305b261ecSmrg} 164405b261ecSmrg 164505b261ecSmrgint 164605b261ecSmrgProcCopyGC(ClientPtr client) 164705b261ecSmrg{ 164805b261ecSmrg GC *dstGC; 164905b261ecSmrg GC *pGC; 165005b261ecSmrg int result; 165105b261ecSmrg REQUEST(xCopyGCReq); 165205b261ecSmrg REQUEST_SIZE_MATCH(xCopyGCReq); 165305b261ecSmrg 165405b261ecSmrg result = dixLookupGC(&pGC, stuff->srcGC, client, DixReadAccess); 165505b261ecSmrg if (result != Success) 165605b261ecSmrg return result; 165705b261ecSmrg result = dixLookupGC(&dstGC, stuff->dstGC, client, DixWriteAccess); 165805b261ecSmrg if (result != Success) 165905b261ecSmrg return result; 166005b261ecSmrg if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 166105b261ecSmrg return (BadMatch); 166205b261ecSmrg result = CopyGC(pGC, dstGC, stuff->mask); 166305b261ecSmrg if (client->noClientException != Success) 166405b261ecSmrg return(client->noClientException); 166505b261ecSmrg else 166605b261ecSmrg { 166705b261ecSmrg client->errorValue = clientErrorValue; 166805b261ecSmrg return(result); 166905b261ecSmrg } 167005b261ecSmrg} 167105b261ecSmrg 167205b261ecSmrgint 167305b261ecSmrgProcSetDashes(ClientPtr client) 167405b261ecSmrg{ 167505b261ecSmrg GC *pGC; 167605b261ecSmrg int result; 167705b261ecSmrg REQUEST(xSetDashesReq); 167805b261ecSmrg 167905b261ecSmrg REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 168005b261ecSmrg if (stuff->nDashes == 0) 168105b261ecSmrg { 168205b261ecSmrg client->errorValue = 0; 168305b261ecSmrg return BadValue; 168405b261ecSmrg } 168505b261ecSmrg 168605b261ecSmrg result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess); 168705b261ecSmrg if (result != Success) 168805b261ecSmrg return result; 168905b261ecSmrg 169005b261ecSmrg result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 169105b261ecSmrg (unsigned char *)&stuff[1]); 169205b261ecSmrg if (client->noClientException != Success) 169305b261ecSmrg return(client->noClientException); 169405b261ecSmrg else 169505b261ecSmrg { 169605b261ecSmrg client->errorValue = clientErrorValue; 169705b261ecSmrg return(result); 169805b261ecSmrg } 169905b261ecSmrg} 170005b261ecSmrg 170105b261ecSmrgint 170205b261ecSmrgProcSetClipRectangles(ClientPtr client) 170305b261ecSmrg{ 170405b261ecSmrg int nr, result; 170505b261ecSmrg GC *pGC; 170605b261ecSmrg REQUEST(xSetClipRectanglesReq); 170705b261ecSmrg 170805b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 170905b261ecSmrg if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 171005b261ecSmrg (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) 171105b261ecSmrg { 171205b261ecSmrg client->errorValue = stuff->ordering; 171305b261ecSmrg return BadValue; 171405b261ecSmrg } 171505b261ecSmrg result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess); 171605b261ecSmrg if (result != Success) 171705b261ecSmrg return result; 171805b261ecSmrg 171905b261ecSmrg nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 172005b261ecSmrg if (nr & 4) 172105b261ecSmrg return(BadLength); 172205b261ecSmrg nr >>= 3; 172305b261ecSmrg result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 172405b261ecSmrg nr, (xRectangle *)&stuff[1], (int)stuff->ordering); 172505b261ecSmrg if (client->noClientException != Success) 172605b261ecSmrg return(client->noClientException); 172705b261ecSmrg else 172805b261ecSmrg return(result); 172905b261ecSmrg} 173005b261ecSmrg 173105b261ecSmrgint 173205b261ecSmrgProcFreeGC(ClientPtr client) 173305b261ecSmrg{ 173405b261ecSmrg GC *pGC; 173505b261ecSmrg int rc; 173605b261ecSmrg REQUEST(xResourceReq); 173705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 173805b261ecSmrg 173905b261ecSmrg rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 174005b261ecSmrg if (rc != Success) 174105b261ecSmrg return rc; 174205b261ecSmrg 174305b261ecSmrg FreeResource(stuff->id, RT_NONE); 174405b261ecSmrg return(client->noClientException); 174505b261ecSmrg} 174605b261ecSmrg 174705b261ecSmrgint 174805b261ecSmrgProcClearToBackground(ClientPtr client) 174905b261ecSmrg{ 175005b261ecSmrg REQUEST(xClearAreaReq); 175105b261ecSmrg WindowPtr pWin; 175205b261ecSmrg int rc; 175305b261ecSmrg 175405b261ecSmrg REQUEST_SIZE_MATCH(xClearAreaReq); 175505b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 175605b261ecSmrg if (rc != Success) 175705b261ecSmrg return rc; 175805b261ecSmrg if (pWin->drawable.class == InputOnly) 175905b261ecSmrg { 176005b261ecSmrg client->errorValue = stuff->window; 176105b261ecSmrg return (BadMatch); 176205b261ecSmrg } 176305b261ecSmrg if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) 176405b261ecSmrg { 176505b261ecSmrg client->errorValue = stuff->exposures; 176605b261ecSmrg return(BadValue); 176705b261ecSmrg } 176805b261ecSmrg (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y, 176905b261ecSmrg stuff->width, stuff->height, 177005b261ecSmrg (Bool)stuff->exposures); 177105b261ecSmrg return(client->noClientException); 177205b261ecSmrg} 177305b261ecSmrg 177405b261ecSmrgint 177505b261ecSmrgProcCopyArea(ClientPtr client) 177605b261ecSmrg{ 177705b261ecSmrg DrawablePtr pDst; 177805b261ecSmrg DrawablePtr pSrc; 177905b261ecSmrg GC *pGC; 178005b261ecSmrg REQUEST(xCopyAreaReq); 178105b261ecSmrg RegionPtr pRgn; 178205b261ecSmrg int rc; 178305b261ecSmrg 178405b261ecSmrg REQUEST_SIZE_MATCH(xCopyAreaReq); 178505b261ecSmrg 178605b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 178705b261ecSmrg if (stuff->dstDrawable != stuff->srcDrawable) 178805b261ecSmrg { 178905b261ecSmrg rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 179005b261ecSmrg DixReadAccess); 179105b261ecSmrg if (rc != Success) 179205b261ecSmrg return rc; 179305b261ecSmrg if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) 179405b261ecSmrg { 179505b261ecSmrg client->errorValue = stuff->dstDrawable; 179605b261ecSmrg return (BadMatch); 179705b261ecSmrg } 179805b261ecSmrg } 179905b261ecSmrg else 180005b261ecSmrg pSrc = pDst; 180105b261ecSmrg 180205b261ecSmrg pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 180305b261ecSmrg stuff->width, stuff->height, 180405b261ecSmrg stuff->dstX, stuff->dstY); 180505b261ecSmrg if (pGC->graphicsExposures) 180605b261ecSmrg { 180705b261ecSmrg (*pDst->pScreen->SendGraphicsExpose) 180805b261ecSmrg (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 180905b261ecSmrg if (pRgn) 181005b261ecSmrg REGION_DESTROY(pDst->pScreen, pRgn); 181105b261ecSmrg } 181205b261ecSmrg 181305b261ecSmrg return(client->noClientException); 181405b261ecSmrg} 181505b261ecSmrg 181605b261ecSmrgint 181705b261ecSmrgProcCopyPlane(ClientPtr client) 181805b261ecSmrg{ 181905b261ecSmrg DrawablePtr psrcDraw, pdstDraw; 182005b261ecSmrg GC *pGC; 182105b261ecSmrg REQUEST(xCopyPlaneReq); 182205b261ecSmrg RegionPtr pRgn; 182305b261ecSmrg int rc; 182405b261ecSmrg 182505b261ecSmrg REQUEST_SIZE_MATCH(xCopyPlaneReq); 182605b261ecSmrg 182705b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client); 182805b261ecSmrg if (stuff->dstDrawable != stuff->srcDrawable) 182905b261ecSmrg { 183005b261ecSmrg rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 183105b261ecSmrg DixReadAccess); 183205b261ecSmrg if (rc != Success) 183305b261ecSmrg return rc; 183405b261ecSmrg 183505b261ecSmrg if (pdstDraw->pScreen != psrcDraw->pScreen) 183605b261ecSmrg { 183705b261ecSmrg client->errorValue = stuff->dstDrawable; 183805b261ecSmrg return (BadMatch); 183905b261ecSmrg } 184005b261ecSmrg } 184105b261ecSmrg else 184205b261ecSmrg psrcDraw = pdstDraw; 184305b261ecSmrg 184405b261ecSmrg /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 184505b261ecSmrg if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 184605b261ecSmrg (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) 184705b261ecSmrg { 184805b261ecSmrg client->errorValue = stuff->bitPlane; 184905b261ecSmrg return(BadValue); 185005b261ecSmrg } 185105b261ecSmrg 185205b261ecSmrg pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, 185305b261ecSmrg stuff->width, stuff->height, 185405b261ecSmrg stuff->dstX, stuff->dstY, stuff->bitPlane); 185505b261ecSmrg if (pGC->graphicsExposures) 185605b261ecSmrg { 185705b261ecSmrg (*pdstDraw->pScreen->SendGraphicsExpose) 185805b261ecSmrg (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 185905b261ecSmrg if (pRgn) 186005b261ecSmrg REGION_DESTROY(pdstDraw->pScreen, pRgn); 186105b261ecSmrg } 186205b261ecSmrg return(client->noClientException); 186305b261ecSmrg} 186405b261ecSmrg 186505b261ecSmrgint 186605b261ecSmrgProcPolyPoint(ClientPtr client) 186705b261ecSmrg{ 186805b261ecSmrg int npoint; 186905b261ecSmrg GC *pGC; 187005b261ecSmrg DrawablePtr pDraw; 187105b261ecSmrg REQUEST(xPolyPointReq); 187205b261ecSmrg 187305b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyPointReq); 187405b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 187505b261ecSmrg (stuff->coordMode != CoordModePrevious)) 187605b261ecSmrg { 187705b261ecSmrg client->errorValue = stuff->coordMode; 187805b261ecSmrg return BadValue; 187905b261ecSmrg } 188005b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 188105b261ecSmrg npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2; 188205b261ecSmrg if (npoint) 188305b261ecSmrg (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, 188405b261ecSmrg (xPoint *) &stuff[1]); 188505b261ecSmrg return (client->noClientException); 188605b261ecSmrg} 188705b261ecSmrg 188805b261ecSmrgint 188905b261ecSmrgProcPolyLine(ClientPtr client) 189005b261ecSmrg{ 189105b261ecSmrg int npoint; 189205b261ecSmrg GC *pGC; 189305b261ecSmrg DrawablePtr pDraw; 189405b261ecSmrg REQUEST(xPolyLineReq); 189505b261ecSmrg 189605b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyLineReq); 189705b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 189805b261ecSmrg (stuff->coordMode != CoordModePrevious)) 189905b261ecSmrg { 190005b261ecSmrg client->errorValue = stuff->coordMode; 190105b261ecSmrg return BadValue; 190205b261ecSmrg } 190305b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 190405b261ecSmrg npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2; 190505b261ecSmrg if (npoint > 1) 190605b261ecSmrg (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 190705b261ecSmrg (DDXPointPtr) &stuff[1]); 190805b261ecSmrg return(client->noClientException); 190905b261ecSmrg} 191005b261ecSmrg 191105b261ecSmrgint 191205b261ecSmrgProcPolySegment(ClientPtr client) 191305b261ecSmrg{ 191405b261ecSmrg int nsegs; 191505b261ecSmrg GC *pGC; 191605b261ecSmrg DrawablePtr pDraw; 191705b261ecSmrg REQUEST(xPolySegmentReq); 191805b261ecSmrg 191905b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 192005b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 192105b261ecSmrg nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 192205b261ecSmrg if (nsegs & 4) 192305b261ecSmrg return(BadLength); 192405b261ecSmrg nsegs >>= 3; 192505b261ecSmrg if (nsegs) 192605b261ecSmrg (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 192705b261ecSmrg return (client->noClientException); 192805b261ecSmrg} 192905b261ecSmrg 193005b261ecSmrgint 193105b261ecSmrgProcPolyRectangle (ClientPtr client) 193205b261ecSmrg{ 193305b261ecSmrg int nrects; 193405b261ecSmrg GC *pGC; 193505b261ecSmrg DrawablePtr pDraw; 193605b261ecSmrg REQUEST(xPolyRectangleReq); 193705b261ecSmrg 193805b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 193905b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 194005b261ecSmrg nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 194105b261ecSmrg if (nrects & 4) 194205b261ecSmrg return(BadLength); 194305b261ecSmrg nrects >>= 3; 194405b261ecSmrg if (nrects) 194505b261ecSmrg (*pGC->ops->PolyRectangle)(pDraw, pGC, 194605b261ecSmrg nrects, (xRectangle *) &stuff[1]); 194705b261ecSmrg return(client->noClientException); 194805b261ecSmrg} 194905b261ecSmrg 195005b261ecSmrgint 195105b261ecSmrgProcPolyArc(ClientPtr client) 195205b261ecSmrg{ 195305b261ecSmrg int narcs; 195405b261ecSmrg GC *pGC; 195505b261ecSmrg DrawablePtr pDraw; 195605b261ecSmrg REQUEST(xPolyArcReq); 195705b261ecSmrg 195805b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyArcReq); 195905b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 196005b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 196105b261ecSmrg if (narcs % sizeof(xArc)) 196205b261ecSmrg return(BadLength); 196305b261ecSmrg narcs /= sizeof(xArc); 196405b261ecSmrg if (narcs) 196505b261ecSmrg (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]); 196605b261ecSmrg return (client->noClientException); 196705b261ecSmrg} 196805b261ecSmrg 196905b261ecSmrgint 197005b261ecSmrgProcFillPoly(ClientPtr client) 197105b261ecSmrg{ 197205b261ecSmrg int things; 197305b261ecSmrg GC *pGC; 197405b261ecSmrg DrawablePtr pDraw; 197505b261ecSmrg REQUEST(xFillPolyReq); 197605b261ecSmrg 197705b261ecSmrg REQUEST_AT_LEAST_SIZE(xFillPolyReq); 197805b261ecSmrg if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 197905b261ecSmrg (stuff->shape != Convex)) 198005b261ecSmrg { 198105b261ecSmrg client->errorValue = stuff->shape; 198205b261ecSmrg return BadValue; 198305b261ecSmrg } 198405b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 198505b261ecSmrg (stuff->coordMode != CoordModePrevious)) 198605b261ecSmrg { 198705b261ecSmrg client->errorValue = stuff->coordMode; 198805b261ecSmrg return BadValue; 198905b261ecSmrg } 199005b261ecSmrg 199105b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 199205b261ecSmrg things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2; 199305b261ecSmrg if (things) 199405b261ecSmrg (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 199505b261ecSmrg stuff->coordMode, things, 199605b261ecSmrg (DDXPointPtr) &stuff[1]); 199705b261ecSmrg return(client->noClientException); 199805b261ecSmrg} 199905b261ecSmrg 200005b261ecSmrgint 200105b261ecSmrgProcPolyFillRectangle(ClientPtr client) 200205b261ecSmrg{ 200305b261ecSmrg int things; 200405b261ecSmrg GC *pGC; 200505b261ecSmrg DrawablePtr pDraw; 200605b261ecSmrg REQUEST(xPolyFillRectangleReq); 200705b261ecSmrg 200805b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 200905b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 201005b261ecSmrg things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 201105b261ecSmrg if (things & 4) 201205b261ecSmrg return(BadLength); 201305b261ecSmrg things >>= 3; 201405b261ecSmrg 201505b261ecSmrg if (things) 201605b261ecSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 201705b261ecSmrg (xRectangle *) &stuff[1]); 201805b261ecSmrg return (client->noClientException); 201905b261ecSmrg} 202005b261ecSmrg 202105b261ecSmrgint 202205b261ecSmrgProcPolyFillArc(ClientPtr client) 202305b261ecSmrg{ 202405b261ecSmrg int narcs; 202505b261ecSmrg GC *pGC; 202605b261ecSmrg DrawablePtr pDraw; 202705b261ecSmrg REQUEST(xPolyFillArcReq); 202805b261ecSmrg 202905b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 203005b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 203105b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 203205b261ecSmrg if (narcs % sizeof(xArc)) 203305b261ecSmrg return(BadLength); 203405b261ecSmrg narcs /= sizeof(xArc); 203505b261ecSmrg if (narcs) 203605b261ecSmrg (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 203705b261ecSmrg return (client->noClientException); 203805b261ecSmrg} 203905b261ecSmrg 204005b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 204105b261ecSmrg 204205b261ecSmrgint 204305b261ecSmrgServerOrder (void) 204405b261ecSmrg{ 204505b261ecSmrg int whichbyte = 1; 204605b261ecSmrg 204705b261ecSmrg if (*((char *) &whichbyte)) 204805b261ecSmrg return LSBFirst; 204905b261ecSmrg return MSBFirst; 205005b261ecSmrg} 205105b261ecSmrg 205205b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 205305b261ecSmrg 205405b261ecSmrgvoid 205505b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order) 205605b261ecSmrg{ 205705b261ecSmrg switch (bpp) { 205805b261ecSmrg case 1: /* yuck */ 205905b261ecSmrg if (BITMAP_BIT_ORDER != order) 206005b261ecSmrg BitOrderInvert ((unsigned char *) base, nbytes); 206105b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 206205b261ecSmrg ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order); 206305b261ecSmrg#endif 206405b261ecSmrg break; 206505b261ecSmrg case 4: 206605b261ecSmrg break; /* yuck */ 206705b261ecSmrg case 8: 206805b261ecSmrg break; 206905b261ecSmrg case 16: 207005b261ecSmrg if (IMAGE_BYTE_ORDER != order) 207105b261ecSmrg TwoByteSwap ((unsigned char *) base, nbytes); 207205b261ecSmrg break; 207305b261ecSmrg case 32: 207405b261ecSmrg if (IMAGE_BYTE_ORDER != order) 207505b261ecSmrg FourByteSwap ((unsigned char *) base, nbytes); 207605b261ecSmrg break; 207705b261ecSmrg } 207805b261ecSmrg} 207905b261ecSmrg#else 208005b261ecSmrg#define ReformatImage(b,n,bpp,o) 208105b261ecSmrg#endif 208205b261ecSmrg 208305b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to 208405b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 208505b261ecSmrg * to use internally. Removes need for internal alignment checking. 208605b261ecSmrg * All of the PutImage functions could be changed individually, but 208705b261ecSmrg * as currently written, they call other routines which require things 208805b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here. 208905b261ecSmrg * If an image would be padded differently for 64- versus 32-, then 209005b261ecSmrg * copy each scanline to a 64-bit padded scanline. 209105b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit 209205b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction. 209305b261ecSmrg */ 209405b261ecSmrgint 209505b261ecSmrgProcPutImage(ClientPtr client) 209605b261ecSmrg{ 209705b261ecSmrg GC *pGC; 209805b261ecSmrg DrawablePtr pDraw; 209905b261ecSmrg long length; /* length of scanline server padded */ 210005b261ecSmrg long lengthProto; /* length of scanline protocol padded */ 210105b261ecSmrg char *tmpImage; 210205b261ecSmrg REQUEST(xPutImageReq); 210305b261ecSmrg 210405b261ecSmrg REQUEST_AT_LEAST_SIZE(xPutImageReq); 210505b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 210605b261ecSmrg if (stuff->format == XYBitmap) 210705b261ecSmrg { 210805b261ecSmrg if ((stuff->depth != 1) || 210905b261ecSmrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 211005b261ecSmrg return BadMatch; 211105b261ecSmrg length = BitmapBytePad(stuff->width + stuff->leftPad); 211205b261ecSmrg } 211305b261ecSmrg else if (stuff->format == XYPixmap) 211405b261ecSmrg { 211505b261ecSmrg if ((pDraw->depth != stuff->depth) || 211605b261ecSmrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 211705b261ecSmrg return BadMatch; 211805b261ecSmrg length = BitmapBytePad(stuff->width + stuff->leftPad); 211905b261ecSmrg length *= stuff->depth; 212005b261ecSmrg } 212105b261ecSmrg else if (stuff->format == ZPixmap) 212205b261ecSmrg { 212305b261ecSmrg if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 212405b261ecSmrg return BadMatch; 212505b261ecSmrg length = PixmapBytePad(stuff->width, stuff->depth); 212605b261ecSmrg } 212705b261ecSmrg else 212805b261ecSmrg { 212905b261ecSmrg client->errorValue = stuff->format; 213005b261ecSmrg return BadValue; 213105b261ecSmrg } 213205b261ecSmrg 213305b261ecSmrg tmpImage = (char *)&stuff[1]; 213405b261ecSmrg lengthProto = length; 213505b261ecSmrg 213605b261ecSmrg if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 213705b261ecSmrg (sizeof(xPutImageReq) >> 2)) != client->req_len) 213805b261ecSmrg return BadLength; 213905b261ecSmrg 214005b261ecSmrg ReformatImage (tmpImage, lengthProto * stuff->height, 214105b261ecSmrg stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1, 214205b261ecSmrg ClientOrder(client)); 214305b261ecSmrg 214405b261ecSmrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 214505b261ecSmrg stuff->width, stuff->height, 214605b261ecSmrg stuff->leftPad, stuff->format, tmpImage); 214705b261ecSmrg 214805b261ecSmrg return (client->noClientException); 214905b261ecSmrg} 215005b261ecSmrg 215105b261ecSmrgstatic int 215205b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable, 215305b261ecSmrg int x, int y, int width, int height, 215405b261ecSmrg Mask planemask, xGetImageReply **im_return) 215505b261ecSmrg{ 215605b261ecSmrg DrawablePtr pDraw; 215705b261ecSmrg int nlines, linesPerBuf, rc; 215805b261ecSmrg int linesDone; 215905b261ecSmrg long widthBytesLine, length; 216005b261ecSmrg Mask plane = 0; 216105b261ecSmrg char *pBuf; 216205b261ecSmrg xGetImageReply xgi; 216305b261ecSmrg RegionPtr pVisibleRegion = NULL; 216405b261ecSmrg 216505b261ecSmrg if ((format != XYPixmap) && (format != ZPixmap)) 216605b261ecSmrg { 216705b261ecSmrg client->errorValue = format; 216805b261ecSmrg return(BadValue); 216905b261ecSmrg } 217005b261ecSmrg rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 217105b261ecSmrg if (rc != Success) 217205b261ecSmrg return rc; 217305b261ecSmrg 217405b261ecSmrg if(pDraw->type == DRAWABLE_WINDOW) 217505b261ecSmrg { 217605b261ecSmrg if( /* check for being viewable */ 217705b261ecSmrg !((WindowPtr) pDraw)->realized || 217805b261ecSmrg /* check for being on screen */ 217905b261ecSmrg pDraw->x + x < 0 || 218005b261ecSmrg pDraw->x + x + width > pDraw->pScreen->width || 218105b261ecSmrg pDraw->y + y < 0 || 218205b261ecSmrg pDraw->y + y + height > pDraw->pScreen->height || 218305b261ecSmrg /* check for being inside of border */ 218405b261ecSmrg x < - wBorderWidth((WindowPtr)pDraw) || 218505b261ecSmrg x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || 218605b261ecSmrg y < -wBorderWidth((WindowPtr)pDraw) || 218705b261ecSmrg y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height 218805b261ecSmrg ) 218905b261ecSmrg return(BadMatch); 219005b261ecSmrg xgi.visual = wVisual (((WindowPtr) pDraw)); 219105b261ecSmrg } 219205b261ecSmrg else 219305b261ecSmrg { 219405b261ecSmrg if(x < 0 || 219505b261ecSmrg x+width > (int)pDraw->width || 219605b261ecSmrg y < 0 || 219705b261ecSmrg y+height > (int)pDraw->height 219805b261ecSmrg ) 219905b261ecSmrg return(BadMatch); 220005b261ecSmrg xgi.visual = None; 220105b261ecSmrg } 220205b261ecSmrg 220305b261ecSmrg xgi.type = X_Reply; 220405b261ecSmrg xgi.sequenceNumber = client->sequence; 220505b261ecSmrg xgi.depth = pDraw->depth; 220605b261ecSmrg if(format == ZPixmap) 220705b261ecSmrg { 220805b261ecSmrg widthBytesLine = PixmapBytePad(width, pDraw->depth); 220905b261ecSmrg length = widthBytesLine * height; 221005b261ecSmrg 221105b261ecSmrg } 221205b261ecSmrg else 221305b261ecSmrg { 221405b261ecSmrg widthBytesLine = BitmapBytePad(width); 221505b261ecSmrg plane = ((Mask)1) << (pDraw->depth - 1); 221605b261ecSmrg /* only planes asked for */ 221705b261ecSmrg length = widthBytesLine * height * 221805b261ecSmrg Ones(planemask & (plane | (plane - 1))); 221905b261ecSmrg 222005b261ecSmrg } 222105b261ecSmrg 222205b261ecSmrg xgi.length = length; 222305b261ecSmrg 222405b261ecSmrg if (im_return) { 222505b261ecSmrg pBuf = (char *)xalloc(sz_xGetImageReply + length); 222605b261ecSmrg if (!pBuf) 222705b261ecSmrg return (BadAlloc); 222805b261ecSmrg if (widthBytesLine == 0) 222905b261ecSmrg linesPerBuf = 0; 223005b261ecSmrg else 223105b261ecSmrg linesPerBuf = height; 223205b261ecSmrg *im_return = (xGetImageReply *)pBuf; 223305b261ecSmrg *(xGetImageReply *)pBuf = xgi; 223405b261ecSmrg pBuf += sz_xGetImageReply; 223505b261ecSmrg } else { 223605b261ecSmrg xgi.length = (xgi.length + 3) >> 2; 223705b261ecSmrg if (widthBytesLine == 0 || height == 0) 223805b261ecSmrg linesPerBuf = 0; 223905b261ecSmrg else if (widthBytesLine >= IMAGE_BUFSIZE) 224005b261ecSmrg linesPerBuf = 1; 224105b261ecSmrg else 224205b261ecSmrg { 224305b261ecSmrg linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 224405b261ecSmrg if (linesPerBuf > height) 224505b261ecSmrg linesPerBuf = height; 224605b261ecSmrg } 224705b261ecSmrg length = linesPerBuf * widthBytesLine; 224805b261ecSmrg if (linesPerBuf < height) 224905b261ecSmrg { 225005b261ecSmrg /* we have to make sure intermediate buffers don't need padding */ 225105b261ecSmrg while ((linesPerBuf > 1) && 225205b261ecSmrg (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))) 225305b261ecSmrg { 225405b261ecSmrg linesPerBuf--; 225505b261ecSmrg length -= widthBytesLine; 225605b261ecSmrg } 225705b261ecSmrg while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)) 225805b261ecSmrg { 225905b261ecSmrg linesPerBuf++; 226005b261ecSmrg length += widthBytesLine; 226105b261ecSmrg } 226205b261ecSmrg } 226305b261ecSmrg if(!(pBuf = (char *) ALLOCATE_LOCAL(length))) 226405b261ecSmrg return (BadAlloc); 226505b261ecSmrg WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); 226605b261ecSmrg } 226705b261ecSmrg 226805b261ecSmrg if (pDraw->type == DRAWABLE_WINDOW && 226905b261ecSmrg !XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw)) 227005b261ecSmrg { 227105b261ecSmrg pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); 227205b261ecSmrg if (pVisibleRegion) 227305b261ecSmrg { 227405b261ecSmrg REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, 227505b261ecSmrg -pDraw->x, -pDraw->y); 227605b261ecSmrg } 227705b261ecSmrg } 227805b261ecSmrg 227905b261ecSmrg if (linesPerBuf == 0) 228005b261ecSmrg { 228105b261ecSmrg /* nothing to do */ 228205b261ecSmrg } 228305b261ecSmrg else if (format == ZPixmap) 228405b261ecSmrg { 228505b261ecSmrg linesDone = 0; 228605b261ecSmrg while (height - linesDone > 0) 228705b261ecSmrg { 228805b261ecSmrg nlines = min(linesPerBuf, height - linesDone); 228905b261ecSmrg (*pDraw->pScreen->GetImage) (pDraw, 229005b261ecSmrg x, 229105b261ecSmrg y + linesDone, 229205b261ecSmrg width, 229305b261ecSmrg nlines, 229405b261ecSmrg format, 229505b261ecSmrg planemask, 229605b261ecSmrg (pointer) pBuf); 229705b261ecSmrg if (pVisibleRegion) 229805b261ecSmrg XaceCensorImage(client, pVisibleRegion, widthBytesLine, 229905b261ecSmrg pDraw, x, y + linesDone, width, 230005b261ecSmrg nlines, format, pBuf); 230105b261ecSmrg 230205b261ecSmrg /* Note that this is NOT a call to WriteSwappedDataToClient, 230305b261ecSmrg as we do NOT byte swap */ 230405b261ecSmrg if (!im_return) 230505b261ecSmrg { 230605b261ecSmrg ReformatImage (pBuf, (int)(nlines * widthBytesLine), 230705b261ecSmrg BitsPerPixel (pDraw->depth), 230805b261ecSmrg ClientOrder(client)); 230905b261ecSmrg 231005b261ecSmrg/* Don't split me, gcc pukes when you do */ 231105b261ecSmrg (void)WriteToClient(client, 231205b261ecSmrg (int)(nlines * widthBytesLine), 231305b261ecSmrg pBuf); 231405b261ecSmrg } 231505b261ecSmrg linesDone += nlines; 231605b261ecSmrg } 231705b261ecSmrg } 231805b261ecSmrg else /* XYPixmap */ 231905b261ecSmrg { 232005b261ecSmrg for (; plane; plane >>= 1) 232105b261ecSmrg { 232205b261ecSmrg if (planemask & plane) 232305b261ecSmrg { 232405b261ecSmrg linesDone = 0; 232505b261ecSmrg while (height - linesDone > 0) 232605b261ecSmrg { 232705b261ecSmrg nlines = min(linesPerBuf, height - linesDone); 232805b261ecSmrg (*pDraw->pScreen->GetImage) (pDraw, 232905b261ecSmrg x, 233005b261ecSmrg y + linesDone, 233105b261ecSmrg width, 233205b261ecSmrg nlines, 233305b261ecSmrg format, 233405b261ecSmrg plane, 233505b261ecSmrg (pointer)pBuf); 233605b261ecSmrg if (pVisibleRegion) 233705b261ecSmrg XaceCensorImage(client, pVisibleRegion, 233805b261ecSmrg widthBytesLine, 233905b261ecSmrg pDraw, x, y + linesDone, width, 234005b261ecSmrg nlines, format, pBuf); 234105b261ecSmrg 234205b261ecSmrg /* Note: NOT a call to WriteSwappedDataToClient, 234305b261ecSmrg as we do NOT byte swap */ 234405b261ecSmrg if (im_return) { 234505b261ecSmrg pBuf += nlines * widthBytesLine; 234605b261ecSmrg } else { 234705b261ecSmrg ReformatImage (pBuf, 234805b261ecSmrg (int)(nlines * widthBytesLine), 234905b261ecSmrg 1, 235005b261ecSmrg ClientOrder (client)); 235105b261ecSmrg 235205b261ecSmrg/* Don't split me, gcc pukes when you do */ 235305b261ecSmrg (void)WriteToClient(client, 235405b261ecSmrg (int)(nlines * widthBytesLine), 235505b261ecSmrg pBuf); 235605b261ecSmrg } 235705b261ecSmrg linesDone += nlines; 235805b261ecSmrg } 235905b261ecSmrg } 236005b261ecSmrg } 236105b261ecSmrg } 236205b261ecSmrg if (pVisibleRegion) 236305b261ecSmrg REGION_DESTROY(pDraw->pScreen, pVisibleRegion); 236405b261ecSmrg if (!im_return) 236505b261ecSmrg DEALLOCATE_LOCAL(pBuf); 236605b261ecSmrg return (client->noClientException); 236705b261ecSmrg} 236805b261ecSmrg 236905b261ecSmrgint 237005b261ecSmrgProcGetImage(ClientPtr client) 237105b261ecSmrg{ 237205b261ecSmrg REQUEST(xGetImageReq); 237305b261ecSmrg 237405b261ecSmrg REQUEST_SIZE_MATCH(xGetImageReq); 237505b261ecSmrg 237605b261ecSmrg return DoGetImage(client, stuff->format, stuff->drawable, 237705b261ecSmrg stuff->x, stuff->y, 237805b261ecSmrg (int)stuff->width, (int)stuff->height, 237905b261ecSmrg stuff->planeMask, (xGetImageReply **)NULL); 238005b261ecSmrg} 238105b261ecSmrg 238205b261ecSmrgint 238305b261ecSmrgProcPolyText(ClientPtr client) 238405b261ecSmrg{ 238505b261ecSmrg int err; 238605b261ecSmrg REQUEST(xPolyTextReq); 238705b261ecSmrg DrawablePtr pDraw; 238805b261ecSmrg GC *pGC; 238905b261ecSmrg 239005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyTextReq); 239105b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 239205b261ecSmrg 239305b261ecSmrg err = PolyText(client, 239405b261ecSmrg pDraw, 239505b261ecSmrg pGC, 239605b261ecSmrg (unsigned char *)&stuff[1], 239705b261ecSmrg ((unsigned char *) stuff) + (client->req_len << 2), 239805b261ecSmrg stuff->x, 239905b261ecSmrg stuff->y, 240005b261ecSmrg stuff->reqType, 240105b261ecSmrg stuff->drawable); 240205b261ecSmrg 240305b261ecSmrg if (err == Success) 240405b261ecSmrg { 240505b261ecSmrg return(client->noClientException); 240605b261ecSmrg } 240705b261ecSmrg else 240805b261ecSmrg return err; 240905b261ecSmrg} 241005b261ecSmrg 241105b261ecSmrgint 241205b261ecSmrgProcImageText8(ClientPtr client) 241305b261ecSmrg{ 241405b261ecSmrg int err; 241505b261ecSmrg DrawablePtr pDraw; 241605b261ecSmrg GC *pGC; 241705b261ecSmrg 241805b261ecSmrg REQUEST(xImageTextReq); 241905b261ecSmrg 242005b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 242105b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 242205b261ecSmrg 242305b261ecSmrg err = ImageText(client, 242405b261ecSmrg pDraw, 242505b261ecSmrg pGC, 242605b261ecSmrg stuff->nChars, 242705b261ecSmrg (unsigned char *)&stuff[1], 242805b261ecSmrg stuff->x, 242905b261ecSmrg stuff->y, 243005b261ecSmrg stuff->reqType, 243105b261ecSmrg stuff->drawable); 243205b261ecSmrg 243305b261ecSmrg if (err == Success) 243405b261ecSmrg { 243505b261ecSmrg return(client->noClientException); 243605b261ecSmrg } 243705b261ecSmrg else 243805b261ecSmrg return err; 243905b261ecSmrg} 244005b261ecSmrg 244105b261ecSmrgint 244205b261ecSmrgProcImageText16(ClientPtr client) 244305b261ecSmrg{ 244405b261ecSmrg int err; 244505b261ecSmrg DrawablePtr pDraw; 244605b261ecSmrg GC *pGC; 244705b261ecSmrg 244805b261ecSmrg REQUEST(xImageTextReq); 244905b261ecSmrg 245005b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 245105b261ecSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 245205b261ecSmrg 245305b261ecSmrg err = ImageText(client, 245405b261ecSmrg pDraw, 245505b261ecSmrg pGC, 245605b261ecSmrg stuff->nChars, 245705b261ecSmrg (unsigned char *)&stuff[1], 245805b261ecSmrg stuff->x, 245905b261ecSmrg stuff->y, 246005b261ecSmrg stuff->reqType, 246105b261ecSmrg stuff->drawable); 246205b261ecSmrg 246305b261ecSmrg if (err == Success) 246405b261ecSmrg { 246505b261ecSmrg return(client->noClientException); 246605b261ecSmrg } 246705b261ecSmrg else 246805b261ecSmrg return err; 246905b261ecSmrg} 247005b261ecSmrg 247105b261ecSmrg 247205b261ecSmrgint 247305b261ecSmrgProcCreateColormap(ClientPtr client) 247405b261ecSmrg{ 247505b261ecSmrg VisualPtr pVisual; 247605b261ecSmrg ColormapPtr pmap; 247705b261ecSmrg Colormap mid; 247805b261ecSmrg WindowPtr pWin; 247905b261ecSmrg ScreenPtr pScreen; 248005b261ecSmrg REQUEST(xCreateColormapReq); 248105b261ecSmrg int i, result; 248205b261ecSmrg 248305b261ecSmrg REQUEST_SIZE_MATCH(xCreateColormapReq); 248405b261ecSmrg 248505b261ecSmrg if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) 248605b261ecSmrg { 248705b261ecSmrg client->errorValue = stuff->alloc; 248805b261ecSmrg return(BadValue); 248905b261ecSmrg } 249005b261ecSmrg mid = stuff->mid; 249105b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 249205b261ecSmrg result = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); 249305b261ecSmrg if (result != Success) 249405b261ecSmrg return result; 249505b261ecSmrg 249605b261ecSmrg pScreen = pWin->drawable.pScreen; 249705b261ecSmrg for (i = 0, pVisual = pScreen->visuals; 249805b261ecSmrg i < pScreen->numVisuals; 249905b261ecSmrg i++, pVisual++) 250005b261ecSmrg { 250105b261ecSmrg if (pVisual->vid != stuff->visual) 250205b261ecSmrg continue; 250305b261ecSmrg result = CreateColormap(mid, pScreen, pVisual, &pmap, 250405b261ecSmrg (int)stuff->alloc, client->index); 250505b261ecSmrg if (client->noClientException != Success) 250605b261ecSmrg return(client->noClientException); 250705b261ecSmrg else 250805b261ecSmrg return(result); 250905b261ecSmrg } 251005b261ecSmrg client->errorValue = stuff->visual; 251105b261ecSmrg return(BadMatch); 251205b261ecSmrg} 251305b261ecSmrg 251405b261ecSmrgint 251505b261ecSmrgProcFreeColormap(ClientPtr client) 251605b261ecSmrg{ 251705b261ecSmrg ColormapPtr pmap; 251805b261ecSmrg REQUEST(xResourceReq); 251905b261ecSmrg 252005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 252105b261ecSmrg pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP, 252205b261ecSmrg DixDestroyAccess); 252305b261ecSmrg if (pmap) 252405b261ecSmrg { 252505b261ecSmrg /* Freeing a default colormap is a no-op */ 252605b261ecSmrg if (!(pmap->flags & IsDefault)) 252705b261ecSmrg FreeResource(stuff->id, RT_NONE); 252805b261ecSmrg return (client->noClientException); 252905b261ecSmrg } 253005b261ecSmrg else 253105b261ecSmrg { 253205b261ecSmrg client->errorValue = stuff->id; 253305b261ecSmrg return (BadColor); 253405b261ecSmrg } 253505b261ecSmrg} 253605b261ecSmrg 253705b261ecSmrg 253805b261ecSmrgint 253905b261ecSmrgProcCopyColormapAndFree(ClientPtr client) 254005b261ecSmrg{ 254105b261ecSmrg Colormap mid; 254205b261ecSmrg ColormapPtr pSrcMap; 254305b261ecSmrg REQUEST(xCopyColormapAndFreeReq); 254405b261ecSmrg int result; 254505b261ecSmrg 254605b261ecSmrg REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 254705b261ecSmrg mid = stuff->mid; 254805b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 254905b261ecSmrg if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap, 255005b261ecSmrg RT_COLORMAP, DixReadAccess|DixWriteAccess)) ) 255105b261ecSmrg { 255205b261ecSmrg result = CopyColormapAndFree(mid, pSrcMap, client->index); 255305b261ecSmrg if (client->noClientException != Success) 255405b261ecSmrg return(client->noClientException); 255505b261ecSmrg else 255605b261ecSmrg return(result); 255705b261ecSmrg } 255805b261ecSmrg else 255905b261ecSmrg { 256005b261ecSmrg client->errorValue = stuff->srcCmap; 256105b261ecSmrg return(BadColor); 256205b261ecSmrg } 256305b261ecSmrg} 256405b261ecSmrg 256505b261ecSmrgint 256605b261ecSmrgProcInstallColormap(ClientPtr client) 256705b261ecSmrg{ 256805b261ecSmrg ColormapPtr pcmp; 256905b261ecSmrg REQUEST(xResourceReq); 257005b261ecSmrg 257105b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 257205b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id, 257305b261ecSmrg RT_COLORMAP, DixReadAccess); 257405b261ecSmrg if (pcmp) 257505b261ecSmrg { 257605b261ecSmrg (*(pcmp->pScreen->InstallColormap)) (pcmp); 257705b261ecSmrg return (client->noClientException); 257805b261ecSmrg } 257905b261ecSmrg else 258005b261ecSmrg { 258105b261ecSmrg client->errorValue = stuff->id; 258205b261ecSmrg return (BadColor); 258305b261ecSmrg } 258405b261ecSmrg} 258505b261ecSmrg 258605b261ecSmrgint 258705b261ecSmrgProcUninstallColormap(ClientPtr client) 258805b261ecSmrg{ 258905b261ecSmrg ColormapPtr pcmp; 259005b261ecSmrg REQUEST(xResourceReq); 259105b261ecSmrg 259205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 259305b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id, 259405b261ecSmrg RT_COLORMAP, DixReadAccess); 259505b261ecSmrg if (pcmp) 259605b261ecSmrg { 259705b261ecSmrg if(pcmp->mid != pcmp->pScreen->defColormap) 259805b261ecSmrg (*(pcmp->pScreen->UninstallColormap)) (pcmp); 259905b261ecSmrg return (client->noClientException); 260005b261ecSmrg } 260105b261ecSmrg else 260205b261ecSmrg { 260305b261ecSmrg client->errorValue = stuff->id; 260405b261ecSmrg return (BadColor); 260505b261ecSmrg } 260605b261ecSmrg} 260705b261ecSmrg 260805b261ecSmrgint 260905b261ecSmrgProcListInstalledColormaps(ClientPtr client) 261005b261ecSmrg{ 261105b261ecSmrg xListInstalledColormapsReply *preply; 261205b261ecSmrg int nummaps, rc; 261305b261ecSmrg WindowPtr pWin; 261405b261ecSmrg REQUEST(xResourceReq); 261505b261ecSmrg 261605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 261705b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess); 261805b261ecSmrg if (rc != Success) 261905b261ecSmrg return rc; 262005b261ecSmrg 262105b261ecSmrg preply = (xListInstalledColormapsReply *) 262205b261ecSmrg ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) + 262305b261ecSmrg pWin->drawable.pScreen->maxInstalledCmaps * 262405b261ecSmrg sizeof(Colormap)); 262505b261ecSmrg if(!preply) 262605b261ecSmrg return(BadAlloc); 262705b261ecSmrg 262805b261ecSmrg preply->type = X_Reply; 262905b261ecSmrg preply->sequenceNumber = client->sequence; 263005b261ecSmrg nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 263105b261ecSmrg (pWin->drawable.pScreen, (Colormap *)&preply[1]); 263205b261ecSmrg preply->nColormaps = nummaps; 263305b261ecSmrg preply->length = nummaps; 263405b261ecSmrg WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply); 263505b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 263605b261ecSmrg WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 263705b261ecSmrg DEALLOCATE_LOCAL(preply); 263805b261ecSmrg return(client->noClientException); 263905b261ecSmrg} 264005b261ecSmrg 264105b261ecSmrgint 264205b261ecSmrgProcAllocColor (ClientPtr client) 264305b261ecSmrg{ 264405b261ecSmrg ColormapPtr pmap; 264505b261ecSmrg int retval; 264605b261ecSmrg xAllocColorReply acr; 264705b261ecSmrg REQUEST(xAllocColorReq); 264805b261ecSmrg 264905b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorReq); 265005b261ecSmrg pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 265105b261ecSmrg RT_COLORMAP, DixWriteAccess); 265205b261ecSmrg if (pmap) 265305b261ecSmrg { 265405b261ecSmrg acr.type = X_Reply; 265505b261ecSmrg acr.length = 0; 265605b261ecSmrg acr.sequenceNumber = client->sequence; 265705b261ecSmrg acr.red = stuff->red; 265805b261ecSmrg acr.green = stuff->green; 265905b261ecSmrg acr.blue = stuff->blue; 266005b261ecSmrg acr.pixel = 0; 266105b261ecSmrg if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 266205b261ecSmrg &acr.pixel, client->index)) ) 266305b261ecSmrg { 266405b261ecSmrg if (client->noClientException != Success) 266505b261ecSmrg return(client->noClientException); 266605b261ecSmrg else 266705b261ecSmrg return (retval); 266805b261ecSmrg } 266905b261ecSmrg#ifdef PANORAMIX 267005b261ecSmrg if (noPanoramiXExtension || !pmap->pScreen->myNum) 267105b261ecSmrg#endif 267205b261ecSmrg WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 267305b261ecSmrg return (client->noClientException); 267405b261ecSmrg 267505b261ecSmrg } 267605b261ecSmrg else 267705b261ecSmrg { 267805b261ecSmrg client->errorValue = stuff->cmap; 267905b261ecSmrg return (BadColor); 268005b261ecSmrg } 268105b261ecSmrg} 268205b261ecSmrg 268305b261ecSmrgint 268405b261ecSmrgProcAllocNamedColor (ClientPtr client) 268505b261ecSmrg{ 268605b261ecSmrg ColormapPtr pcmp; 268705b261ecSmrg REQUEST(xAllocNamedColorReq); 268805b261ecSmrg 268905b261ecSmrg REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 269005b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 269105b261ecSmrg RT_COLORMAP, DixWriteAccess); 269205b261ecSmrg if (pcmp) 269305b261ecSmrg { 269405b261ecSmrg int retval; 269505b261ecSmrg 269605b261ecSmrg xAllocNamedColorReply ancr; 269705b261ecSmrg 269805b261ecSmrg ancr.type = X_Reply; 269905b261ecSmrg ancr.length = 0; 270005b261ecSmrg ancr.sequenceNumber = client->sequence; 270105b261ecSmrg 270205b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 270305b261ecSmrg &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) 270405b261ecSmrg { 270505b261ecSmrg ancr.screenRed = ancr.exactRed; 270605b261ecSmrg ancr.screenGreen = ancr.exactGreen; 270705b261ecSmrg ancr.screenBlue = ancr.exactBlue; 270805b261ecSmrg ancr.pixel = 0; 270905b261ecSmrg if( (retval = AllocColor(pcmp, 271005b261ecSmrg &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, 271105b261ecSmrg &ancr.pixel, client->index)) ) 271205b261ecSmrg { 271305b261ecSmrg if (client->noClientException != Success) 271405b261ecSmrg return(client->noClientException); 271505b261ecSmrg else 271605b261ecSmrg return(retval); 271705b261ecSmrg } 271805b261ecSmrg#ifdef PANORAMIX 271905b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 272005b261ecSmrg#endif 272105b261ecSmrg WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr); 272205b261ecSmrg return (client->noClientException); 272305b261ecSmrg } 272405b261ecSmrg else 272505b261ecSmrg return(BadName); 272605b261ecSmrg 272705b261ecSmrg } 272805b261ecSmrg else 272905b261ecSmrg { 273005b261ecSmrg client->errorValue = stuff->cmap; 273105b261ecSmrg return (BadColor); 273205b261ecSmrg } 273305b261ecSmrg} 273405b261ecSmrg 273505b261ecSmrgint 273605b261ecSmrgProcAllocColorCells (ClientPtr client) 273705b261ecSmrg{ 273805b261ecSmrg ColormapPtr pcmp; 273905b261ecSmrg REQUEST(xAllocColorCellsReq); 274005b261ecSmrg 274105b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorCellsReq); 274205b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 274305b261ecSmrg RT_COLORMAP, DixWriteAccess); 274405b261ecSmrg if (pcmp) 274505b261ecSmrg { 274605b261ecSmrg xAllocColorCellsReply accr; 274705b261ecSmrg int npixels, nmasks, retval; 274805b261ecSmrg long length; 274905b261ecSmrg Pixel *ppixels, *pmasks; 275005b261ecSmrg 275105b261ecSmrg npixels = stuff->colors; 275205b261ecSmrg if (!npixels) 275305b261ecSmrg { 275405b261ecSmrg client->errorValue = npixels; 275505b261ecSmrg return (BadValue); 275605b261ecSmrg } 275705b261ecSmrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 275805b261ecSmrg { 275905b261ecSmrg client->errorValue = stuff->contiguous; 276005b261ecSmrg return (BadValue); 276105b261ecSmrg } 276205b261ecSmrg nmasks = stuff->planes; 276305b261ecSmrg length = ((long)npixels + (long)nmasks) * sizeof(Pixel); 276405b261ecSmrg ppixels = (Pixel *)ALLOCATE_LOCAL(length); 276505b261ecSmrg if(!ppixels) 276605b261ecSmrg return(BadAlloc); 276705b261ecSmrg pmasks = ppixels + npixels; 276805b261ecSmrg 276905b261ecSmrg if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 277005b261ecSmrg (Bool)stuff->contiguous, ppixels, pmasks)) ) 277105b261ecSmrg { 277205b261ecSmrg DEALLOCATE_LOCAL(ppixels); 277305b261ecSmrg if (client->noClientException != Success) 277405b261ecSmrg return(client->noClientException); 277505b261ecSmrg else 277605b261ecSmrg return(retval); 277705b261ecSmrg } 277805b261ecSmrg#ifdef PANORAMIX 277905b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 278005b261ecSmrg#endif 278105b261ecSmrg { 278205b261ecSmrg accr.type = X_Reply; 278305b261ecSmrg accr.length = length >> 2; 278405b261ecSmrg accr.sequenceNumber = client->sequence; 278505b261ecSmrg accr.nPixels = npixels; 278605b261ecSmrg accr.nMasks = nmasks; 278705b261ecSmrg WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr); 278805b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 278905b261ecSmrg WriteSwappedDataToClient(client, length, ppixels); 279005b261ecSmrg } 279105b261ecSmrg DEALLOCATE_LOCAL(ppixels); 279205b261ecSmrg return (client->noClientException); 279305b261ecSmrg } 279405b261ecSmrg else 279505b261ecSmrg { 279605b261ecSmrg client->errorValue = stuff->cmap; 279705b261ecSmrg return (BadColor); 279805b261ecSmrg } 279905b261ecSmrg} 280005b261ecSmrg 280105b261ecSmrgint 280205b261ecSmrgProcAllocColorPlanes(ClientPtr client) 280305b261ecSmrg{ 280405b261ecSmrg ColormapPtr pcmp; 280505b261ecSmrg REQUEST(xAllocColorPlanesReq); 280605b261ecSmrg 280705b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 280805b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 280905b261ecSmrg RT_COLORMAP, DixWriteAccess); 281005b261ecSmrg if (pcmp) 281105b261ecSmrg { 281205b261ecSmrg xAllocColorPlanesReply acpr; 281305b261ecSmrg int npixels, retval; 281405b261ecSmrg long length; 281505b261ecSmrg Pixel *ppixels; 281605b261ecSmrg 281705b261ecSmrg npixels = stuff->colors; 281805b261ecSmrg if (!npixels) 281905b261ecSmrg { 282005b261ecSmrg client->errorValue = npixels; 282105b261ecSmrg return (BadValue); 282205b261ecSmrg } 282305b261ecSmrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 282405b261ecSmrg { 282505b261ecSmrg client->errorValue = stuff->contiguous; 282605b261ecSmrg return (BadValue); 282705b261ecSmrg } 282805b261ecSmrg acpr.type = X_Reply; 282905b261ecSmrg acpr.sequenceNumber = client->sequence; 283005b261ecSmrg acpr.nPixels = npixels; 283105b261ecSmrg length = (long)npixels * sizeof(Pixel); 283205b261ecSmrg ppixels = (Pixel *)ALLOCATE_LOCAL(length); 283305b261ecSmrg if(!ppixels) 283405b261ecSmrg return(BadAlloc); 283505b261ecSmrg if( (retval = AllocColorPlanes(client->index, pcmp, npixels, 283605b261ecSmrg (int)stuff->red, (int)stuff->green, (int)stuff->blue, 283705b261ecSmrg (Bool)stuff->contiguous, ppixels, 283805b261ecSmrg &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) ) 283905b261ecSmrg { 284005b261ecSmrg DEALLOCATE_LOCAL(ppixels); 284105b261ecSmrg if (client->noClientException != Success) 284205b261ecSmrg return(client->noClientException); 284305b261ecSmrg else 284405b261ecSmrg return(retval); 284505b261ecSmrg } 284605b261ecSmrg acpr.length = length >> 2; 284705b261ecSmrg#ifdef PANORAMIX 284805b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 284905b261ecSmrg#endif 285005b261ecSmrg { 285105b261ecSmrg WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 285205b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 285305b261ecSmrg WriteSwappedDataToClient(client, length, ppixels); 285405b261ecSmrg } 285505b261ecSmrg DEALLOCATE_LOCAL(ppixels); 285605b261ecSmrg return (client->noClientException); 285705b261ecSmrg } 285805b261ecSmrg else 285905b261ecSmrg { 286005b261ecSmrg client->errorValue = stuff->cmap; 286105b261ecSmrg return (BadColor); 286205b261ecSmrg } 286305b261ecSmrg} 286405b261ecSmrg 286505b261ecSmrgint 286605b261ecSmrgProcFreeColors(ClientPtr client) 286705b261ecSmrg{ 286805b261ecSmrg ColormapPtr pcmp; 286905b261ecSmrg REQUEST(xFreeColorsReq); 287005b261ecSmrg 287105b261ecSmrg REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 287205b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 287305b261ecSmrg RT_COLORMAP, DixWriteAccess); 287405b261ecSmrg if (pcmp) 287505b261ecSmrg { 287605b261ecSmrg int count; 287705b261ecSmrg int retval; 287805b261ecSmrg 287905b261ecSmrg if(pcmp->flags & AllAllocated) 288005b261ecSmrg return(BadAccess); 288105b261ecSmrg count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2; 288205b261ecSmrg retval = FreeColors(pcmp, client->index, count, 288305b261ecSmrg (Pixel *)&stuff[1], (Pixel)stuff->planeMask); 288405b261ecSmrg if (client->noClientException != Success) 288505b261ecSmrg return(client->noClientException); 288605b261ecSmrg else 288705b261ecSmrg { 288805b261ecSmrg client->errorValue = clientErrorValue; 288905b261ecSmrg return(retval); 289005b261ecSmrg } 289105b261ecSmrg 289205b261ecSmrg } 289305b261ecSmrg else 289405b261ecSmrg { 289505b261ecSmrg client->errorValue = stuff->cmap; 289605b261ecSmrg return (BadColor); 289705b261ecSmrg } 289805b261ecSmrg} 289905b261ecSmrg 290005b261ecSmrgint 290105b261ecSmrgProcStoreColors (ClientPtr client) 290205b261ecSmrg{ 290305b261ecSmrg ColormapPtr pcmp; 290405b261ecSmrg REQUEST(xStoreColorsReq); 290505b261ecSmrg 290605b261ecSmrg REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 290705b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 290805b261ecSmrg RT_COLORMAP, DixWriteAccess); 290905b261ecSmrg if (pcmp) 291005b261ecSmrg { 291105b261ecSmrg int count; 291205b261ecSmrg int retval; 291305b261ecSmrg 291405b261ecSmrg count = (client->req_len << 2) - sizeof(xStoreColorsReq); 291505b261ecSmrg if (count % sizeof(xColorItem)) 291605b261ecSmrg return(BadLength); 291705b261ecSmrg count /= sizeof(xColorItem); 291805b261ecSmrg retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]); 291905b261ecSmrg if (client->noClientException != Success) 292005b261ecSmrg return(client->noClientException); 292105b261ecSmrg else 292205b261ecSmrg { 292305b261ecSmrg client->errorValue = clientErrorValue; 292405b261ecSmrg return(retval); 292505b261ecSmrg } 292605b261ecSmrg } 292705b261ecSmrg else 292805b261ecSmrg { 292905b261ecSmrg client->errorValue = stuff->cmap; 293005b261ecSmrg return (BadColor); 293105b261ecSmrg } 293205b261ecSmrg} 293305b261ecSmrg 293405b261ecSmrgint 293505b261ecSmrgProcStoreNamedColor (ClientPtr client) 293605b261ecSmrg{ 293705b261ecSmrg ColormapPtr pcmp; 293805b261ecSmrg REQUEST(xStoreNamedColorReq); 293905b261ecSmrg 294005b261ecSmrg REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 294105b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 294205b261ecSmrg RT_COLORMAP, DixWriteAccess); 294305b261ecSmrg if (pcmp) 294405b261ecSmrg { 294505b261ecSmrg xColorItem def; 294605b261ecSmrg int retval; 294705b261ecSmrg 294805b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], 294905b261ecSmrg stuff->nbytes, &def.red, &def.green, &def.blue)) 295005b261ecSmrg { 295105b261ecSmrg def.flags = stuff->flags; 295205b261ecSmrg def.pixel = stuff->pixel; 295305b261ecSmrg retval = StoreColors(pcmp, 1, &def); 295405b261ecSmrg if (client->noClientException != Success) 295505b261ecSmrg return(client->noClientException); 295605b261ecSmrg else 295705b261ecSmrg return(retval); 295805b261ecSmrg } 295905b261ecSmrg return (BadName); 296005b261ecSmrg } 296105b261ecSmrg else 296205b261ecSmrg { 296305b261ecSmrg client->errorValue = stuff->cmap; 296405b261ecSmrg return (BadColor); 296505b261ecSmrg } 296605b261ecSmrg} 296705b261ecSmrg 296805b261ecSmrgint 296905b261ecSmrgProcQueryColors(ClientPtr client) 297005b261ecSmrg{ 297105b261ecSmrg ColormapPtr pcmp; 297205b261ecSmrg REQUEST(xQueryColorsReq); 297305b261ecSmrg 297405b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 297505b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 297605b261ecSmrg RT_COLORMAP, DixReadAccess); 297705b261ecSmrg if (pcmp) 297805b261ecSmrg { 297905b261ecSmrg int count, retval; 298005b261ecSmrg xrgb *prgbs; 298105b261ecSmrg xQueryColorsReply qcr; 298205b261ecSmrg 298305b261ecSmrg count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2; 298405b261ecSmrg prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb)); 298505b261ecSmrg if(!prgbs && count) 298605b261ecSmrg return(BadAlloc); 298705b261ecSmrg if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) ) 298805b261ecSmrg { 298905b261ecSmrg if (prgbs) DEALLOCATE_LOCAL(prgbs); 299005b261ecSmrg if (client->noClientException != Success) 299105b261ecSmrg return(client->noClientException); 299205b261ecSmrg else 299305b261ecSmrg { 299405b261ecSmrg client->errorValue = clientErrorValue; 299505b261ecSmrg return (retval); 299605b261ecSmrg } 299705b261ecSmrg } 299805b261ecSmrg qcr.type = X_Reply; 299905b261ecSmrg qcr.length = (count * sizeof(xrgb)) >> 2; 300005b261ecSmrg qcr.sequenceNumber = client->sequence; 300105b261ecSmrg qcr.nColors = count; 300205b261ecSmrg WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 300305b261ecSmrg if (count) 300405b261ecSmrg { 300505b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 300605b261ecSmrg WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 300705b261ecSmrg } 300805b261ecSmrg if (prgbs) DEALLOCATE_LOCAL(prgbs); 300905b261ecSmrg return(client->noClientException); 301005b261ecSmrg 301105b261ecSmrg } 301205b261ecSmrg else 301305b261ecSmrg { 301405b261ecSmrg client->errorValue = stuff->cmap; 301505b261ecSmrg return (BadColor); 301605b261ecSmrg } 301705b261ecSmrg} 301805b261ecSmrg 301905b261ecSmrgint 302005b261ecSmrgProcLookupColor(ClientPtr client) 302105b261ecSmrg{ 302205b261ecSmrg ColormapPtr pcmp; 302305b261ecSmrg REQUEST(xLookupColorReq); 302405b261ecSmrg 302505b261ecSmrg REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 302605b261ecSmrg pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap, 302705b261ecSmrg RT_COLORMAP, DixReadAccess); 302805b261ecSmrg if (pcmp) 302905b261ecSmrg { 303005b261ecSmrg xLookupColorReply lcr; 303105b261ecSmrg 303205b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 303305b261ecSmrg &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) 303405b261ecSmrg { 303505b261ecSmrg lcr.type = X_Reply; 303605b261ecSmrg lcr.length = 0; 303705b261ecSmrg lcr.sequenceNumber = client->sequence; 303805b261ecSmrg lcr.screenRed = lcr.exactRed; 303905b261ecSmrg lcr.screenGreen = lcr.exactGreen; 304005b261ecSmrg lcr.screenBlue = lcr.exactBlue; 304105b261ecSmrg (*pcmp->pScreen->ResolveColor)(&lcr.screenRed, 304205b261ecSmrg &lcr.screenGreen, 304305b261ecSmrg &lcr.screenBlue, 304405b261ecSmrg pcmp->pVisual); 304505b261ecSmrg WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 304605b261ecSmrg return(client->noClientException); 304705b261ecSmrg } 304805b261ecSmrg return (BadName); 304905b261ecSmrg } 305005b261ecSmrg else 305105b261ecSmrg { 305205b261ecSmrg client->errorValue = stuff->cmap; 305305b261ecSmrg return (BadColor); 305405b261ecSmrg } 305505b261ecSmrg} 305605b261ecSmrg 305705b261ecSmrgint 305805b261ecSmrgProcCreateCursor (ClientPtr client) 305905b261ecSmrg{ 306005b261ecSmrg CursorPtr pCursor; 306105b261ecSmrg PixmapPtr src; 306205b261ecSmrg PixmapPtr msk; 306305b261ecSmrg unsigned char * srcbits; 306405b261ecSmrg unsigned char * mskbits; 306505b261ecSmrg unsigned short width, height; 306605b261ecSmrg long n; 306705b261ecSmrg CursorMetricRec cm; 306805b261ecSmrg 306905b261ecSmrg 307005b261ecSmrg REQUEST(xCreateCursorReq); 307105b261ecSmrg 307205b261ecSmrg REQUEST_SIZE_MATCH(xCreateCursorReq); 307305b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 307405b261ecSmrg 307505b261ecSmrg src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source, 307605b261ecSmrg RT_PIXMAP, DixReadAccess); 307705b261ecSmrg msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask, 307805b261ecSmrg RT_PIXMAP, DixReadAccess); 307905b261ecSmrg if ( src == (PixmapPtr)NULL) 308005b261ecSmrg { 308105b261ecSmrg client->errorValue = stuff->source; 308205b261ecSmrg return (BadPixmap); 308305b261ecSmrg } 308405b261ecSmrg if ( msk == (PixmapPtr)NULL) 308505b261ecSmrg { 308605b261ecSmrg if (stuff->mask != None) 308705b261ecSmrg { 308805b261ecSmrg client->errorValue = stuff->mask; 308905b261ecSmrg return (BadPixmap); 309005b261ecSmrg } 309105b261ecSmrg } 309205b261ecSmrg else if ( src->drawable.width != msk->drawable.width 309305b261ecSmrg || src->drawable.height != msk->drawable.height 309405b261ecSmrg || src->drawable.depth != 1 309505b261ecSmrg || msk->drawable.depth != 1) 309605b261ecSmrg return (BadMatch); 309705b261ecSmrg 309805b261ecSmrg width = src->drawable.width; 309905b261ecSmrg height = src->drawable.height; 310005b261ecSmrg 310105b261ecSmrg if ( stuff->x > width 310205b261ecSmrg || stuff->y > height ) 310305b261ecSmrg return (BadMatch); 310405b261ecSmrg 310505b261ecSmrg n = BitmapBytePad(width)*height; 310605b261ecSmrg srcbits = (unsigned char *)xalloc(n); 310705b261ecSmrg if (!srcbits) 310805b261ecSmrg return (BadAlloc); 310905b261ecSmrg mskbits = (unsigned char *)xalloc(n); 311005b261ecSmrg if (!mskbits) 311105b261ecSmrg { 311205b261ecSmrg xfree(srcbits); 311305b261ecSmrg return (BadAlloc); 311405b261ecSmrg } 311505b261ecSmrg 311605b261ecSmrg /* zeroing the (pad) bits helps some ddx cursor handling */ 311705b261ecSmrg bzero((char *)srcbits, n); 311805b261ecSmrg (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height, 311905b261ecSmrg XYPixmap, 1, (pointer)srcbits); 312005b261ecSmrg if ( msk == (PixmapPtr)NULL) 312105b261ecSmrg { 312205b261ecSmrg unsigned char *bits = mskbits; 312305b261ecSmrg while (--n >= 0) 312405b261ecSmrg *bits++ = ~0; 312505b261ecSmrg } 312605b261ecSmrg else 312705b261ecSmrg { 312805b261ecSmrg /* zeroing the (pad) bits helps some ddx cursor handling */ 312905b261ecSmrg bzero((char *)mskbits, n); 313005b261ecSmrg (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width, 313105b261ecSmrg height, XYPixmap, 1, (pointer)mskbits); 313205b261ecSmrg } 313305b261ecSmrg cm.width = width; 313405b261ecSmrg cm.height = height; 313505b261ecSmrg cm.xhot = stuff->x; 313605b261ecSmrg cm.yhot = stuff->y; 313705b261ecSmrg pCursor = AllocCursor( srcbits, mskbits, &cm, 313805b261ecSmrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 313905b261ecSmrg stuff->backRed, stuff->backGreen, stuff->backBlue); 314005b261ecSmrg 314105b261ecSmrg if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 314205b261ecSmrg return (client->noClientException); 314305b261ecSmrg return BadAlloc; 314405b261ecSmrg} 314505b261ecSmrg 314605b261ecSmrgint 314705b261ecSmrgProcCreateGlyphCursor (ClientPtr client) 314805b261ecSmrg{ 314905b261ecSmrg CursorPtr pCursor; 315005b261ecSmrg int res; 315105b261ecSmrg 315205b261ecSmrg REQUEST(xCreateGlyphCursorReq); 315305b261ecSmrg 315405b261ecSmrg REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 315505b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 315605b261ecSmrg 315705b261ecSmrg res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 315805b261ecSmrg stuff->mask, stuff->maskChar, 315905b261ecSmrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 316005b261ecSmrg stuff->backRed, stuff->backGreen, stuff->backBlue, 316105b261ecSmrg &pCursor, client); 316205b261ecSmrg if (res != Success) 316305b261ecSmrg return res; 316405b261ecSmrg if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 316505b261ecSmrg return client->noClientException; 316605b261ecSmrg return BadAlloc; 316705b261ecSmrg} 316805b261ecSmrg 316905b261ecSmrg 317005b261ecSmrgint 317105b261ecSmrgProcFreeCursor (ClientPtr client) 317205b261ecSmrg{ 317305b261ecSmrg CursorPtr pCursor; 317405b261ecSmrg REQUEST(xResourceReq); 317505b261ecSmrg 317605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 317705b261ecSmrg pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id, 317805b261ecSmrg RT_CURSOR, DixDestroyAccess); 317905b261ecSmrg if (pCursor) 318005b261ecSmrg { 318105b261ecSmrg FreeResource(stuff->id, RT_NONE); 318205b261ecSmrg return (client->noClientException); 318305b261ecSmrg } 318405b261ecSmrg else 318505b261ecSmrg { 318605b261ecSmrg client->errorValue = stuff->id; 318705b261ecSmrg return (BadCursor); 318805b261ecSmrg } 318905b261ecSmrg} 319005b261ecSmrg 319105b261ecSmrgint 319205b261ecSmrgProcQueryBestSize (ClientPtr client) 319305b261ecSmrg{ 319405b261ecSmrg xQueryBestSizeReply reply; 319505b261ecSmrg DrawablePtr pDraw; 319605b261ecSmrg ScreenPtr pScreen; 319705b261ecSmrg int rc; 319805b261ecSmrg REQUEST(xQueryBestSizeReq); 319905b261ecSmrg REQUEST_SIZE_MATCH(xQueryBestSizeReq); 320005b261ecSmrg 320105b261ecSmrg if ((stuff->class != CursorShape) && 320205b261ecSmrg (stuff->class != TileShape) && 320305b261ecSmrg (stuff->class != StippleShape)) 320405b261ecSmrg { 320505b261ecSmrg client->errorValue = stuff->class; 320605b261ecSmrg return(BadValue); 320705b261ecSmrg } 320805b261ecSmrg 320905b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 321005b261ecSmrg DixReadAccess); 321105b261ecSmrg if (rc != Success) 321205b261ecSmrg return rc; 321305b261ecSmrg if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 321405b261ecSmrg return (BadMatch); 321505b261ecSmrg pScreen = pDraw->pScreen; 321605b261ecSmrg (* pScreen->QueryBestSize)(stuff->class, &stuff->width, 321705b261ecSmrg &stuff->height, pScreen); 321805b261ecSmrg reply.type = X_Reply; 321905b261ecSmrg reply.length = 0; 322005b261ecSmrg reply.sequenceNumber = client->sequence; 322105b261ecSmrg reply.width = stuff->width; 322205b261ecSmrg reply.height = stuff->height; 322305b261ecSmrg WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 322405b261ecSmrg return (client->noClientException); 322505b261ecSmrg} 322605b261ecSmrg 322705b261ecSmrg 322805b261ecSmrgint 322905b261ecSmrgProcSetScreenSaver (ClientPtr client) 323005b261ecSmrg{ 323105b261ecSmrg int blankingOption, exposureOption; 323205b261ecSmrg REQUEST(xSetScreenSaverReq); 323305b261ecSmrg 323405b261ecSmrg REQUEST_SIZE_MATCH(xSetScreenSaverReq); 323505b261ecSmrg blankingOption = stuff->preferBlank; 323605b261ecSmrg if ((blankingOption != DontPreferBlanking) && 323705b261ecSmrg (blankingOption != PreferBlanking) && 323805b261ecSmrg (blankingOption != DefaultBlanking)) 323905b261ecSmrg { 324005b261ecSmrg client->errorValue = blankingOption; 324105b261ecSmrg return BadValue; 324205b261ecSmrg } 324305b261ecSmrg exposureOption = stuff->allowExpose; 324405b261ecSmrg if ((exposureOption != DontAllowExposures) && 324505b261ecSmrg (exposureOption != AllowExposures) && 324605b261ecSmrg (exposureOption != DefaultExposures)) 324705b261ecSmrg { 324805b261ecSmrg client->errorValue = exposureOption; 324905b261ecSmrg return BadValue; 325005b261ecSmrg } 325105b261ecSmrg if (stuff->timeout < -1) 325205b261ecSmrg { 325305b261ecSmrg client->errorValue = stuff->timeout; 325405b261ecSmrg return BadValue; 325505b261ecSmrg } 325605b261ecSmrg if (stuff->interval < -1) 325705b261ecSmrg { 325805b261ecSmrg client->errorValue = stuff->interval; 325905b261ecSmrg return BadValue; 326005b261ecSmrg } 326105b261ecSmrg 326205b261ecSmrg if (blankingOption == DefaultBlanking) 326305b261ecSmrg ScreenSaverBlanking = defaultScreenSaverBlanking; 326405b261ecSmrg else 326505b261ecSmrg ScreenSaverBlanking = blankingOption; 326605b261ecSmrg if (exposureOption == DefaultExposures) 326705b261ecSmrg ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 326805b261ecSmrg else 326905b261ecSmrg ScreenSaverAllowExposures = exposureOption; 327005b261ecSmrg 327105b261ecSmrg if (stuff->timeout >= 0) 327205b261ecSmrg ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 327305b261ecSmrg else 327405b261ecSmrg ScreenSaverTime = defaultScreenSaverTime; 327505b261ecSmrg if (stuff->interval >= 0) 327605b261ecSmrg ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 327705b261ecSmrg else 327805b261ecSmrg ScreenSaverInterval = defaultScreenSaverInterval; 327905b261ecSmrg 328005b261ecSmrg SetScreenSaverTimer(); 328105b261ecSmrg return (client->noClientException); 328205b261ecSmrg} 328305b261ecSmrg 328405b261ecSmrgint 328505b261ecSmrgProcGetScreenSaver(ClientPtr client) 328605b261ecSmrg{ 328705b261ecSmrg xGetScreenSaverReply rep; 328805b261ecSmrg 328905b261ecSmrg REQUEST_SIZE_MATCH(xReq); 329005b261ecSmrg rep.type = X_Reply; 329105b261ecSmrg rep.length = 0; 329205b261ecSmrg rep.sequenceNumber = client->sequence; 329305b261ecSmrg rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; 329405b261ecSmrg rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; 329505b261ecSmrg rep.preferBlanking = ScreenSaverBlanking; 329605b261ecSmrg rep.allowExposures = ScreenSaverAllowExposures; 329705b261ecSmrg WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 329805b261ecSmrg return (client->noClientException); 329905b261ecSmrg} 330005b261ecSmrg 330105b261ecSmrgint 330205b261ecSmrgProcChangeHosts(ClientPtr client) 330305b261ecSmrg{ 330405b261ecSmrg REQUEST(xChangeHostsReq); 330505b261ecSmrg int result; 330605b261ecSmrg 330705b261ecSmrg REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 330805b261ecSmrg 330905b261ecSmrg if(stuff->mode == HostInsert) 331005b261ecSmrg result = AddHost(client, (int)stuff->hostFamily, 331105b261ecSmrg stuff->hostLength, (pointer)&stuff[1]); 331205b261ecSmrg else if (stuff->mode == HostDelete) 331305b261ecSmrg result = RemoveHost(client, (int)stuff->hostFamily, 331405b261ecSmrg stuff->hostLength, (pointer)&stuff[1]); 331505b261ecSmrg else 331605b261ecSmrg { 331705b261ecSmrg client->errorValue = stuff->mode; 331805b261ecSmrg return BadValue; 331905b261ecSmrg } 332005b261ecSmrg if (!result) 332105b261ecSmrg result = client->noClientException; 332205b261ecSmrg return (result); 332305b261ecSmrg} 332405b261ecSmrg 332505b261ecSmrgint 332605b261ecSmrgProcListHosts(ClientPtr client) 332705b261ecSmrg{ 332805b261ecSmrg xListHostsReply reply; 332905b261ecSmrg int len, nHosts, result; 333005b261ecSmrg pointer pdata; 333105b261ecSmrg /* REQUEST(xListHostsReq); */ 333205b261ecSmrg 333305b261ecSmrg REQUEST_SIZE_MATCH(xListHostsReq); 333405b261ecSmrg 333505b261ecSmrg /* untrusted clients can't list hosts */ 333605b261ecSmrg if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixReadAccess)) 333705b261ecSmrg return BadAccess; 333805b261ecSmrg 333905b261ecSmrg result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); 334005b261ecSmrg if (result != Success) 334105b261ecSmrg return(result); 334205b261ecSmrg reply.type = X_Reply; 334305b261ecSmrg reply.sequenceNumber = client->sequence; 334405b261ecSmrg reply.nHosts = nHosts; 334505b261ecSmrg reply.length = len >> 2; 334605b261ecSmrg WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 334705b261ecSmrg if (nHosts) 334805b261ecSmrg { 334905b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 335005b261ecSmrg WriteSwappedDataToClient(client, len, pdata); 335105b261ecSmrg } 335205b261ecSmrg xfree(pdata); 335305b261ecSmrg return (client->noClientException); 335405b261ecSmrg} 335505b261ecSmrg 335605b261ecSmrgint 335705b261ecSmrgProcChangeAccessControl(ClientPtr client) 335805b261ecSmrg{ 335905b261ecSmrg int result; 336005b261ecSmrg REQUEST(xSetAccessControlReq); 336105b261ecSmrg 336205b261ecSmrg REQUEST_SIZE_MATCH(xSetAccessControlReq); 336305b261ecSmrg if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) 336405b261ecSmrg { 336505b261ecSmrg client->errorValue = stuff->mode; 336605b261ecSmrg return BadValue; 336705b261ecSmrg } 336805b261ecSmrg result = ChangeAccessControl(client, stuff->mode == EnableAccess); 336905b261ecSmrg if (!result) 337005b261ecSmrg result = client->noClientException; 337105b261ecSmrg return (result); 337205b261ecSmrg} 337305b261ecSmrg 337405b261ecSmrg/********************* 337505b261ecSmrg * CloseDownRetainedResources 337605b261ecSmrg * 337705b261ecSmrg * Find all clients that are gone and have terminated in RetainTemporary 337805b261ecSmrg * and destroy their resources. 337905b261ecSmrg *********************/ 338005b261ecSmrg 338105b261ecSmrgstatic void 338205b261ecSmrgCloseDownRetainedResources(void) 338305b261ecSmrg{ 338405b261ecSmrg int i; 338505b261ecSmrg ClientPtr client; 338605b261ecSmrg 338705b261ecSmrg for (i=1; i<currentMaxClients; i++) 338805b261ecSmrg { 338905b261ecSmrg client = clients[i]; 339005b261ecSmrg if (client && (client->closeDownMode == RetainTemporary) 339105b261ecSmrg && (client->clientGone)) 339205b261ecSmrg CloseDownClient(client); 339305b261ecSmrg } 339405b261ecSmrg} 339505b261ecSmrg 339605b261ecSmrgint 339705b261ecSmrgProcKillClient(ClientPtr client) 339805b261ecSmrg{ 339905b261ecSmrg REQUEST(xResourceReq); 340005b261ecSmrg ClientPtr killclient; 340105b261ecSmrg int rc; 340205b261ecSmrg 340305b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 340405b261ecSmrg if (stuff->id == AllTemporary) 340505b261ecSmrg { 340605b261ecSmrg CloseDownRetainedResources(); 340705b261ecSmrg return (client->noClientException); 340805b261ecSmrg } 340905b261ecSmrg 341005b261ecSmrg rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 341105b261ecSmrg if (rc == Success) { 341205b261ecSmrg CloseDownClient(killclient); 341305b261ecSmrg /* if an LBX proxy gets killed, isItTimeToYield will be set */ 341405b261ecSmrg if (isItTimeToYield || (client == killclient)) 341505b261ecSmrg { 341605b261ecSmrg /* force yield and return Success, so that Dispatch() 341705b261ecSmrg * doesn't try to touch client 341805b261ecSmrg */ 341905b261ecSmrg isItTimeToYield = TRUE; 342005b261ecSmrg return (Success); 342105b261ecSmrg } 342205b261ecSmrg return (client->noClientException); 342305b261ecSmrg } 342405b261ecSmrg else 342505b261ecSmrg return rc; 342605b261ecSmrg} 342705b261ecSmrg 342805b261ecSmrgint 342905b261ecSmrgProcSetFontPath(ClientPtr client) 343005b261ecSmrg{ 343105b261ecSmrg unsigned char *ptr; 343205b261ecSmrg unsigned long nbytes, total; 343305b261ecSmrg long nfonts; 343405b261ecSmrg int n, result; 343505b261ecSmrg int error; 343605b261ecSmrg REQUEST(xSetFontPathReq); 343705b261ecSmrg 343805b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 343905b261ecSmrg 344005b261ecSmrg nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 344105b261ecSmrg total = nbytes; 344205b261ecSmrg ptr = (unsigned char *)&stuff[1]; 344305b261ecSmrg nfonts = stuff->nFonts; 344405b261ecSmrg while (--nfonts >= 0) 344505b261ecSmrg { 344605b261ecSmrg if ((total == 0) || (total < (n = (*ptr + 1)))) 344705b261ecSmrg return(BadLength); 344805b261ecSmrg total -= n; 344905b261ecSmrg ptr += n; 345005b261ecSmrg } 345105b261ecSmrg if (total >= 4) 345205b261ecSmrg return(BadLength); 345305b261ecSmrg result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1], 345405b261ecSmrg &error); 345505b261ecSmrg if (!result) 345605b261ecSmrg { 345705b261ecSmrg result = client->noClientException; 345805b261ecSmrg client->errorValue = error; 345905b261ecSmrg } 346005b261ecSmrg return (result); 346105b261ecSmrg} 346205b261ecSmrg 346305b261ecSmrgint 346405b261ecSmrgProcGetFontPath(ClientPtr client) 346505b261ecSmrg{ 346605b261ecSmrg xGetFontPathReply reply; 346705b261ecSmrg int stringLens, numpaths; 346805b261ecSmrg unsigned char *bufferStart; 346905b261ecSmrg /* REQUEST (xReq); */ 347005b261ecSmrg 347105b261ecSmrg REQUEST_SIZE_MATCH(xReq); 347205b261ecSmrg bufferStart = GetFontPath(&numpaths, &stringLens); 347305b261ecSmrg 347405b261ecSmrg reply.type = X_Reply; 347505b261ecSmrg reply.sequenceNumber = client->sequence; 347605b261ecSmrg reply.length = (stringLens + numpaths + 3) >> 2; 347705b261ecSmrg reply.nPaths = numpaths; 347805b261ecSmrg 347905b261ecSmrg WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 348005b261ecSmrg if (stringLens || numpaths) 348105b261ecSmrg (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart); 348205b261ecSmrg return(client->noClientException); 348305b261ecSmrg} 348405b261ecSmrg 348505b261ecSmrgint 348605b261ecSmrgProcChangeCloseDownMode(ClientPtr client) 348705b261ecSmrg{ 348805b261ecSmrg REQUEST(xSetCloseDownModeReq); 348905b261ecSmrg 349005b261ecSmrg REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 349105b261ecSmrg if ((stuff->mode == AllTemporary) || 349205b261ecSmrg (stuff->mode == RetainPermanent) || 349305b261ecSmrg (stuff->mode == RetainTemporary)) 349405b261ecSmrg { 349505b261ecSmrg client->closeDownMode = stuff->mode; 349605b261ecSmrg return (client->noClientException); 349705b261ecSmrg } 349805b261ecSmrg else 349905b261ecSmrg { 350005b261ecSmrg client->errorValue = stuff->mode; 350105b261ecSmrg return (BadValue); 350205b261ecSmrg } 350305b261ecSmrg} 350405b261ecSmrg 350505b261ecSmrgint ProcForceScreenSaver(ClientPtr client) 350605b261ecSmrg{ 350705b261ecSmrg REQUEST(xForceScreenSaverReq); 350805b261ecSmrg 350905b261ecSmrg REQUEST_SIZE_MATCH(xForceScreenSaverReq); 351005b261ecSmrg 351105b261ecSmrg if ((stuff->mode != ScreenSaverReset) && 351205b261ecSmrg (stuff->mode != ScreenSaverActive)) 351305b261ecSmrg { 351405b261ecSmrg client->errorValue = stuff->mode; 351505b261ecSmrg return BadValue; 351605b261ecSmrg } 351705b261ecSmrg SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode); 351805b261ecSmrg return client->noClientException; 351905b261ecSmrg} 352005b261ecSmrg 352105b261ecSmrgint ProcNoOperation(ClientPtr client) 352205b261ecSmrg{ 352305b261ecSmrg REQUEST_AT_LEAST_SIZE(xReq); 352405b261ecSmrg 352505b261ecSmrg /* noop -- don't do anything */ 352605b261ecSmrg return(client->noClientException); 352705b261ecSmrg} 352805b261ecSmrg 352905b261ecSmrgvoid 353005b261ecSmrgInitProcVectors(void) 353105b261ecSmrg{ 353205b261ecSmrg int i; 353305b261ecSmrg for (i = 0; i<256; i++) 353405b261ecSmrg { 353505b261ecSmrg if(!ProcVector[i]) 353605b261ecSmrg { 353705b261ecSmrg ProcVector[i] = SwappedProcVector[i] = ProcBadRequest; 353805b261ecSmrg ReplySwapVector[i] = ReplyNotSwappd; 353905b261ecSmrg } 354005b261ecSmrg } 354105b261ecSmrg for(i = LASTEvent; i < 128; i++) 354205b261ecSmrg { 354305b261ecSmrg EventSwapVector[i] = NotImplemented; 354405b261ecSmrg } 354505b261ecSmrg 354605b261ecSmrg} 354705b261ecSmrg 354805b261ecSmrg/********************** 354905b261ecSmrg * CloseDownClient 355005b261ecSmrg * 355105b261ecSmrg * Client can either mark his resources destroy or retain. If retained and 355205b261ecSmrg * then killed again, the client is really destroyed. 355305b261ecSmrg *********************/ 355405b261ecSmrg 355505b261ecSmrgchar dispatchExceptionAtReset = DE_RESET; 355605b261ecSmrg 355705b261ecSmrgvoid 355805b261ecSmrgCloseDownClient(ClientPtr client) 355905b261ecSmrg{ 356005b261ecSmrg Bool really_close_down = client->clientGone || 356105b261ecSmrg client->closeDownMode == DestroyAll; 356205b261ecSmrg 356305b261ecSmrg if (!client->clientGone) 356405b261ecSmrg { 356505b261ecSmrg /* ungrab server if grabbing client dies */ 356605b261ecSmrg if (grabState != GrabNone && grabClient == client) 356705b261ecSmrg { 356805b261ecSmrg UngrabServer(client); 356905b261ecSmrg } 357005b261ecSmrg BITCLEAR(grabWaiters, client->index); 357105b261ecSmrg DeleteClientFromAnySelections(client); 357205b261ecSmrg ReleaseActiveGrabs(client); 357305b261ecSmrg DeleteClientFontStuff(client); 357405b261ecSmrg if (!really_close_down) 357505b261ecSmrg { 357605b261ecSmrg /* This frees resources that should never be retained 357705b261ecSmrg * no matter what the close down mode is. Actually we 357805b261ecSmrg * could do this unconditionally, but it's probably 357905b261ecSmrg * better not to traverse all the client's resources 358005b261ecSmrg * twice (once here, once a few lines down in 358105b261ecSmrg * FreeClientResources) in the common case of 358205b261ecSmrg * really_close_down == TRUE. 358305b261ecSmrg */ 358405b261ecSmrg FreeClientNeverRetainResources(client); 358505b261ecSmrg client->clientState = ClientStateRetained; 358605b261ecSmrg if (ClientStateCallback) 358705b261ecSmrg { 358805b261ecSmrg NewClientInfoRec clientinfo; 358905b261ecSmrg 359005b261ecSmrg clientinfo.client = client; 359105b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 359205b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 359305b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 359405b261ecSmrg } 359505b261ecSmrg } 359605b261ecSmrg client->clientGone = TRUE; /* so events aren't sent to client */ 359705b261ecSmrg if (ClientIsAsleep(client)) 359805b261ecSmrg ClientSignal (client); 359905b261ecSmrg ProcessWorkQueueZombies(); 360005b261ecSmrg CloseDownConnection(client); 360105b261ecSmrg 360205b261ecSmrg /* If the client made it to the Running stage, nClients has 360305b261ecSmrg * been incremented on its behalf, so we need to decrement it 360405b261ecSmrg * now. If it hasn't gotten to Running, nClients has *not* 360505b261ecSmrg * been incremented, so *don't* decrement it. 360605b261ecSmrg */ 360705b261ecSmrg if (client->clientState != ClientStateInitial && 360805b261ecSmrg client->clientState != ClientStateAuthenticating ) 360905b261ecSmrg { 361005b261ecSmrg --nClients; 361105b261ecSmrg } 361205b261ecSmrg } 361305b261ecSmrg 361405b261ecSmrg if (really_close_down) 361505b261ecSmrg { 361605b261ecSmrg if (client->clientState == ClientStateRunning && nClients == 0) 361705b261ecSmrg dispatchException |= dispatchExceptionAtReset; 361805b261ecSmrg 361905b261ecSmrg client->clientState = ClientStateGone; 362005b261ecSmrg if (ClientStateCallback) 362105b261ecSmrg { 362205b261ecSmrg NewClientInfoRec clientinfo; 362305b261ecSmrg 362405b261ecSmrg clientinfo.client = client; 362505b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 362605b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 362705b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 362805b261ecSmrg } 362905b261ecSmrg FreeClientResources(client); 363005b261ecSmrg#ifdef XSERVER_DTRACE 363105b261ecSmrg XSERVER_CLIENT_DISCONNECT(client->index); 363205b261ecSmrg#endif 363305b261ecSmrg if (client->index < nextFreeClientID) 363405b261ecSmrg nextFreeClientID = client->index; 363505b261ecSmrg clients[client->index] = NullClient; 363605b261ecSmrg#ifdef SMART_SCHEDULE 363705b261ecSmrg SmartLastClient = NullClient; 363805b261ecSmrg#endif 363905b261ecSmrg xfree(client); 364005b261ecSmrg 364105b261ecSmrg while (!clients[currentMaxClients-1]) 364205b261ecSmrg currentMaxClients--; 364305b261ecSmrg } 364405b261ecSmrg} 364505b261ecSmrg 364605b261ecSmrgstatic void 364705b261ecSmrgKillAllClients(void) 364805b261ecSmrg{ 364905b261ecSmrg int i; 365005b261ecSmrg for (i=1; i<currentMaxClients; i++) 365105b261ecSmrg if (clients[i]) { 365205b261ecSmrg /* Make sure Retained clients are released. */ 365305b261ecSmrg clients[i]->closeDownMode = DestroyAll; 365405b261ecSmrg CloseDownClient(clients[i]); 365505b261ecSmrg } 365605b261ecSmrg} 365705b261ecSmrg 365805b261ecSmrgextern int clientPrivateLen; 365905b261ecSmrgextern unsigned *clientPrivateSizes; 366005b261ecSmrgextern unsigned totalClientSize; 366105b261ecSmrg 366205b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv) 366305b261ecSmrg{ 366405b261ecSmrg client->index = i; 366505b261ecSmrg client->sequence = 0; 366605b261ecSmrg client->clientAsMask = ((Mask)i) << CLIENTOFFSET; 366705b261ecSmrg client->clientGone = FALSE; 366805b261ecSmrg if (i) 366905b261ecSmrg { 367005b261ecSmrg client->closeDownMode = DestroyAll; 367105b261ecSmrg client->lastDrawable = (DrawablePtr)WindowTable[0]; 367205b261ecSmrg client->lastDrawableID = WindowTable[0]->drawable.id; 367305b261ecSmrg } 367405b261ecSmrg else 367505b261ecSmrg { 367605b261ecSmrg client->closeDownMode = RetainPermanent; 367705b261ecSmrg client->lastDrawable = (DrawablePtr)NULL; 367805b261ecSmrg client->lastDrawableID = INVALID; 367905b261ecSmrg } 368005b261ecSmrg client->lastGC = (GCPtr) NULL; 368105b261ecSmrg client->lastGCID = INVALID; 368205b261ecSmrg client->numSaved = 0; 368305b261ecSmrg client->saveSet = (SaveSetElt *)NULL; 368405b261ecSmrg client->noClientException = Success; 368505b261ecSmrg#ifdef DEBUG 368605b261ecSmrg client->requestLogIndex = 0; 368705b261ecSmrg#endif 368805b261ecSmrg client->requestVector = InitialVector; 368905b261ecSmrg client->osPrivate = ospriv; 369005b261ecSmrg client->swapped = FALSE; 369105b261ecSmrg client->big_requests = FALSE; 369205b261ecSmrg client->priority = 0; 369305b261ecSmrg client->clientState = ClientStateInitial; 369405b261ecSmrg#ifdef XKB 369505b261ecSmrg if (!noXkbExtension) { 369605b261ecSmrg client->xkbClientFlags = 0; 369705b261ecSmrg client->mapNotifyMask = 0; 369805b261ecSmrg QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); 369905b261ecSmrg } 370005b261ecSmrg#endif 370105b261ecSmrg client->replyBytesRemaining = 0; 370205b261ecSmrg#ifdef XAPPGROUP 370305b261ecSmrg client->appgroup = NULL; 370405b261ecSmrg#endif 370505b261ecSmrg client->fontResFunc = NULL; 370605b261ecSmrg#ifdef SMART_SCHEDULE 370705b261ecSmrg client->smart_priority = 0; 370805b261ecSmrg client->smart_start_tick = SmartScheduleTime; 370905b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 371005b261ecSmrg client->smart_check_tick = SmartScheduleTime; 371105b261ecSmrg#endif 371205b261ecSmrg} 371305b261ecSmrg 371405b261ecSmrgint 371505b261ecSmrgInitClientPrivates(ClientPtr client) 371605b261ecSmrg{ 371705b261ecSmrg char *ptr; 371805b261ecSmrg DevUnion *ppriv; 371905b261ecSmrg unsigned *sizes; 372005b261ecSmrg unsigned size; 372105b261ecSmrg int i; 372205b261ecSmrg 372305b261ecSmrg if (totalClientSize == sizeof(ClientRec)) 372405b261ecSmrg ppriv = (DevUnion *)NULL; 372505b261ecSmrg else if (client->index) 372605b261ecSmrg ppriv = (DevUnion *)(client + 1); 372705b261ecSmrg else 372805b261ecSmrg { 372905b261ecSmrg ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec)); 373005b261ecSmrg if (!ppriv) 373105b261ecSmrg return 0; 373205b261ecSmrg } 373305b261ecSmrg client->devPrivates = ppriv; 373405b261ecSmrg sizes = clientPrivateSizes; 373505b261ecSmrg ptr = (char *)(ppriv + clientPrivateLen); 373605b261ecSmrg if (ppriv) 373705b261ecSmrg bzero(ppriv, totalClientSize - sizeof(ClientRec)); 373805b261ecSmrg for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++) 373905b261ecSmrg { 374005b261ecSmrg if ( (size = *sizes) ) 374105b261ecSmrg { 374205b261ecSmrg ppriv->ptr = (pointer)ptr; 374305b261ecSmrg ptr += size; 374405b261ecSmrg } 374505b261ecSmrg else 374605b261ecSmrg ppriv->ptr = (pointer)NULL; 374705b261ecSmrg } 374805b261ecSmrg 374905b261ecSmrg /* Allow registrants to initialize the serverClient devPrivates */ 375005b261ecSmrg if (!client->index && ClientStateCallback) 375105b261ecSmrg { 375205b261ecSmrg NewClientInfoRec clientinfo; 375305b261ecSmrg 375405b261ecSmrg clientinfo.client = client; 375505b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 375605b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 375705b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 375805b261ecSmrg } 375905b261ecSmrg return 1; 376005b261ecSmrg} 376105b261ecSmrg 376205b261ecSmrg/************************ 376305b261ecSmrg * int NextAvailableClient(ospriv) 376405b261ecSmrg * 376505b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes. 376605b261ecSmrg * Returns NULL if there are no free clients. 376705b261ecSmrg *************************/ 376805b261ecSmrg 376905b261ecSmrgClientPtr NextAvailableClient(pointer ospriv) 377005b261ecSmrg{ 377105b261ecSmrg int i; 377205b261ecSmrg ClientPtr client; 377305b261ecSmrg xReq data; 377405b261ecSmrg 377505b261ecSmrg i = nextFreeClientID; 377605b261ecSmrg if (i == MAXCLIENTS) 377705b261ecSmrg return (ClientPtr)NULL; 377805b261ecSmrg clients[i] = client = (ClientPtr)xalloc(totalClientSize); 377905b261ecSmrg if (!client) 378005b261ecSmrg return (ClientPtr)NULL; 378105b261ecSmrg InitClient(client, i, ospriv); 378205b261ecSmrg InitClientPrivates(client); 378305b261ecSmrg if (!InitClientResources(client)) 378405b261ecSmrg { 378505b261ecSmrg xfree(client); 378605b261ecSmrg return (ClientPtr)NULL; 378705b261ecSmrg } 378805b261ecSmrg data.reqType = 1; 378905b261ecSmrg data.length = (sz_xReq + sz_xConnClientPrefix) >> 2; 379005b261ecSmrg if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) 379105b261ecSmrg { 379205b261ecSmrg FreeClientResources(client); 379305b261ecSmrg xfree(client); 379405b261ecSmrg return (ClientPtr)NULL; 379505b261ecSmrg } 379605b261ecSmrg if (i == currentMaxClients) 379705b261ecSmrg currentMaxClients++; 379805b261ecSmrg while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) 379905b261ecSmrg nextFreeClientID++; 380005b261ecSmrg if (ClientStateCallback) 380105b261ecSmrg { 380205b261ecSmrg NewClientInfoRec clientinfo; 380305b261ecSmrg 380405b261ecSmrg clientinfo.client = client; 380505b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 380605b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 380705b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 380805b261ecSmrg } 380905b261ecSmrg return(client); 381005b261ecSmrg} 381105b261ecSmrg 381205b261ecSmrgint 381305b261ecSmrgProcInitialConnection(ClientPtr client) 381405b261ecSmrg{ 381505b261ecSmrg REQUEST(xReq); 381605b261ecSmrg xConnClientPrefix *prefix; 381705b261ecSmrg int whichbyte = 1; 381805b261ecSmrg 381905b261ecSmrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 382005b261ecSmrg if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) 382105b261ecSmrg return (client->noClientException = -1); 382205b261ecSmrg if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || 382305b261ecSmrg (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) 382405b261ecSmrg { 382505b261ecSmrg client->swapped = TRUE; 382605b261ecSmrg SwapConnClientPrefix(prefix); 382705b261ecSmrg } 382805b261ecSmrg stuff->reqType = 2; 382905b261ecSmrg stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) + 383005b261ecSmrg ((prefix->nbytesAuthString + (unsigned)3) >> 2); 383105b261ecSmrg if (client->swapped) 383205b261ecSmrg { 383305b261ecSmrg swaps(&stuff->length, whichbyte); 383405b261ecSmrg } 383505b261ecSmrg ResetCurrentRequest(client); 383605b261ecSmrg return (client->noClientException); 383705b261ecSmrg} 383805b261ecSmrg 383905b261ecSmrgint 384005b261ecSmrgSendConnSetup(ClientPtr client, char *reason) 384105b261ecSmrg{ 384205b261ecSmrg xWindowRoot *root; 384305b261ecSmrg int i; 384405b261ecSmrg int numScreens; 384505b261ecSmrg char* lConnectionInfo; 384605b261ecSmrg xConnSetupPrefix* lconnSetupPrefix; 384705b261ecSmrg 384805b261ecSmrg if (reason) 384905b261ecSmrg { 385005b261ecSmrg xConnSetupPrefix csp; 385105b261ecSmrg 385205b261ecSmrg csp.success = xFalse; 385305b261ecSmrg csp.lengthReason = strlen(reason); 385405b261ecSmrg csp.length = (csp.lengthReason + (unsigned)3) >> 2; 385505b261ecSmrg csp.majorVersion = X_PROTOCOL; 385605b261ecSmrg csp.minorVersion = X_PROTOCOL_REVISION; 385705b261ecSmrg if (client->swapped) 385805b261ecSmrg WriteSConnSetupPrefix(client, &csp); 385905b261ecSmrg else 386005b261ecSmrg (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); 386105b261ecSmrg (void)WriteToClient(client, (int)csp.lengthReason, reason); 386205b261ecSmrg return (client->noClientException = -1); 386305b261ecSmrg } 386405b261ecSmrg 386505b261ecSmrg numScreens = screenInfo.numScreens; 386605b261ecSmrg lConnectionInfo = ConnectionInfo; 386705b261ecSmrg lconnSetupPrefix = &connSetupPrefix; 386805b261ecSmrg 386905b261ecSmrg /* We're about to start speaking X protocol back to the client by 387005b261ecSmrg * sending the connection setup info. This means the authorization 387105b261ecSmrg * step is complete, and we can count the client as an 387205b261ecSmrg * authorized one. 387305b261ecSmrg */ 387405b261ecSmrg nClients++; 387505b261ecSmrg 387605b261ecSmrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 387705b261ecSmrg client->sequence = 0; 387805b261ecSmrg#ifdef XAPPGROUP 387905b261ecSmrg XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens); 388005b261ecSmrg#endif 388105b261ecSmrg ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask; 388205b261ecSmrg ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 388305b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 388405b261ecSmrg ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client); 388505b261ecSmrg ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client); 388605b261ecSmrg#endif 388705b261ecSmrg /* fill in the "currentInputMask" */ 388805b261ecSmrg root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart); 388905b261ecSmrg#ifdef PANORAMIX 389005b261ecSmrg if (noPanoramiXExtension) 389105b261ecSmrg numScreens = screenInfo.numScreens; 389205b261ecSmrg else 389305b261ecSmrg numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; 389405b261ecSmrg#endif 389505b261ecSmrg 389605b261ecSmrg for (i=0; i<numScreens; i++) 389705b261ecSmrg { 389805b261ecSmrg unsigned int j; 389905b261ecSmrg xDepth *pDepth; 390005b261ecSmrg 390105b261ecSmrg root->currentInputMask = WindowTable[i]->eventMask | 390205b261ecSmrg wOtherEventMasks (WindowTable[i]); 390305b261ecSmrg pDepth = (xDepth *)(root + 1); 390405b261ecSmrg for (j = 0; j < root->nDepths; j++) 390505b261ecSmrg { 390605b261ecSmrg pDepth = (xDepth *)(((char *)(pDepth + 1)) + 390705b261ecSmrg pDepth->nVisuals * sizeof(xVisualType)); 390805b261ecSmrg } 390905b261ecSmrg root = (xWindowRoot *)pDepth; 391005b261ecSmrg } 391105b261ecSmrg 391205b261ecSmrg if (client->swapped) 391305b261ecSmrg { 391405b261ecSmrg WriteSConnSetupPrefix(client, lconnSetupPrefix); 391505b261ecSmrg WriteSConnectionInfo(client, 391605b261ecSmrg (unsigned long)(lconnSetupPrefix->length << 2), 391705b261ecSmrg lConnectionInfo); 391805b261ecSmrg } 391905b261ecSmrg else 392005b261ecSmrg { 392105b261ecSmrg (void)WriteToClient(client, sizeof(xConnSetupPrefix), 392205b261ecSmrg (char *) lconnSetupPrefix); 392305b261ecSmrg (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2), 392405b261ecSmrg lConnectionInfo); 392505b261ecSmrg } 392605b261ecSmrg client->clientState = ClientStateRunning; 392705b261ecSmrg if (ClientStateCallback) 392805b261ecSmrg { 392905b261ecSmrg NewClientInfoRec clientinfo; 393005b261ecSmrg 393105b261ecSmrg clientinfo.client = client; 393205b261ecSmrg clientinfo.prefix = lconnSetupPrefix; 393305b261ecSmrg clientinfo.setup = (xConnSetup *)lConnectionInfo; 393405b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 393505b261ecSmrg } 393605b261ecSmrg return (client->noClientException); 393705b261ecSmrg} 393805b261ecSmrg 393905b261ecSmrgint 394005b261ecSmrgProcEstablishConnection(ClientPtr client) 394105b261ecSmrg{ 394205b261ecSmrg char *reason, *auth_proto, *auth_string; 394305b261ecSmrg xConnClientPrefix *prefix; 394405b261ecSmrg REQUEST(xReq); 394505b261ecSmrg 394605b261ecSmrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 394705b261ecSmrg auth_proto = (char *)prefix + sz_xConnClientPrefix; 394805b261ecSmrg auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3); 394905b261ecSmrg if ((prefix->majorVersion != X_PROTOCOL) || 395005b261ecSmrg (prefix->minorVersion != X_PROTOCOL_REVISION)) 395105b261ecSmrg reason = "Protocol version mismatch"; 395205b261ecSmrg else 395305b261ecSmrg reason = ClientAuthorized(client, 395405b261ecSmrg (unsigned short)prefix->nbytesAuthProto, 395505b261ecSmrg auth_proto, 395605b261ecSmrg (unsigned short)prefix->nbytesAuthString, 395705b261ecSmrg auth_string); 395805b261ecSmrg /* 395905b261ecSmrg * If Kerberos is being used for this client, the clientState 396005b261ecSmrg * will be set to ClientStateAuthenticating at this point. 396105b261ecSmrg * More messages need to be exchanged among the X server, Kerberos 396205b261ecSmrg * server, and client to figure out if everyone is authorized. 396305b261ecSmrg * So we don't want to send the connection setup info yet, since 396405b261ecSmrg * the auth step isn't really done. 396505b261ecSmrg */ 396605b261ecSmrg if (client->clientState == ClientStateCheckingSecurity) 396705b261ecSmrg client->clientState = ClientStateCheckedSecurity; 396805b261ecSmrg else if (client->clientState != ClientStateAuthenticating) 396905b261ecSmrg return(SendConnSetup(client, reason)); 397005b261ecSmrg return(client->noClientException); 397105b261ecSmrg} 397205b261ecSmrg 397305b261ecSmrg_X_EXPORT void 397405b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 397505b261ecSmrg XID resId, int errorCode) 397605b261ecSmrg{ 397705b261ecSmrg xError rep; 397805b261ecSmrg 397905b261ecSmrg rep.type = X_Error; 398005b261ecSmrg rep.sequenceNumber = client->sequence; 398105b261ecSmrg rep.errorCode = errorCode; 398205b261ecSmrg rep.majorCode = majorCode; 398305b261ecSmrg rep.minorCode = minorCode; 398405b261ecSmrg rep.resourceID = resId; 398505b261ecSmrg 398605b261ecSmrg WriteEventsToClient (client, 1, (xEvent *)&rep); 398705b261ecSmrg} 398805b261ecSmrg 398905b261ecSmrgvoid 399005b261ecSmrgDeleteWindowFromAnySelections(WindowPtr pWin) 399105b261ecSmrg{ 399205b261ecSmrg int i; 399305b261ecSmrg 399405b261ecSmrg for (i = 0; i< NumCurrentSelections; i++) 399505b261ecSmrg if (CurrentSelections[i].pWin == pWin) 399605b261ecSmrg { 399705b261ecSmrg if (SelectionCallback) 399805b261ecSmrg { 399905b261ecSmrg SelectionInfoRec info; 400005b261ecSmrg 400105b261ecSmrg info.selection = &CurrentSelections[i]; 400205b261ecSmrg info.kind = SelectionWindowDestroy; 400305b261ecSmrg CallCallbacks(&SelectionCallback, &info); 400405b261ecSmrg } 400505b261ecSmrg CurrentSelections[i].pWin = (WindowPtr)NULL; 400605b261ecSmrg CurrentSelections[i].window = None; 400705b261ecSmrg CurrentSelections[i].client = NullClient; 400805b261ecSmrg } 400905b261ecSmrg} 401005b261ecSmrg 401105b261ecSmrgstatic void 401205b261ecSmrgDeleteClientFromAnySelections(ClientPtr client) 401305b261ecSmrg{ 401405b261ecSmrg int i; 401505b261ecSmrg 401605b261ecSmrg for (i = 0; i< NumCurrentSelections; i++) 401705b261ecSmrg if (CurrentSelections[i].client == client) 401805b261ecSmrg { 401905b261ecSmrg if (SelectionCallback) 402005b261ecSmrg { 402105b261ecSmrg SelectionInfoRec info; 402205b261ecSmrg 402305b261ecSmrg info.selection = &CurrentSelections[i]; 402405b261ecSmrg info.kind = SelectionWindowDestroy; 402505b261ecSmrg CallCallbacks(&SelectionCallback, &info); 402605b261ecSmrg } 402705b261ecSmrg CurrentSelections[i].pWin = (WindowPtr)NULL; 402805b261ecSmrg CurrentSelections[i].window = None; 402905b261ecSmrg CurrentSelections[i].client = NullClient; 403005b261ecSmrg } 403105b261ecSmrg} 403205b261ecSmrg 403305b261ecSmrgvoid 403405b261ecSmrgMarkClientException(ClientPtr client) 403505b261ecSmrg{ 403605b261ecSmrg client->noClientException = -1; 403705b261ecSmrg} 403805b261ecSmrg 403905b261ecSmrg#ifdef XSERVER_DTRACE 404005b261ecSmrg#include <ctype.h> 404105b261ecSmrg 404205b261ecSmrg/* Load table of request names for dtrace probes */ 404305b261ecSmrgstatic void LoadRequestNames(void) 404405b261ecSmrg{ 404505b261ecSmrg int i; 404605b261ecSmrg FILE *xedb; 404705b261ecSmrg extern void LoadExtensionNames(char **RequestNames); 404805b261ecSmrg 404905b261ecSmrg bzero(RequestNames, 256 * sizeof(char *)); 405005b261ecSmrg 405105b261ecSmrg xedb = fopen(XERRORDB_PATH, "r"); 405205b261ecSmrg if (xedb != NULL) { 405305b261ecSmrg char buf[256]; 405405b261ecSmrg while (fgets(buf, sizeof(buf), xedb)) { 405505b261ecSmrg if ((strncmp("XRequest.", buf, 9) == 0) && (isdigit(buf[9]))) { 405605b261ecSmrg char *name; 405705b261ecSmrg i = strtol(buf + 9, &name, 10); 405805b261ecSmrg if (RequestNames[i] == 0) { 405905b261ecSmrg char *end = strchr(name, '\n'); 406005b261ecSmrg if (end) { *end = '\0'; } 406105b261ecSmrg RequestNames[i] = strdup(name + 1); 406205b261ecSmrg } 406305b261ecSmrg } 406405b261ecSmrg } 406505b261ecSmrg fclose(xedb); 406605b261ecSmrg } 406705b261ecSmrg 406805b261ecSmrg LoadExtensionNames(RequestNames); 406905b261ecSmrg 407005b261ecSmrg for (i = 0; i < 256; i++) { 407105b261ecSmrg if (RequestNames[i] == 0) { 407205b261ecSmrg#define RN_SIZE 12 /* "Request#' + up to 3 digits + \0 */ 407305b261ecSmrg RequestNames[i] = xalloc(RN_SIZE); 407405b261ecSmrg if (RequestNames[i]) { 407505b261ecSmrg snprintf(RequestNames[i], RN_SIZE, "Request#%d", i); 407605b261ecSmrg } 407705b261ecSmrg } 407805b261ecSmrg /* fprintf(stderr, "%d: %s\n", i, RequestNames[i]); */ 407905b261ecSmrg } 408005b261ecSmrg} 408105b261ecSmrg 408205b261ecSmrgstatic void FreeRequestNames(void) 408305b261ecSmrg{ 408405b261ecSmrg int i; 408505b261ecSmrg 408605b261ecSmrg for (i = 0; i < 256; i++) { 408705b261ecSmrg if (RequestNames[i] != 0) { 408805b261ecSmrg free(RequestNames[i]); 408905b261ecSmrg RequestNames[i] = 0; 409005b261ecSmrg } 409105b261ecSmrg } 409205b261ecSmrg} 409305b261ecSmrg 409405b261ecSmrg#endif 4095