dispatch.c revision 0b0d8713
105b261ecSmrg/************************************************************ 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1989, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrg 2605b261ecSmrgCopyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 2705b261ecSmrg 2805b261ecSmrg All Rights Reserved 2905b261ecSmrg 3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3205b261ecSmrgprovided that the above copyright notice appear in all copies and that 3305b261ecSmrgboth that copyright notice and this permission notice appear in 3405b261ecSmrgsupporting documentation, and that the name of Digital not be 3505b261ecSmrgused in advertising or publicity pertaining to distribution of the 3605b261ecSmrgsoftware without specific, written prior permission. 3705b261ecSmrg 3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4405b261ecSmrgSOFTWARE. 4505b261ecSmrg 4605b261ecSmrg********************************************************/ 4705b261ecSmrg 4805b261ecSmrg/* The panoramix components contained the following notice */ 4905b261ecSmrg/***************************************************************** 5005b261ecSmrg 5105b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 5205b261ecSmrg 5305b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 5405b261ecSmrgof this software and associated documentation files (the "Software"), to deal 5505b261ecSmrgin the Software without restriction, including without limitation the rights 5605b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5705b261ecSmrgcopies of the Software. 5805b261ecSmrg 5905b261ecSmrgThe above copyright notice and this permission notice shall be included in 6005b261ecSmrgall copies or substantial portions of the Software. 6105b261ecSmrg 6205b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6305b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6405b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 6505b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 6605b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 6705b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 6805b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6905b261ecSmrg 7005b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation 7105b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other 7205b261ecSmrgdealings in this Software without prior written authorization from Digital 7305b261ecSmrgEquipment Corporation. 7405b261ecSmrg 7505b261ecSmrg******************************************************************/ 7605b261ecSmrg 7705b261ecSmrg/* XSERVER_DTRACE additions: 789ace9065Smrg * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. 7905b261ecSmrg * 8005b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 816747b715Smrg * copy of this software and associated documentation files (the "Software"), 826747b715Smrg * to deal in the Software without restriction, including without limitation 836747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 846747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 856747b715Smrg * Software is furnished to do so, subject to the following conditions: 866747b715Smrg * 876747b715Smrg * The above copyright notice and this permission notice (including the next 886747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 896747b715Smrg * Software. 906747b715Smrg * 916747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 926747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 936747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 946747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 956747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 966747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 976747b715Smrg * DEALINGS IN THE SOFTWARE. 9805b261ecSmrg */ 9905b261ecSmrg 10005b261ecSmrg 10105b261ecSmrg 10205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 10305b261ecSmrg#include <dix-config.h> 1046747b715Smrg#include <version-config.h> 10505b261ecSmrg#endif 10605b261ecSmrg 10705b261ecSmrg#ifdef PANORAMIX_DEBUG 10805b261ecSmrg#include <stdio.h> 10905b261ecSmrgint ProcInitialConnection(); 11005b261ecSmrg#endif 11105b261ecSmrg 11205b261ecSmrg#include "windowstr.h" 11305b261ecSmrg#include <X11/fonts/fontstruct.h> 11405b261ecSmrg#include "dixfontstr.h" 11505b261ecSmrg#include "gcstruct.h" 11605b261ecSmrg#include "selection.h" 11705b261ecSmrg#include "colormapst.h" 11805b261ecSmrg#include "cursorstr.h" 11905b261ecSmrg#include "scrnintstr.h" 12005b261ecSmrg#include "opaque.h" 12105b261ecSmrg#include "input.h" 12205b261ecSmrg#include "servermd.h" 12305b261ecSmrg#include "extnsionst.h" 12405b261ecSmrg#include "dixfont.h" 12505b261ecSmrg#include "dispatch.h" 12605b261ecSmrg#include "swaprep.h" 12705b261ecSmrg#include "swapreq.h" 1284642e01fSmrg#include "privates.h" 12905b261ecSmrg#include "xace.h" 13005b261ecSmrg#include "inputstr.h" 1316747b715Smrg#include "xkbsrv.h" 1326747b715Smrg#include "site.h" 13305b261ecSmrg 13405b261ecSmrg#ifdef XSERVER_DTRACE 1354642e01fSmrg#include "registry.h" 13605b261ecSmrg#include <sys/types.h> 13705b261ecSmrgtypedef const char *string; 13805b261ecSmrg#include "Xserver-dtrace.h" 13905b261ecSmrg#endif 14005b261ecSmrg 14105b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32) 14205b261ecSmrg#define BITMASK(i) (1U << ((i) & 31)) 14305b261ecSmrg#define MASKIDX(i) ((i) >> 5) 14405b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)] 14505b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) 14605b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) 14705b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) 14805b261ecSmrg 1496747b715SmrgxConnSetupPrefix connSetupPrefix; 1506747b715Smrg 1516747b715SmrgPaddingInfo PixmapWidthPaddingInfo[33]; 15205b261ecSmrg 15305b261ecSmrgstatic ClientPtr grabClient; 15405b261ecSmrg#define GrabNone 0 15505b261ecSmrg#define GrabActive 1 15605b261ecSmrg#define GrabKickout 2 15705b261ecSmrgstatic int grabState = GrabNone; 15805b261ecSmrgstatic long grabWaiters[mskcnt]; 1596747b715SmrgCallbackListPtr ServerGrabCallback = NULL; 16005b261ecSmrgHWEventQueuePtr checkForInput[2]; 1616747b715Smrgint connBlockScreenStart; 16205b261ecSmrg 16305b261ecSmrgstatic void KillAllClients(void); 16405b261ecSmrg 16505b261ecSmrgstatic int nextFreeClientID; /* always MIN free client ID */ 16605b261ecSmrg 16705b261ecSmrgstatic int nClients; /* number of authorized clients */ 16805b261ecSmrg 1696747b715SmrgCallbackListPtr ClientStateCallback; 17005b261ecSmrg 17105b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they 17205b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't 17305b261ecSmrg * need to actually check value in memory when used and may miss changes from 17405b261ecSmrg * signal handlers. 17505b261ecSmrg */ 1766747b715Smrgvolatile char dispatchException = 0; 1776747b715Smrgvolatile char isItTimeToYield; 17805b261ecSmrg 17905b261ecSmrg#define SAME_SCREENS(a, b) (\ 18005b261ecSmrg (a.pScreen == b.pScreen)) 18105b261ecSmrg 1824642e01fSmrgvoid 18305b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) 18405b261ecSmrg{ 18505b261ecSmrg checkForInput[0] = c0; 18605b261ecSmrg checkForInput[1] = c1; 18705b261ecSmrg} 18805b261ecSmrg 1896747b715Smrgvoid 19005b261ecSmrgUpdateCurrentTime(void) 19105b261ecSmrg{ 19205b261ecSmrg TimeStamp systime; 19305b261ecSmrg 19405b261ecSmrg /* To avoid time running backwards, we must call GetTimeInMillis before 19505b261ecSmrg * calling ProcessInputEvents. 19605b261ecSmrg */ 19705b261ecSmrg systime.months = currentTime.months; 19805b261ecSmrg systime.milliseconds = GetTimeInMillis(); 19905b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 20005b261ecSmrg systime.months++; 20105b261ecSmrg if (*checkForInput[0] != *checkForInput[1]) 20205b261ecSmrg ProcessInputEvents(); 20305b261ecSmrg if (CompareTimeStamps(systime, currentTime) == LATER) 20405b261ecSmrg currentTime = systime; 20505b261ecSmrg} 20605b261ecSmrg 20705b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ 2086747b715Smrgvoid 20905b261ecSmrgUpdateCurrentTimeIf(void) 21005b261ecSmrg{ 21105b261ecSmrg TimeStamp systime; 21205b261ecSmrg 21305b261ecSmrg systime.months = currentTime.months; 21405b261ecSmrg systime.milliseconds = GetTimeInMillis(); 21505b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 21605b261ecSmrg systime.months++; 21705b261ecSmrg if (*checkForInput[0] == *checkForInput[1]) 21805b261ecSmrg currentTime = systime; 21905b261ecSmrg} 22005b261ecSmrg 22105b261ecSmrg 22205b261ecSmrg#undef SMART_DEBUG 22305b261ecSmrg 22405b261ecSmrg#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ 22505b261ecSmrg#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ 22605b261ecSmrg 2276747b715SmrgBool SmartScheduleDisable = FALSE; 2286747b715Smrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; 2296747b715Smrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; 2306747b715Smrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; 2316747b715Smrglong SmartScheduleTime; 2326747b715Smrgint SmartScheduleLatencyLimited = 0; 23305b261ecSmrgstatic ClientPtr SmartLastClient; 23405b261ecSmrgstatic int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; 23505b261ecSmrg 23605b261ecSmrg#ifdef SMART_DEBUG 23705b261ecSmrglong SmartLastPrint; 23805b261ecSmrg#endif 23905b261ecSmrg 24005b261ecSmrgvoid Dispatch(void); 24105b261ecSmrg 24205b261ecSmrgstatic int 24305b261ecSmrgSmartScheduleClient (int *clientReady, int nready) 24405b261ecSmrg{ 24505b261ecSmrg ClientPtr pClient; 24605b261ecSmrg int i; 24705b261ecSmrg int client; 24805b261ecSmrg int bestPrio, best = 0; 24905b261ecSmrg int bestRobin, robin; 25005b261ecSmrg long now = SmartScheduleTime; 25105b261ecSmrg long idle; 25205b261ecSmrg 25305b261ecSmrg bestPrio = -0x7fffffff; 25405b261ecSmrg bestRobin = 0; 25505b261ecSmrg idle = 2 * SmartScheduleSlice; 25605b261ecSmrg for (i = 0; i < nready; i++) 25705b261ecSmrg { 25805b261ecSmrg client = clientReady[i]; 25905b261ecSmrg pClient = clients[client]; 26005b261ecSmrg /* Praise clients which are idle */ 26105b261ecSmrg if ((now - pClient->smart_check_tick) >= idle) 26205b261ecSmrg { 26305b261ecSmrg if (pClient->smart_priority < 0) 26405b261ecSmrg pClient->smart_priority++; 26505b261ecSmrg } 26605b261ecSmrg pClient->smart_check_tick = now; 26705b261ecSmrg 26805b261ecSmrg /* check priority to select best client */ 26905b261ecSmrg robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; 27005b261ecSmrg if (pClient->smart_priority > bestPrio || 27105b261ecSmrg (pClient->smart_priority == bestPrio && robin > bestRobin)) 27205b261ecSmrg { 27305b261ecSmrg bestPrio = pClient->smart_priority; 27405b261ecSmrg bestRobin = robin; 27505b261ecSmrg best = client; 27605b261ecSmrg } 27705b261ecSmrg#ifdef SMART_DEBUG 27805b261ecSmrg if ((now - SmartLastPrint) >= 5000) 27905b261ecSmrg fprintf (stderr, " %2d: %3d", client, pClient->smart_priority); 28005b261ecSmrg#endif 28105b261ecSmrg } 28205b261ecSmrg#ifdef SMART_DEBUG 28305b261ecSmrg if ((now - SmartLastPrint) >= 5000) 28405b261ecSmrg { 28505b261ecSmrg fprintf (stderr, " use %2d\n", best); 28605b261ecSmrg SmartLastPrint = now; 28705b261ecSmrg } 28805b261ecSmrg#endif 28905b261ecSmrg pClient = clients[best]; 29005b261ecSmrg SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index; 29105b261ecSmrg /* 29205b261ecSmrg * Set current client pointer 29305b261ecSmrg */ 29405b261ecSmrg if (SmartLastClient != pClient) 29505b261ecSmrg { 29605b261ecSmrg pClient->smart_start_tick = now; 29705b261ecSmrg SmartLastClient = pClient; 29805b261ecSmrg } 29905b261ecSmrg /* 30005b261ecSmrg * Adjust slice 30105b261ecSmrg */ 302b1d344b3Smrg if (nready == 1 && SmartScheduleLatencyLimited == 0) 30305b261ecSmrg { 30405b261ecSmrg /* 30505b261ecSmrg * If it's been a long time since another client 30605b261ecSmrg * has run, bump the slice up to get maximal 30705b261ecSmrg * performance from a single client 30805b261ecSmrg */ 30905b261ecSmrg if ((now - pClient->smart_start_tick) > 1000 && 31005b261ecSmrg SmartScheduleSlice < SmartScheduleMaxSlice) 31105b261ecSmrg { 31205b261ecSmrg SmartScheduleSlice += SmartScheduleInterval; 31305b261ecSmrg } 31405b261ecSmrg } 31505b261ecSmrg else 31605b261ecSmrg { 31705b261ecSmrg SmartScheduleSlice = SmartScheduleInterval; 31805b261ecSmrg } 31905b261ecSmrg return best; 32005b261ecSmrg} 32105b261ecSmrg 322b1d344b3Smrgvoid 323b1d344b3SmrgEnableLimitedSchedulingLatency(void) 324b1d344b3Smrg{ 325b1d344b3Smrg ++SmartScheduleLatencyLimited; 326b1d344b3Smrg SmartScheduleSlice = SmartScheduleInterval; 327b1d344b3Smrg} 328b1d344b3Smrg 329b1d344b3Smrgvoid 330b1d344b3SmrgDisableLimitedSchedulingLatency(void) 331b1d344b3Smrg{ 332b1d344b3Smrg --SmartScheduleLatencyLimited; 333b1d344b3Smrg 334b1d344b3Smrg /* protect against bugs */ 335b1d344b3Smrg if (SmartScheduleLatencyLimited < 0) 336b1d344b3Smrg SmartScheduleLatencyLimited = 0; 337b1d344b3Smrg} 338b1d344b3Smrg 33905b261ecSmrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType 34005b261ecSmrg 34105b261ecSmrgvoid 34205b261ecSmrgDispatch(void) 34305b261ecSmrg{ 34405b261ecSmrg int *clientReady; /* array of request ready clients */ 34505b261ecSmrg int result; 34605b261ecSmrg ClientPtr client; 34705b261ecSmrg int nready; 34805b261ecSmrg HWEventQueuePtr* icheck = checkForInput; 34905b261ecSmrg long start_tick; 35005b261ecSmrg 35105b261ecSmrg nextFreeClientID = 1; 35205b261ecSmrg nClients = 0; 35305b261ecSmrg 3546747b715Smrg clientReady = malloc(sizeof(int) * MaxClients); 35505b261ecSmrg if (!clientReady) 35605b261ecSmrg return; 35705b261ecSmrg 358b1d344b3Smrg SmartScheduleSlice = SmartScheduleInterval; 35905b261ecSmrg while (!dispatchException) 36005b261ecSmrg { 36105b261ecSmrg if (*icheck[0] != *icheck[1]) 36205b261ecSmrg { 36305b261ecSmrg ProcessInputEvents(); 36405b261ecSmrg FlushIfCriticalOutputPending(); 36505b261ecSmrg } 36605b261ecSmrg 36705b261ecSmrg nready = WaitForSomething(clientReady); 36805b261ecSmrg 36905b261ecSmrg if (nready && !SmartScheduleDisable) 37005b261ecSmrg { 37105b261ecSmrg clientReady[0] = SmartScheduleClient (clientReady, nready); 37205b261ecSmrg nready = 1; 37305b261ecSmrg } 37405b261ecSmrg /***************** 37505b261ecSmrg * Handle events in round robin fashion, doing input between 37605b261ecSmrg * each round 37705b261ecSmrg *****************/ 37805b261ecSmrg 37905b261ecSmrg while (!dispatchException && (--nready >= 0)) 38005b261ecSmrg { 38105b261ecSmrg client = clients[clientReady[nready]]; 38205b261ecSmrg if (! client) 38305b261ecSmrg { 38405b261ecSmrg /* KillClient can cause this to happen */ 38505b261ecSmrg continue; 38605b261ecSmrg } 38705b261ecSmrg /* GrabServer activation can cause this to be true */ 38805b261ecSmrg if (grabState == GrabKickout) 38905b261ecSmrg { 39005b261ecSmrg grabState = GrabActive; 39105b261ecSmrg break; 39205b261ecSmrg } 39305b261ecSmrg isItTimeToYield = FALSE; 39405b261ecSmrg 39505b261ecSmrg start_tick = SmartScheduleTime; 39605b261ecSmrg while (!isItTimeToYield) 39705b261ecSmrg { 39805b261ecSmrg if (*icheck[0] != *icheck[1]) 39905b261ecSmrg ProcessInputEvents(); 4004642e01fSmrg 4014642e01fSmrg FlushIfCriticalOutputPending(); 40205b261ecSmrg if (!SmartScheduleDisable && 40305b261ecSmrg (SmartScheduleTime - start_tick) >= SmartScheduleSlice) 40405b261ecSmrg { 40505b261ecSmrg /* Penalize clients which consume ticks */ 40605b261ecSmrg if (client->smart_priority > SMART_MIN_PRIORITY) 40705b261ecSmrg client->smart_priority--; 40805b261ecSmrg break; 40905b261ecSmrg } 41005b261ecSmrg /* now, finally, deal with client requests */ 41105b261ecSmrg 41205b261ecSmrg result = ReadRequestFromClient(client); 41305b261ecSmrg if (result <= 0) 41405b261ecSmrg { 41505b261ecSmrg if (result < 0) 41605b261ecSmrg CloseDownClient(client); 41705b261ecSmrg break; 41805b261ecSmrg } 41905b261ecSmrg 42005b261ecSmrg client->sequence++; 42105b261ecSmrg#ifdef XSERVER_DTRACE 4224642e01fSmrg XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP, 42305b261ecSmrg ((xReq *)client->requestBuffer)->length, 42405b261ecSmrg client->index, client->requestBuffer); 42505b261ecSmrg#endif 42605b261ecSmrg if (result > (maxBigRequestSize << 2)) 42705b261ecSmrg result = BadLength; 42805b261ecSmrg else { 4294642e01fSmrg result = XaceHookDispatch(client, MAJOROP); 4304642e01fSmrg if (result == Success) 4314642e01fSmrg result = (* client->requestVector[MAJOROP])(client); 4324642e01fSmrg XaceHookAuditEnd(client, result); 43305b261ecSmrg } 43405b261ecSmrg#ifdef XSERVER_DTRACE 4354642e01fSmrg XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP, 43605b261ecSmrg client->sequence, client->index, result); 43705b261ecSmrg#endif 43805b261ecSmrg 4396747b715Smrg if (client->noClientException != Success) 44005b261ecSmrg { 4416747b715Smrg CloseDownClient(client); 44205b261ecSmrg break; 4436747b715Smrg } 4446747b715Smrg else if (result != Success) 4456747b715Smrg { 4466747b715Smrg SendErrorToClient(client, MAJOROP, 4476747b715Smrg MinorOpcodeOfRequest(client), 4486747b715Smrg client->errorValue, result); 4496747b715Smrg break; 4506747b715Smrg } 45105b261ecSmrg } 45205b261ecSmrg FlushAllOutput(); 45305b261ecSmrg client = clients[clientReady[nready]]; 45405b261ecSmrg if (client) 45505b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 45605b261ecSmrg } 45705b261ecSmrg dispatchException &= ~DE_PRIORITYCHANGE; 45805b261ecSmrg } 45905b261ecSmrg#if defined(DDXBEFORERESET) 46005b261ecSmrg ddxBeforeReset (); 46105b261ecSmrg#endif 46205b261ecSmrg KillAllClients(); 4636747b715Smrg free(clientReady); 46405b261ecSmrg dispatchException &= ~DE_RESET; 465b1d344b3Smrg SmartScheduleLatencyLimited = 0; 46605b261ecSmrg} 46705b261ecSmrg 46805b261ecSmrg#undef MAJOROP 46905b261ecSmrg 4706747b715Smrgstatic int VendorRelease = VENDOR_RELEASE; 4716747b715Smrgstatic char *VendorString = VENDOR_NAME; 4726747b715Smrg 4736747b715Smrgstatic const int padlength[4] = {0, 3, 2, 1}; 4746747b715Smrg 4756747b715Smrgvoid 4766747b715SmrgSetVendorRelease(int release) 4776747b715Smrg{ 4786747b715Smrg VendorRelease = release; 4796747b715Smrg} 4806747b715Smrg 4816747b715Smrgvoid 4826747b715SmrgSetVendorString(char *string) 4836747b715Smrg{ 4846747b715Smrg VendorString = string; 4856747b715Smrg} 4866747b715Smrg 4876747b715SmrgBool 4886747b715SmrgCreateConnectionBlock(void) 4896747b715Smrg{ 4906747b715Smrg xConnSetup setup; 4916747b715Smrg xWindowRoot root; 4926747b715Smrg xDepth depth; 4936747b715Smrg xVisualType visual; 4946747b715Smrg xPixmapFormat format; 4956747b715Smrg unsigned long vid; 4966747b715Smrg int i, j, k, 4976747b715Smrg lenofblock, 4986747b715Smrg sizesofar = 0; 4996747b715Smrg char *pBuf; 5006747b715Smrg 5016747b715Smrg 5026747b715Smrg memset(&setup, 0, sizeof(xConnSetup)); 5036747b715Smrg /* Leave off the ridBase and ridMask, these must be sent with 5046747b715Smrg connection */ 5056747b715Smrg 5066747b715Smrg setup.release = VendorRelease; 5076747b715Smrg /* 5086747b715Smrg * per-server image and bitmap parameters are defined in Xmd.h 5096747b715Smrg */ 5106747b715Smrg setup.imageByteOrder = screenInfo.imageByteOrder; 5116747b715Smrg 5126747b715Smrg setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; 5136747b715Smrg setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; 5146747b715Smrg 5156747b715Smrg setup.bitmapBitOrder = screenInfo.bitmapBitOrder; 5166747b715Smrg setup.motionBufferSize = NumMotionEvents(); 5176747b715Smrg setup.numRoots = screenInfo.numScreens; 5186747b715Smrg setup.nbytesVendor = strlen(VendorString); 5196747b715Smrg setup.numFormats = screenInfo.numPixmapFormats; 5206747b715Smrg setup.maxRequestSize = MAX_REQUEST_SIZE; 5216747b715Smrg QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); 5226747b715Smrg 5236747b715Smrg lenofblock = sizeof(xConnSetup) + 5246747b715Smrg pad_to_int32(setup.nbytesVendor) + 5256747b715Smrg (setup.numFormats * sizeof(xPixmapFormat)) + 5266747b715Smrg (setup.numRoots * sizeof(xWindowRoot)); 5276747b715Smrg ConnectionInfo = malloc(lenofblock); 5286747b715Smrg if (!ConnectionInfo) 5296747b715Smrg return FALSE; 5306747b715Smrg 5316747b715Smrg memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup)); 5326747b715Smrg sizesofar = sizeof(xConnSetup); 5336747b715Smrg pBuf = ConnectionInfo + sizeof(xConnSetup); 5346747b715Smrg 5356747b715Smrg memmove(pBuf, VendorString, (int)setup.nbytesVendor); 5366747b715Smrg sizesofar += setup.nbytesVendor; 5376747b715Smrg pBuf += setup.nbytesVendor; 5386747b715Smrg i = padlength[setup.nbytesVendor & 3]; 5396747b715Smrg sizesofar += i; 5406747b715Smrg while (--i >= 0) 5416747b715Smrg *pBuf++ = 0; 5426747b715Smrg 5436747b715Smrg memset(&format, 0, sizeof(xPixmapFormat)); 5446747b715Smrg for (i=0; i<screenInfo.numPixmapFormats; i++) 5456747b715Smrg { 5466747b715Smrg format.depth = screenInfo.formats[i].depth; 5476747b715Smrg format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; 5486747b715Smrg format.scanLinePad = screenInfo.formats[i].scanlinePad; 5496747b715Smrg memmove(pBuf, (char *)&format, sizeof(xPixmapFormat)); 5506747b715Smrg pBuf += sizeof(xPixmapFormat); 5516747b715Smrg sizesofar += sizeof(xPixmapFormat); 5526747b715Smrg } 5536747b715Smrg 5546747b715Smrg connBlockScreenStart = sizesofar; 5556747b715Smrg memset(&depth, 0, sizeof(xDepth)); 5566747b715Smrg memset(&visual, 0, sizeof(xVisualType)); 5576747b715Smrg for (i=0; i<screenInfo.numScreens; i++) 5586747b715Smrg { 5596747b715Smrg ScreenPtr pScreen; 5606747b715Smrg DepthPtr pDepth; 5616747b715Smrg VisualPtr pVisual; 5626747b715Smrg 5636747b715Smrg pScreen = screenInfo.screens[i]; 5646747b715Smrg root.windowId = pScreen->root->drawable.id; 5656747b715Smrg root.defaultColormap = pScreen->defColormap; 5666747b715Smrg root.whitePixel = pScreen->whitePixel; 5676747b715Smrg root.blackPixel = pScreen->blackPixel; 5686747b715Smrg root.currentInputMask = 0; /* filled in when sent */ 5696747b715Smrg root.pixWidth = pScreen->width; 5706747b715Smrg root.pixHeight = pScreen->height; 5716747b715Smrg root.mmWidth = pScreen->mmWidth; 5726747b715Smrg root.mmHeight = pScreen->mmHeight; 5736747b715Smrg root.minInstalledMaps = pScreen->minInstalledCmaps; 5746747b715Smrg root.maxInstalledMaps = pScreen->maxInstalledCmaps; 5756747b715Smrg root.rootVisualID = pScreen->rootVisual; 5766747b715Smrg root.backingStore = pScreen->backingStoreSupport; 5776747b715Smrg root.saveUnders = FALSE; 5786747b715Smrg root.rootDepth = pScreen->rootDepth; 5796747b715Smrg root.nDepths = pScreen->numDepths; 5806747b715Smrg memmove(pBuf, (char *)&root, sizeof(xWindowRoot)); 5816747b715Smrg sizesofar += sizeof(xWindowRoot); 5826747b715Smrg pBuf += sizeof(xWindowRoot); 5836747b715Smrg 5846747b715Smrg pDepth = pScreen->allowedDepths; 5856747b715Smrg for(j = 0; j < pScreen->numDepths; j++, pDepth++) 5866747b715Smrg { 5876747b715Smrg lenofblock += sizeof(xDepth) + 5886747b715Smrg (pDepth->numVids * sizeof(xVisualType)); 5896747b715Smrg pBuf = (char *)realloc(ConnectionInfo, lenofblock); 5906747b715Smrg if (!pBuf) 5916747b715Smrg { 5926747b715Smrg free(ConnectionInfo); 5936747b715Smrg return FALSE; 5946747b715Smrg } 5956747b715Smrg ConnectionInfo = pBuf; 5966747b715Smrg pBuf += sizesofar; 5976747b715Smrg depth.depth = pDepth->depth; 5986747b715Smrg depth.nVisuals = pDepth->numVids; 5996747b715Smrg memmove(pBuf, (char *)&depth, sizeof(xDepth)); 6006747b715Smrg pBuf += sizeof(xDepth); 6016747b715Smrg sizesofar += sizeof(xDepth); 6026747b715Smrg for(k = 0; k < pDepth->numVids; k++) 6036747b715Smrg { 6046747b715Smrg vid = pDepth->vids[k]; 6056747b715Smrg for (pVisual = pScreen->visuals; 6066747b715Smrg pVisual->vid != vid; 6076747b715Smrg pVisual++) 6086747b715Smrg ; 6096747b715Smrg visual.visualID = vid; 6106747b715Smrg visual.class = pVisual->class; 6116747b715Smrg visual.bitsPerRGB = pVisual->bitsPerRGBValue; 6126747b715Smrg visual.colormapEntries = pVisual->ColormapEntries; 6136747b715Smrg visual.redMask = pVisual->redMask; 6146747b715Smrg visual.greenMask = pVisual->greenMask; 6156747b715Smrg visual.blueMask = pVisual->blueMask; 6166747b715Smrg memmove(pBuf, (char *)&visual, sizeof(xVisualType)); 6176747b715Smrg pBuf += sizeof(xVisualType); 6186747b715Smrg sizesofar += sizeof(xVisualType); 6196747b715Smrg } 6206747b715Smrg } 6216747b715Smrg } 6226747b715Smrg connSetupPrefix.success = xTrue; 6236747b715Smrg connSetupPrefix.length = lenofblock/4; 6246747b715Smrg connSetupPrefix.majorVersion = X_PROTOCOL; 6256747b715Smrg connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; 6266747b715Smrg return TRUE; 6276747b715Smrg} 6286747b715Smrg 6296747b715Smrg 6306747b715Smrgint 63105b261ecSmrgProcBadRequest(ClientPtr client) 63205b261ecSmrg{ 6336747b715Smrg return BadRequest; 63405b261ecSmrg} 63505b261ecSmrg 63605b261ecSmrgint 63705b261ecSmrgProcCreateWindow(ClientPtr client) 63805b261ecSmrg{ 63905b261ecSmrg WindowPtr pParent, pWin; 64005b261ecSmrg REQUEST(xCreateWindowReq); 6414642e01fSmrg int len, rc; 64205b261ecSmrg 64305b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateWindowReq); 64405b261ecSmrg 64505b261ecSmrg LEGAL_NEW_RESOURCE(stuff->wid, client); 6464642e01fSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 64705b261ecSmrg if (rc != Success) 64805b261ecSmrg return rc; 6496747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); 65005b261ecSmrg if (Ones(stuff->mask) != len) 65105b261ecSmrg return BadLength; 65205b261ecSmrg if (!stuff->width || !stuff->height) 65305b261ecSmrg { 65405b261ecSmrg client->errorValue = 0; 65505b261ecSmrg return BadValue; 65605b261ecSmrg } 65705b261ecSmrg pWin = CreateWindow(stuff->wid, pParent, stuff->x, 65805b261ecSmrg stuff->y, stuff->width, stuff->height, 65905b261ecSmrg stuff->borderWidth, stuff->class, 66005b261ecSmrg stuff->mask, (XID *) &stuff[1], 66105b261ecSmrg (int)stuff->depth, 6624642e01fSmrg client, stuff->visual, &rc); 66305b261ecSmrg if (pWin) 66405b261ecSmrg { 66505b261ecSmrg Mask mask = pWin->eventMask; 66605b261ecSmrg 66705b261ecSmrg pWin->eventMask = 0; /* subterfuge in case AddResource fails */ 66805b261ecSmrg if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin)) 66905b261ecSmrg return BadAlloc; 67005b261ecSmrg pWin->eventMask = mask; 67105b261ecSmrg } 6726747b715Smrg return rc; 67305b261ecSmrg} 67405b261ecSmrg 67505b261ecSmrgint 67605b261ecSmrgProcChangeWindowAttributes(ClientPtr client) 67705b261ecSmrg{ 67805b261ecSmrg WindowPtr pWin; 67905b261ecSmrg REQUEST(xChangeWindowAttributesReq); 6806747b715Smrg int len, rc; 6814642e01fSmrg Mask access_mode = 0; 68205b261ecSmrg 68305b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); 6844642e01fSmrg access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; 6854642e01fSmrg access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; 6864642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); 68705b261ecSmrg if (rc != Success) 68805b261ecSmrg return rc; 6896747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); 69005b261ecSmrg if (len != Ones(stuff->valueMask)) 69105b261ecSmrg return BadLength; 6926747b715Smrg return ChangeWindowAttributes(pWin, 69305b261ecSmrg stuff->valueMask, 69405b261ecSmrg (XID *) &stuff[1], 69505b261ecSmrg client); 69605b261ecSmrg} 69705b261ecSmrg 69805b261ecSmrgint 69905b261ecSmrgProcGetWindowAttributes(ClientPtr client) 70005b261ecSmrg{ 70105b261ecSmrg WindowPtr pWin; 70205b261ecSmrg REQUEST(xResourceReq); 70305b261ecSmrg xGetWindowAttributesReply wa; 70405b261ecSmrg int rc; 70505b261ecSmrg 70605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 7074642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 70805b261ecSmrg if (rc != Success) 70905b261ecSmrg return rc; 7106747b715Smrg memset(&wa, 0, sizeof(xGetWindowAttributesReply)); 71105b261ecSmrg GetWindowAttributes(pWin, client, &wa); 71205b261ecSmrg WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); 7136747b715Smrg return Success; 71405b261ecSmrg} 71505b261ecSmrg 71605b261ecSmrgint 71705b261ecSmrgProcDestroyWindow(ClientPtr client) 71805b261ecSmrg{ 71905b261ecSmrg WindowPtr pWin; 72005b261ecSmrg REQUEST(xResourceReq); 72105b261ecSmrg int rc; 72205b261ecSmrg 72305b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 72405b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 72505b261ecSmrg if (rc != Success) 72605b261ecSmrg return rc; 7274642e01fSmrg if (pWin->parent) { 7284642e01fSmrg rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, 7294642e01fSmrg DixRemoveAccess); 7304642e01fSmrg if (rc != Success) 7314642e01fSmrg return rc; 73205b261ecSmrg FreeResource(stuff->id, RT_NONE); 7334642e01fSmrg } 7346747b715Smrg return Success; 73505b261ecSmrg} 73605b261ecSmrg 73705b261ecSmrgint 73805b261ecSmrgProcDestroySubwindows(ClientPtr client) 73905b261ecSmrg{ 74005b261ecSmrg WindowPtr pWin; 74105b261ecSmrg REQUEST(xResourceReq); 74205b261ecSmrg int rc; 74305b261ecSmrg 74405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 7454642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); 74605b261ecSmrg if (rc != Success) 74705b261ecSmrg return rc; 74805b261ecSmrg DestroySubwindows(pWin, client); 7496747b715Smrg return Success; 75005b261ecSmrg} 75105b261ecSmrg 75205b261ecSmrgint 75305b261ecSmrgProcChangeSaveSet(ClientPtr client) 75405b261ecSmrg{ 75505b261ecSmrg WindowPtr pWin; 75605b261ecSmrg REQUEST(xChangeSaveSetReq); 7576747b715Smrg int rc; 75805b261ecSmrg 75905b261ecSmrg REQUEST_SIZE_MATCH(xChangeSaveSetReq); 7604642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 76105b261ecSmrg if (rc != Success) 76205b261ecSmrg return rc; 76305b261ecSmrg if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) 76405b261ecSmrg return BadMatch; 76505b261ecSmrg if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) 7666747b715Smrg return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); 7676747b715Smrg client->errorValue = stuff->mode; 7686747b715Smrg return BadValue; 76905b261ecSmrg} 77005b261ecSmrg 77105b261ecSmrgint 77205b261ecSmrgProcReparentWindow(ClientPtr client) 77305b261ecSmrg{ 77405b261ecSmrg WindowPtr pWin, pParent; 77505b261ecSmrg REQUEST(xReparentWindowReq); 7766747b715Smrg int rc; 77705b261ecSmrg 77805b261ecSmrg REQUEST_SIZE_MATCH(xReparentWindowReq); 7794642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 78005b261ecSmrg if (rc != Success) 78105b261ecSmrg return rc; 7824642e01fSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 78305b261ecSmrg if (rc != Success) 78405b261ecSmrg return rc; 7856747b715Smrg if (!SAME_SCREENS(pWin->drawable, pParent->drawable)) 7866747b715Smrg return BadMatch; 7876747b715Smrg if ((pWin->backgroundState == ParentRelative) && 7886747b715Smrg (pParent->drawable.depth != pWin->drawable.depth)) 7896747b715Smrg return BadMatch; 7906747b715Smrg if ((pWin->drawable.class != InputOnly) && 7916747b715Smrg (pParent->drawable.class == InputOnly)) 7926747b715Smrg return BadMatch; 7936747b715Smrg return ReparentWindow(pWin, pParent, 7946747b715Smrg (short)stuff->x, (short)stuff->y, client); 79505b261ecSmrg} 79605b261ecSmrg 79705b261ecSmrgint 79805b261ecSmrgProcMapWindow(ClientPtr client) 79905b261ecSmrg{ 80005b261ecSmrg WindowPtr pWin; 80105b261ecSmrg REQUEST(xResourceReq); 80205b261ecSmrg int rc; 80305b261ecSmrg 80405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8054642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); 80605b261ecSmrg if (rc != Success) 80705b261ecSmrg return rc; 80805b261ecSmrg MapWindow(pWin, client); 80905b261ecSmrg /* update cache to say it is mapped */ 8106747b715Smrg return Success; 81105b261ecSmrg} 81205b261ecSmrg 81305b261ecSmrgint 81405b261ecSmrgProcMapSubwindows(ClientPtr client) 81505b261ecSmrg{ 81605b261ecSmrg WindowPtr pWin; 81705b261ecSmrg REQUEST(xResourceReq); 81805b261ecSmrg int rc; 81905b261ecSmrg 82005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8214642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 82205b261ecSmrg if (rc != Success) 82305b261ecSmrg return rc; 82405b261ecSmrg MapSubwindows(pWin, client); 82505b261ecSmrg /* update cache to say it is mapped */ 8266747b715Smrg return Success; 82705b261ecSmrg} 82805b261ecSmrg 82905b261ecSmrgint 83005b261ecSmrgProcUnmapWindow(ClientPtr client) 83105b261ecSmrg{ 83205b261ecSmrg WindowPtr pWin; 83305b261ecSmrg REQUEST(xResourceReq); 83405b261ecSmrg int rc; 83505b261ecSmrg 83605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8374642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); 83805b261ecSmrg if (rc != Success) 83905b261ecSmrg return rc; 84005b261ecSmrg UnmapWindow(pWin, FALSE); 84105b261ecSmrg /* update cache to say it is mapped */ 8426747b715Smrg return Success; 84305b261ecSmrg} 84405b261ecSmrg 84505b261ecSmrgint 84605b261ecSmrgProcUnmapSubwindows(ClientPtr client) 84705b261ecSmrg{ 84805b261ecSmrg WindowPtr pWin; 84905b261ecSmrg REQUEST(xResourceReq); 85005b261ecSmrg int rc; 85105b261ecSmrg 85205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8534642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 85405b261ecSmrg if (rc != Success) 85505b261ecSmrg return rc; 85605b261ecSmrg UnmapSubwindows(pWin); 8576747b715Smrg return Success; 85805b261ecSmrg} 85905b261ecSmrg 86005b261ecSmrgint 86105b261ecSmrgProcConfigureWindow(ClientPtr client) 86205b261ecSmrg{ 86305b261ecSmrg WindowPtr pWin; 86405b261ecSmrg REQUEST(xConfigureWindowReq); 86505b261ecSmrg int len, rc; 86605b261ecSmrg 86705b261ecSmrg REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); 8684642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, 8694642e01fSmrg DixManageAccess|DixSetAttrAccess); 87005b261ecSmrg if (rc != Success) 87105b261ecSmrg return rc; 8726747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); 87305b261ecSmrg if (Ones((Mask)stuff->mask) != len) 87405b261ecSmrg return BadLength; 8756747b715Smrg return ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], client); 87605b261ecSmrg} 87705b261ecSmrg 87805b261ecSmrgint 87905b261ecSmrgProcCirculateWindow(ClientPtr client) 88005b261ecSmrg{ 88105b261ecSmrg WindowPtr pWin; 88205b261ecSmrg REQUEST(xCirculateWindowReq); 88305b261ecSmrg int rc; 88405b261ecSmrg 88505b261ecSmrg REQUEST_SIZE_MATCH(xCirculateWindowReq); 88605b261ecSmrg if ((stuff->direction != RaiseLowest) && 88705b261ecSmrg (stuff->direction != LowerHighest)) 88805b261ecSmrg { 88905b261ecSmrg client->errorValue = stuff->direction; 89005b261ecSmrg return BadValue; 89105b261ecSmrg } 8924642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 89305b261ecSmrg if (rc != Success) 89405b261ecSmrg return rc; 89505b261ecSmrg CirculateWindow(pWin, (int)stuff->direction, client); 8966747b715Smrg return Success; 89705b261ecSmrg} 89805b261ecSmrg 89905b261ecSmrgstatic int 90005b261ecSmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep) 90105b261ecSmrg{ 90205b261ecSmrg DrawablePtr pDraw; 90305b261ecSmrg int rc; 90405b261ecSmrg REQUEST(xResourceReq); 90505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 90605b261ecSmrg 9074642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); 90805b261ecSmrg if (rc != Success) 90905b261ecSmrg return rc; 91005b261ecSmrg 91105b261ecSmrg rep->type = X_Reply; 91205b261ecSmrg rep->length = 0; 91305b261ecSmrg rep->sequenceNumber = client->sequence; 9146747b715Smrg rep->root = pDraw->pScreen->root->drawable.id; 91505b261ecSmrg rep->depth = pDraw->depth; 91605b261ecSmrg rep->width = pDraw->width; 91705b261ecSmrg rep->height = pDraw->height; 91805b261ecSmrg 9199ace9065Smrg if (WindowDrawable(pDraw->type)) 92005b261ecSmrg { 92105b261ecSmrg WindowPtr pWin = (WindowPtr)pDraw; 92205b261ecSmrg rep->x = pWin->origin.x - wBorderWidth (pWin); 92305b261ecSmrg rep->y = pWin->origin.y - wBorderWidth (pWin); 92405b261ecSmrg rep->borderWidth = pWin->borderWidth; 92505b261ecSmrg } 9269ace9065Smrg else /* DRAWABLE_PIXMAP */ 92705b261ecSmrg { 92805b261ecSmrg rep->x = rep->y = rep->borderWidth = 0; 92905b261ecSmrg } 93005b261ecSmrg 93105b261ecSmrg return Success; 93205b261ecSmrg} 93305b261ecSmrg 93405b261ecSmrg 93505b261ecSmrgint 93605b261ecSmrgProcGetGeometry(ClientPtr client) 93705b261ecSmrg{ 93805b261ecSmrg xGetGeometryReply rep; 93905b261ecSmrg int status; 94005b261ecSmrg 9416747b715Smrg memset(&rep, 0, sizeof(xGetGeometryReply)); 94205b261ecSmrg if ((status = GetGeometry(client, &rep)) != Success) 94305b261ecSmrg return status; 94405b261ecSmrg 94505b261ecSmrg WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); 9466747b715Smrg return Success; 94705b261ecSmrg} 94805b261ecSmrg 94905b261ecSmrg 95005b261ecSmrgint 95105b261ecSmrgProcQueryTree(ClientPtr client) 95205b261ecSmrg{ 95305b261ecSmrg xQueryTreeReply reply; 95405b261ecSmrg int rc, numChildren = 0; 95505b261ecSmrg WindowPtr pChild, pWin, pHead; 95605b261ecSmrg Window *childIDs = (Window *)NULL; 95705b261ecSmrg REQUEST(xResourceReq); 95805b261ecSmrg 95905b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 9604642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 96105b261ecSmrg if (rc != Success) 96205b261ecSmrg return rc; 9636747b715Smrg memset(&reply, 0, sizeof(xQueryTreeReply)); 96405b261ecSmrg reply.type = X_Reply; 9656747b715Smrg reply.root = pWin->drawable.pScreen->root->drawable.id; 96605b261ecSmrg reply.sequenceNumber = client->sequence; 96705b261ecSmrg if (pWin->parent) 96805b261ecSmrg reply.parent = pWin->parent->drawable.id; 96905b261ecSmrg else 97005b261ecSmrg reply.parent = (Window)None; 97105b261ecSmrg pHead = RealChildHead(pWin); 97205b261ecSmrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 97305b261ecSmrg numChildren++; 97405b261ecSmrg if (numChildren) 97505b261ecSmrg { 97605b261ecSmrg int curChild = 0; 97705b261ecSmrg 9786747b715Smrg childIDs = malloc(numChildren * sizeof(Window)); 97905b261ecSmrg if (!childIDs) 98005b261ecSmrg return BadAlloc; 98105b261ecSmrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 98205b261ecSmrg childIDs[curChild++] = pChild->drawable.id; 98305b261ecSmrg } 98405b261ecSmrg 98505b261ecSmrg reply.nChildren = numChildren; 9866747b715Smrg reply.length = bytes_to_int32(numChildren * sizeof(Window)); 98705b261ecSmrg 98805b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); 98905b261ecSmrg if (numChildren) 99005b261ecSmrg { 99105b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 99205b261ecSmrg WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs); 9936747b715Smrg free(childIDs); 99405b261ecSmrg } 99505b261ecSmrg 9966747b715Smrg return Success; 99705b261ecSmrg} 99805b261ecSmrg 99905b261ecSmrgint 100005b261ecSmrgProcInternAtom(ClientPtr client) 100105b261ecSmrg{ 100205b261ecSmrg Atom atom; 100305b261ecSmrg char *tchar; 100405b261ecSmrg REQUEST(xInternAtomReq); 100505b261ecSmrg 100605b261ecSmrg REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); 100705b261ecSmrg if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) 100805b261ecSmrg { 100905b261ecSmrg client->errorValue = stuff->onlyIfExists; 10106747b715Smrg return BadValue; 101105b261ecSmrg } 101205b261ecSmrg tchar = (char *) &stuff[1]; 101305b261ecSmrg atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); 101405b261ecSmrg if (atom != BAD_RESOURCE) 101505b261ecSmrg { 101605b261ecSmrg xInternAtomReply reply; 10176747b715Smrg memset(&reply, 0, sizeof(xInternAtomReply)); 101805b261ecSmrg reply.type = X_Reply; 101905b261ecSmrg reply.length = 0; 102005b261ecSmrg reply.sequenceNumber = client->sequence; 102105b261ecSmrg reply.atom = atom; 102205b261ecSmrg WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); 10236747b715Smrg return Success; 102405b261ecSmrg } 102505b261ecSmrg else 10266747b715Smrg return BadAlloc; 102705b261ecSmrg} 102805b261ecSmrg 102905b261ecSmrgint 103005b261ecSmrgProcGetAtomName(ClientPtr client) 103105b261ecSmrg{ 10326747b715Smrg const char *str; 103305b261ecSmrg xGetAtomNameReply reply; 103405b261ecSmrg int len; 103505b261ecSmrg REQUEST(xResourceReq); 103605b261ecSmrg 103705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 103805b261ecSmrg if ( (str = NameForAtom(stuff->id)) ) 103905b261ecSmrg { 104005b261ecSmrg len = strlen(str); 10416747b715Smrg memset(&reply, 0, sizeof(xGetAtomNameReply)); 104205b261ecSmrg reply.type = X_Reply; 10436747b715Smrg reply.length = bytes_to_int32(len); 104405b261ecSmrg reply.sequenceNumber = client->sequence; 104505b261ecSmrg reply.nameLength = len; 104605b261ecSmrg WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); 104705b261ecSmrg (void)WriteToClient(client, len, str); 10486747b715Smrg return Success; 104905b261ecSmrg } 105005b261ecSmrg else 105105b261ecSmrg { 105205b261ecSmrg client->errorValue = stuff->id; 10536747b715Smrg return BadAtom; 105405b261ecSmrg } 105505b261ecSmrg} 105605b261ecSmrg 105705b261ecSmrgint 105805b261ecSmrgProcGrabServer(ClientPtr client) 105905b261ecSmrg{ 10604642e01fSmrg int rc; 106105b261ecSmrg REQUEST_SIZE_MATCH(xReq); 106205b261ecSmrg if (grabState != GrabNone && client != grabClient) 106305b261ecSmrg { 106405b261ecSmrg ResetCurrentRequest(client); 106505b261ecSmrg client->sequence--; 106605b261ecSmrg BITSET(grabWaiters, client->index); 106705b261ecSmrg IgnoreClient(client); 10686747b715Smrg return Success; 106905b261ecSmrg } 10704642e01fSmrg rc = OnlyListenToOneClient(client); 10714642e01fSmrg if (rc != Success) 10724642e01fSmrg return rc; 107305b261ecSmrg grabState = GrabKickout; 107405b261ecSmrg grabClient = client; 107505b261ecSmrg 107605b261ecSmrg if (ServerGrabCallback) 107705b261ecSmrg { 107805b261ecSmrg ServerGrabInfoRec grabinfo; 107905b261ecSmrg grabinfo.client = client; 108005b261ecSmrg grabinfo.grabstate = SERVER_GRABBED; 108105b261ecSmrg CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 108205b261ecSmrg } 108305b261ecSmrg 10846747b715Smrg return Success; 108505b261ecSmrg} 108605b261ecSmrg 108705b261ecSmrgstatic void 108805b261ecSmrgUngrabServer(ClientPtr client) 108905b261ecSmrg{ 109005b261ecSmrg int i; 109105b261ecSmrg 109205b261ecSmrg grabState = GrabNone; 109305b261ecSmrg ListenToAllClients(); 109405b261ecSmrg for (i = mskcnt; --i >= 0 && !grabWaiters[i]; ) 109505b261ecSmrg ; 109605b261ecSmrg if (i >= 0) 109705b261ecSmrg { 109805b261ecSmrg i <<= 5; 109905b261ecSmrg while (!GETBIT(grabWaiters, i)) 110005b261ecSmrg i++; 110105b261ecSmrg BITCLEAR(grabWaiters, i); 110205b261ecSmrg AttendClient(clients[i]); 110305b261ecSmrg } 110405b261ecSmrg 110505b261ecSmrg if (ServerGrabCallback) 110605b261ecSmrg { 110705b261ecSmrg ServerGrabInfoRec grabinfo; 110805b261ecSmrg grabinfo.client = client; 110905b261ecSmrg grabinfo.grabstate = SERVER_UNGRABBED; 111005b261ecSmrg CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 111105b261ecSmrg } 111205b261ecSmrg} 111305b261ecSmrg 111405b261ecSmrgint 111505b261ecSmrgProcUngrabServer(ClientPtr client) 111605b261ecSmrg{ 111705b261ecSmrg REQUEST_SIZE_MATCH(xReq); 111805b261ecSmrg UngrabServer(client); 11196747b715Smrg return Success; 112005b261ecSmrg} 112105b261ecSmrg 112205b261ecSmrgint 112305b261ecSmrgProcTranslateCoords(ClientPtr client) 112405b261ecSmrg{ 112505b261ecSmrg REQUEST(xTranslateCoordsReq); 112605b261ecSmrg 112705b261ecSmrg WindowPtr pWin, pDst; 112805b261ecSmrg xTranslateCoordsReply rep; 112905b261ecSmrg int rc; 113005b261ecSmrg 113105b261ecSmrg REQUEST_SIZE_MATCH(xTranslateCoordsReq); 11324642e01fSmrg rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); 113305b261ecSmrg if (rc != Success) 113405b261ecSmrg return rc; 11354642e01fSmrg rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); 113605b261ecSmrg if (rc != Success) 113705b261ecSmrg return rc; 11386747b715Smrg memset(&rep, 0, sizeof(xTranslateCoordsReply)); 113905b261ecSmrg rep.type = X_Reply; 114005b261ecSmrg rep.length = 0; 114105b261ecSmrg rep.sequenceNumber = client->sequence; 114205b261ecSmrg if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) 114305b261ecSmrg { 114405b261ecSmrg rep.sameScreen = xFalse; 114505b261ecSmrg rep.child = None; 114605b261ecSmrg rep.dstX = rep.dstY = 0; 114705b261ecSmrg } 114805b261ecSmrg else 114905b261ecSmrg { 115005b261ecSmrg INT16 x, y; 115105b261ecSmrg rep.sameScreen = xTrue; 115205b261ecSmrg rep.child = None; 115305b261ecSmrg /* computing absolute coordinates -- adjust to destination later */ 115405b261ecSmrg x = pWin->drawable.x + stuff->srcX; 115505b261ecSmrg y = pWin->drawable.y + stuff->srcY; 115605b261ecSmrg pWin = pDst->firstChild; 115705b261ecSmrg while (pWin) 115805b261ecSmrg { 115905b261ecSmrg BoxRec box; 116005b261ecSmrg if ((pWin->mapped) && 116105b261ecSmrg (x >= pWin->drawable.x - wBorderWidth (pWin)) && 116205b261ecSmrg (x < pWin->drawable.x + (int)pWin->drawable.width + 116305b261ecSmrg wBorderWidth (pWin)) && 116405b261ecSmrg (y >= pWin->drawable.y - wBorderWidth (pWin)) && 116505b261ecSmrg (y < pWin->drawable.y + (int)pWin->drawable.height + 116605b261ecSmrg wBorderWidth (pWin)) 116705b261ecSmrg /* When a window is shaped, a further check 116805b261ecSmrg * is made to see if the point is inside 116905b261ecSmrg * borderSize 117005b261ecSmrg */ 117105b261ecSmrg && (!wBoundingShape(pWin) || 11726747b715Smrg RegionContainsPoint(&pWin->borderSize, x, y, &box)) 117305b261ecSmrg 117405b261ecSmrg && (!wInputShape(pWin) || 11756747b715Smrg RegionContainsPoint(wInputShape(pWin), 11766747b715Smrg x - pWin->drawable.x, 11776747b715Smrg y - pWin->drawable.y, &box)) 117805b261ecSmrg ) 117905b261ecSmrg { 118005b261ecSmrg rep.child = pWin->drawable.id; 118105b261ecSmrg pWin = (WindowPtr) NULL; 118205b261ecSmrg } 118305b261ecSmrg else 118405b261ecSmrg pWin = pWin->nextSib; 118505b261ecSmrg } 118605b261ecSmrg /* adjust to destination coordinates */ 118705b261ecSmrg rep.dstX = x - pDst->drawable.x; 118805b261ecSmrg rep.dstY = y - pDst->drawable.y; 118905b261ecSmrg } 119005b261ecSmrg WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); 11916747b715Smrg return Success; 119205b261ecSmrg} 119305b261ecSmrg 119405b261ecSmrgint 119505b261ecSmrgProcOpenFont(ClientPtr client) 119605b261ecSmrg{ 119705b261ecSmrg int err; 119805b261ecSmrg REQUEST(xOpenFontReq); 119905b261ecSmrg 120005b261ecSmrg REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); 120105b261ecSmrg client->errorValue = stuff->fid; 120205b261ecSmrg LEGAL_NEW_RESOURCE(stuff->fid, client); 120305b261ecSmrg err = OpenFont(client, stuff->fid, (Mask) 0, 120405b261ecSmrg stuff->nbytes, (char *)&stuff[1]); 120505b261ecSmrg if (err == Success) 120605b261ecSmrg { 12076747b715Smrg return Success; 120805b261ecSmrg } 120905b261ecSmrg else 121005b261ecSmrg return err; 121105b261ecSmrg} 121205b261ecSmrg 121305b261ecSmrgint 121405b261ecSmrgProcCloseFont(ClientPtr client) 121505b261ecSmrg{ 121605b261ecSmrg FontPtr pFont; 12176747b715Smrg int rc; 121805b261ecSmrg REQUEST(xResourceReq); 121905b261ecSmrg 122005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 12216747b715Smrg rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, 12226747b715Smrg client, DixDestroyAccess); 12236747b715Smrg if (rc == Success) 122405b261ecSmrg { 122505b261ecSmrg FreeResource(stuff->id, RT_NONE); 12266747b715Smrg return Success; 122705b261ecSmrg } 122805b261ecSmrg else 122905b261ecSmrg { 123005b261ecSmrg client->errorValue = stuff->id; 12316747b715Smrg return rc; 123205b261ecSmrg } 123305b261ecSmrg} 123405b261ecSmrg 123505b261ecSmrgint 123605b261ecSmrgProcQueryFont(ClientPtr client) 123705b261ecSmrg{ 123805b261ecSmrg xQueryFontReply *reply; 123905b261ecSmrg FontPtr pFont; 12404642e01fSmrg int rc; 124105b261ecSmrg REQUEST(xResourceReq); 124205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 12434642e01fSmrg 12446747b715Smrg rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess); 12454642e01fSmrg if (rc != Success) 12466747b715Smrg return rc; 124705b261ecSmrg 124805b261ecSmrg { 124905b261ecSmrg xCharInfo *pmax = FONTINKMAX(pFont); 125005b261ecSmrg xCharInfo *pmin = FONTINKMIN(pFont); 125105b261ecSmrg int nprotoxcistructs; 125205b261ecSmrg int rlength; 125305b261ecSmrg 125405b261ecSmrg nprotoxcistructs = ( 125505b261ecSmrg pmax->rightSideBearing == pmin->rightSideBearing && 125605b261ecSmrg pmax->leftSideBearing == pmin->leftSideBearing && 125705b261ecSmrg pmax->descent == pmin->descent && 125805b261ecSmrg pmax->ascent == pmin->ascent && 125905b261ecSmrg pmax->characterWidth == pmin->characterWidth) ? 126005b261ecSmrg 0 : N2dChars(pFont); 126105b261ecSmrg 126205b261ecSmrg rlength = sizeof(xQueryFontReply) + 126305b261ecSmrg FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + 126405b261ecSmrg nprotoxcistructs * sizeof(xCharInfo); 12656747b715Smrg reply = calloc(1, rlength); 126605b261ecSmrg if(!reply) 126705b261ecSmrg { 12686747b715Smrg return BadAlloc; 126905b261ecSmrg } 127005b261ecSmrg 127105b261ecSmrg reply->type = X_Reply; 12726747b715Smrg reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); 127305b261ecSmrg reply->sequenceNumber = client->sequence; 127405b261ecSmrg QueryFont( pFont, reply, nprotoxcistructs); 127505b261ecSmrg 127605b261ecSmrg WriteReplyToClient(client, rlength, reply); 12776747b715Smrg free(reply); 12786747b715Smrg return Success; 127905b261ecSmrg } 128005b261ecSmrg} 128105b261ecSmrg 128205b261ecSmrgint 128305b261ecSmrgProcQueryTextExtents(ClientPtr client) 128405b261ecSmrg{ 128505b261ecSmrg xQueryTextExtentsReply reply; 128605b261ecSmrg FontPtr pFont; 128705b261ecSmrg ExtentInfoRec info; 128805b261ecSmrg unsigned long length; 12894642e01fSmrg int rc; 12904642e01fSmrg REQUEST(xQueryTextExtentsReq); 129105b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); 129205b261ecSmrg 12936747b715Smrg rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess); 12944642e01fSmrg if (rc != Success) 12956747b715Smrg return rc; 12964642e01fSmrg 12976747b715Smrg length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); 129805b261ecSmrg length = length << 1; 129905b261ecSmrg if (stuff->oddLength) 130005b261ecSmrg { 130105b261ecSmrg if (length == 0) 13026747b715Smrg return BadLength; 130305b261ecSmrg length--; 130405b261ecSmrg } 130505b261ecSmrg if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info)) 13066747b715Smrg return BadAlloc; 130705b261ecSmrg reply.type = X_Reply; 130805b261ecSmrg reply.length = 0; 130905b261ecSmrg reply.sequenceNumber = client->sequence; 131005b261ecSmrg reply.drawDirection = info.drawDirection; 131105b261ecSmrg reply.fontAscent = info.fontAscent; 131205b261ecSmrg reply.fontDescent = info.fontDescent; 131305b261ecSmrg reply.overallAscent = info.overallAscent; 131405b261ecSmrg reply.overallDescent = info.overallDescent; 131505b261ecSmrg reply.overallWidth = info.overallWidth; 131605b261ecSmrg reply.overallLeft = info.overallLeft; 131705b261ecSmrg reply.overallRight = info.overallRight; 131805b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); 13196747b715Smrg return Success; 132005b261ecSmrg} 132105b261ecSmrg 132205b261ecSmrgint 132305b261ecSmrgProcListFonts(ClientPtr client) 132405b261ecSmrg{ 132505b261ecSmrg REQUEST(xListFontsReq); 132605b261ecSmrg 132705b261ecSmrg REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); 132805b261ecSmrg 132905b261ecSmrg return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 133005b261ecSmrg stuff->maxNames); 133105b261ecSmrg} 133205b261ecSmrg 133305b261ecSmrgint 133405b261ecSmrgProcListFontsWithInfo(ClientPtr client) 133505b261ecSmrg{ 133605b261ecSmrg REQUEST(xListFontsWithInfoReq); 133705b261ecSmrg 133805b261ecSmrg REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); 133905b261ecSmrg 134005b261ecSmrg return StartListFontsWithInfo(client, stuff->nbytes, 134105b261ecSmrg (unsigned char *) &stuff[1], stuff->maxNames); 134205b261ecSmrg} 134305b261ecSmrg 134405b261ecSmrg/** 134505b261ecSmrg * 134605b261ecSmrg * \param value must conform to DeleteType 134705b261ecSmrg */ 134805b261ecSmrgint 134905b261ecSmrgdixDestroyPixmap(pointer value, XID pid) 135005b261ecSmrg{ 135105b261ecSmrg PixmapPtr pPixmap = (PixmapPtr)value; 135205b261ecSmrg return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 135305b261ecSmrg} 135405b261ecSmrg 135505b261ecSmrgint 135605b261ecSmrgProcCreatePixmap(ClientPtr client) 135705b261ecSmrg{ 135805b261ecSmrg PixmapPtr pMap; 135905b261ecSmrg DrawablePtr pDraw; 136005b261ecSmrg REQUEST(xCreatePixmapReq); 136105b261ecSmrg DepthPtr pDepth; 136205b261ecSmrg int i, rc; 136305b261ecSmrg 136405b261ecSmrg REQUEST_SIZE_MATCH(xCreatePixmapReq); 136505b261ecSmrg client->errorValue = stuff->pid; 136605b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 136705b261ecSmrg 136805b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 13694642e01fSmrg DixGetAttrAccess); 137005b261ecSmrg if (rc != Success) 137105b261ecSmrg return rc; 137205b261ecSmrg 137305b261ecSmrg if (!stuff->width || !stuff->height) 137405b261ecSmrg { 137505b261ecSmrg client->errorValue = 0; 137605b261ecSmrg return BadValue; 137705b261ecSmrg } 137805b261ecSmrg if (stuff->width > 32767 || stuff->height > 32767) 137905b261ecSmrg { 138005b261ecSmrg /* It is allowed to try and allocate a pixmap which is larger than 138105b261ecSmrg * 32767 in either dimension. However, all of the framebuffer code 138205b261ecSmrg * is buggy and does not reliably draw to such big pixmaps, basically 138305b261ecSmrg * because the Region data structure operates with signed shorts 138405b261ecSmrg * for the rectangles in it. 138505b261ecSmrg * 138605b261ecSmrg * Furthermore, several places in the X server computes the 138705b261ecSmrg * size in bytes of the pixmap and tries to store it in an 138805b261ecSmrg * integer. This integer can overflow and cause the allocated size 138905b261ecSmrg * to be much smaller. 139005b261ecSmrg * 139105b261ecSmrg * So, such big pixmaps are rejected here with a BadAlloc 139205b261ecSmrg */ 139305b261ecSmrg return BadAlloc; 139405b261ecSmrg } 139505b261ecSmrg if (stuff->depth != 1) 139605b261ecSmrg { 139705b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 139805b261ecSmrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 139905b261ecSmrg if (pDepth->depth == stuff->depth) 140005b261ecSmrg goto CreatePmap; 140105b261ecSmrg client->errorValue = stuff->depth; 140205b261ecSmrg return BadValue; 140305b261ecSmrg } 140405b261ecSmrgCreatePmap: 140505b261ecSmrg pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) 140605b261ecSmrg (pDraw->pScreen, stuff->width, 14074642e01fSmrg stuff->height, stuff->depth, 0); 140805b261ecSmrg if (pMap) 140905b261ecSmrg { 141005b261ecSmrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 141105b261ecSmrg pMap->drawable.id = stuff->pid; 14124642e01fSmrg /* security creation/labeling check */ 14134642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 14144642e01fSmrg pMap, RT_NONE, NULL, DixCreateAccess); 14154642e01fSmrg if (rc != Success) { 14164642e01fSmrg (*pDraw->pScreen->DestroyPixmap)(pMap); 14174642e01fSmrg return rc; 14184642e01fSmrg } 141905b261ecSmrg if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) 14206747b715Smrg return Success; 142105b261ecSmrg } 14226747b715Smrg return BadAlloc; 142305b261ecSmrg} 142405b261ecSmrg 142505b261ecSmrgint 142605b261ecSmrgProcFreePixmap(ClientPtr client) 142705b261ecSmrg{ 142805b261ecSmrg PixmapPtr pMap; 14294642e01fSmrg int rc; 143005b261ecSmrg REQUEST(xResourceReq); 143105b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 14324642e01fSmrg 1433b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client, 14344642e01fSmrg DixDestroyAccess); 14354642e01fSmrg if (rc == Success) 143605b261ecSmrg { 143705b261ecSmrg FreeResource(stuff->id, RT_NONE); 14386747b715Smrg return Success; 143905b261ecSmrg } 144005b261ecSmrg else 144105b261ecSmrg { 144205b261ecSmrg client->errorValue = stuff->id; 14436747b715Smrg return rc; 144405b261ecSmrg } 144505b261ecSmrg} 144605b261ecSmrg 144705b261ecSmrgint 144805b261ecSmrgProcCreateGC(ClientPtr client) 144905b261ecSmrg{ 145005b261ecSmrg int error, rc; 145105b261ecSmrg GC *pGC; 145205b261ecSmrg DrawablePtr pDraw; 145305b261ecSmrg unsigned len; 145405b261ecSmrg REQUEST(xCreateGCReq); 145505b261ecSmrg 145605b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateGCReq); 145705b261ecSmrg client->errorValue = stuff->gc; 145805b261ecSmrg LEGAL_NEW_RESOURCE(stuff->gc, client); 14594642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 14604642e01fSmrg DixGetAttrAccess); 146105b261ecSmrg if (rc != Success) 146205b261ecSmrg return rc; 146305b261ecSmrg 14646747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); 146505b261ecSmrg if (len != Ones(stuff->mask)) 146605b261ecSmrg return BadLength; 14674642e01fSmrg pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, 14684642e01fSmrg stuff->gc, client); 146905b261ecSmrg if (error != Success) 147005b261ecSmrg return error; 147105b261ecSmrg if (!AddResource(stuff->gc, RT_GC, (pointer)pGC)) 14726747b715Smrg return BadAlloc; 14736747b715Smrg return Success; 147405b261ecSmrg} 147505b261ecSmrg 147605b261ecSmrgint 147705b261ecSmrgProcChangeGC(ClientPtr client) 147805b261ecSmrg{ 147905b261ecSmrg GC *pGC; 148005b261ecSmrg int result; 148105b261ecSmrg unsigned len; 148205b261ecSmrg REQUEST(xChangeGCReq); 148305b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeGCReq); 148405b261ecSmrg 14854642e01fSmrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 148605b261ecSmrg if (result != Success) 148705b261ecSmrg return result; 148805b261ecSmrg 14896747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); 149005b261ecSmrg if (len != Ones(stuff->mask)) 149105b261ecSmrg return BadLength; 149205b261ecSmrg 14936747b715Smrg return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]); 149405b261ecSmrg} 149505b261ecSmrg 149605b261ecSmrgint 149705b261ecSmrgProcCopyGC(ClientPtr client) 149805b261ecSmrg{ 149905b261ecSmrg GC *dstGC; 150005b261ecSmrg GC *pGC; 150105b261ecSmrg int result; 150205b261ecSmrg REQUEST(xCopyGCReq); 150305b261ecSmrg REQUEST_SIZE_MATCH(xCopyGCReq); 150405b261ecSmrg 15054642e01fSmrg result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); 150605b261ecSmrg if (result != Success) 150705b261ecSmrg return result; 15084642e01fSmrg result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); 150905b261ecSmrg if (result != Success) 151005b261ecSmrg return result; 151105b261ecSmrg if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 15126747b715Smrg return BadMatch; 15136747b715Smrg if (stuff->mask & ~GCAllBits) 151405b261ecSmrg { 15156747b715Smrg client->errorValue = stuff->mask; 15166747b715Smrg return BadValue; 151705b261ecSmrg } 15186747b715Smrg return CopyGC(pGC, dstGC, stuff->mask); 151905b261ecSmrg} 152005b261ecSmrg 152105b261ecSmrgint 152205b261ecSmrgProcSetDashes(ClientPtr client) 152305b261ecSmrg{ 152405b261ecSmrg GC *pGC; 152505b261ecSmrg int result; 152605b261ecSmrg REQUEST(xSetDashesReq); 152705b261ecSmrg 152805b261ecSmrg REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 152905b261ecSmrg if (stuff->nDashes == 0) 153005b261ecSmrg { 153105b261ecSmrg client->errorValue = 0; 153205b261ecSmrg return BadValue; 153305b261ecSmrg } 153405b261ecSmrg 15354642e01fSmrg result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 153605b261ecSmrg if (result != Success) 153705b261ecSmrg return result; 153805b261ecSmrg 15396747b715Smrg /* If there's an error, either there's no sensible errorValue, 15406747b715Smrg * or there was a dash segment of 0. */ 15416747b715Smrg client->errorValue = 0; 15426747b715Smrg return SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 154305b261ecSmrg (unsigned char *)&stuff[1]); 154405b261ecSmrg} 154505b261ecSmrg 154605b261ecSmrgint 154705b261ecSmrgProcSetClipRectangles(ClientPtr client) 154805b261ecSmrg{ 154905b261ecSmrg int nr, result; 155005b261ecSmrg GC *pGC; 155105b261ecSmrg REQUEST(xSetClipRectanglesReq); 155205b261ecSmrg 155305b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 155405b261ecSmrg if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 155505b261ecSmrg (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) 155605b261ecSmrg { 155705b261ecSmrg client->errorValue = stuff->ordering; 155805b261ecSmrg return BadValue; 155905b261ecSmrg } 15604642e01fSmrg result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 156105b261ecSmrg if (result != Success) 156205b261ecSmrg return result; 156305b261ecSmrg 156405b261ecSmrg nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 156505b261ecSmrg if (nr & 4) 15666747b715Smrg return BadLength; 156705b261ecSmrg nr >>= 3; 15686747b715Smrg return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 156905b261ecSmrg nr, (xRectangle *)&stuff[1], (int)stuff->ordering); 157005b261ecSmrg} 157105b261ecSmrg 157205b261ecSmrgint 157305b261ecSmrgProcFreeGC(ClientPtr client) 157405b261ecSmrg{ 157505b261ecSmrg GC *pGC; 157605b261ecSmrg int rc; 157705b261ecSmrg REQUEST(xResourceReq); 157805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 157905b261ecSmrg 158005b261ecSmrg rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 158105b261ecSmrg if (rc != Success) 158205b261ecSmrg return rc; 158305b261ecSmrg 158405b261ecSmrg FreeResource(stuff->id, RT_NONE); 15856747b715Smrg return Success; 158605b261ecSmrg} 158705b261ecSmrg 158805b261ecSmrgint 158905b261ecSmrgProcClearToBackground(ClientPtr client) 159005b261ecSmrg{ 159105b261ecSmrg REQUEST(xClearAreaReq); 159205b261ecSmrg WindowPtr pWin; 159305b261ecSmrg int rc; 159405b261ecSmrg 159505b261ecSmrg REQUEST_SIZE_MATCH(xClearAreaReq); 159605b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 159705b261ecSmrg if (rc != Success) 159805b261ecSmrg return rc; 159905b261ecSmrg if (pWin->drawable.class == InputOnly) 160005b261ecSmrg { 160105b261ecSmrg client->errorValue = stuff->window; 16026747b715Smrg return BadMatch; 160305b261ecSmrg } 160405b261ecSmrg if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) 160505b261ecSmrg { 160605b261ecSmrg client->errorValue = stuff->exposures; 16076747b715Smrg return BadValue; 160805b261ecSmrg } 160905b261ecSmrg (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y, 161005b261ecSmrg stuff->width, stuff->height, 161105b261ecSmrg (Bool)stuff->exposures); 16126747b715Smrg return Success; 161305b261ecSmrg} 161405b261ecSmrg 161505b261ecSmrgint 161605b261ecSmrgProcCopyArea(ClientPtr client) 161705b261ecSmrg{ 161805b261ecSmrg DrawablePtr pDst; 161905b261ecSmrg DrawablePtr pSrc; 162005b261ecSmrg GC *pGC; 162105b261ecSmrg REQUEST(xCopyAreaReq); 162205b261ecSmrg RegionPtr pRgn; 162305b261ecSmrg int rc; 162405b261ecSmrg 162505b261ecSmrg REQUEST_SIZE_MATCH(xCopyAreaReq); 162605b261ecSmrg 16274642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 162805b261ecSmrg if (stuff->dstDrawable != stuff->srcDrawable) 162905b261ecSmrg { 163005b261ecSmrg rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 163105b261ecSmrg DixReadAccess); 163205b261ecSmrg if (rc != Success) 163305b261ecSmrg return rc; 163405b261ecSmrg if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) 163505b261ecSmrg { 163605b261ecSmrg client->errorValue = stuff->dstDrawable; 16376747b715Smrg return BadMatch; 163805b261ecSmrg } 163905b261ecSmrg } 164005b261ecSmrg else 164105b261ecSmrg pSrc = pDst; 164205b261ecSmrg 164305b261ecSmrg pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 164405b261ecSmrg stuff->width, stuff->height, 164505b261ecSmrg stuff->dstX, stuff->dstY); 164605b261ecSmrg if (pGC->graphicsExposures) 164705b261ecSmrg { 164805b261ecSmrg (*pDst->pScreen->SendGraphicsExpose) 164905b261ecSmrg (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 165005b261ecSmrg if (pRgn) 16516747b715Smrg RegionDestroy(pRgn); 165205b261ecSmrg } 165305b261ecSmrg 16546747b715Smrg return Success; 165505b261ecSmrg} 165605b261ecSmrg 165705b261ecSmrgint 165805b261ecSmrgProcCopyPlane(ClientPtr client) 165905b261ecSmrg{ 166005b261ecSmrg DrawablePtr psrcDraw, pdstDraw; 166105b261ecSmrg GC *pGC; 166205b261ecSmrg REQUEST(xCopyPlaneReq); 166305b261ecSmrg RegionPtr pRgn; 166405b261ecSmrg int rc; 166505b261ecSmrg 166605b261ecSmrg REQUEST_SIZE_MATCH(xCopyPlaneReq); 166705b261ecSmrg 16684642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); 166905b261ecSmrg if (stuff->dstDrawable != stuff->srcDrawable) 167005b261ecSmrg { 167105b261ecSmrg rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 167205b261ecSmrg DixReadAccess); 167305b261ecSmrg if (rc != Success) 167405b261ecSmrg return rc; 167505b261ecSmrg 167605b261ecSmrg if (pdstDraw->pScreen != psrcDraw->pScreen) 167705b261ecSmrg { 167805b261ecSmrg client->errorValue = stuff->dstDrawable; 16796747b715Smrg return BadMatch; 168005b261ecSmrg } 168105b261ecSmrg } 168205b261ecSmrg else 168305b261ecSmrg psrcDraw = pdstDraw; 168405b261ecSmrg 168505b261ecSmrg /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 168605b261ecSmrg if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 168705b261ecSmrg (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) 168805b261ecSmrg { 168905b261ecSmrg client->errorValue = stuff->bitPlane; 16906747b715Smrg return BadValue; 169105b261ecSmrg } 169205b261ecSmrg 169305b261ecSmrg pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, 169405b261ecSmrg stuff->width, stuff->height, 169505b261ecSmrg stuff->dstX, stuff->dstY, stuff->bitPlane); 169605b261ecSmrg if (pGC->graphicsExposures) 169705b261ecSmrg { 169805b261ecSmrg (*pdstDraw->pScreen->SendGraphicsExpose) 169905b261ecSmrg (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 170005b261ecSmrg if (pRgn) 17016747b715Smrg RegionDestroy(pRgn); 170205b261ecSmrg } 17036747b715Smrg return Success; 170405b261ecSmrg} 170505b261ecSmrg 170605b261ecSmrgint 170705b261ecSmrgProcPolyPoint(ClientPtr client) 170805b261ecSmrg{ 170905b261ecSmrg int npoint; 171005b261ecSmrg GC *pGC; 171105b261ecSmrg DrawablePtr pDraw; 171205b261ecSmrg REQUEST(xPolyPointReq); 171305b261ecSmrg 171405b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyPointReq); 171505b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 171605b261ecSmrg (stuff->coordMode != CoordModePrevious)) 171705b261ecSmrg { 171805b261ecSmrg client->errorValue = stuff->coordMode; 171905b261ecSmrg return BadValue; 172005b261ecSmrg } 17214642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 17226747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); 172305b261ecSmrg if (npoint) 172405b261ecSmrg (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, 172505b261ecSmrg (xPoint *) &stuff[1]); 17266747b715Smrg return Success; 172705b261ecSmrg} 172805b261ecSmrg 172905b261ecSmrgint 173005b261ecSmrgProcPolyLine(ClientPtr client) 173105b261ecSmrg{ 173205b261ecSmrg int npoint; 173305b261ecSmrg GC *pGC; 173405b261ecSmrg DrawablePtr pDraw; 173505b261ecSmrg REQUEST(xPolyLineReq); 173605b261ecSmrg 173705b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyLineReq); 173805b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 173905b261ecSmrg (stuff->coordMode != CoordModePrevious)) 174005b261ecSmrg { 174105b261ecSmrg client->errorValue = stuff->coordMode; 174205b261ecSmrg return BadValue; 174305b261ecSmrg } 17444642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 17456747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); 174605b261ecSmrg if (npoint > 1) 174705b261ecSmrg (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 174805b261ecSmrg (DDXPointPtr) &stuff[1]); 17496747b715Smrg return Success; 175005b261ecSmrg} 175105b261ecSmrg 175205b261ecSmrgint 175305b261ecSmrgProcPolySegment(ClientPtr client) 175405b261ecSmrg{ 175505b261ecSmrg int nsegs; 175605b261ecSmrg GC *pGC; 175705b261ecSmrg DrawablePtr pDraw; 175805b261ecSmrg REQUEST(xPolySegmentReq); 175905b261ecSmrg 176005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 17614642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 176205b261ecSmrg nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 176305b261ecSmrg if (nsegs & 4) 17646747b715Smrg return BadLength; 176505b261ecSmrg nsegs >>= 3; 176605b261ecSmrg if (nsegs) 176705b261ecSmrg (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 17686747b715Smrg return Success; 176905b261ecSmrg} 177005b261ecSmrg 177105b261ecSmrgint 177205b261ecSmrgProcPolyRectangle (ClientPtr client) 177305b261ecSmrg{ 177405b261ecSmrg int nrects; 177505b261ecSmrg GC *pGC; 177605b261ecSmrg DrawablePtr pDraw; 177705b261ecSmrg REQUEST(xPolyRectangleReq); 177805b261ecSmrg 177905b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 17804642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 178105b261ecSmrg nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 178205b261ecSmrg if (nrects & 4) 17836747b715Smrg return BadLength; 178405b261ecSmrg nrects >>= 3; 178505b261ecSmrg if (nrects) 178605b261ecSmrg (*pGC->ops->PolyRectangle)(pDraw, pGC, 178705b261ecSmrg nrects, (xRectangle *) &stuff[1]); 17886747b715Smrg return Success; 178905b261ecSmrg} 179005b261ecSmrg 179105b261ecSmrgint 179205b261ecSmrgProcPolyArc(ClientPtr client) 179305b261ecSmrg{ 179405b261ecSmrg int narcs; 179505b261ecSmrg GC *pGC; 179605b261ecSmrg DrawablePtr pDraw; 179705b261ecSmrg REQUEST(xPolyArcReq); 179805b261ecSmrg 179905b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyArcReq); 18004642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 180105b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 180205b261ecSmrg if (narcs % sizeof(xArc)) 18036747b715Smrg return BadLength; 180405b261ecSmrg narcs /= sizeof(xArc); 180505b261ecSmrg if (narcs) 180605b261ecSmrg (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]); 18076747b715Smrg return Success; 180805b261ecSmrg} 180905b261ecSmrg 181005b261ecSmrgint 181105b261ecSmrgProcFillPoly(ClientPtr client) 181205b261ecSmrg{ 181305b261ecSmrg int things; 181405b261ecSmrg GC *pGC; 181505b261ecSmrg DrawablePtr pDraw; 181605b261ecSmrg REQUEST(xFillPolyReq); 181705b261ecSmrg 181805b261ecSmrg REQUEST_AT_LEAST_SIZE(xFillPolyReq); 181905b261ecSmrg if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 182005b261ecSmrg (stuff->shape != Convex)) 182105b261ecSmrg { 182205b261ecSmrg client->errorValue = stuff->shape; 182305b261ecSmrg return BadValue; 182405b261ecSmrg } 182505b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 182605b261ecSmrg (stuff->coordMode != CoordModePrevious)) 182705b261ecSmrg { 182805b261ecSmrg client->errorValue = stuff->coordMode; 182905b261ecSmrg return BadValue; 183005b261ecSmrg } 183105b261ecSmrg 18324642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 18336747b715Smrg things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); 183405b261ecSmrg if (things) 183505b261ecSmrg (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 183605b261ecSmrg stuff->coordMode, things, 183705b261ecSmrg (DDXPointPtr) &stuff[1]); 18386747b715Smrg return Success; 183905b261ecSmrg} 184005b261ecSmrg 184105b261ecSmrgint 184205b261ecSmrgProcPolyFillRectangle(ClientPtr client) 184305b261ecSmrg{ 184405b261ecSmrg int things; 184505b261ecSmrg GC *pGC; 184605b261ecSmrg DrawablePtr pDraw; 184705b261ecSmrg REQUEST(xPolyFillRectangleReq); 184805b261ecSmrg 184905b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 18504642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 185105b261ecSmrg things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 185205b261ecSmrg if (things & 4) 18536747b715Smrg return BadLength; 185405b261ecSmrg things >>= 3; 185505b261ecSmrg 185605b261ecSmrg if (things) 185705b261ecSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 185805b261ecSmrg (xRectangle *) &stuff[1]); 18596747b715Smrg return Success; 186005b261ecSmrg} 186105b261ecSmrg 186205b261ecSmrgint 186305b261ecSmrgProcPolyFillArc(ClientPtr client) 186405b261ecSmrg{ 186505b261ecSmrg int narcs; 186605b261ecSmrg GC *pGC; 186705b261ecSmrg DrawablePtr pDraw; 186805b261ecSmrg REQUEST(xPolyFillArcReq); 186905b261ecSmrg 187005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 18714642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 187205b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 187305b261ecSmrg if (narcs % sizeof(xArc)) 18746747b715Smrg return BadLength; 187505b261ecSmrg narcs /= sizeof(xArc); 187605b261ecSmrg if (narcs) 187705b261ecSmrg (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 18786747b715Smrg return Success; 187905b261ecSmrg} 188005b261ecSmrg 188105b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 188205b261ecSmrg 188305b261ecSmrgint 188405b261ecSmrgServerOrder (void) 188505b261ecSmrg{ 188605b261ecSmrg int whichbyte = 1; 188705b261ecSmrg 188805b261ecSmrg if (*((char *) &whichbyte)) 188905b261ecSmrg return LSBFirst; 189005b261ecSmrg return MSBFirst; 189105b261ecSmrg} 189205b261ecSmrg 189305b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 189405b261ecSmrg 189505b261ecSmrgvoid 189605b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order) 189705b261ecSmrg{ 189805b261ecSmrg switch (bpp) { 189905b261ecSmrg case 1: /* yuck */ 190005b261ecSmrg if (BITMAP_BIT_ORDER != order) 190105b261ecSmrg BitOrderInvert ((unsigned char *) base, nbytes); 190205b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 190305b261ecSmrg ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order); 190405b261ecSmrg#endif 190505b261ecSmrg break; 190605b261ecSmrg case 4: 190705b261ecSmrg break; /* yuck */ 190805b261ecSmrg case 8: 190905b261ecSmrg break; 191005b261ecSmrg case 16: 191105b261ecSmrg if (IMAGE_BYTE_ORDER != order) 191205b261ecSmrg TwoByteSwap ((unsigned char *) base, nbytes); 191305b261ecSmrg break; 191405b261ecSmrg case 32: 191505b261ecSmrg if (IMAGE_BYTE_ORDER != order) 191605b261ecSmrg FourByteSwap ((unsigned char *) base, nbytes); 191705b261ecSmrg break; 191805b261ecSmrg } 191905b261ecSmrg} 192005b261ecSmrg#else 192105b261ecSmrg#define ReformatImage(b,n,bpp,o) 192205b261ecSmrg#endif 192305b261ecSmrg 192405b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to 192505b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 192605b261ecSmrg * to use internally. Removes need for internal alignment checking. 192705b261ecSmrg * All of the PutImage functions could be changed individually, but 192805b261ecSmrg * as currently written, they call other routines which require things 192905b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here. 193005b261ecSmrg * If an image would be padded differently for 64- versus 32-, then 193105b261ecSmrg * copy each scanline to a 64-bit padded scanline. 193205b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit 193305b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction. 193405b261ecSmrg */ 193505b261ecSmrgint 193605b261ecSmrgProcPutImage(ClientPtr client) 193705b261ecSmrg{ 193805b261ecSmrg GC *pGC; 193905b261ecSmrg DrawablePtr pDraw; 194005b261ecSmrg long length; /* length of scanline server padded */ 194105b261ecSmrg long lengthProto; /* length of scanline protocol padded */ 194205b261ecSmrg char *tmpImage; 194305b261ecSmrg REQUEST(xPutImageReq); 194405b261ecSmrg 194505b261ecSmrg REQUEST_AT_LEAST_SIZE(xPutImageReq); 19464642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 194705b261ecSmrg if (stuff->format == XYBitmap) 194805b261ecSmrg { 194905b261ecSmrg if ((stuff->depth != 1) || 195005b261ecSmrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 195105b261ecSmrg return BadMatch; 195205b261ecSmrg length = BitmapBytePad(stuff->width + stuff->leftPad); 195305b261ecSmrg } 195405b261ecSmrg else if (stuff->format == XYPixmap) 195505b261ecSmrg { 195605b261ecSmrg if ((pDraw->depth != stuff->depth) || 195705b261ecSmrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 195805b261ecSmrg return BadMatch; 195905b261ecSmrg length = BitmapBytePad(stuff->width + stuff->leftPad); 196005b261ecSmrg length *= stuff->depth; 196105b261ecSmrg } 196205b261ecSmrg else if (stuff->format == ZPixmap) 196305b261ecSmrg { 196405b261ecSmrg if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 196505b261ecSmrg return BadMatch; 196605b261ecSmrg length = PixmapBytePad(stuff->width, stuff->depth); 196705b261ecSmrg } 196805b261ecSmrg else 196905b261ecSmrg { 197005b261ecSmrg client->errorValue = stuff->format; 197105b261ecSmrg return BadValue; 197205b261ecSmrg } 197305b261ecSmrg 197405b261ecSmrg tmpImage = (char *)&stuff[1]; 197505b261ecSmrg lengthProto = length; 19760b0d8713Smrg 19770b0d8713Smrg if (lengthProto >= (INT32_MAX / stuff->height)) 19780b0d8713Smrg return BadLength; 197905b261ecSmrg 19806747b715Smrg if ((bytes_to_int32(lengthProto * stuff->height) + 19816747b715Smrg bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) 198205b261ecSmrg return BadLength; 198305b261ecSmrg 198405b261ecSmrg ReformatImage (tmpImage, lengthProto * stuff->height, 198505b261ecSmrg stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1, 198605b261ecSmrg ClientOrder(client)); 198705b261ecSmrg 198805b261ecSmrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 198905b261ecSmrg stuff->width, stuff->height, 199005b261ecSmrg stuff->leftPad, stuff->format, tmpImage); 199105b261ecSmrg 19926747b715Smrg return Success; 199305b261ecSmrg} 199405b261ecSmrg 199505b261ecSmrgstatic int 199605b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable, 199705b261ecSmrg int x, int y, int width, int height, 199805b261ecSmrg Mask planemask, xGetImageReply **im_return) 199905b261ecSmrg{ 20006747b715Smrg DrawablePtr pDraw, pBoundingDraw; 200105b261ecSmrg int nlines, linesPerBuf, rc; 20026747b715Smrg int linesDone; 20036747b715Smrg /* coordinates relative to the bounding drawable */ 20046747b715Smrg int relx, rely; 200505b261ecSmrg long widthBytesLine, length; 200605b261ecSmrg Mask plane = 0; 200705b261ecSmrg char *pBuf; 200805b261ecSmrg xGetImageReply xgi; 200905b261ecSmrg RegionPtr pVisibleRegion = NULL; 201005b261ecSmrg 201105b261ecSmrg if ((format != XYPixmap) && (format != ZPixmap)) 201205b261ecSmrg { 201305b261ecSmrg client->errorValue = format; 20146747b715Smrg return BadValue; 201505b261ecSmrg } 201605b261ecSmrg rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 201705b261ecSmrg if (rc != Success) 201805b261ecSmrg return rc; 201905b261ecSmrg 20206747b715Smrg memset(&xgi, 0, sizeof(xGetImageReply)); 20216747b715Smrg 20226747b715Smrg relx = x; 20236747b715Smrg rely = y; 20246747b715Smrg 202505b261ecSmrg if(pDraw->type == DRAWABLE_WINDOW) 202605b261ecSmrg { 20276747b715Smrg WindowPtr pWin = (WindowPtr)pDraw; 20286747b715Smrg 20296747b715Smrg /* "If the drawable is a window, the window must be viewable ... or a 20306747b715Smrg * BadMatch error results" */ 20316747b715Smrg if (!pWin->viewable) 20326747b715Smrg return BadMatch; 20336747b715Smrg 20346747b715Smrg relx += pDraw->x; 20356747b715Smrg rely += pDraw->y; 20366747b715Smrg 20376747b715Smrg if (pDraw->pScreen->GetWindowPixmap) { 20386747b715Smrg PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); 20396747b715Smrg 20406747b715Smrg pBoundingDraw = &pPix->drawable; 20416747b715Smrg#ifdef COMPOSITE 20426747b715Smrg relx -= pPix->screen_x; 20436747b715Smrg rely -= pPix->screen_y; 20446747b715Smrg#endif 20456747b715Smrg } 20466747b715Smrg else 20476747b715Smrg { 20486747b715Smrg pBoundingDraw = (DrawablePtr)pDraw->pScreen->root; 20496747b715Smrg } 20506747b715Smrg 20516747b715Smrg xgi.visual = wVisual (pWin); 205205b261ecSmrg } 205305b261ecSmrg else 205405b261ecSmrg { 20556747b715Smrg pBoundingDraw = pDraw; 205605b261ecSmrg xgi.visual = None; 205705b261ecSmrg } 205805b261ecSmrg 20596747b715Smrg /* "If the drawable is a pixmap, the given rectangle must be wholly 20606747b715Smrg * contained within the pixmap, or a BadMatch error results. If the 20616747b715Smrg * drawable is a window [...] it must be the case that if there were no 20626747b715Smrg * inferiors or overlapping windows, the specified rectangle of the window 20636747b715Smrg * would be fully visible on the screen and wholly contained within the 20646747b715Smrg * outside edges of the window, or a BadMatch error results." 20656747b715Smrg * 20666747b715Smrg * We relax the window case slightly to mean that the rectangle must exist 20676747b715Smrg * within the bounds of the window's backing pixmap. In particular, this 20686747b715Smrg * means that a GetImage request may succeed or fail with BadMatch depending 20696747b715Smrg * on whether any of its ancestor windows are redirected. */ 20706747b715Smrg if(relx < 0 || relx + width > (int)pBoundingDraw->width || 20716747b715Smrg rely < 0 || rely + height > (int)pBoundingDraw->height) 20726747b715Smrg return BadMatch; 20736747b715Smrg 207405b261ecSmrg xgi.type = X_Reply; 207505b261ecSmrg xgi.sequenceNumber = client->sequence; 207605b261ecSmrg xgi.depth = pDraw->depth; 207705b261ecSmrg if(format == ZPixmap) 207805b261ecSmrg { 207905b261ecSmrg widthBytesLine = PixmapBytePad(width, pDraw->depth); 208005b261ecSmrg length = widthBytesLine * height; 208105b261ecSmrg 208205b261ecSmrg } 208305b261ecSmrg else 208405b261ecSmrg { 208505b261ecSmrg widthBytesLine = BitmapBytePad(width); 208605b261ecSmrg plane = ((Mask)1) << (pDraw->depth - 1); 208705b261ecSmrg /* only planes asked for */ 208805b261ecSmrg length = widthBytesLine * height * 208905b261ecSmrg Ones(planemask & (plane | (plane - 1))); 209005b261ecSmrg 209105b261ecSmrg } 209205b261ecSmrg 209305b261ecSmrg xgi.length = length; 209405b261ecSmrg 209505b261ecSmrg if (im_return) { 20966747b715Smrg pBuf = calloc(1, sz_xGetImageReply + length); 209705b261ecSmrg if (!pBuf) 20986747b715Smrg return BadAlloc; 209905b261ecSmrg if (widthBytesLine == 0) 210005b261ecSmrg linesPerBuf = 0; 210105b261ecSmrg else 210205b261ecSmrg linesPerBuf = height; 210305b261ecSmrg *im_return = (xGetImageReply *)pBuf; 210405b261ecSmrg *(xGetImageReply *)pBuf = xgi; 210505b261ecSmrg pBuf += sz_xGetImageReply; 210605b261ecSmrg } else { 21076747b715Smrg xgi.length = bytes_to_int32(xgi.length); 210805b261ecSmrg if (widthBytesLine == 0 || height == 0) 210905b261ecSmrg linesPerBuf = 0; 211005b261ecSmrg else if (widthBytesLine >= IMAGE_BUFSIZE) 211105b261ecSmrg linesPerBuf = 1; 211205b261ecSmrg else 211305b261ecSmrg { 211405b261ecSmrg linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 211505b261ecSmrg if (linesPerBuf > height) 211605b261ecSmrg linesPerBuf = height; 211705b261ecSmrg } 211805b261ecSmrg length = linesPerBuf * widthBytesLine; 211905b261ecSmrg if (linesPerBuf < height) 212005b261ecSmrg { 212105b261ecSmrg /* we have to make sure intermediate buffers don't need padding */ 212205b261ecSmrg while ((linesPerBuf > 1) && 212305b261ecSmrg (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))) 212405b261ecSmrg { 212505b261ecSmrg linesPerBuf--; 212605b261ecSmrg length -= widthBytesLine; 212705b261ecSmrg } 212805b261ecSmrg while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)) 212905b261ecSmrg { 213005b261ecSmrg linesPerBuf++; 213105b261ecSmrg length += widthBytesLine; 213205b261ecSmrg } 213305b261ecSmrg } 21346747b715Smrg if(!(pBuf = calloc(1, length))) 21356747b715Smrg return BadAlloc; 213605b261ecSmrg WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); 213705b261ecSmrg } 213805b261ecSmrg 21394642e01fSmrg if (pDraw->type == DRAWABLE_WINDOW) 214005b261ecSmrg { 214105b261ecSmrg pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); 214205b261ecSmrg if (pVisibleRegion) 214305b261ecSmrg { 21446747b715Smrg RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y); 214505b261ecSmrg } 214605b261ecSmrg } 214705b261ecSmrg 214805b261ecSmrg if (linesPerBuf == 0) 214905b261ecSmrg { 215005b261ecSmrg /* nothing to do */ 215105b261ecSmrg } 215205b261ecSmrg else if (format == ZPixmap) 215305b261ecSmrg { 215405b261ecSmrg linesDone = 0; 215505b261ecSmrg while (height - linesDone > 0) 215605b261ecSmrg { 215705b261ecSmrg nlines = min(linesPerBuf, height - linesDone); 215805b261ecSmrg (*pDraw->pScreen->GetImage) (pDraw, 215905b261ecSmrg x, 216005b261ecSmrg y + linesDone, 216105b261ecSmrg width, 216205b261ecSmrg nlines, 216305b261ecSmrg format, 216405b261ecSmrg planemask, 216505b261ecSmrg (pointer) pBuf); 216605b261ecSmrg if (pVisibleRegion) 216705b261ecSmrg XaceCensorImage(client, pVisibleRegion, widthBytesLine, 216805b261ecSmrg pDraw, x, y + linesDone, width, 216905b261ecSmrg nlines, format, pBuf); 217005b261ecSmrg 217105b261ecSmrg /* Note that this is NOT a call to WriteSwappedDataToClient, 217205b261ecSmrg as we do NOT byte swap */ 217305b261ecSmrg if (!im_return) 217405b261ecSmrg { 217505b261ecSmrg ReformatImage (pBuf, (int)(nlines * widthBytesLine), 217605b261ecSmrg BitsPerPixel (pDraw->depth), 217705b261ecSmrg ClientOrder(client)); 217805b261ecSmrg 217905b261ecSmrg/* Don't split me, gcc pukes when you do */ 218005b261ecSmrg (void)WriteToClient(client, 218105b261ecSmrg (int)(nlines * widthBytesLine), 218205b261ecSmrg pBuf); 218305b261ecSmrg } 218405b261ecSmrg linesDone += nlines; 218505b261ecSmrg } 218605b261ecSmrg } 218705b261ecSmrg else /* XYPixmap */ 218805b261ecSmrg { 218905b261ecSmrg for (; plane; plane >>= 1) 219005b261ecSmrg { 219105b261ecSmrg if (planemask & plane) 219205b261ecSmrg { 219305b261ecSmrg linesDone = 0; 219405b261ecSmrg while (height - linesDone > 0) 219505b261ecSmrg { 219605b261ecSmrg nlines = min(linesPerBuf, height - linesDone); 219705b261ecSmrg (*pDraw->pScreen->GetImage) (pDraw, 219805b261ecSmrg x, 219905b261ecSmrg y + linesDone, 220005b261ecSmrg width, 220105b261ecSmrg nlines, 220205b261ecSmrg format, 220305b261ecSmrg plane, 220405b261ecSmrg (pointer)pBuf); 220505b261ecSmrg if (pVisibleRegion) 220605b261ecSmrg XaceCensorImage(client, pVisibleRegion, 220705b261ecSmrg widthBytesLine, 220805b261ecSmrg pDraw, x, y + linesDone, width, 220905b261ecSmrg nlines, format, pBuf); 221005b261ecSmrg 221105b261ecSmrg /* Note: NOT a call to WriteSwappedDataToClient, 221205b261ecSmrg as we do NOT byte swap */ 221305b261ecSmrg if (im_return) { 221405b261ecSmrg pBuf += nlines * widthBytesLine; 221505b261ecSmrg } else { 221605b261ecSmrg ReformatImage (pBuf, 221705b261ecSmrg (int)(nlines * widthBytesLine), 221805b261ecSmrg 1, 221905b261ecSmrg ClientOrder (client)); 222005b261ecSmrg 222105b261ecSmrg/* Don't split me, gcc pukes when you do */ 222205b261ecSmrg (void)WriteToClient(client, 222305b261ecSmrg (int)(nlines * widthBytesLine), 222405b261ecSmrg pBuf); 222505b261ecSmrg } 222605b261ecSmrg linesDone += nlines; 222705b261ecSmrg } 222805b261ecSmrg } 222905b261ecSmrg } 223005b261ecSmrg } 223105b261ecSmrg if (pVisibleRegion) 22326747b715Smrg RegionDestroy(pVisibleRegion); 223305b261ecSmrg if (!im_return) 22346747b715Smrg free(pBuf); 22356747b715Smrg return Success; 223605b261ecSmrg} 223705b261ecSmrg 223805b261ecSmrgint 223905b261ecSmrgProcGetImage(ClientPtr client) 224005b261ecSmrg{ 224105b261ecSmrg REQUEST(xGetImageReq); 224205b261ecSmrg 224305b261ecSmrg REQUEST_SIZE_MATCH(xGetImageReq); 224405b261ecSmrg 224505b261ecSmrg return DoGetImage(client, stuff->format, stuff->drawable, 224605b261ecSmrg stuff->x, stuff->y, 224705b261ecSmrg (int)stuff->width, (int)stuff->height, 224805b261ecSmrg stuff->planeMask, (xGetImageReply **)NULL); 224905b261ecSmrg} 225005b261ecSmrg 225105b261ecSmrgint 225205b261ecSmrgProcPolyText(ClientPtr client) 225305b261ecSmrg{ 225405b261ecSmrg int err; 225505b261ecSmrg REQUEST(xPolyTextReq); 225605b261ecSmrg DrawablePtr pDraw; 225705b261ecSmrg GC *pGC; 225805b261ecSmrg 225905b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyTextReq); 22604642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 226105b261ecSmrg 226205b261ecSmrg err = PolyText(client, 226305b261ecSmrg pDraw, 226405b261ecSmrg pGC, 226505b261ecSmrg (unsigned char *)&stuff[1], 226605b261ecSmrg ((unsigned char *) stuff) + (client->req_len << 2), 226705b261ecSmrg stuff->x, 226805b261ecSmrg stuff->y, 226905b261ecSmrg stuff->reqType, 227005b261ecSmrg stuff->drawable); 227105b261ecSmrg 227205b261ecSmrg if (err == Success) 227305b261ecSmrg { 22746747b715Smrg return Success; 227505b261ecSmrg } 227605b261ecSmrg else 227705b261ecSmrg return err; 227805b261ecSmrg} 227905b261ecSmrg 228005b261ecSmrgint 228105b261ecSmrgProcImageText8(ClientPtr client) 228205b261ecSmrg{ 228305b261ecSmrg int err; 228405b261ecSmrg DrawablePtr pDraw; 228505b261ecSmrg GC *pGC; 228605b261ecSmrg 228705b261ecSmrg REQUEST(xImageTextReq); 228805b261ecSmrg 228905b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 22904642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 229105b261ecSmrg 229205b261ecSmrg err = ImageText(client, 229305b261ecSmrg pDraw, 229405b261ecSmrg pGC, 229505b261ecSmrg stuff->nChars, 229605b261ecSmrg (unsigned char *)&stuff[1], 229705b261ecSmrg stuff->x, 229805b261ecSmrg stuff->y, 229905b261ecSmrg stuff->reqType, 230005b261ecSmrg stuff->drawable); 230105b261ecSmrg 230205b261ecSmrg if (err == Success) 230305b261ecSmrg { 23046747b715Smrg return Success; 230505b261ecSmrg } 230605b261ecSmrg else 230705b261ecSmrg return err; 230805b261ecSmrg} 230905b261ecSmrg 231005b261ecSmrgint 231105b261ecSmrgProcImageText16(ClientPtr client) 231205b261ecSmrg{ 231305b261ecSmrg int err; 231405b261ecSmrg DrawablePtr pDraw; 231505b261ecSmrg GC *pGC; 231605b261ecSmrg 231705b261ecSmrg REQUEST(xImageTextReq); 231805b261ecSmrg 231905b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 23204642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 232105b261ecSmrg 232205b261ecSmrg err = ImageText(client, 232305b261ecSmrg pDraw, 232405b261ecSmrg pGC, 232505b261ecSmrg stuff->nChars, 232605b261ecSmrg (unsigned char *)&stuff[1], 232705b261ecSmrg stuff->x, 232805b261ecSmrg stuff->y, 232905b261ecSmrg stuff->reqType, 233005b261ecSmrg stuff->drawable); 233105b261ecSmrg 233205b261ecSmrg if (err == Success) 233305b261ecSmrg { 23346747b715Smrg return Success; 233505b261ecSmrg } 233605b261ecSmrg else 233705b261ecSmrg return err; 233805b261ecSmrg} 233905b261ecSmrg 234005b261ecSmrg 234105b261ecSmrgint 234205b261ecSmrgProcCreateColormap(ClientPtr client) 234305b261ecSmrg{ 234405b261ecSmrg VisualPtr pVisual; 234505b261ecSmrg ColormapPtr pmap; 234605b261ecSmrg Colormap mid; 234705b261ecSmrg WindowPtr pWin; 234805b261ecSmrg ScreenPtr pScreen; 234905b261ecSmrg REQUEST(xCreateColormapReq); 235005b261ecSmrg int i, result; 235105b261ecSmrg 235205b261ecSmrg REQUEST_SIZE_MATCH(xCreateColormapReq); 235305b261ecSmrg 235405b261ecSmrg if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) 235505b261ecSmrg { 235605b261ecSmrg client->errorValue = stuff->alloc; 23576747b715Smrg return BadValue; 235805b261ecSmrg } 235905b261ecSmrg mid = stuff->mid; 236005b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 23614642e01fSmrg result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 236205b261ecSmrg if (result != Success) 236305b261ecSmrg return result; 236405b261ecSmrg 236505b261ecSmrg pScreen = pWin->drawable.pScreen; 236605b261ecSmrg for (i = 0, pVisual = pScreen->visuals; 236705b261ecSmrg i < pScreen->numVisuals; 236805b261ecSmrg i++, pVisual++) 236905b261ecSmrg { 237005b261ecSmrg if (pVisual->vid != stuff->visual) 237105b261ecSmrg continue; 23726747b715Smrg return CreateColormap(mid, pScreen, pVisual, &pmap, 237305b261ecSmrg (int)stuff->alloc, client->index); 237405b261ecSmrg } 237505b261ecSmrg client->errorValue = stuff->visual; 23766747b715Smrg return BadMatch; 237705b261ecSmrg} 237805b261ecSmrg 237905b261ecSmrgint 238005b261ecSmrgProcFreeColormap(ClientPtr client) 238105b261ecSmrg{ 238205b261ecSmrg ColormapPtr pmap; 23834642e01fSmrg int rc; 238405b261ecSmrg REQUEST(xResourceReq); 238505b261ecSmrg 238605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 2387b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client, 23884642e01fSmrg DixDestroyAccess); 23894642e01fSmrg if (rc == Success) 239005b261ecSmrg { 239105b261ecSmrg /* Freeing a default colormap is a no-op */ 239205b261ecSmrg if (!(pmap->flags & IsDefault)) 239305b261ecSmrg FreeResource(stuff->id, RT_NONE); 23946747b715Smrg return Success; 239505b261ecSmrg } 239605b261ecSmrg else 239705b261ecSmrg { 239805b261ecSmrg client->errorValue = stuff->id; 23996747b715Smrg return rc; 240005b261ecSmrg } 240105b261ecSmrg} 240205b261ecSmrg 240305b261ecSmrg 240405b261ecSmrgint 240505b261ecSmrgProcCopyColormapAndFree(ClientPtr client) 240605b261ecSmrg{ 240705b261ecSmrg Colormap mid; 240805b261ecSmrg ColormapPtr pSrcMap; 240905b261ecSmrg REQUEST(xCopyColormapAndFreeReq); 24104642e01fSmrg int rc; 241105b261ecSmrg 241205b261ecSmrg REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 241305b261ecSmrg mid = stuff->mid; 241405b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 2415b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP, 24164642e01fSmrg client, DixReadAccess|DixRemoveAccess); 24174642e01fSmrg if (rc == Success) 24186747b715Smrg return CopyColormapAndFree(mid, pSrcMap, client->index); 24196747b715Smrg client->errorValue = stuff->srcCmap; 24206747b715Smrg return rc; 242105b261ecSmrg} 242205b261ecSmrg 242305b261ecSmrgint 242405b261ecSmrgProcInstallColormap(ClientPtr client) 242505b261ecSmrg{ 242605b261ecSmrg ColormapPtr pcmp; 24274642e01fSmrg int rc; 242805b261ecSmrg REQUEST(xResourceReq); 242905b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24304642e01fSmrg 2431b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 24324642e01fSmrg DixInstallAccess); 24334642e01fSmrg if (rc != Success) 24344642e01fSmrg goto out; 24354642e01fSmrg 24364642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 24376747b715Smrg if (rc != Success) { 24386747b715Smrg if (rc == BadValue) 24396747b715Smrg rc = BadColor; 24404642e01fSmrg goto out; 24416747b715Smrg } 24424642e01fSmrg 24434642e01fSmrg (*(pcmp->pScreen->InstallColormap)) (pcmp); 24446747b715Smrg return Success; 24454642e01fSmrg 24464642e01fSmrgout: 24474642e01fSmrg client->errorValue = stuff->id; 24486747b715Smrg return rc; 244905b261ecSmrg} 245005b261ecSmrg 245105b261ecSmrgint 245205b261ecSmrgProcUninstallColormap(ClientPtr client) 245305b261ecSmrg{ 245405b261ecSmrg ColormapPtr pcmp; 24554642e01fSmrg int rc; 245605b261ecSmrg REQUEST(xResourceReq); 245705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24584642e01fSmrg 2459b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 24604642e01fSmrg DixUninstallAccess); 24614642e01fSmrg if (rc != Success) 24624642e01fSmrg goto out; 24634642e01fSmrg 24644642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 24656747b715Smrg if (rc != Success) { 24666747b715Smrg if (rc == BadValue) 24676747b715Smrg rc = BadColor; 24684642e01fSmrg goto out; 24696747b715Smrg } 24704642e01fSmrg 24714642e01fSmrg if(pcmp->mid != pcmp->pScreen->defColormap) 24724642e01fSmrg (*(pcmp->pScreen->UninstallColormap)) (pcmp); 24736747b715Smrg return Success; 24744642e01fSmrg 24754642e01fSmrgout: 24764642e01fSmrg client->errorValue = stuff->id; 24776747b715Smrg return rc; 247805b261ecSmrg} 247905b261ecSmrg 248005b261ecSmrgint 248105b261ecSmrgProcListInstalledColormaps(ClientPtr client) 248205b261ecSmrg{ 248305b261ecSmrg xListInstalledColormapsReply *preply; 248405b261ecSmrg int nummaps, rc; 248505b261ecSmrg WindowPtr pWin; 248605b261ecSmrg REQUEST(xResourceReq); 248705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24884642e01fSmrg 24894642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 249005b261ecSmrg if (rc != Success) 24916747b715Smrg return rc; 24924642e01fSmrg 24934642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 24944642e01fSmrg DixGetAttrAccess); 24954642e01fSmrg if (rc != Success) 24966747b715Smrg return rc; 249705b261ecSmrg 24986747b715Smrg preply = malloc(sizeof(xListInstalledColormapsReply) + 249905b261ecSmrg pWin->drawable.pScreen->maxInstalledCmaps * 250005b261ecSmrg sizeof(Colormap)); 250105b261ecSmrg if(!preply) 25026747b715Smrg return BadAlloc; 250305b261ecSmrg 250405b261ecSmrg preply->type = X_Reply; 250505b261ecSmrg preply->sequenceNumber = client->sequence; 250605b261ecSmrg nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 250705b261ecSmrg (pWin->drawable.pScreen, (Colormap *)&preply[1]); 250805b261ecSmrg preply->nColormaps = nummaps; 250905b261ecSmrg preply->length = nummaps; 251005b261ecSmrg WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply); 251105b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 251205b261ecSmrg WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 25136747b715Smrg free(preply); 25146747b715Smrg return Success; 251505b261ecSmrg} 251605b261ecSmrg 251705b261ecSmrgint 251805b261ecSmrgProcAllocColor (ClientPtr client) 251905b261ecSmrg{ 252005b261ecSmrg ColormapPtr pmap; 25214642e01fSmrg int rc; 252205b261ecSmrg xAllocColorReply acr; 252305b261ecSmrg REQUEST(xAllocColorReq); 252405b261ecSmrg 252505b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorReq); 2526b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client, 25274642e01fSmrg DixAddAccess); 25284642e01fSmrg if (rc == Success) 252905b261ecSmrg { 253005b261ecSmrg acr.type = X_Reply; 253105b261ecSmrg acr.length = 0; 253205b261ecSmrg acr.sequenceNumber = client->sequence; 253305b261ecSmrg acr.red = stuff->red; 253405b261ecSmrg acr.green = stuff->green; 253505b261ecSmrg acr.blue = stuff->blue; 253605b261ecSmrg acr.pixel = 0; 25374642e01fSmrg if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 253805b261ecSmrg &acr.pixel, client->index)) ) 25396747b715Smrg return rc; 254005b261ecSmrg#ifdef PANORAMIX 254105b261ecSmrg if (noPanoramiXExtension || !pmap->pScreen->myNum) 254205b261ecSmrg#endif 254305b261ecSmrg WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 25446747b715Smrg return Success; 254505b261ecSmrg 254605b261ecSmrg } 254705b261ecSmrg else 254805b261ecSmrg { 254905b261ecSmrg client->errorValue = stuff->cmap; 25506747b715Smrg return rc; 255105b261ecSmrg } 255205b261ecSmrg} 255305b261ecSmrg 255405b261ecSmrgint 255505b261ecSmrgProcAllocNamedColor (ClientPtr client) 255605b261ecSmrg{ 255705b261ecSmrg ColormapPtr pcmp; 25584642e01fSmrg int rc; 255905b261ecSmrg REQUEST(xAllocNamedColorReq); 256005b261ecSmrg 256105b261ecSmrg REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 2562b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 25634642e01fSmrg DixAddAccess); 25644642e01fSmrg if (rc == Success) 256505b261ecSmrg { 256605b261ecSmrg xAllocNamedColorReply ancr; 256705b261ecSmrg 256805b261ecSmrg ancr.type = X_Reply; 256905b261ecSmrg ancr.length = 0; 257005b261ecSmrg ancr.sequenceNumber = client->sequence; 257105b261ecSmrg 257205b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 257305b261ecSmrg &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) 257405b261ecSmrg { 257505b261ecSmrg ancr.screenRed = ancr.exactRed; 257605b261ecSmrg ancr.screenGreen = ancr.exactGreen; 257705b261ecSmrg ancr.screenBlue = ancr.exactBlue; 257805b261ecSmrg ancr.pixel = 0; 25794642e01fSmrg if( (rc = AllocColor(pcmp, 258005b261ecSmrg &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, 258105b261ecSmrg &ancr.pixel, client->index)) ) 25826747b715Smrg return rc; 258305b261ecSmrg#ifdef PANORAMIX 258405b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 258505b261ecSmrg#endif 258605b261ecSmrg WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr); 25876747b715Smrg return Success; 258805b261ecSmrg } 258905b261ecSmrg else 25906747b715Smrg return BadName; 259105b261ecSmrg 259205b261ecSmrg } 259305b261ecSmrg else 259405b261ecSmrg { 259505b261ecSmrg client->errorValue = stuff->cmap; 25966747b715Smrg return rc; 259705b261ecSmrg } 259805b261ecSmrg} 259905b261ecSmrg 260005b261ecSmrgint 260105b261ecSmrgProcAllocColorCells (ClientPtr client) 260205b261ecSmrg{ 260305b261ecSmrg ColormapPtr pcmp; 26044642e01fSmrg int rc; 260505b261ecSmrg REQUEST(xAllocColorCellsReq); 260605b261ecSmrg 260705b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorCellsReq); 2608b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 26094642e01fSmrg DixAddAccess); 26104642e01fSmrg if (rc == Success) 261105b261ecSmrg { 261205b261ecSmrg xAllocColorCellsReply accr; 26134642e01fSmrg int npixels, nmasks; 261405b261ecSmrg long length; 261505b261ecSmrg Pixel *ppixels, *pmasks; 261605b261ecSmrg 261705b261ecSmrg npixels = stuff->colors; 261805b261ecSmrg if (!npixels) 261905b261ecSmrg { 262005b261ecSmrg client->errorValue = npixels; 26216747b715Smrg return BadValue; 262205b261ecSmrg } 262305b261ecSmrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 262405b261ecSmrg { 262505b261ecSmrg client->errorValue = stuff->contiguous; 26266747b715Smrg return BadValue; 262705b261ecSmrg } 262805b261ecSmrg nmasks = stuff->planes; 262905b261ecSmrg length = ((long)npixels + (long)nmasks) * sizeof(Pixel); 26306747b715Smrg ppixels = malloc(length); 263105b261ecSmrg if(!ppixels) 26326747b715Smrg return BadAlloc; 263305b261ecSmrg pmasks = ppixels + npixels; 263405b261ecSmrg 26354642e01fSmrg if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 263605b261ecSmrg (Bool)stuff->contiguous, ppixels, pmasks)) ) 263705b261ecSmrg { 26386747b715Smrg free(ppixels); 26396747b715Smrg return rc; 264005b261ecSmrg } 264105b261ecSmrg#ifdef PANORAMIX 264205b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 264305b261ecSmrg#endif 264405b261ecSmrg { 264505b261ecSmrg accr.type = X_Reply; 26466747b715Smrg accr.length = bytes_to_int32(length); 264705b261ecSmrg accr.sequenceNumber = client->sequence; 264805b261ecSmrg accr.nPixels = npixels; 264905b261ecSmrg accr.nMasks = nmasks; 265005b261ecSmrg WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr); 265105b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 265205b261ecSmrg WriteSwappedDataToClient(client, length, ppixels); 265305b261ecSmrg } 26546747b715Smrg free(ppixels); 26556747b715Smrg return Success; 265605b261ecSmrg } 265705b261ecSmrg else 265805b261ecSmrg { 265905b261ecSmrg client->errorValue = stuff->cmap; 26606747b715Smrg return rc; 266105b261ecSmrg } 266205b261ecSmrg} 266305b261ecSmrg 266405b261ecSmrgint 266505b261ecSmrgProcAllocColorPlanes(ClientPtr client) 266605b261ecSmrg{ 266705b261ecSmrg ColormapPtr pcmp; 26684642e01fSmrg int rc; 266905b261ecSmrg REQUEST(xAllocColorPlanesReq); 267005b261ecSmrg 267105b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 2672b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 26734642e01fSmrg DixAddAccess); 26744642e01fSmrg if (rc == Success) 267505b261ecSmrg { 267605b261ecSmrg xAllocColorPlanesReply acpr; 26774642e01fSmrg int npixels; 267805b261ecSmrg long length; 267905b261ecSmrg Pixel *ppixels; 268005b261ecSmrg 268105b261ecSmrg npixels = stuff->colors; 268205b261ecSmrg if (!npixels) 268305b261ecSmrg { 268405b261ecSmrg client->errorValue = npixels; 26856747b715Smrg return BadValue; 268605b261ecSmrg } 268705b261ecSmrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 268805b261ecSmrg { 268905b261ecSmrg client->errorValue = stuff->contiguous; 26906747b715Smrg return BadValue; 269105b261ecSmrg } 269205b261ecSmrg acpr.type = X_Reply; 269305b261ecSmrg acpr.sequenceNumber = client->sequence; 269405b261ecSmrg acpr.nPixels = npixels; 269505b261ecSmrg length = (long)npixels * sizeof(Pixel); 26966747b715Smrg ppixels = malloc(length); 269705b261ecSmrg if(!ppixels) 26986747b715Smrg return BadAlloc; 26994642e01fSmrg if( (rc = AllocColorPlanes(client->index, pcmp, npixels, 270005b261ecSmrg (int)stuff->red, (int)stuff->green, (int)stuff->blue, 270105b261ecSmrg (Bool)stuff->contiguous, ppixels, 270205b261ecSmrg &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) ) 270305b261ecSmrg { 27046747b715Smrg free(ppixels); 27056747b715Smrg return rc; 270605b261ecSmrg } 27076747b715Smrg acpr.length = bytes_to_int32(length); 270805b261ecSmrg#ifdef PANORAMIX 270905b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 271005b261ecSmrg#endif 271105b261ecSmrg { 271205b261ecSmrg WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 271305b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 271405b261ecSmrg WriteSwappedDataToClient(client, length, ppixels); 271505b261ecSmrg } 27166747b715Smrg free(ppixels); 27176747b715Smrg return Success; 271805b261ecSmrg } 271905b261ecSmrg else 272005b261ecSmrg { 272105b261ecSmrg client->errorValue = stuff->cmap; 27226747b715Smrg return rc; 272305b261ecSmrg } 272405b261ecSmrg} 272505b261ecSmrg 272605b261ecSmrgint 272705b261ecSmrgProcFreeColors(ClientPtr client) 272805b261ecSmrg{ 272905b261ecSmrg ColormapPtr pcmp; 27304642e01fSmrg int rc; 273105b261ecSmrg REQUEST(xFreeColorsReq); 273205b261ecSmrg 273305b261ecSmrg REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 2734b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 27354642e01fSmrg DixRemoveAccess); 27364642e01fSmrg if (rc == Success) 273705b261ecSmrg { 273805b261ecSmrg int count; 273905b261ecSmrg 274005b261ecSmrg if(pcmp->flags & AllAllocated) 27416747b715Smrg return BadAccess; 27426747b715Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); 27436747b715Smrg return FreeColors(pcmp, client->index, count, 274405b261ecSmrg (Pixel *)&stuff[1], (Pixel)stuff->planeMask); 274505b261ecSmrg } 274605b261ecSmrg else 274705b261ecSmrg { 274805b261ecSmrg client->errorValue = stuff->cmap; 27496747b715Smrg return rc; 275005b261ecSmrg } 275105b261ecSmrg} 275205b261ecSmrg 275305b261ecSmrgint 275405b261ecSmrgProcStoreColors (ClientPtr client) 275505b261ecSmrg{ 275605b261ecSmrg ColormapPtr pcmp; 27574642e01fSmrg int rc; 275805b261ecSmrg REQUEST(xStoreColorsReq); 275905b261ecSmrg 276005b261ecSmrg REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 2761b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 27624642e01fSmrg DixWriteAccess); 27634642e01fSmrg if (rc == Success) 276405b261ecSmrg { 276505b261ecSmrg int count; 276605b261ecSmrg 276705b261ecSmrg count = (client->req_len << 2) - sizeof(xStoreColorsReq); 276805b261ecSmrg if (count % sizeof(xColorItem)) 27696747b715Smrg return BadLength; 277005b261ecSmrg count /= sizeof(xColorItem); 27716747b715Smrg return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client); 277205b261ecSmrg } 277305b261ecSmrg else 277405b261ecSmrg { 277505b261ecSmrg client->errorValue = stuff->cmap; 27766747b715Smrg return rc; 277705b261ecSmrg } 277805b261ecSmrg} 277905b261ecSmrg 278005b261ecSmrgint 278105b261ecSmrgProcStoreNamedColor (ClientPtr client) 278205b261ecSmrg{ 278305b261ecSmrg ColormapPtr pcmp; 27844642e01fSmrg int rc; 278505b261ecSmrg REQUEST(xStoreNamedColorReq); 278605b261ecSmrg 278705b261ecSmrg REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 2788b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 27894642e01fSmrg DixWriteAccess); 27904642e01fSmrg if (rc == Success) 279105b261ecSmrg { 279205b261ecSmrg xColorItem def; 279305b261ecSmrg 279405b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], 279505b261ecSmrg stuff->nbytes, &def.red, &def.green, &def.blue)) 279605b261ecSmrg { 279705b261ecSmrg def.flags = stuff->flags; 279805b261ecSmrg def.pixel = stuff->pixel; 27996747b715Smrg return StoreColors(pcmp, 1, &def, client); 280005b261ecSmrg } 28016747b715Smrg return BadName; 280205b261ecSmrg } 280305b261ecSmrg else 280405b261ecSmrg { 280505b261ecSmrg client->errorValue = stuff->cmap; 28066747b715Smrg return rc; 280705b261ecSmrg } 280805b261ecSmrg} 280905b261ecSmrg 281005b261ecSmrgint 281105b261ecSmrgProcQueryColors(ClientPtr client) 281205b261ecSmrg{ 281305b261ecSmrg ColormapPtr pcmp; 28144642e01fSmrg int rc; 281505b261ecSmrg REQUEST(xQueryColorsReq); 281605b261ecSmrg 281705b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 2818b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 28194642e01fSmrg DixReadAccess); 28204642e01fSmrg if (rc == Success) 282105b261ecSmrg { 28224642e01fSmrg int count; 282305b261ecSmrg xrgb *prgbs; 282405b261ecSmrg xQueryColorsReply qcr; 282505b261ecSmrg 28266747b715Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); 28276747b715Smrg prgbs = calloc(1, count * sizeof(xrgb)); 282805b261ecSmrg if(!prgbs && count) 28296747b715Smrg return BadAlloc; 28306747b715Smrg if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) ) 283105b261ecSmrg { 28326747b715Smrg free(prgbs); 28336747b715Smrg return rc; 283405b261ecSmrg } 28356747b715Smrg memset(&qcr, 0, sizeof(xQueryColorsReply)); 283605b261ecSmrg qcr.type = X_Reply; 28376747b715Smrg qcr.length = bytes_to_int32(count * sizeof(xrgb)); 283805b261ecSmrg qcr.sequenceNumber = client->sequence; 283905b261ecSmrg qcr.nColors = count; 284005b261ecSmrg WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 284105b261ecSmrg if (count) 284205b261ecSmrg { 284305b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 284405b261ecSmrg WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 284505b261ecSmrg } 28466747b715Smrg free(prgbs); 28476747b715Smrg return Success; 284805b261ecSmrg 284905b261ecSmrg } 285005b261ecSmrg else 285105b261ecSmrg { 285205b261ecSmrg client->errorValue = stuff->cmap; 28536747b715Smrg return rc; 285405b261ecSmrg } 285505b261ecSmrg} 285605b261ecSmrg 285705b261ecSmrgint 285805b261ecSmrgProcLookupColor(ClientPtr client) 285905b261ecSmrg{ 286005b261ecSmrg ColormapPtr pcmp; 28614642e01fSmrg int rc; 286205b261ecSmrg REQUEST(xLookupColorReq); 286305b261ecSmrg 286405b261ecSmrg REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 2865b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 28664642e01fSmrg DixReadAccess); 28674642e01fSmrg if (rc == Success) 286805b261ecSmrg { 286905b261ecSmrg xLookupColorReply lcr; 287005b261ecSmrg 287105b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 287205b261ecSmrg &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) 287305b261ecSmrg { 287405b261ecSmrg lcr.type = X_Reply; 287505b261ecSmrg lcr.length = 0; 287605b261ecSmrg lcr.sequenceNumber = client->sequence; 287705b261ecSmrg lcr.screenRed = lcr.exactRed; 287805b261ecSmrg lcr.screenGreen = lcr.exactGreen; 287905b261ecSmrg lcr.screenBlue = lcr.exactBlue; 288005b261ecSmrg (*pcmp->pScreen->ResolveColor)(&lcr.screenRed, 288105b261ecSmrg &lcr.screenGreen, 288205b261ecSmrg &lcr.screenBlue, 288305b261ecSmrg pcmp->pVisual); 288405b261ecSmrg WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 28856747b715Smrg return Success; 288605b261ecSmrg } 28876747b715Smrg return BadName; 288805b261ecSmrg } 288905b261ecSmrg else 289005b261ecSmrg { 289105b261ecSmrg client->errorValue = stuff->cmap; 28926747b715Smrg return rc; 289305b261ecSmrg } 289405b261ecSmrg} 289505b261ecSmrg 289605b261ecSmrgint 289705b261ecSmrgProcCreateCursor (ClientPtr client) 289805b261ecSmrg{ 289905b261ecSmrg CursorPtr pCursor; 290005b261ecSmrg PixmapPtr src; 290105b261ecSmrg PixmapPtr msk; 290205b261ecSmrg unsigned char * srcbits; 290305b261ecSmrg unsigned char * mskbits; 290405b261ecSmrg unsigned short width, height; 290505b261ecSmrg long n; 290605b261ecSmrg CursorMetricRec cm; 29074642e01fSmrg int rc; 290805b261ecSmrg 290905b261ecSmrg REQUEST(xCreateCursorReq); 291005b261ecSmrg 291105b261ecSmrg REQUEST_SIZE_MATCH(xCreateCursorReq); 291205b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 291305b261ecSmrg 2914b86d567bSmrg rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client, 29154642e01fSmrg DixReadAccess); 29164642e01fSmrg if (rc != Success) { 291705b261ecSmrg client->errorValue = stuff->source; 29186747b715Smrg return rc; 291905b261ecSmrg } 29204642e01fSmrg 2921b86d567bSmrg rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client, 29224642e01fSmrg DixReadAccess); 29234642e01fSmrg if (rc != Success) 292405b261ecSmrg { 292505b261ecSmrg if (stuff->mask != None) 292605b261ecSmrg { 292705b261ecSmrg client->errorValue = stuff->mask; 29286747b715Smrg return rc; 292905b261ecSmrg } 293005b261ecSmrg } 293105b261ecSmrg else if ( src->drawable.width != msk->drawable.width 293205b261ecSmrg || src->drawable.height != msk->drawable.height 293305b261ecSmrg || src->drawable.depth != 1 293405b261ecSmrg || msk->drawable.depth != 1) 29356747b715Smrg return BadMatch; 293605b261ecSmrg 293705b261ecSmrg width = src->drawable.width; 293805b261ecSmrg height = src->drawable.height; 293905b261ecSmrg 294005b261ecSmrg if ( stuff->x > width 294105b261ecSmrg || stuff->y > height ) 29426747b715Smrg return BadMatch; 294305b261ecSmrg 294405b261ecSmrg n = BitmapBytePad(width)*height; 29456747b715Smrg srcbits = calloc(1, n); 294605b261ecSmrg if (!srcbits) 29476747b715Smrg return BadAlloc; 29486747b715Smrg mskbits = malloc(n); 294905b261ecSmrg if (!mskbits) 295005b261ecSmrg { 29516747b715Smrg free(srcbits); 29526747b715Smrg return BadAlloc; 295305b261ecSmrg } 295405b261ecSmrg 295505b261ecSmrg (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height, 295605b261ecSmrg XYPixmap, 1, (pointer)srcbits); 295705b261ecSmrg if ( msk == (PixmapPtr)NULL) 295805b261ecSmrg { 295905b261ecSmrg unsigned char *bits = mskbits; 296005b261ecSmrg while (--n >= 0) 296105b261ecSmrg *bits++ = ~0; 296205b261ecSmrg } 296305b261ecSmrg else 296405b261ecSmrg { 296505b261ecSmrg /* zeroing the (pad) bits helps some ddx cursor handling */ 29666747b715Smrg memset((char *)mskbits, 0, n); 296705b261ecSmrg (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width, 296805b261ecSmrg height, XYPixmap, 1, (pointer)mskbits); 296905b261ecSmrg } 297005b261ecSmrg cm.width = width; 297105b261ecSmrg cm.height = height; 297205b261ecSmrg cm.xhot = stuff->x; 297305b261ecSmrg cm.yhot = stuff->y; 29744642e01fSmrg rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 29754642e01fSmrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 29764642e01fSmrg stuff->backRed, stuff->backGreen, stuff->backBlue, 29774642e01fSmrg &pCursor, client, stuff->cid); 297805b261ecSmrg 29794642e01fSmrg if (rc != Success) 29804642e01fSmrg return rc; 29814642e01fSmrg if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 29824642e01fSmrg return BadAlloc; 29834642e01fSmrg 29846747b715Smrg return Success; 298505b261ecSmrg} 298605b261ecSmrg 298705b261ecSmrgint 298805b261ecSmrgProcCreateGlyphCursor (ClientPtr client) 298905b261ecSmrg{ 299005b261ecSmrg CursorPtr pCursor; 299105b261ecSmrg int res; 299205b261ecSmrg 299305b261ecSmrg REQUEST(xCreateGlyphCursorReq); 299405b261ecSmrg 299505b261ecSmrg REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 299605b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 299705b261ecSmrg 299805b261ecSmrg res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 299905b261ecSmrg stuff->mask, stuff->maskChar, 300005b261ecSmrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 300105b261ecSmrg stuff->backRed, stuff->backGreen, stuff->backBlue, 30024642e01fSmrg &pCursor, client, stuff->cid); 300305b261ecSmrg if (res != Success) 300405b261ecSmrg return res; 300505b261ecSmrg if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 30066747b715Smrg return Success; 300705b261ecSmrg return BadAlloc; 300805b261ecSmrg} 300905b261ecSmrg 301005b261ecSmrg 301105b261ecSmrgint 301205b261ecSmrgProcFreeCursor (ClientPtr client) 301305b261ecSmrg{ 301405b261ecSmrg CursorPtr pCursor; 30154642e01fSmrg int rc; 301605b261ecSmrg REQUEST(xResourceReq); 301705b261ecSmrg 301805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 3019b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client, 30204642e01fSmrg DixDestroyAccess); 30214642e01fSmrg if (rc == Success) 302205b261ecSmrg { 302305b261ecSmrg FreeResource(stuff->id, RT_NONE); 30246747b715Smrg return Success; 302505b261ecSmrg } 302605b261ecSmrg else 302705b261ecSmrg { 302805b261ecSmrg client->errorValue = stuff->id; 30296747b715Smrg return rc; 303005b261ecSmrg } 303105b261ecSmrg} 303205b261ecSmrg 303305b261ecSmrgint 303405b261ecSmrgProcQueryBestSize (ClientPtr client) 303505b261ecSmrg{ 303605b261ecSmrg xQueryBestSizeReply reply; 303705b261ecSmrg DrawablePtr pDraw; 303805b261ecSmrg ScreenPtr pScreen; 303905b261ecSmrg int rc; 304005b261ecSmrg REQUEST(xQueryBestSizeReq); 304105b261ecSmrg REQUEST_SIZE_MATCH(xQueryBestSizeReq); 304205b261ecSmrg 304305b261ecSmrg if ((stuff->class != CursorShape) && 304405b261ecSmrg (stuff->class != TileShape) && 304505b261ecSmrg (stuff->class != StippleShape)) 304605b261ecSmrg { 304705b261ecSmrg client->errorValue = stuff->class; 30486747b715Smrg return BadValue; 304905b261ecSmrg } 305005b261ecSmrg 305105b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 30524642e01fSmrg DixGetAttrAccess); 305305b261ecSmrg if (rc != Success) 305405b261ecSmrg return rc; 305505b261ecSmrg if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 30566747b715Smrg return BadMatch; 305705b261ecSmrg pScreen = pDraw->pScreen; 30584642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 30594642e01fSmrg if (rc != Success) 30604642e01fSmrg return rc; 306105b261ecSmrg (* pScreen->QueryBestSize)(stuff->class, &stuff->width, 306205b261ecSmrg &stuff->height, pScreen); 30636747b715Smrg memset(&reply, 0, sizeof(xQueryBestSizeReply)); 306405b261ecSmrg reply.type = X_Reply; 306505b261ecSmrg reply.length = 0; 306605b261ecSmrg reply.sequenceNumber = client->sequence; 306705b261ecSmrg reply.width = stuff->width; 306805b261ecSmrg reply.height = stuff->height; 306905b261ecSmrg WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 30706747b715Smrg return Success; 307105b261ecSmrg} 307205b261ecSmrg 307305b261ecSmrg 307405b261ecSmrgint 307505b261ecSmrgProcSetScreenSaver (ClientPtr client) 307605b261ecSmrg{ 30774642e01fSmrg int rc, i, blankingOption, exposureOption; 307805b261ecSmrg REQUEST(xSetScreenSaverReq); 307905b261ecSmrg REQUEST_SIZE_MATCH(xSetScreenSaverReq); 30804642e01fSmrg 30814642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 30824642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 30834642e01fSmrg DixSetAttrAccess); 30844642e01fSmrg if (rc != Success) 30854642e01fSmrg return rc; 30864642e01fSmrg } 30874642e01fSmrg 308805b261ecSmrg blankingOption = stuff->preferBlank; 308905b261ecSmrg if ((blankingOption != DontPreferBlanking) && 309005b261ecSmrg (blankingOption != PreferBlanking) && 309105b261ecSmrg (blankingOption != DefaultBlanking)) 309205b261ecSmrg { 309305b261ecSmrg client->errorValue = blankingOption; 309405b261ecSmrg return BadValue; 309505b261ecSmrg } 309605b261ecSmrg exposureOption = stuff->allowExpose; 309705b261ecSmrg if ((exposureOption != DontAllowExposures) && 309805b261ecSmrg (exposureOption != AllowExposures) && 309905b261ecSmrg (exposureOption != DefaultExposures)) 310005b261ecSmrg { 310105b261ecSmrg client->errorValue = exposureOption; 310205b261ecSmrg return BadValue; 310305b261ecSmrg } 310405b261ecSmrg if (stuff->timeout < -1) 310505b261ecSmrg { 310605b261ecSmrg client->errorValue = stuff->timeout; 310705b261ecSmrg return BadValue; 310805b261ecSmrg } 310905b261ecSmrg if (stuff->interval < -1) 311005b261ecSmrg { 311105b261ecSmrg client->errorValue = stuff->interval; 311205b261ecSmrg return BadValue; 311305b261ecSmrg } 311405b261ecSmrg 311505b261ecSmrg if (blankingOption == DefaultBlanking) 311605b261ecSmrg ScreenSaverBlanking = defaultScreenSaverBlanking; 311705b261ecSmrg else 311805b261ecSmrg ScreenSaverBlanking = blankingOption; 311905b261ecSmrg if (exposureOption == DefaultExposures) 312005b261ecSmrg ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 312105b261ecSmrg else 312205b261ecSmrg ScreenSaverAllowExposures = exposureOption; 312305b261ecSmrg 312405b261ecSmrg if (stuff->timeout >= 0) 312505b261ecSmrg ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 312605b261ecSmrg else 312705b261ecSmrg ScreenSaverTime = defaultScreenSaverTime; 312805b261ecSmrg if (stuff->interval >= 0) 312905b261ecSmrg ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 313005b261ecSmrg else 313105b261ecSmrg ScreenSaverInterval = defaultScreenSaverInterval; 313205b261ecSmrg 313305b261ecSmrg SetScreenSaverTimer(); 31346747b715Smrg return Success; 313505b261ecSmrg} 313605b261ecSmrg 313705b261ecSmrgint 313805b261ecSmrgProcGetScreenSaver(ClientPtr client) 313905b261ecSmrg{ 314005b261ecSmrg xGetScreenSaverReply rep; 31414642e01fSmrg int rc, i; 314205b261ecSmrg REQUEST_SIZE_MATCH(xReq); 31434642e01fSmrg 31444642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 31454642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 31464642e01fSmrg DixGetAttrAccess); 31474642e01fSmrg if (rc != Success) 31484642e01fSmrg return rc; 31494642e01fSmrg } 31504642e01fSmrg 315105b261ecSmrg rep.type = X_Reply; 315205b261ecSmrg rep.length = 0; 315305b261ecSmrg rep.sequenceNumber = client->sequence; 315405b261ecSmrg rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; 315505b261ecSmrg rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; 315605b261ecSmrg rep.preferBlanking = ScreenSaverBlanking; 315705b261ecSmrg rep.allowExposures = ScreenSaverAllowExposures; 315805b261ecSmrg WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 31596747b715Smrg return Success; 316005b261ecSmrg} 316105b261ecSmrg 316205b261ecSmrgint 316305b261ecSmrgProcChangeHosts(ClientPtr client) 316405b261ecSmrg{ 316505b261ecSmrg REQUEST(xChangeHostsReq); 316605b261ecSmrg 316705b261ecSmrg REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 316805b261ecSmrg 316905b261ecSmrg if(stuff->mode == HostInsert) 31706747b715Smrg return AddHost(client, (int)stuff->hostFamily, 317105b261ecSmrg stuff->hostLength, (pointer)&stuff[1]); 31726747b715Smrg if (stuff->mode == HostDelete) 31736747b715Smrg return RemoveHost(client, (int)stuff->hostFamily, 317405b261ecSmrg stuff->hostLength, (pointer)&stuff[1]); 31756747b715Smrg client->errorValue = stuff->mode; 31766747b715Smrg return BadValue; 317705b261ecSmrg} 317805b261ecSmrg 317905b261ecSmrgint 318005b261ecSmrgProcListHosts(ClientPtr client) 318105b261ecSmrg{ 318205b261ecSmrg xListHostsReply reply; 318305b261ecSmrg int len, nHosts, result; 318405b261ecSmrg pointer pdata; 318505b261ecSmrg /* REQUEST(xListHostsReq); */ 318605b261ecSmrg 318705b261ecSmrg REQUEST_SIZE_MATCH(xListHostsReq); 318805b261ecSmrg 318905b261ecSmrg /* untrusted clients can't list hosts */ 31904642e01fSmrg result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); 31914642e01fSmrg if (result != Success) 31924642e01fSmrg return result; 319305b261ecSmrg 319405b261ecSmrg result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); 319505b261ecSmrg if (result != Success) 31966747b715Smrg return result; 319705b261ecSmrg reply.type = X_Reply; 319805b261ecSmrg reply.sequenceNumber = client->sequence; 319905b261ecSmrg reply.nHosts = nHosts; 32006747b715Smrg reply.length = bytes_to_int32(len); 320105b261ecSmrg WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 320205b261ecSmrg if (nHosts) 320305b261ecSmrg { 320405b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 320505b261ecSmrg WriteSwappedDataToClient(client, len, pdata); 320605b261ecSmrg } 32076747b715Smrg free(pdata); 32086747b715Smrg return Success; 320905b261ecSmrg} 321005b261ecSmrg 321105b261ecSmrgint 321205b261ecSmrgProcChangeAccessControl(ClientPtr client) 321305b261ecSmrg{ 321405b261ecSmrg REQUEST(xSetAccessControlReq); 321505b261ecSmrg 321605b261ecSmrg REQUEST_SIZE_MATCH(xSetAccessControlReq); 321705b261ecSmrg if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) 321805b261ecSmrg { 321905b261ecSmrg client->errorValue = stuff->mode; 322005b261ecSmrg return BadValue; 322105b261ecSmrg } 32226747b715Smrg return ChangeAccessControl(client, stuff->mode == EnableAccess); 322305b261ecSmrg} 322405b261ecSmrg 322505b261ecSmrg/********************* 322605b261ecSmrg * CloseDownRetainedResources 322705b261ecSmrg * 322805b261ecSmrg * Find all clients that are gone and have terminated in RetainTemporary 322905b261ecSmrg * and destroy their resources. 323005b261ecSmrg *********************/ 323105b261ecSmrg 323205b261ecSmrgstatic void 323305b261ecSmrgCloseDownRetainedResources(void) 323405b261ecSmrg{ 323505b261ecSmrg int i; 323605b261ecSmrg ClientPtr client; 323705b261ecSmrg 323805b261ecSmrg for (i=1; i<currentMaxClients; i++) 323905b261ecSmrg { 324005b261ecSmrg client = clients[i]; 324105b261ecSmrg if (client && (client->closeDownMode == RetainTemporary) 324205b261ecSmrg && (client->clientGone)) 324305b261ecSmrg CloseDownClient(client); 324405b261ecSmrg } 324505b261ecSmrg} 324605b261ecSmrg 324705b261ecSmrgint 324805b261ecSmrgProcKillClient(ClientPtr client) 324905b261ecSmrg{ 325005b261ecSmrg REQUEST(xResourceReq); 325105b261ecSmrg ClientPtr killclient; 325205b261ecSmrg int rc; 325305b261ecSmrg 325405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 325505b261ecSmrg if (stuff->id == AllTemporary) 325605b261ecSmrg { 325705b261ecSmrg CloseDownRetainedResources(); 32586747b715Smrg return Success; 325905b261ecSmrg } 326005b261ecSmrg 326105b261ecSmrg rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 326205b261ecSmrg if (rc == Success) { 326305b261ecSmrg CloseDownClient(killclient); 326405b261ecSmrg /* if an LBX proxy gets killed, isItTimeToYield will be set */ 326505b261ecSmrg if (isItTimeToYield || (client == killclient)) 326605b261ecSmrg { 326705b261ecSmrg /* force yield and return Success, so that Dispatch() 326805b261ecSmrg * doesn't try to touch client 326905b261ecSmrg */ 327005b261ecSmrg isItTimeToYield = TRUE; 32716747b715Smrg return Success; 327205b261ecSmrg } 32736747b715Smrg return Success; 327405b261ecSmrg } 327505b261ecSmrg else 327605b261ecSmrg return rc; 327705b261ecSmrg} 327805b261ecSmrg 327905b261ecSmrgint 328005b261ecSmrgProcSetFontPath(ClientPtr client) 328105b261ecSmrg{ 328205b261ecSmrg unsigned char *ptr; 328305b261ecSmrg unsigned long nbytes, total; 328405b261ecSmrg long nfonts; 32856747b715Smrg int n; 328605b261ecSmrg REQUEST(xSetFontPathReq); 328705b261ecSmrg 328805b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 328905b261ecSmrg 329005b261ecSmrg nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 329105b261ecSmrg total = nbytes; 329205b261ecSmrg ptr = (unsigned char *)&stuff[1]; 329305b261ecSmrg nfonts = stuff->nFonts; 329405b261ecSmrg while (--nfonts >= 0) 329505b261ecSmrg { 329605b261ecSmrg if ((total == 0) || (total < (n = (*ptr + 1)))) 32976747b715Smrg return BadLength; 329805b261ecSmrg total -= n; 329905b261ecSmrg ptr += n; 330005b261ecSmrg } 330105b261ecSmrg if (total >= 4) 33026747b715Smrg return BadLength; 33036747b715Smrg return SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]); 330405b261ecSmrg} 330505b261ecSmrg 330605b261ecSmrgint 330705b261ecSmrgProcGetFontPath(ClientPtr client) 330805b261ecSmrg{ 330905b261ecSmrg xGetFontPathReply reply; 33104642e01fSmrg int rc, stringLens, numpaths; 331105b261ecSmrg unsigned char *bufferStart; 331205b261ecSmrg /* REQUEST (xReq); */ 331305b261ecSmrg 331405b261ecSmrg REQUEST_SIZE_MATCH(xReq); 33154642e01fSmrg rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); 33164642e01fSmrg if (rc != Success) 33174642e01fSmrg return rc; 331805b261ecSmrg 331905b261ecSmrg reply.type = X_Reply; 332005b261ecSmrg reply.sequenceNumber = client->sequence; 33216747b715Smrg reply.length = bytes_to_int32(stringLens + numpaths); 332205b261ecSmrg reply.nPaths = numpaths; 332305b261ecSmrg 332405b261ecSmrg WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 332505b261ecSmrg if (stringLens || numpaths) 332605b261ecSmrg (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart); 33276747b715Smrg return Success; 332805b261ecSmrg} 332905b261ecSmrg 333005b261ecSmrgint 333105b261ecSmrgProcChangeCloseDownMode(ClientPtr client) 333205b261ecSmrg{ 33334642e01fSmrg int rc; 333405b261ecSmrg REQUEST(xSetCloseDownModeReq); 333505b261ecSmrg REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 33364642e01fSmrg 33374642e01fSmrg rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); 33384642e01fSmrg if (rc != Success) 33394642e01fSmrg return rc; 33404642e01fSmrg 334105b261ecSmrg if ((stuff->mode == AllTemporary) || 334205b261ecSmrg (stuff->mode == RetainPermanent) || 334305b261ecSmrg (stuff->mode == RetainTemporary)) 334405b261ecSmrg { 334505b261ecSmrg client->closeDownMode = stuff->mode; 33466747b715Smrg return Success; 334705b261ecSmrg } 334805b261ecSmrg else 334905b261ecSmrg { 335005b261ecSmrg client->errorValue = stuff->mode; 33516747b715Smrg return BadValue; 335205b261ecSmrg } 335305b261ecSmrg} 335405b261ecSmrg 335505b261ecSmrgint ProcForceScreenSaver(ClientPtr client) 335605b261ecSmrg{ 33574642e01fSmrg int rc; 335805b261ecSmrg REQUEST(xForceScreenSaverReq); 335905b261ecSmrg 336005b261ecSmrg REQUEST_SIZE_MATCH(xForceScreenSaverReq); 336105b261ecSmrg 336205b261ecSmrg if ((stuff->mode != ScreenSaverReset) && 336305b261ecSmrg (stuff->mode != ScreenSaverActive)) 336405b261ecSmrg { 336505b261ecSmrg client->errorValue = stuff->mode; 336605b261ecSmrg return BadValue; 336705b261ecSmrg } 33684642e01fSmrg rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode); 33694642e01fSmrg if (rc != Success) 33704642e01fSmrg return rc; 33716747b715Smrg return Success; 337205b261ecSmrg} 337305b261ecSmrg 337405b261ecSmrgint ProcNoOperation(ClientPtr client) 337505b261ecSmrg{ 337605b261ecSmrg REQUEST_AT_LEAST_SIZE(xReq); 337705b261ecSmrg 337805b261ecSmrg /* noop -- don't do anything */ 33796747b715Smrg return Success; 338005b261ecSmrg} 338105b261ecSmrg 338205b261ecSmrg/********************** 338305b261ecSmrg * CloseDownClient 338405b261ecSmrg * 338505b261ecSmrg * Client can either mark his resources destroy or retain. If retained and 338605b261ecSmrg * then killed again, the client is really destroyed. 338705b261ecSmrg *********************/ 338805b261ecSmrg 338905b261ecSmrgchar dispatchExceptionAtReset = DE_RESET; 339005b261ecSmrg 339105b261ecSmrgvoid 339205b261ecSmrgCloseDownClient(ClientPtr client) 339305b261ecSmrg{ 339405b261ecSmrg Bool really_close_down = client->clientGone || 339505b261ecSmrg client->closeDownMode == DestroyAll; 339605b261ecSmrg 339705b261ecSmrg if (!client->clientGone) 339805b261ecSmrg { 339905b261ecSmrg /* ungrab server if grabbing client dies */ 340005b261ecSmrg if (grabState != GrabNone && grabClient == client) 340105b261ecSmrg { 340205b261ecSmrg UngrabServer(client); 340305b261ecSmrg } 340405b261ecSmrg BITCLEAR(grabWaiters, client->index); 340505b261ecSmrg DeleteClientFromAnySelections(client); 340605b261ecSmrg ReleaseActiveGrabs(client); 340705b261ecSmrg DeleteClientFontStuff(client); 340805b261ecSmrg if (!really_close_down) 340905b261ecSmrg { 341005b261ecSmrg /* This frees resources that should never be retained 341105b261ecSmrg * no matter what the close down mode is. Actually we 341205b261ecSmrg * could do this unconditionally, but it's probably 341305b261ecSmrg * better not to traverse all the client's resources 341405b261ecSmrg * twice (once here, once a few lines down in 341505b261ecSmrg * FreeClientResources) in the common case of 341605b261ecSmrg * really_close_down == TRUE. 341705b261ecSmrg */ 341805b261ecSmrg FreeClientNeverRetainResources(client); 341905b261ecSmrg client->clientState = ClientStateRetained; 342005b261ecSmrg if (ClientStateCallback) 342105b261ecSmrg { 342205b261ecSmrg NewClientInfoRec clientinfo; 342305b261ecSmrg 342405b261ecSmrg clientinfo.client = client; 342505b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 342605b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 342705b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 342805b261ecSmrg } 342905b261ecSmrg } 343005b261ecSmrg client->clientGone = TRUE; /* so events aren't sent to client */ 343105b261ecSmrg if (ClientIsAsleep(client)) 343205b261ecSmrg ClientSignal (client); 343305b261ecSmrg ProcessWorkQueueZombies(); 343405b261ecSmrg CloseDownConnection(client); 343505b261ecSmrg 343605b261ecSmrg /* If the client made it to the Running stage, nClients has 343705b261ecSmrg * been incremented on its behalf, so we need to decrement it 343805b261ecSmrg * now. If it hasn't gotten to Running, nClients has *not* 343905b261ecSmrg * been incremented, so *don't* decrement it. 344005b261ecSmrg */ 344105b261ecSmrg if (client->clientState != ClientStateInitial && 344205b261ecSmrg client->clientState != ClientStateAuthenticating ) 344305b261ecSmrg { 344405b261ecSmrg --nClients; 344505b261ecSmrg } 344605b261ecSmrg } 344705b261ecSmrg 344805b261ecSmrg if (really_close_down) 344905b261ecSmrg { 345005b261ecSmrg if (client->clientState == ClientStateRunning && nClients == 0) 345105b261ecSmrg dispatchException |= dispatchExceptionAtReset; 345205b261ecSmrg 345305b261ecSmrg client->clientState = ClientStateGone; 345405b261ecSmrg if (ClientStateCallback) 345505b261ecSmrg { 345605b261ecSmrg NewClientInfoRec clientinfo; 345705b261ecSmrg 345805b261ecSmrg clientinfo.client = client; 345905b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 346005b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 346105b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 346205b261ecSmrg } 346305b261ecSmrg FreeClientResources(client); 346405b261ecSmrg#ifdef XSERVER_DTRACE 346505b261ecSmrg XSERVER_CLIENT_DISCONNECT(client->index); 346605b261ecSmrg#endif 346705b261ecSmrg if (client->index < nextFreeClientID) 346805b261ecSmrg nextFreeClientID = client->index; 346905b261ecSmrg clients[client->index] = NullClient; 347005b261ecSmrg SmartLastClient = NullClient; 34716747b715Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 347205b261ecSmrg 347305b261ecSmrg while (!clients[currentMaxClients-1]) 347405b261ecSmrg currentMaxClients--; 347505b261ecSmrg } 347605b261ecSmrg} 347705b261ecSmrg 347805b261ecSmrgstatic void 347905b261ecSmrgKillAllClients(void) 348005b261ecSmrg{ 348105b261ecSmrg int i; 348205b261ecSmrg for (i=1; i<currentMaxClients; i++) 348305b261ecSmrg if (clients[i]) { 348405b261ecSmrg /* Make sure Retained clients are released. */ 348505b261ecSmrg clients[i]->closeDownMode = DestroyAll; 348605b261ecSmrg CloseDownClient(clients[i]); 348705b261ecSmrg } 348805b261ecSmrg} 348905b261ecSmrg 349005b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv) 349105b261ecSmrg{ 349205b261ecSmrg client->index = i; 349305b261ecSmrg client->clientAsMask = ((Mask)i) << CLIENTOFFSET; 34944642e01fSmrg client->closeDownMode = i ? DestroyAll : RetainPermanent; 349505b261ecSmrg client->requestVector = InitialVector; 349605b261ecSmrg client->osPrivate = ospriv; 34976747b715Smrg QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); 349805b261ecSmrg client->smart_start_tick = SmartScheduleTime; 349905b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 350005b261ecSmrg client->smart_check_tick = SmartScheduleTime; 350105b261ecSmrg} 350205b261ecSmrg 350305b261ecSmrg/************************ 350405b261ecSmrg * int NextAvailableClient(ospriv) 350505b261ecSmrg * 350605b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes. 350705b261ecSmrg * Returns NULL if there are no free clients. 350805b261ecSmrg *************************/ 350905b261ecSmrg 351005b261ecSmrgClientPtr NextAvailableClient(pointer ospriv) 351105b261ecSmrg{ 351205b261ecSmrg int i; 351305b261ecSmrg ClientPtr client; 351405b261ecSmrg xReq data; 351505b261ecSmrg 351605b261ecSmrg i = nextFreeClientID; 351705b261ecSmrg if (i == MAXCLIENTS) 351805b261ecSmrg return (ClientPtr)NULL; 35196747b715Smrg clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT); 352005b261ecSmrg if (!client) 352105b261ecSmrg return (ClientPtr)NULL; 352205b261ecSmrg InitClient(client, i, ospriv); 352305b261ecSmrg if (!InitClientResources(client)) 352405b261ecSmrg { 35256747b715Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 352605b261ecSmrg return (ClientPtr)NULL; 352705b261ecSmrg } 352805b261ecSmrg data.reqType = 1; 35296747b715Smrg data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); 353005b261ecSmrg if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) 353105b261ecSmrg { 353205b261ecSmrg FreeClientResources(client); 35336747b715Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 353405b261ecSmrg return (ClientPtr)NULL; 353505b261ecSmrg } 353605b261ecSmrg if (i == currentMaxClients) 353705b261ecSmrg currentMaxClients++; 353805b261ecSmrg while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) 353905b261ecSmrg nextFreeClientID++; 354005b261ecSmrg if (ClientStateCallback) 354105b261ecSmrg { 354205b261ecSmrg NewClientInfoRec clientinfo; 354305b261ecSmrg 354405b261ecSmrg clientinfo.client = client; 354505b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 354605b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 354705b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 354805b261ecSmrg } 35496747b715Smrg return client; 355005b261ecSmrg} 355105b261ecSmrg 355205b261ecSmrgint 355305b261ecSmrgProcInitialConnection(ClientPtr client) 355405b261ecSmrg{ 355505b261ecSmrg REQUEST(xReq); 355605b261ecSmrg xConnClientPrefix *prefix; 355705b261ecSmrg int whichbyte = 1; 355805b261ecSmrg 355905b261ecSmrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 356005b261ecSmrg if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) 35616747b715Smrg return client->noClientException = -1; 356205b261ecSmrg if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || 356305b261ecSmrg (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) 356405b261ecSmrg { 356505b261ecSmrg client->swapped = TRUE; 356605b261ecSmrg SwapConnClientPrefix(prefix); 356705b261ecSmrg } 356805b261ecSmrg stuff->reqType = 2; 35696747b715Smrg stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + 35706747b715Smrg bytes_to_int32(prefix->nbytesAuthString); 357105b261ecSmrg if (client->swapped) 357205b261ecSmrg { 357305b261ecSmrg swaps(&stuff->length, whichbyte); 357405b261ecSmrg } 357505b261ecSmrg ResetCurrentRequest(client); 35766747b715Smrg return Success; 357705b261ecSmrg} 357805b261ecSmrg 35794642e01fSmrgstatic int 358005b261ecSmrgSendConnSetup(ClientPtr client, char *reason) 358105b261ecSmrg{ 358205b261ecSmrg xWindowRoot *root; 358305b261ecSmrg int i; 358405b261ecSmrg int numScreens; 358505b261ecSmrg char* lConnectionInfo; 358605b261ecSmrg xConnSetupPrefix* lconnSetupPrefix; 358705b261ecSmrg 358805b261ecSmrg if (reason) 358905b261ecSmrg { 359005b261ecSmrg xConnSetupPrefix csp; 359105b261ecSmrg 359205b261ecSmrg csp.success = xFalse; 359305b261ecSmrg csp.lengthReason = strlen(reason); 35946747b715Smrg csp.length = bytes_to_int32(csp.lengthReason); 359505b261ecSmrg csp.majorVersion = X_PROTOCOL; 359605b261ecSmrg csp.minorVersion = X_PROTOCOL_REVISION; 359705b261ecSmrg if (client->swapped) 359805b261ecSmrg WriteSConnSetupPrefix(client, &csp); 359905b261ecSmrg else 360005b261ecSmrg (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); 360105b261ecSmrg (void)WriteToClient(client, (int)csp.lengthReason, reason); 36026747b715Smrg return client->noClientException = -1; 360305b261ecSmrg } 360405b261ecSmrg 360505b261ecSmrg numScreens = screenInfo.numScreens; 360605b261ecSmrg lConnectionInfo = ConnectionInfo; 360705b261ecSmrg lconnSetupPrefix = &connSetupPrefix; 360805b261ecSmrg 360905b261ecSmrg /* We're about to start speaking X protocol back to the client by 361005b261ecSmrg * sending the connection setup info. This means the authorization 361105b261ecSmrg * step is complete, and we can count the client as an 361205b261ecSmrg * authorized one. 361305b261ecSmrg */ 361405b261ecSmrg nClients++; 361505b261ecSmrg 361605b261ecSmrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 361705b261ecSmrg client->sequence = 0; 361805b261ecSmrg ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask; 361905b261ecSmrg ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 362005b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 362105b261ecSmrg ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client); 362205b261ecSmrg ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client); 362305b261ecSmrg#endif 362405b261ecSmrg /* fill in the "currentInputMask" */ 362505b261ecSmrg root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart); 362605b261ecSmrg#ifdef PANORAMIX 362705b261ecSmrg if (noPanoramiXExtension) 362805b261ecSmrg numScreens = screenInfo.numScreens; 362905b261ecSmrg else 363005b261ecSmrg numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; 363105b261ecSmrg#endif 363205b261ecSmrg 363305b261ecSmrg for (i=0; i<numScreens; i++) 363405b261ecSmrg { 363505b261ecSmrg unsigned int j; 363605b261ecSmrg xDepth *pDepth; 36376747b715Smrg WindowPtr pRoot = screenInfo.screens[i]->root; 363805b261ecSmrg 36396747b715Smrg root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot); 364005b261ecSmrg pDepth = (xDepth *)(root + 1); 364105b261ecSmrg for (j = 0; j < root->nDepths; j++) 364205b261ecSmrg { 364305b261ecSmrg pDepth = (xDepth *)(((char *)(pDepth + 1)) + 364405b261ecSmrg pDepth->nVisuals * sizeof(xVisualType)); 364505b261ecSmrg } 364605b261ecSmrg root = (xWindowRoot *)pDepth; 364705b261ecSmrg } 364805b261ecSmrg 364905b261ecSmrg if (client->swapped) 365005b261ecSmrg { 365105b261ecSmrg WriteSConnSetupPrefix(client, lconnSetupPrefix); 365205b261ecSmrg WriteSConnectionInfo(client, 365305b261ecSmrg (unsigned long)(lconnSetupPrefix->length << 2), 365405b261ecSmrg lConnectionInfo); 365505b261ecSmrg } 365605b261ecSmrg else 365705b261ecSmrg { 365805b261ecSmrg (void)WriteToClient(client, sizeof(xConnSetupPrefix), 365905b261ecSmrg (char *) lconnSetupPrefix); 366005b261ecSmrg (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2), 366105b261ecSmrg lConnectionInfo); 366205b261ecSmrg } 366305b261ecSmrg client->clientState = ClientStateRunning; 366405b261ecSmrg if (ClientStateCallback) 366505b261ecSmrg { 366605b261ecSmrg NewClientInfoRec clientinfo; 366705b261ecSmrg 366805b261ecSmrg clientinfo.client = client; 366905b261ecSmrg clientinfo.prefix = lconnSetupPrefix; 367005b261ecSmrg clientinfo.setup = (xConnSetup *)lConnectionInfo; 367105b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 367205b261ecSmrg } 36736747b715Smrg return Success; 367405b261ecSmrg} 367505b261ecSmrg 367605b261ecSmrgint 367705b261ecSmrgProcEstablishConnection(ClientPtr client) 367805b261ecSmrg{ 367905b261ecSmrg char *reason, *auth_proto, *auth_string; 368005b261ecSmrg xConnClientPrefix *prefix; 368105b261ecSmrg REQUEST(xReq); 368205b261ecSmrg 368305b261ecSmrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 368405b261ecSmrg auth_proto = (char *)prefix + sz_xConnClientPrefix; 36856747b715Smrg auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); 368605b261ecSmrg if ((prefix->majorVersion != X_PROTOCOL) || 368705b261ecSmrg (prefix->minorVersion != X_PROTOCOL_REVISION)) 368805b261ecSmrg reason = "Protocol version mismatch"; 368905b261ecSmrg else 369005b261ecSmrg reason = ClientAuthorized(client, 369105b261ecSmrg (unsigned short)prefix->nbytesAuthProto, 369205b261ecSmrg auth_proto, 369305b261ecSmrg (unsigned short)prefix->nbytesAuthString, 369405b261ecSmrg auth_string); 369505b261ecSmrg /* 369605b261ecSmrg * If Kerberos is being used for this client, the clientState 369705b261ecSmrg * will be set to ClientStateAuthenticating at this point. 369805b261ecSmrg * More messages need to be exchanged among the X server, Kerberos 369905b261ecSmrg * server, and client to figure out if everyone is authorized. 370005b261ecSmrg * So we don't want to send the connection setup info yet, since 370105b261ecSmrg * the auth step isn't really done. 370205b261ecSmrg */ 370305b261ecSmrg if (client->clientState == ClientStateCheckingSecurity) 370405b261ecSmrg client->clientState = ClientStateCheckedSecurity; 370505b261ecSmrg else if (client->clientState != ClientStateAuthenticating) 370605b261ecSmrg return(SendConnSetup(client, reason)); 37076747b715Smrg return Success; 370805b261ecSmrg} 370905b261ecSmrg 37106747b715Smrgvoid 371105b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 371205b261ecSmrg XID resId, int errorCode) 371305b261ecSmrg{ 371405b261ecSmrg xError rep; 371505b261ecSmrg 37166747b715Smrg memset(&rep, 0, sizeof(xError)); 371705b261ecSmrg rep.type = X_Error; 371805b261ecSmrg rep.errorCode = errorCode; 371905b261ecSmrg rep.majorCode = majorCode; 372005b261ecSmrg rep.minorCode = minorCode; 372105b261ecSmrg rep.resourceID = resId; 372205b261ecSmrg 372305b261ecSmrg WriteEventsToClient (client, 1, (xEvent *)&rep); 372405b261ecSmrg} 372505b261ecSmrg 372605b261ecSmrgvoid 372705b261ecSmrgMarkClientException(ClientPtr client) 372805b261ecSmrg{ 372905b261ecSmrg client->noClientException = -1; 373005b261ecSmrg} 37316747b715Smrg 37326747b715Smrg/* 37336747b715Smrg * This array encodes the answer to the question "what is the log base 2 37346747b715Smrg * of the number of pixels that fit in a scanline pad unit?" 37356747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37366747b715Smrg */ 37376747b715Smrgstatic int answer[6][4] = { 37386747b715Smrg /* pad pad pad pad*/ 37396747b715Smrg /* 8 16 32 64 */ 37406747b715Smrg 37416747b715Smrg { 3, 4, 5 , 6 }, /* 1 bit per pixel */ 37426747b715Smrg { 1, 2, 3 , 4 }, /* 4 bits per pixel */ 37436747b715Smrg { 0, 1, 2 , 3 }, /* 8 bits per pixel */ 37446747b715Smrg { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ 37456747b715Smrg { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ 37466747b715Smrg { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ 37476747b715Smrg}; 37486747b715Smrg 37496747b715Smrg/* 37506747b715Smrg * This array gives the answer to the question "what is the first index for 37516747b715Smrg * the answer array above given the number of bits per pixel?" 37526747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37536747b715Smrg */ 37546747b715Smrgstatic int indexForBitsPerPixel[ 33 ] = { 37556747b715Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 37566747b715Smrg 1, ~0, ~0, ~0, /* 4 bits per pixel */ 37576747b715Smrg 2, ~0, ~0, ~0, /* 8 bits per pixel */ 37586747b715Smrg ~0,~0, ~0, ~0, 37596747b715Smrg 3, ~0, ~0, ~0, /* 16 bits per pixel */ 37606747b715Smrg ~0,~0, ~0, ~0, 37616747b715Smrg 4, ~0, ~0, ~0, /* 24 bits per pixel */ 37626747b715Smrg ~0,~0, ~0, ~0, 37636747b715Smrg 5 /* 32 bits per pixel */ 37646747b715Smrg}; 37656747b715Smrg 37666747b715Smrg/* 37676747b715Smrg * This array gives the bytesperPixel value for cases where the number 37686747b715Smrg * of bits per pixel is a multiple of 8 but not a power of 2. 37696747b715Smrg */ 37706747b715Smrgstatic int answerBytesPerPixel[ 33 ] = { 37716747b715Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 37726747b715Smrg 0, ~0, ~0, ~0, /* 4 bits per pixel */ 37736747b715Smrg 0, ~0, ~0, ~0, /* 8 bits per pixel */ 37746747b715Smrg ~0,~0, ~0, ~0, 37756747b715Smrg 0, ~0, ~0, ~0, /* 16 bits per pixel */ 37766747b715Smrg ~0,~0, ~0, ~0, 37776747b715Smrg 3, ~0, ~0, ~0, /* 24 bits per pixel */ 37786747b715Smrg ~0,~0, ~0, ~0, 37796747b715Smrg 0 /* 32 bits per pixel */ 37806747b715Smrg}; 37816747b715Smrg 37826747b715Smrg/* 37836747b715Smrg * This array gives the answer to the question "what is the second index for 37846747b715Smrg * the answer array above given the number of bits per scanline pad unit?" 37856747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37866747b715Smrg */ 37876747b715Smrgstatic int indexForScanlinePad[ 65 ] = { 37886747b715Smrg ~0, ~0, ~0, ~0, 37896747b715Smrg ~0, ~0, ~0, ~0, 37906747b715Smrg 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ 37916747b715Smrg ~0, ~0, ~0, ~0, 37926747b715Smrg 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ 37936747b715Smrg ~0, ~0, ~0, ~0, 37946747b715Smrg ~0, ~0, ~0, ~0, 37956747b715Smrg ~0, ~0, ~0, ~0, 37966747b715Smrg 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ 37976747b715Smrg ~0, ~0, ~0, ~0, 37986747b715Smrg ~0, ~0, ~0, ~0, 37996747b715Smrg ~0, ~0, ~0, ~0, 38006747b715Smrg ~0, ~0, ~0, ~0, 38016747b715Smrg ~0, ~0, ~0, ~0, 38026747b715Smrg ~0, ~0, ~0, ~0, 38036747b715Smrg ~0, ~0, ~0, ~0, 38046747b715Smrg 3 /* 64 bits per scanline pad unit */ 38056747b715Smrg}; 38066747b715Smrg 38076747b715Smrg/* 38086747b715Smrg grow the array of screenRecs if necessary. 38096747b715Smrg call the device-supplied initialization procedure 38106747b715Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv. 38116747b715Smrg return the number of successfully installed screens. 38126747b715Smrg 38136747b715Smrg*/ 38146747b715Smrg 38156747b715Smrgint 38166747b715SmrgAddScreen( 38176747b715Smrg Bool (* pfnInit)( 38186747b715Smrg int /*index*/, 38196747b715Smrg ScreenPtr /*pScreen*/, 38206747b715Smrg int /*argc*/, 38216747b715Smrg char ** /*argv*/ 38226747b715Smrg ), 38236747b715Smrg int argc, 38246747b715Smrg char **argv) 38256747b715Smrg{ 38266747b715Smrg 38276747b715Smrg int i; 38286747b715Smrg int scanlinepad, format, depth, bitsPerPixel, j, k; 38296747b715Smrg ScreenPtr pScreen; 38306747b715Smrg 38316747b715Smrg i = screenInfo.numScreens; 38326747b715Smrg if (i == MAXSCREENS) 38336747b715Smrg return -1; 38346747b715Smrg 38356747b715Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 38366747b715Smrg if (!pScreen) 38376747b715Smrg return -1; 38386747b715Smrg 38396747b715Smrg if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { 38406747b715Smrg free (pScreen); 38416747b715Smrg return -1; 38426747b715Smrg } 38436747b715Smrg pScreen->myNum = i; 38446747b715Smrg pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ 38456747b715Smrg pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ 38466747b715Smrg pScreen->CreateScreenResources = 0; 38476747b715Smrg 38486747b715Smrg /* 38496747b715Smrg * This loop gets run once for every Screen that gets added, 38506747b715Smrg * but thats ok. If the ddx layer initializes the formats 38516747b715Smrg * one at a time calling AddScreen() after each, then each 38526747b715Smrg * iteration will make it a little more accurate. Worst case 38536747b715Smrg * we do this loop N * numPixmapFormats where N is # of screens. 38546747b715Smrg * Anyway, this must be called after InitOutput and before the 38556747b715Smrg * screen init routine is called. 38566747b715Smrg */ 38576747b715Smrg for (format=0; format<screenInfo.numPixmapFormats; format++) 38586747b715Smrg { 38596747b715Smrg depth = screenInfo.formats[format].depth; 38606747b715Smrg bitsPerPixel = screenInfo.formats[format].bitsPerPixel; 38616747b715Smrg scanlinepad = screenInfo.formats[format].scanlinePad; 38626747b715Smrg j = indexForBitsPerPixel[ bitsPerPixel ]; 38636747b715Smrg k = indexForScanlinePad[ scanlinepad ]; 38646747b715Smrg PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k]; 38656747b715Smrg PixmapWidthPaddingInfo[ depth ].padRoundUp = 38666747b715Smrg (scanlinepad/bitsPerPixel) - 1; 38676747b715Smrg j = indexForBitsPerPixel[ 8 ]; /* bits per byte */ 38686747b715Smrg PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k]; 38696747b715Smrg PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel; 38706747b715Smrg if (answerBytesPerPixel[bitsPerPixel]) 38716747b715Smrg { 38726747b715Smrg PixmapWidthPaddingInfo[ depth ].notPower2 = 1; 38736747b715Smrg PixmapWidthPaddingInfo[ depth ].bytesPerPixel = 38746747b715Smrg answerBytesPerPixel[bitsPerPixel]; 38756747b715Smrg } 38766747b715Smrg else 38776747b715Smrg { 38786747b715Smrg PixmapWidthPaddingInfo[ depth ].notPower2 = 0; 38796747b715Smrg } 38806747b715Smrg } 38816747b715Smrg 38826747b715Smrg /* This is where screen specific stuff gets initialized. Load the 38836747b715Smrg screen structure, call the hardware, whatever. 38846747b715Smrg This is also where the default colormap should be allocated and 38856747b715Smrg also pixel values for blackPixel, whitePixel, and the cursor 38866747b715Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 38876747b715Smrg any of the strings pointed to by argv. They may be passed to 38886747b715Smrg multiple screens. 38896747b715Smrg */ 38906747b715Smrg screenInfo.screens[i] = pScreen; 38916747b715Smrg screenInfo.numScreens++; 38926747b715Smrg if (!(*pfnInit)(i, pScreen, argc, argv)) 38936747b715Smrg { 38946747b715Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 38956747b715Smrg free(pScreen); 38966747b715Smrg screenInfo.numScreens--; 38976747b715Smrg return -1; 38986747b715Smrg } 38996747b715Smrg 39006747b715Smrg dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0); 39016747b715Smrg 39026747b715Smrg return i; 39036747b715Smrg} 3904