dispatch.c revision 9ace9065
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; 14214642e01fSmrg (*pDraw->pScreen->DestroyPixmap)(pMap); 142205b261ecSmrg } 14236747b715Smrg return BadAlloc; 142405b261ecSmrg} 142505b261ecSmrg 142605b261ecSmrgint 142705b261ecSmrgProcFreePixmap(ClientPtr client) 142805b261ecSmrg{ 142905b261ecSmrg PixmapPtr pMap; 14304642e01fSmrg int rc; 143105b261ecSmrg REQUEST(xResourceReq); 143205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 14334642e01fSmrg 1434b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client, 14354642e01fSmrg DixDestroyAccess); 14364642e01fSmrg if (rc == Success) 143705b261ecSmrg { 143805b261ecSmrg FreeResource(stuff->id, RT_NONE); 14396747b715Smrg return Success; 144005b261ecSmrg } 144105b261ecSmrg else 144205b261ecSmrg { 144305b261ecSmrg client->errorValue = stuff->id; 14446747b715Smrg return rc; 144505b261ecSmrg } 144605b261ecSmrg} 144705b261ecSmrg 144805b261ecSmrgint 144905b261ecSmrgProcCreateGC(ClientPtr client) 145005b261ecSmrg{ 145105b261ecSmrg int error, rc; 145205b261ecSmrg GC *pGC; 145305b261ecSmrg DrawablePtr pDraw; 145405b261ecSmrg unsigned len; 145505b261ecSmrg REQUEST(xCreateGCReq); 145605b261ecSmrg 145705b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateGCReq); 145805b261ecSmrg client->errorValue = stuff->gc; 145905b261ecSmrg LEGAL_NEW_RESOURCE(stuff->gc, client); 14604642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 14614642e01fSmrg DixGetAttrAccess); 146205b261ecSmrg if (rc != Success) 146305b261ecSmrg return rc; 146405b261ecSmrg 14656747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); 146605b261ecSmrg if (len != Ones(stuff->mask)) 146705b261ecSmrg return BadLength; 14684642e01fSmrg pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, 14694642e01fSmrg stuff->gc, client); 147005b261ecSmrg if (error != Success) 147105b261ecSmrg return error; 147205b261ecSmrg if (!AddResource(stuff->gc, RT_GC, (pointer)pGC)) 14736747b715Smrg return BadAlloc; 14746747b715Smrg return Success; 147505b261ecSmrg} 147605b261ecSmrg 147705b261ecSmrgint 147805b261ecSmrgProcChangeGC(ClientPtr client) 147905b261ecSmrg{ 148005b261ecSmrg GC *pGC; 148105b261ecSmrg int result; 148205b261ecSmrg unsigned len; 148305b261ecSmrg REQUEST(xChangeGCReq); 148405b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeGCReq); 148505b261ecSmrg 14864642e01fSmrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 148705b261ecSmrg if (result != Success) 148805b261ecSmrg return result; 148905b261ecSmrg 14906747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); 149105b261ecSmrg if (len != Ones(stuff->mask)) 149205b261ecSmrg return BadLength; 149305b261ecSmrg 14946747b715Smrg return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]); 149505b261ecSmrg} 149605b261ecSmrg 149705b261ecSmrgint 149805b261ecSmrgProcCopyGC(ClientPtr client) 149905b261ecSmrg{ 150005b261ecSmrg GC *dstGC; 150105b261ecSmrg GC *pGC; 150205b261ecSmrg int result; 150305b261ecSmrg REQUEST(xCopyGCReq); 150405b261ecSmrg REQUEST_SIZE_MATCH(xCopyGCReq); 150505b261ecSmrg 15064642e01fSmrg result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); 150705b261ecSmrg if (result != Success) 150805b261ecSmrg return result; 15094642e01fSmrg result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); 151005b261ecSmrg if (result != Success) 151105b261ecSmrg return result; 151205b261ecSmrg if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 15136747b715Smrg return BadMatch; 15146747b715Smrg if (stuff->mask & ~GCAllBits) 151505b261ecSmrg { 15166747b715Smrg client->errorValue = stuff->mask; 15176747b715Smrg return BadValue; 151805b261ecSmrg } 15196747b715Smrg return CopyGC(pGC, dstGC, stuff->mask); 152005b261ecSmrg} 152105b261ecSmrg 152205b261ecSmrgint 152305b261ecSmrgProcSetDashes(ClientPtr client) 152405b261ecSmrg{ 152505b261ecSmrg GC *pGC; 152605b261ecSmrg int result; 152705b261ecSmrg REQUEST(xSetDashesReq); 152805b261ecSmrg 152905b261ecSmrg REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 153005b261ecSmrg if (stuff->nDashes == 0) 153105b261ecSmrg { 153205b261ecSmrg client->errorValue = 0; 153305b261ecSmrg return BadValue; 153405b261ecSmrg } 153505b261ecSmrg 15364642e01fSmrg result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 153705b261ecSmrg if (result != Success) 153805b261ecSmrg return result; 153905b261ecSmrg 15406747b715Smrg /* If there's an error, either there's no sensible errorValue, 15416747b715Smrg * or there was a dash segment of 0. */ 15426747b715Smrg client->errorValue = 0; 15436747b715Smrg return SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 154405b261ecSmrg (unsigned char *)&stuff[1]); 154505b261ecSmrg} 154605b261ecSmrg 154705b261ecSmrgint 154805b261ecSmrgProcSetClipRectangles(ClientPtr client) 154905b261ecSmrg{ 155005b261ecSmrg int nr, result; 155105b261ecSmrg GC *pGC; 155205b261ecSmrg REQUEST(xSetClipRectanglesReq); 155305b261ecSmrg 155405b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 155505b261ecSmrg if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 155605b261ecSmrg (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) 155705b261ecSmrg { 155805b261ecSmrg client->errorValue = stuff->ordering; 155905b261ecSmrg return BadValue; 156005b261ecSmrg } 15614642e01fSmrg result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 156205b261ecSmrg if (result != Success) 156305b261ecSmrg return result; 156405b261ecSmrg 156505b261ecSmrg nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 156605b261ecSmrg if (nr & 4) 15676747b715Smrg return BadLength; 156805b261ecSmrg nr >>= 3; 15696747b715Smrg return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 157005b261ecSmrg nr, (xRectangle *)&stuff[1], (int)stuff->ordering); 157105b261ecSmrg} 157205b261ecSmrg 157305b261ecSmrgint 157405b261ecSmrgProcFreeGC(ClientPtr client) 157505b261ecSmrg{ 157605b261ecSmrg GC *pGC; 157705b261ecSmrg int rc; 157805b261ecSmrg REQUEST(xResourceReq); 157905b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 158005b261ecSmrg 158105b261ecSmrg rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 158205b261ecSmrg if (rc != Success) 158305b261ecSmrg return rc; 158405b261ecSmrg 158505b261ecSmrg FreeResource(stuff->id, RT_NONE); 15866747b715Smrg return Success; 158705b261ecSmrg} 158805b261ecSmrg 158905b261ecSmrgint 159005b261ecSmrgProcClearToBackground(ClientPtr client) 159105b261ecSmrg{ 159205b261ecSmrg REQUEST(xClearAreaReq); 159305b261ecSmrg WindowPtr pWin; 159405b261ecSmrg int rc; 159505b261ecSmrg 159605b261ecSmrg REQUEST_SIZE_MATCH(xClearAreaReq); 159705b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 159805b261ecSmrg if (rc != Success) 159905b261ecSmrg return rc; 160005b261ecSmrg if (pWin->drawable.class == InputOnly) 160105b261ecSmrg { 160205b261ecSmrg client->errorValue = stuff->window; 16036747b715Smrg return BadMatch; 160405b261ecSmrg } 160505b261ecSmrg if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) 160605b261ecSmrg { 160705b261ecSmrg client->errorValue = stuff->exposures; 16086747b715Smrg return BadValue; 160905b261ecSmrg } 161005b261ecSmrg (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y, 161105b261ecSmrg stuff->width, stuff->height, 161205b261ecSmrg (Bool)stuff->exposures); 16136747b715Smrg return Success; 161405b261ecSmrg} 161505b261ecSmrg 161605b261ecSmrgint 161705b261ecSmrgProcCopyArea(ClientPtr client) 161805b261ecSmrg{ 161905b261ecSmrg DrawablePtr pDst; 162005b261ecSmrg DrawablePtr pSrc; 162105b261ecSmrg GC *pGC; 162205b261ecSmrg REQUEST(xCopyAreaReq); 162305b261ecSmrg RegionPtr pRgn; 162405b261ecSmrg int rc; 162505b261ecSmrg 162605b261ecSmrg REQUEST_SIZE_MATCH(xCopyAreaReq); 162705b261ecSmrg 16284642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 162905b261ecSmrg if (stuff->dstDrawable != stuff->srcDrawable) 163005b261ecSmrg { 163105b261ecSmrg rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 163205b261ecSmrg DixReadAccess); 163305b261ecSmrg if (rc != Success) 163405b261ecSmrg return rc; 163505b261ecSmrg if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) 163605b261ecSmrg { 163705b261ecSmrg client->errorValue = stuff->dstDrawable; 16386747b715Smrg return BadMatch; 163905b261ecSmrg } 164005b261ecSmrg } 164105b261ecSmrg else 164205b261ecSmrg pSrc = pDst; 164305b261ecSmrg 164405b261ecSmrg pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 164505b261ecSmrg stuff->width, stuff->height, 164605b261ecSmrg stuff->dstX, stuff->dstY); 164705b261ecSmrg if (pGC->graphicsExposures) 164805b261ecSmrg { 164905b261ecSmrg (*pDst->pScreen->SendGraphicsExpose) 165005b261ecSmrg (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 165105b261ecSmrg if (pRgn) 16526747b715Smrg RegionDestroy(pRgn); 165305b261ecSmrg } 165405b261ecSmrg 16556747b715Smrg return Success; 165605b261ecSmrg} 165705b261ecSmrg 165805b261ecSmrgint 165905b261ecSmrgProcCopyPlane(ClientPtr client) 166005b261ecSmrg{ 166105b261ecSmrg DrawablePtr psrcDraw, pdstDraw; 166205b261ecSmrg GC *pGC; 166305b261ecSmrg REQUEST(xCopyPlaneReq); 166405b261ecSmrg RegionPtr pRgn; 166505b261ecSmrg int rc; 166605b261ecSmrg 166705b261ecSmrg REQUEST_SIZE_MATCH(xCopyPlaneReq); 166805b261ecSmrg 16694642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); 167005b261ecSmrg if (stuff->dstDrawable != stuff->srcDrawable) 167105b261ecSmrg { 167205b261ecSmrg rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 167305b261ecSmrg DixReadAccess); 167405b261ecSmrg if (rc != Success) 167505b261ecSmrg return rc; 167605b261ecSmrg 167705b261ecSmrg if (pdstDraw->pScreen != psrcDraw->pScreen) 167805b261ecSmrg { 167905b261ecSmrg client->errorValue = stuff->dstDrawable; 16806747b715Smrg return BadMatch; 168105b261ecSmrg } 168205b261ecSmrg } 168305b261ecSmrg else 168405b261ecSmrg psrcDraw = pdstDraw; 168505b261ecSmrg 168605b261ecSmrg /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 168705b261ecSmrg if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 168805b261ecSmrg (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) 168905b261ecSmrg { 169005b261ecSmrg client->errorValue = stuff->bitPlane; 16916747b715Smrg return BadValue; 169205b261ecSmrg } 169305b261ecSmrg 169405b261ecSmrg pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, 169505b261ecSmrg stuff->width, stuff->height, 169605b261ecSmrg stuff->dstX, stuff->dstY, stuff->bitPlane); 169705b261ecSmrg if (pGC->graphicsExposures) 169805b261ecSmrg { 169905b261ecSmrg (*pdstDraw->pScreen->SendGraphicsExpose) 170005b261ecSmrg (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 170105b261ecSmrg if (pRgn) 17026747b715Smrg RegionDestroy(pRgn); 170305b261ecSmrg } 17046747b715Smrg return Success; 170505b261ecSmrg} 170605b261ecSmrg 170705b261ecSmrgint 170805b261ecSmrgProcPolyPoint(ClientPtr client) 170905b261ecSmrg{ 171005b261ecSmrg int npoint; 171105b261ecSmrg GC *pGC; 171205b261ecSmrg DrawablePtr pDraw; 171305b261ecSmrg REQUEST(xPolyPointReq); 171405b261ecSmrg 171505b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyPointReq); 171605b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 171705b261ecSmrg (stuff->coordMode != CoordModePrevious)) 171805b261ecSmrg { 171905b261ecSmrg client->errorValue = stuff->coordMode; 172005b261ecSmrg return BadValue; 172105b261ecSmrg } 17224642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 17236747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); 172405b261ecSmrg if (npoint) 172505b261ecSmrg (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, 172605b261ecSmrg (xPoint *) &stuff[1]); 17276747b715Smrg return Success; 172805b261ecSmrg} 172905b261ecSmrg 173005b261ecSmrgint 173105b261ecSmrgProcPolyLine(ClientPtr client) 173205b261ecSmrg{ 173305b261ecSmrg int npoint; 173405b261ecSmrg GC *pGC; 173505b261ecSmrg DrawablePtr pDraw; 173605b261ecSmrg REQUEST(xPolyLineReq); 173705b261ecSmrg 173805b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyLineReq); 173905b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 174005b261ecSmrg (stuff->coordMode != CoordModePrevious)) 174105b261ecSmrg { 174205b261ecSmrg client->errorValue = stuff->coordMode; 174305b261ecSmrg return BadValue; 174405b261ecSmrg } 17454642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 17466747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); 174705b261ecSmrg if (npoint > 1) 174805b261ecSmrg (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 174905b261ecSmrg (DDXPointPtr) &stuff[1]); 17506747b715Smrg return Success; 175105b261ecSmrg} 175205b261ecSmrg 175305b261ecSmrgint 175405b261ecSmrgProcPolySegment(ClientPtr client) 175505b261ecSmrg{ 175605b261ecSmrg int nsegs; 175705b261ecSmrg GC *pGC; 175805b261ecSmrg DrawablePtr pDraw; 175905b261ecSmrg REQUEST(xPolySegmentReq); 176005b261ecSmrg 176105b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 17624642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 176305b261ecSmrg nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 176405b261ecSmrg if (nsegs & 4) 17656747b715Smrg return BadLength; 176605b261ecSmrg nsegs >>= 3; 176705b261ecSmrg if (nsegs) 176805b261ecSmrg (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 17696747b715Smrg return Success; 177005b261ecSmrg} 177105b261ecSmrg 177205b261ecSmrgint 177305b261ecSmrgProcPolyRectangle (ClientPtr client) 177405b261ecSmrg{ 177505b261ecSmrg int nrects; 177605b261ecSmrg GC *pGC; 177705b261ecSmrg DrawablePtr pDraw; 177805b261ecSmrg REQUEST(xPolyRectangleReq); 177905b261ecSmrg 178005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 17814642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 178205b261ecSmrg nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 178305b261ecSmrg if (nrects & 4) 17846747b715Smrg return BadLength; 178505b261ecSmrg nrects >>= 3; 178605b261ecSmrg if (nrects) 178705b261ecSmrg (*pGC->ops->PolyRectangle)(pDraw, pGC, 178805b261ecSmrg nrects, (xRectangle *) &stuff[1]); 17896747b715Smrg return Success; 179005b261ecSmrg} 179105b261ecSmrg 179205b261ecSmrgint 179305b261ecSmrgProcPolyArc(ClientPtr client) 179405b261ecSmrg{ 179505b261ecSmrg int narcs; 179605b261ecSmrg GC *pGC; 179705b261ecSmrg DrawablePtr pDraw; 179805b261ecSmrg REQUEST(xPolyArcReq); 179905b261ecSmrg 180005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyArcReq); 18014642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 180205b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 180305b261ecSmrg if (narcs % sizeof(xArc)) 18046747b715Smrg return BadLength; 180505b261ecSmrg narcs /= sizeof(xArc); 180605b261ecSmrg if (narcs) 180705b261ecSmrg (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]); 18086747b715Smrg return Success; 180905b261ecSmrg} 181005b261ecSmrg 181105b261ecSmrgint 181205b261ecSmrgProcFillPoly(ClientPtr client) 181305b261ecSmrg{ 181405b261ecSmrg int things; 181505b261ecSmrg GC *pGC; 181605b261ecSmrg DrawablePtr pDraw; 181705b261ecSmrg REQUEST(xFillPolyReq); 181805b261ecSmrg 181905b261ecSmrg REQUEST_AT_LEAST_SIZE(xFillPolyReq); 182005b261ecSmrg if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 182105b261ecSmrg (stuff->shape != Convex)) 182205b261ecSmrg { 182305b261ecSmrg client->errorValue = stuff->shape; 182405b261ecSmrg return BadValue; 182505b261ecSmrg } 182605b261ecSmrg if ((stuff->coordMode != CoordModeOrigin) && 182705b261ecSmrg (stuff->coordMode != CoordModePrevious)) 182805b261ecSmrg { 182905b261ecSmrg client->errorValue = stuff->coordMode; 183005b261ecSmrg return BadValue; 183105b261ecSmrg } 183205b261ecSmrg 18334642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 18346747b715Smrg things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); 183505b261ecSmrg if (things) 183605b261ecSmrg (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 183705b261ecSmrg stuff->coordMode, things, 183805b261ecSmrg (DDXPointPtr) &stuff[1]); 18396747b715Smrg return Success; 184005b261ecSmrg} 184105b261ecSmrg 184205b261ecSmrgint 184305b261ecSmrgProcPolyFillRectangle(ClientPtr client) 184405b261ecSmrg{ 184505b261ecSmrg int things; 184605b261ecSmrg GC *pGC; 184705b261ecSmrg DrawablePtr pDraw; 184805b261ecSmrg REQUEST(xPolyFillRectangleReq); 184905b261ecSmrg 185005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 18514642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 185205b261ecSmrg things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 185305b261ecSmrg if (things & 4) 18546747b715Smrg return BadLength; 185505b261ecSmrg things >>= 3; 185605b261ecSmrg 185705b261ecSmrg if (things) 185805b261ecSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 185905b261ecSmrg (xRectangle *) &stuff[1]); 18606747b715Smrg return Success; 186105b261ecSmrg} 186205b261ecSmrg 186305b261ecSmrgint 186405b261ecSmrgProcPolyFillArc(ClientPtr client) 186505b261ecSmrg{ 186605b261ecSmrg int narcs; 186705b261ecSmrg GC *pGC; 186805b261ecSmrg DrawablePtr pDraw; 186905b261ecSmrg REQUEST(xPolyFillArcReq); 187005b261ecSmrg 187105b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 18724642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 187305b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 187405b261ecSmrg if (narcs % sizeof(xArc)) 18756747b715Smrg return BadLength; 187605b261ecSmrg narcs /= sizeof(xArc); 187705b261ecSmrg if (narcs) 187805b261ecSmrg (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 18796747b715Smrg return Success; 188005b261ecSmrg} 188105b261ecSmrg 188205b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 188305b261ecSmrg 188405b261ecSmrgint 188505b261ecSmrgServerOrder (void) 188605b261ecSmrg{ 188705b261ecSmrg int whichbyte = 1; 188805b261ecSmrg 188905b261ecSmrg if (*((char *) &whichbyte)) 189005b261ecSmrg return LSBFirst; 189105b261ecSmrg return MSBFirst; 189205b261ecSmrg} 189305b261ecSmrg 189405b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 189505b261ecSmrg 189605b261ecSmrgvoid 189705b261ecSmrgReformatImage (char *base, int nbytes, int bpp, int order) 189805b261ecSmrg{ 189905b261ecSmrg switch (bpp) { 190005b261ecSmrg case 1: /* yuck */ 190105b261ecSmrg if (BITMAP_BIT_ORDER != order) 190205b261ecSmrg BitOrderInvert ((unsigned char *) base, nbytes); 190305b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 190405b261ecSmrg ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order); 190505b261ecSmrg#endif 190605b261ecSmrg break; 190705b261ecSmrg case 4: 190805b261ecSmrg break; /* yuck */ 190905b261ecSmrg case 8: 191005b261ecSmrg break; 191105b261ecSmrg case 16: 191205b261ecSmrg if (IMAGE_BYTE_ORDER != order) 191305b261ecSmrg TwoByteSwap ((unsigned char *) base, nbytes); 191405b261ecSmrg break; 191505b261ecSmrg case 32: 191605b261ecSmrg if (IMAGE_BYTE_ORDER != order) 191705b261ecSmrg FourByteSwap ((unsigned char *) base, nbytes); 191805b261ecSmrg break; 191905b261ecSmrg } 192005b261ecSmrg} 192105b261ecSmrg#else 192205b261ecSmrg#define ReformatImage(b,n,bpp,o) 192305b261ecSmrg#endif 192405b261ecSmrg 192505b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to 192605b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 192705b261ecSmrg * to use internally. Removes need for internal alignment checking. 192805b261ecSmrg * All of the PutImage functions could be changed individually, but 192905b261ecSmrg * as currently written, they call other routines which require things 193005b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here. 193105b261ecSmrg * If an image would be padded differently for 64- versus 32-, then 193205b261ecSmrg * copy each scanline to a 64-bit padded scanline. 193305b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit 193405b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction. 193505b261ecSmrg */ 193605b261ecSmrgint 193705b261ecSmrgProcPutImage(ClientPtr client) 193805b261ecSmrg{ 193905b261ecSmrg GC *pGC; 194005b261ecSmrg DrawablePtr pDraw; 194105b261ecSmrg long length; /* length of scanline server padded */ 194205b261ecSmrg long lengthProto; /* length of scanline protocol padded */ 194305b261ecSmrg char *tmpImage; 194405b261ecSmrg REQUEST(xPutImageReq); 194505b261ecSmrg 194605b261ecSmrg REQUEST_AT_LEAST_SIZE(xPutImageReq); 19474642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 194805b261ecSmrg if (stuff->format == XYBitmap) 194905b261ecSmrg { 195005b261ecSmrg if ((stuff->depth != 1) || 195105b261ecSmrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 195205b261ecSmrg return BadMatch; 195305b261ecSmrg length = BitmapBytePad(stuff->width + stuff->leftPad); 195405b261ecSmrg } 195505b261ecSmrg else if (stuff->format == XYPixmap) 195605b261ecSmrg { 195705b261ecSmrg if ((pDraw->depth != stuff->depth) || 195805b261ecSmrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 195905b261ecSmrg return BadMatch; 196005b261ecSmrg length = BitmapBytePad(stuff->width + stuff->leftPad); 196105b261ecSmrg length *= stuff->depth; 196205b261ecSmrg } 196305b261ecSmrg else if (stuff->format == ZPixmap) 196405b261ecSmrg { 196505b261ecSmrg if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 196605b261ecSmrg return BadMatch; 196705b261ecSmrg length = PixmapBytePad(stuff->width, stuff->depth); 196805b261ecSmrg } 196905b261ecSmrg else 197005b261ecSmrg { 197105b261ecSmrg client->errorValue = stuff->format; 197205b261ecSmrg return BadValue; 197305b261ecSmrg } 197405b261ecSmrg 197505b261ecSmrg tmpImage = (char *)&stuff[1]; 197605b261ecSmrg lengthProto = length; 197705b261ecSmrg 19786747b715Smrg if ((bytes_to_int32(lengthProto * stuff->height) + 19796747b715Smrg bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) 198005b261ecSmrg return BadLength; 198105b261ecSmrg 198205b261ecSmrg ReformatImage (tmpImage, lengthProto * stuff->height, 198305b261ecSmrg stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1, 198405b261ecSmrg ClientOrder(client)); 198505b261ecSmrg 198605b261ecSmrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 198705b261ecSmrg stuff->width, stuff->height, 198805b261ecSmrg stuff->leftPad, stuff->format, tmpImage); 198905b261ecSmrg 19906747b715Smrg return Success; 199105b261ecSmrg} 199205b261ecSmrg 199305b261ecSmrgstatic int 199405b261ecSmrgDoGetImage(ClientPtr client, int format, Drawable drawable, 199505b261ecSmrg int x, int y, int width, int height, 199605b261ecSmrg Mask planemask, xGetImageReply **im_return) 199705b261ecSmrg{ 19986747b715Smrg DrawablePtr pDraw, pBoundingDraw; 199905b261ecSmrg int nlines, linesPerBuf, rc; 20006747b715Smrg int linesDone; 20016747b715Smrg /* coordinates relative to the bounding drawable */ 20026747b715Smrg int relx, rely; 200305b261ecSmrg long widthBytesLine, length; 200405b261ecSmrg Mask plane = 0; 200505b261ecSmrg char *pBuf; 200605b261ecSmrg xGetImageReply xgi; 200705b261ecSmrg RegionPtr pVisibleRegion = NULL; 200805b261ecSmrg 200905b261ecSmrg if ((format != XYPixmap) && (format != ZPixmap)) 201005b261ecSmrg { 201105b261ecSmrg client->errorValue = format; 20126747b715Smrg return BadValue; 201305b261ecSmrg } 201405b261ecSmrg rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 201505b261ecSmrg if (rc != Success) 201605b261ecSmrg return rc; 201705b261ecSmrg 20186747b715Smrg memset(&xgi, 0, sizeof(xGetImageReply)); 20196747b715Smrg 20206747b715Smrg relx = x; 20216747b715Smrg rely = y; 20226747b715Smrg 202305b261ecSmrg if(pDraw->type == DRAWABLE_WINDOW) 202405b261ecSmrg { 20256747b715Smrg WindowPtr pWin = (WindowPtr)pDraw; 20266747b715Smrg 20276747b715Smrg /* "If the drawable is a window, the window must be viewable ... or a 20286747b715Smrg * BadMatch error results" */ 20296747b715Smrg if (!pWin->viewable) 20306747b715Smrg return BadMatch; 20316747b715Smrg 20326747b715Smrg relx += pDraw->x; 20336747b715Smrg rely += pDraw->y; 20346747b715Smrg 20356747b715Smrg if (pDraw->pScreen->GetWindowPixmap) { 20366747b715Smrg PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); 20376747b715Smrg 20386747b715Smrg pBoundingDraw = &pPix->drawable; 20396747b715Smrg#ifdef COMPOSITE 20406747b715Smrg relx -= pPix->screen_x; 20416747b715Smrg rely -= pPix->screen_y; 20426747b715Smrg#endif 20436747b715Smrg } 20446747b715Smrg else 20456747b715Smrg { 20466747b715Smrg pBoundingDraw = (DrawablePtr)pDraw->pScreen->root; 20476747b715Smrg } 20486747b715Smrg 20496747b715Smrg xgi.visual = wVisual (pWin); 205005b261ecSmrg } 205105b261ecSmrg else 205205b261ecSmrg { 20536747b715Smrg pBoundingDraw = pDraw; 205405b261ecSmrg xgi.visual = None; 205505b261ecSmrg } 205605b261ecSmrg 20576747b715Smrg /* "If the drawable is a pixmap, the given rectangle must be wholly 20586747b715Smrg * contained within the pixmap, or a BadMatch error results. If the 20596747b715Smrg * drawable is a window [...] it must be the case that if there were no 20606747b715Smrg * inferiors or overlapping windows, the specified rectangle of the window 20616747b715Smrg * would be fully visible on the screen and wholly contained within the 20626747b715Smrg * outside edges of the window, or a BadMatch error results." 20636747b715Smrg * 20646747b715Smrg * We relax the window case slightly to mean that the rectangle must exist 20656747b715Smrg * within the bounds of the window's backing pixmap. In particular, this 20666747b715Smrg * means that a GetImage request may succeed or fail with BadMatch depending 20676747b715Smrg * on whether any of its ancestor windows are redirected. */ 20686747b715Smrg if(relx < 0 || relx + width > (int)pBoundingDraw->width || 20696747b715Smrg rely < 0 || rely + height > (int)pBoundingDraw->height) 20706747b715Smrg return BadMatch; 20716747b715Smrg 207205b261ecSmrg xgi.type = X_Reply; 207305b261ecSmrg xgi.sequenceNumber = client->sequence; 207405b261ecSmrg xgi.depth = pDraw->depth; 207505b261ecSmrg if(format == ZPixmap) 207605b261ecSmrg { 207705b261ecSmrg widthBytesLine = PixmapBytePad(width, pDraw->depth); 207805b261ecSmrg length = widthBytesLine * height; 207905b261ecSmrg 208005b261ecSmrg } 208105b261ecSmrg else 208205b261ecSmrg { 208305b261ecSmrg widthBytesLine = BitmapBytePad(width); 208405b261ecSmrg plane = ((Mask)1) << (pDraw->depth - 1); 208505b261ecSmrg /* only planes asked for */ 208605b261ecSmrg length = widthBytesLine * height * 208705b261ecSmrg Ones(planemask & (plane | (plane - 1))); 208805b261ecSmrg 208905b261ecSmrg } 209005b261ecSmrg 209105b261ecSmrg xgi.length = length; 209205b261ecSmrg 209305b261ecSmrg if (im_return) { 20946747b715Smrg pBuf = calloc(1, sz_xGetImageReply + length); 209505b261ecSmrg if (!pBuf) 20966747b715Smrg return BadAlloc; 209705b261ecSmrg if (widthBytesLine == 0) 209805b261ecSmrg linesPerBuf = 0; 209905b261ecSmrg else 210005b261ecSmrg linesPerBuf = height; 210105b261ecSmrg *im_return = (xGetImageReply *)pBuf; 210205b261ecSmrg *(xGetImageReply *)pBuf = xgi; 210305b261ecSmrg pBuf += sz_xGetImageReply; 210405b261ecSmrg } else { 21056747b715Smrg xgi.length = bytes_to_int32(xgi.length); 210605b261ecSmrg if (widthBytesLine == 0 || height == 0) 210705b261ecSmrg linesPerBuf = 0; 210805b261ecSmrg else if (widthBytesLine >= IMAGE_BUFSIZE) 210905b261ecSmrg linesPerBuf = 1; 211005b261ecSmrg else 211105b261ecSmrg { 211205b261ecSmrg linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 211305b261ecSmrg if (linesPerBuf > height) 211405b261ecSmrg linesPerBuf = height; 211505b261ecSmrg } 211605b261ecSmrg length = linesPerBuf * widthBytesLine; 211705b261ecSmrg if (linesPerBuf < height) 211805b261ecSmrg { 211905b261ecSmrg /* we have to make sure intermediate buffers don't need padding */ 212005b261ecSmrg while ((linesPerBuf > 1) && 212105b261ecSmrg (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))) 212205b261ecSmrg { 212305b261ecSmrg linesPerBuf--; 212405b261ecSmrg length -= widthBytesLine; 212505b261ecSmrg } 212605b261ecSmrg while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)) 212705b261ecSmrg { 212805b261ecSmrg linesPerBuf++; 212905b261ecSmrg length += widthBytesLine; 213005b261ecSmrg } 213105b261ecSmrg } 21326747b715Smrg if(!(pBuf = calloc(1, length))) 21336747b715Smrg return BadAlloc; 213405b261ecSmrg WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); 213505b261ecSmrg } 213605b261ecSmrg 21374642e01fSmrg if (pDraw->type == DRAWABLE_WINDOW) 213805b261ecSmrg { 213905b261ecSmrg pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); 214005b261ecSmrg if (pVisibleRegion) 214105b261ecSmrg { 21426747b715Smrg RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y); 214305b261ecSmrg } 214405b261ecSmrg } 214505b261ecSmrg 214605b261ecSmrg if (linesPerBuf == 0) 214705b261ecSmrg { 214805b261ecSmrg /* nothing to do */ 214905b261ecSmrg } 215005b261ecSmrg else if (format == ZPixmap) 215105b261ecSmrg { 215205b261ecSmrg linesDone = 0; 215305b261ecSmrg while (height - linesDone > 0) 215405b261ecSmrg { 215505b261ecSmrg nlines = min(linesPerBuf, height - linesDone); 215605b261ecSmrg (*pDraw->pScreen->GetImage) (pDraw, 215705b261ecSmrg x, 215805b261ecSmrg y + linesDone, 215905b261ecSmrg width, 216005b261ecSmrg nlines, 216105b261ecSmrg format, 216205b261ecSmrg planemask, 216305b261ecSmrg (pointer) pBuf); 216405b261ecSmrg if (pVisibleRegion) 216505b261ecSmrg XaceCensorImage(client, pVisibleRegion, widthBytesLine, 216605b261ecSmrg pDraw, x, y + linesDone, width, 216705b261ecSmrg nlines, format, pBuf); 216805b261ecSmrg 216905b261ecSmrg /* Note that this is NOT a call to WriteSwappedDataToClient, 217005b261ecSmrg as we do NOT byte swap */ 217105b261ecSmrg if (!im_return) 217205b261ecSmrg { 217305b261ecSmrg ReformatImage (pBuf, (int)(nlines * widthBytesLine), 217405b261ecSmrg BitsPerPixel (pDraw->depth), 217505b261ecSmrg ClientOrder(client)); 217605b261ecSmrg 217705b261ecSmrg/* Don't split me, gcc pukes when you do */ 217805b261ecSmrg (void)WriteToClient(client, 217905b261ecSmrg (int)(nlines * widthBytesLine), 218005b261ecSmrg pBuf); 218105b261ecSmrg } 218205b261ecSmrg linesDone += nlines; 218305b261ecSmrg } 218405b261ecSmrg } 218505b261ecSmrg else /* XYPixmap */ 218605b261ecSmrg { 218705b261ecSmrg for (; plane; plane >>= 1) 218805b261ecSmrg { 218905b261ecSmrg if (planemask & plane) 219005b261ecSmrg { 219105b261ecSmrg linesDone = 0; 219205b261ecSmrg while (height - linesDone > 0) 219305b261ecSmrg { 219405b261ecSmrg nlines = min(linesPerBuf, height - linesDone); 219505b261ecSmrg (*pDraw->pScreen->GetImage) (pDraw, 219605b261ecSmrg x, 219705b261ecSmrg y + linesDone, 219805b261ecSmrg width, 219905b261ecSmrg nlines, 220005b261ecSmrg format, 220105b261ecSmrg plane, 220205b261ecSmrg (pointer)pBuf); 220305b261ecSmrg if (pVisibleRegion) 220405b261ecSmrg XaceCensorImage(client, pVisibleRegion, 220505b261ecSmrg widthBytesLine, 220605b261ecSmrg pDraw, x, y + linesDone, width, 220705b261ecSmrg nlines, format, pBuf); 220805b261ecSmrg 220905b261ecSmrg /* Note: NOT a call to WriteSwappedDataToClient, 221005b261ecSmrg as we do NOT byte swap */ 221105b261ecSmrg if (im_return) { 221205b261ecSmrg pBuf += nlines * widthBytesLine; 221305b261ecSmrg } else { 221405b261ecSmrg ReformatImage (pBuf, 221505b261ecSmrg (int)(nlines * widthBytesLine), 221605b261ecSmrg 1, 221705b261ecSmrg ClientOrder (client)); 221805b261ecSmrg 221905b261ecSmrg/* Don't split me, gcc pukes when you do */ 222005b261ecSmrg (void)WriteToClient(client, 222105b261ecSmrg (int)(nlines * widthBytesLine), 222205b261ecSmrg pBuf); 222305b261ecSmrg } 222405b261ecSmrg linesDone += nlines; 222505b261ecSmrg } 222605b261ecSmrg } 222705b261ecSmrg } 222805b261ecSmrg } 222905b261ecSmrg if (pVisibleRegion) 22306747b715Smrg RegionDestroy(pVisibleRegion); 223105b261ecSmrg if (!im_return) 22326747b715Smrg free(pBuf); 22336747b715Smrg return Success; 223405b261ecSmrg} 223505b261ecSmrg 223605b261ecSmrgint 223705b261ecSmrgProcGetImage(ClientPtr client) 223805b261ecSmrg{ 223905b261ecSmrg REQUEST(xGetImageReq); 224005b261ecSmrg 224105b261ecSmrg REQUEST_SIZE_MATCH(xGetImageReq); 224205b261ecSmrg 224305b261ecSmrg return DoGetImage(client, stuff->format, stuff->drawable, 224405b261ecSmrg stuff->x, stuff->y, 224505b261ecSmrg (int)stuff->width, (int)stuff->height, 224605b261ecSmrg stuff->planeMask, (xGetImageReply **)NULL); 224705b261ecSmrg} 224805b261ecSmrg 224905b261ecSmrgint 225005b261ecSmrgProcPolyText(ClientPtr client) 225105b261ecSmrg{ 225205b261ecSmrg int err; 225305b261ecSmrg REQUEST(xPolyTextReq); 225405b261ecSmrg DrawablePtr pDraw; 225505b261ecSmrg GC *pGC; 225605b261ecSmrg 225705b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyTextReq); 22584642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 225905b261ecSmrg 226005b261ecSmrg err = PolyText(client, 226105b261ecSmrg pDraw, 226205b261ecSmrg pGC, 226305b261ecSmrg (unsigned char *)&stuff[1], 226405b261ecSmrg ((unsigned char *) stuff) + (client->req_len << 2), 226505b261ecSmrg stuff->x, 226605b261ecSmrg stuff->y, 226705b261ecSmrg stuff->reqType, 226805b261ecSmrg stuff->drawable); 226905b261ecSmrg 227005b261ecSmrg if (err == Success) 227105b261ecSmrg { 22726747b715Smrg return Success; 227305b261ecSmrg } 227405b261ecSmrg else 227505b261ecSmrg return err; 227605b261ecSmrg} 227705b261ecSmrg 227805b261ecSmrgint 227905b261ecSmrgProcImageText8(ClientPtr client) 228005b261ecSmrg{ 228105b261ecSmrg int err; 228205b261ecSmrg DrawablePtr pDraw; 228305b261ecSmrg GC *pGC; 228405b261ecSmrg 228505b261ecSmrg REQUEST(xImageTextReq); 228605b261ecSmrg 228705b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 22884642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 228905b261ecSmrg 229005b261ecSmrg err = ImageText(client, 229105b261ecSmrg pDraw, 229205b261ecSmrg pGC, 229305b261ecSmrg stuff->nChars, 229405b261ecSmrg (unsigned char *)&stuff[1], 229505b261ecSmrg stuff->x, 229605b261ecSmrg stuff->y, 229705b261ecSmrg stuff->reqType, 229805b261ecSmrg stuff->drawable); 229905b261ecSmrg 230005b261ecSmrg if (err == Success) 230105b261ecSmrg { 23026747b715Smrg return Success; 230305b261ecSmrg } 230405b261ecSmrg else 230505b261ecSmrg return err; 230605b261ecSmrg} 230705b261ecSmrg 230805b261ecSmrgint 230905b261ecSmrgProcImageText16(ClientPtr client) 231005b261ecSmrg{ 231105b261ecSmrg int err; 231205b261ecSmrg DrawablePtr pDraw; 231305b261ecSmrg GC *pGC; 231405b261ecSmrg 231505b261ecSmrg REQUEST(xImageTextReq); 231605b261ecSmrg 231705b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 23184642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 231905b261ecSmrg 232005b261ecSmrg err = ImageText(client, 232105b261ecSmrg pDraw, 232205b261ecSmrg pGC, 232305b261ecSmrg stuff->nChars, 232405b261ecSmrg (unsigned char *)&stuff[1], 232505b261ecSmrg stuff->x, 232605b261ecSmrg stuff->y, 232705b261ecSmrg stuff->reqType, 232805b261ecSmrg stuff->drawable); 232905b261ecSmrg 233005b261ecSmrg if (err == Success) 233105b261ecSmrg { 23326747b715Smrg return Success; 233305b261ecSmrg } 233405b261ecSmrg else 233505b261ecSmrg return err; 233605b261ecSmrg} 233705b261ecSmrg 233805b261ecSmrg 233905b261ecSmrgint 234005b261ecSmrgProcCreateColormap(ClientPtr client) 234105b261ecSmrg{ 234205b261ecSmrg VisualPtr pVisual; 234305b261ecSmrg ColormapPtr pmap; 234405b261ecSmrg Colormap mid; 234505b261ecSmrg WindowPtr pWin; 234605b261ecSmrg ScreenPtr pScreen; 234705b261ecSmrg REQUEST(xCreateColormapReq); 234805b261ecSmrg int i, result; 234905b261ecSmrg 235005b261ecSmrg REQUEST_SIZE_MATCH(xCreateColormapReq); 235105b261ecSmrg 235205b261ecSmrg if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) 235305b261ecSmrg { 235405b261ecSmrg client->errorValue = stuff->alloc; 23556747b715Smrg return BadValue; 235605b261ecSmrg } 235705b261ecSmrg mid = stuff->mid; 235805b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 23594642e01fSmrg result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 236005b261ecSmrg if (result != Success) 236105b261ecSmrg return result; 236205b261ecSmrg 236305b261ecSmrg pScreen = pWin->drawable.pScreen; 236405b261ecSmrg for (i = 0, pVisual = pScreen->visuals; 236505b261ecSmrg i < pScreen->numVisuals; 236605b261ecSmrg i++, pVisual++) 236705b261ecSmrg { 236805b261ecSmrg if (pVisual->vid != stuff->visual) 236905b261ecSmrg continue; 23706747b715Smrg return CreateColormap(mid, pScreen, pVisual, &pmap, 237105b261ecSmrg (int)stuff->alloc, client->index); 237205b261ecSmrg } 237305b261ecSmrg client->errorValue = stuff->visual; 23746747b715Smrg return BadMatch; 237505b261ecSmrg} 237605b261ecSmrg 237705b261ecSmrgint 237805b261ecSmrgProcFreeColormap(ClientPtr client) 237905b261ecSmrg{ 238005b261ecSmrg ColormapPtr pmap; 23814642e01fSmrg int rc; 238205b261ecSmrg REQUEST(xResourceReq); 238305b261ecSmrg 238405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 2385b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client, 23864642e01fSmrg DixDestroyAccess); 23874642e01fSmrg if (rc == Success) 238805b261ecSmrg { 238905b261ecSmrg /* Freeing a default colormap is a no-op */ 239005b261ecSmrg if (!(pmap->flags & IsDefault)) 239105b261ecSmrg FreeResource(stuff->id, RT_NONE); 23926747b715Smrg return Success; 239305b261ecSmrg } 239405b261ecSmrg else 239505b261ecSmrg { 239605b261ecSmrg client->errorValue = stuff->id; 23976747b715Smrg return rc; 239805b261ecSmrg } 239905b261ecSmrg} 240005b261ecSmrg 240105b261ecSmrg 240205b261ecSmrgint 240305b261ecSmrgProcCopyColormapAndFree(ClientPtr client) 240405b261ecSmrg{ 240505b261ecSmrg Colormap mid; 240605b261ecSmrg ColormapPtr pSrcMap; 240705b261ecSmrg REQUEST(xCopyColormapAndFreeReq); 24084642e01fSmrg int rc; 240905b261ecSmrg 241005b261ecSmrg REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 241105b261ecSmrg mid = stuff->mid; 241205b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 2413b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP, 24144642e01fSmrg client, DixReadAccess|DixRemoveAccess); 24154642e01fSmrg if (rc == Success) 24166747b715Smrg return CopyColormapAndFree(mid, pSrcMap, client->index); 24176747b715Smrg client->errorValue = stuff->srcCmap; 24186747b715Smrg return rc; 241905b261ecSmrg} 242005b261ecSmrg 242105b261ecSmrgint 242205b261ecSmrgProcInstallColormap(ClientPtr client) 242305b261ecSmrg{ 242405b261ecSmrg ColormapPtr pcmp; 24254642e01fSmrg int rc; 242605b261ecSmrg REQUEST(xResourceReq); 242705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24284642e01fSmrg 2429b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 24304642e01fSmrg DixInstallAccess); 24314642e01fSmrg if (rc != Success) 24324642e01fSmrg goto out; 24334642e01fSmrg 24344642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 24356747b715Smrg if (rc != Success) { 24366747b715Smrg if (rc == BadValue) 24376747b715Smrg rc = BadColor; 24384642e01fSmrg goto out; 24396747b715Smrg } 24404642e01fSmrg 24414642e01fSmrg (*(pcmp->pScreen->InstallColormap)) (pcmp); 24426747b715Smrg return Success; 24434642e01fSmrg 24444642e01fSmrgout: 24454642e01fSmrg client->errorValue = stuff->id; 24466747b715Smrg return rc; 244705b261ecSmrg} 244805b261ecSmrg 244905b261ecSmrgint 245005b261ecSmrgProcUninstallColormap(ClientPtr client) 245105b261ecSmrg{ 245205b261ecSmrg ColormapPtr pcmp; 24534642e01fSmrg int rc; 245405b261ecSmrg REQUEST(xResourceReq); 245505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24564642e01fSmrg 2457b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 24584642e01fSmrg DixUninstallAccess); 24594642e01fSmrg if (rc != Success) 24604642e01fSmrg goto out; 24614642e01fSmrg 24624642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 24636747b715Smrg if (rc != Success) { 24646747b715Smrg if (rc == BadValue) 24656747b715Smrg rc = BadColor; 24664642e01fSmrg goto out; 24676747b715Smrg } 24684642e01fSmrg 24694642e01fSmrg if(pcmp->mid != pcmp->pScreen->defColormap) 24704642e01fSmrg (*(pcmp->pScreen->UninstallColormap)) (pcmp); 24716747b715Smrg return Success; 24724642e01fSmrg 24734642e01fSmrgout: 24744642e01fSmrg client->errorValue = stuff->id; 24756747b715Smrg return rc; 247605b261ecSmrg} 247705b261ecSmrg 247805b261ecSmrgint 247905b261ecSmrgProcListInstalledColormaps(ClientPtr client) 248005b261ecSmrg{ 248105b261ecSmrg xListInstalledColormapsReply *preply; 248205b261ecSmrg int nummaps, rc; 248305b261ecSmrg WindowPtr pWin; 248405b261ecSmrg REQUEST(xResourceReq); 248505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24864642e01fSmrg 24874642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 248805b261ecSmrg if (rc != Success) 24896747b715Smrg return rc; 24904642e01fSmrg 24914642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 24924642e01fSmrg DixGetAttrAccess); 24934642e01fSmrg if (rc != Success) 24946747b715Smrg return rc; 249505b261ecSmrg 24966747b715Smrg preply = malloc(sizeof(xListInstalledColormapsReply) + 249705b261ecSmrg pWin->drawable.pScreen->maxInstalledCmaps * 249805b261ecSmrg sizeof(Colormap)); 249905b261ecSmrg if(!preply) 25006747b715Smrg return BadAlloc; 250105b261ecSmrg 250205b261ecSmrg preply->type = X_Reply; 250305b261ecSmrg preply->sequenceNumber = client->sequence; 250405b261ecSmrg nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 250505b261ecSmrg (pWin->drawable.pScreen, (Colormap *)&preply[1]); 250605b261ecSmrg preply->nColormaps = nummaps; 250705b261ecSmrg preply->length = nummaps; 250805b261ecSmrg WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply); 250905b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 251005b261ecSmrg WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 25116747b715Smrg free(preply); 25126747b715Smrg return Success; 251305b261ecSmrg} 251405b261ecSmrg 251505b261ecSmrgint 251605b261ecSmrgProcAllocColor (ClientPtr client) 251705b261ecSmrg{ 251805b261ecSmrg ColormapPtr pmap; 25194642e01fSmrg int rc; 252005b261ecSmrg xAllocColorReply acr; 252105b261ecSmrg REQUEST(xAllocColorReq); 252205b261ecSmrg 252305b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorReq); 2524b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client, 25254642e01fSmrg DixAddAccess); 25264642e01fSmrg if (rc == Success) 252705b261ecSmrg { 252805b261ecSmrg acr.type = X_Reply; 252905b261ecSmrg acr.length = 0; 253005b261ecSmrg acr.sequenceNumber = client->sequence; 253105b261ecSmrg acr.red = stuff->red; 253205b261ecSmrg acr.green = stuff->green; 253305b261ecSmrg acr.blue = stuff->blue; 253405b261ecSmrg acr.pixel = 0; 25354642e01fSmrg if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 253605b261ecSmrg &acr.pixel, client->index)) ) 25376747b715Smrg return rc; 253805b261ecSmrg#ifdef PANORAMIX 253905b261ecSmrg if (noPanoramiXExtension || !pmap->pScreen->myNum) 254005b261ecSmrg#endif 254105b261ecSmrg WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 25426747b715Smrg return Success; 254305b261ecSmrg 254405b261ecSmrg } 254505b261ecSmrg else 254605b261ecSmrg { 254705b261ecSmrg client->errorValue = stuff->cmap; 25486747b715Smrg return rc; 254905b261ecSmrg } 255005b261ecSmrg} 255105b261ecSmrg 255205b261ecSmrgint 255305b261ecSmrgProcAllocNamedColor (ClientPtr client) 255405b261ecSmrg{ 255505b261ecSmrg ColormapPtr pcmp; 25564642e01fSmrg int rc; 255705b261ecSmrg REQUEST(xAllocNamedColorReq); 255805b261ecSmrg 255905b261ecSmrg REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 2560b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 25614642e01fSmrg DixAddAccess); 25624642e01fSmrg if (rc == Success) 256305b261ecSmrg { 256405b261ecSmrg xAllocNamedColorReply ancr; 256505b261ecSmrg 256605b261ecSmrg ancr.type = X_Reply; 256705b261ecSmrg ancr.length = 0; 256805b261ecSmrg ancr.sequenceNumber = client->sequence; 256905b261ecSmrg 257005b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 257105b261ecSmrg &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) 257205b261ecSmrg { 257305b261ecSmrg ancr.screenRed = ancr.exactRed; 257405b261ecSmrg ancr.screenGreen = ancr.exactGreen; 257505b261ecSmrg ancr.screenBlue = ancr.exactBlue; 257605b261ecSmrg ancr.pixel = 0; 25774642e01fSmrg if( (rc = AllocColor(pcmp, 257805b261ecSmrg &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, 257905b261ecSmrg &ancr.pixel, client->index)) ) 25806747b715Smrg return rc; 258105b261ecSmrg#ifdef PANORAMIX 258205b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 258305b261ecSmrg#endif 258405b261ecSmrg WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr); 25856747b715Smrg return Success; 258605b261ecSmrg } 258705b261ecSmrg else 25886747b715Smrg return BadName; 258905b261ecSmrg 259005b261ecSmrg } 259105b261ecSmrg else 259205b261ecSmrg { 259305b261ecSmrg client->errorValue = stuff->cmap; 25946747b715Smrg return rc; 259505b261ecSmrg } 259605b261ecSmrg} 259705b261ecSmrg 259805b261ecSmrgint 259905b261ecSmrgProcAllocColorCells (ClientPtr client) 260005b261ecSmrg{ 260105b261ecSmrg ColormapPtr pcmp; 26024642e01fSmrg int rc; 260305b261ecSmrg REQUEST(xAllocColorCellsReq); 260405b261ecSmrg 260505b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorCellsReq); 2606b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 26074642e01fSmrg DixAddAccess); 26084642e01fSmrg if (rc == Success) 260905b261ecSmrg { 261005b261ecSmrg xAllocColorCellsReply accr; 26114642e01fSmrg int npixels, nmasks; 261205b261ecSmrg long length; 261305b261ecSmrg Pixel *ppixels, *pmasks; 261405b261ecSmrg 261505b261ecSmrg npixels = stuff->colors; 261605b261ecSmrg if (!npixels) 261705b261ecSmrg { 261805b261ecSmrg client->errorValue = npixels; 26196747b715Smrg return BadValue; 262005b261ecSmrg } 262105b261ecSmrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 262205b261ecSmrg { 262305b261ecSmrg client->errorValue = stuff->contiguous; 26246747b715Smrg return BadValue; 262505b261ecSmrg } 262605b261ecSmrg nmasks = stuff->planes; 262705b261ecSmrg length = ((long)npixels + (long)nmasks) * sizeof(Pixel); 26286747b715Smrg ppixels = malloc(length); 262905b261ecSmrg if(!ppixels) 26306747b715Smrg return BadAlloc; 263105b261ecSmrg pmasks = ppixels + npixels; 263205b261ecSmrg 26334642e01fSmrg if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 263405b261ecSmrg (Bool)stuff->contiguous, ppixels, pmasks)) ) 263505b261ecSmrg { 26366747b715Smrg free(ppixels); 26376747b715Smrg return rc; 263805b261ecSmrg } 263905b261ecSmrg#ifdef PANORAMIX 264005b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 264105b261ecSmrg#endif 264205b261ecSmrg { 264305b261ecSmrg accr.type = X_Reply; 26446747b715Smrg accr.length = bytes_to_int32(length); 264505b261ecSmrg accr.sequenceNumber = client->sequence; 264605b261ecSmrg accr.nPixels = npixels; 264705b261ecSmrg accr.nMasks = nmasks; 264805b261ecSmrg WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr); 264905b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 265005b261ecSmrg WriteSwappedDataToClient(client, length, ppixels); 265105b261ecSmrg } 26526747b715Smrg free(ppixels); 26536747b715Smrg return Success; 265405b261ecSmrg } 265505b261ecSmrg else 265605b261ecSmrg { 265705b261ecSmrg client->errorValue = stuff->cmap; 26586747b715Smrg return rc; 265905b261ecSmrg } 266005b261ecSmrg} 266105b261ecSmrg 266205b261ecSmrgint 266305b261ecSmrgProcAllocColorPlanes(ClientPtr client) 266405b261ecSmrg{ 266505b261ecSmrg ColormapPtr pcmp; 26664642e01fSmrg int rc; 266705b261ecSmrg REQUEST(xAllocColorPlanesReq); 266805b261ecSmrg 266905b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 2670b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 26714642e01fSmrg DixAddAccess); 26724642e01fSmrg if (rc == Success) 267305b261ecSmrg { 267405b261ecSmrg xAllocColorPlanesReply acpr; 26754642e01fSmrg int npixels; 267605b261ecSmrg long length; 267705b261ecSmrg Pixel *ppixels; 267805b261ecSmrg 267905b261ecSmrg npixels = stuff->colors; 268005b261ecSmrg if (!npixels) 268105b261ecSmrg { 268205b261ecSmrg client->errorValue = npixels; 26836747b715Smrg return BadValue; 268405b261ecSmrg } 268505b261ecSmrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 268605b261ecSmrg { 268705b261ecSmrg client->errorValue = stuff->contiguous; 26886747b715Smrg return BadValue; 268905b261ecSmrg } 269005b261ecSmrg acpr.type = X_Reply; 269105b261ecSmrg acpr.sequenceNumber = client->sequence; 269205b261ecSmrg acpr.nPixels = npixels; 269305b261ecSmrg length = (long)npixels * sizeof(Pixel); 26946747b715Smrg ppixels = malloc(length); 269505b261ecSmrg if(!ppixels) 26966747b715Smrg return BadAlloc; 26974642e01fSmrg if( (rc = AllocColorPlanes(client->index, pcmp, npixels, 269805b261ecSmrg (int)stuff->red, (int)stuff->green, (int)stuff->blue, 269905b261ecSmrg (Bool)stuff->contiguous, ppixels, 270005b261ecSmrg &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) ) 270105b261ecSmrg { 27026747b715Smrg free(ppixels); 27036747b715Smrg return rc; 270405b261ecSmrg } 27056747b715Smrg acpr.length = bytes_to_int32(length); 270605b261ecSmrg#ifdef PANORAMIX 270705b261ecSmrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 270805b261ecSmrg#endif 270905b261ecSmrg { 271005b261ecSmrg WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 271105b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 271205b261ecSmrg WriteSwappedDataToClient(client, length, ppixels); 271305b261ecSmrg } 27146747b715Smrg free(ppixels); 27156747b715Smrg return Success; 271605b261ecSmrg } 271705b261ecSmrg else 271805b261ecSmrg { 271905b261ecSmrg client->errorValue = stuff->cmap; 27206747b715Smrg return rc; 272105b261ecSmrg } 272205b261ecSmrg} 272305b261ecSmrg 272405b261ecSmrgint 272505b261ecSmrgProcFreeColors(ClientPtr client) 272605b261ecSmrg{ 272705b261ecSmrg ColormapPtr pcmp; 27284642e01fSmrg int rc; 272905b261ecSmrg REQUEST(xFreeColorsReq); 273005b261ecSmrg 273105b261ecSmrg REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 2732b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 27334642e01fSmrg DixRemoveAccess); 27344642e01fSmrg if (rc == Success) 273505b261ecSmrg { 273605b261ecSmrg int count; 273705b261ecSmrg 273805b261ecSmrg if(pcmp->flags & AllAllocated) 27396747b715Smrg return BadAccess; 27406747b715Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); 27416747b715Smrg return FreeColors(pcmp, client->index, count, 274205b261ecSmrg (Pixel *)&stuff[1], (Pixel)stuff->planeMask); 274305b261ecSmrg } 274405b261ecSmrg else 274505b261ecSmrg { 274605b261ecSmrg client->errorValue = stuff->cmap; 27476747b715Smrg return rc; 274805b261ecSmrg } 274905b261ecSmrg} 275005b261ecSmrg 275105b261ecSmrgint 275205b261ecSmrgProcStoreColors (ClientPtr client) 275305b261ecSmrg{ 275405b261ecSmrg ColormapPtr pcmp; 27554642e01fSmrg int rc; 275605b261ecSmrg REQUEST(xStoreColorsReq); 275705b261ecSmrg 275805b261ecSmrg REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 2759b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 27604642e01fSmrg DixWriteAccess); 27614642e01fSmrg if (rc == Success) 276205b261ecSmrg { 276305b261ecSmrg int count; 276405b261ecSmrg 276505b261ecSmrg count = (client->req_len << 2) - sizeof(xStoreColorsReq); 276605b261ecSmrg if (count % sizeof(xColorItem)) 27676747b715Smrg return BadLength; 276805b261ecSmrg count /= sizeof(xColorItem); 27696747b715Smrg return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client); 277005b261ecSmrg } 277105b261ecSmrg else 277205b261ecSmrg { 277305b261ecSmrg client->errorValue = stuff->cmap; 27746747b715Smrg return rc; 277505b261ecSmrg } 277605b261ecSmrg} 277705b261ecSmrg 277805b261ecSmrgint 277905b261ecSmrgProcStoreNamedColor (ClientPtr client) 278005b261ecSmrg{ 278105b261ecSmrg ColormapPtr pcmp; 27824642e01fSmrg int rc; 278305b261ecSmrg REQUEST(xStoreNamedColorReq); 278405b261ecSmrg 278505b261ecSmrg REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 2786b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 27874642e01fSmrg DixWriteAccess); 27884642e01fSmrg if (rc == Success) 278905b261ecSmrg { 279005b261ecSmrg xColorItem def; 279105b261ecSmrg 279205b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], 279305b261ecSmrg stuff->nbytes, &def.red, &def.green, &def.blue)) 279405b261ecSmrg { 279505b261ecSmrg def.flags = stuff->flags; 279605b261ecSmrg def.pixel = stuff->pixel; 27976747b715Smrg return StoreColors(pcmp, 1, &def, client); 279805b261ecSmrg } 27996747b715Smrg return BadName; 280005b261ecSmrg } 280105b261ecSmrg else 280205b261ecSmrg { 280305b261ecSmrg client->errorValue = stuff->cmap; 28046747b715Smrg return rc; 280505b261ecSmrg } 280605b261ecSmrg} 280705b261ecSmrg 280805b261ecSmrgint 280905b261ecSmrgProcQueryColors(ClientPtr client) 281005b261ecSmrg{ 281105b261ecSmrg ColormapPtr pcmp; 28124642e01fSmrg int rc; 281305b261ecSmrg REQUEST(xQueryColorsReq); 281405b261ecSmrg 281505b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 2816b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 28174642e01fSmrg DixReadAccess); 28184642e01fSmrg if (rc == Success) 281905b261ecSmrg { 28204642e01fSmrg int count; 282105b261ecSmrg xrgb *prgbs; 282205b261ecSmrg xQueryColorsReply qcr; 282305b261ecSmrg 28246747b715Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); 28256747b715Smrg prgbs = calloc(1, count * sizeof(xrgb)); 282605b261ecSmrg if(!prgbs && count) 28276747b715Smrg return BadAlloc; 28286747b715Smrg if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) ) 282905b261ecSmrg { 28306747b715Smrg free(prgbs); 28316747b715Smrg return rc; 283205b261ecSmrg } 28336747b715Smrg memset(&qcr, 0, sizeof(xQueryColorsReply)); 283405b261ecSmrg qcr.type = X_Reply; 28356747b715Smrg qcr.length = bytes_to_int32(count * sizeof(xrgb)); 283605b261ecSmrg qcr.sequenceNumber = client->sequence; 283705b261ecSmrg qcr.nColors = count; 283805b261ecSmrg WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 283905b261ecSmrg if (count) 284005b261ecSmrg { 284105b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 284205b261ecSmrg WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 284305b261ecSmrg } 28446747b715Smrg free(prgbs); 28456747b715Smrg return Success; 284605b261ecSmrg 284705b261ecSmrg } 284805b261ecSmrg else 284905b261ecSmrg { 285005b261ecSmrg client->errorValue = stuff->cmap; 28516747b715Smrg return rc; 285205b261ecSmrg } 285305b261ecSmrg} 285405b261ecSmrg 285505b261ecSmrgint 285605b261ecSmrgProcLookupColor(ClientPtr client) 285705b261ecSmrg{ 285805b261ecSmrg ColormapPtr pcmp; 28594642e01fSmrg int rc; 286005b261ecSmrg REQUEST(xLookupColorReq); 286105b261ecSmrg 286205b261ecSmrg REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 2863b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 28644642e01fSmrg DixReadAccess); 28654642e01fSmrg if (rc == Success) 286605b261ecSmrg { 286705b261ecSmrg xLookupColorReply lcr; 286805b261ecSmrg 286905b261ecSmrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 287005b261ecSmrg &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) 287105b261ecSmrg { 287205b261ecSmrg lcr.type = X_Reply; 287305b261ecSmrg lcr.length = 0; 287405b261ecSmrg lcr.sequenceNumber = client->sequence; 287505b261ecSmrg lcr.screenRed = lcr.exactRed; 287605b261ecSmrg lcr.screenGreen = lcr.exactGreen; 287705b261ecSmrg lcr.screenBlue = lcr.exactBlue; 287805b261ecSmrg (*pcmp->pScreen->ResolveColor)(&lcr.screenRed, 287905b261ecSmrg &lcr.screenGreen, 288005b261ecSmrg &lcr.screenBlue, 288105b261ecSmrg pcmp->pVisual); 288205b261ecSmrg WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 28836747b715Smrg return Success; 288405b261ecSmrg } 28856747b715Smrg return BadName; 288605b261ecSmrg } 288705b261ecSmrg else 288805b261ecSmrg { 288905b261ecSmrg client->errorValue = stuff->cmap; 28906747b715Smrg return rc; 289105b261ecSmrg } 289205b261ecSmrg} 289305b261ecSmrg 289405b261ecSmrgint 289505b261ecSmrgProcCreateCursor (ClientPtr client) 289605b261ecSmrg{ 289705b261ecSmrg CursorPtr pCursor; 289805b261ecSmrg PixmapPtr src; 289905b261ecSmrg PixmapPtr msk; 290005b261ecSmrg unsigned char * srcbits; 290105b261ecSmrg unsigned char * mskbits; 290205b261ecSmrg unsigned short width, height; 290305b261ecSmrg long n; 290405b261ecSmrg CursorMetricRec cm; 29054642e01fSmrg int rc; 290605b261ecSmrg 290705b261ecSmrg REQUEST(xCreateCursorReq); 290805b261ecSmrg 290905b261ecSmrg REQUEST_SIZE_MATCH(xCreateCursorReq); 291005b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 291105b261ecSmrg 2912b86d567bSmrg rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client, 29134642e01fSmrg DixReadAccess); 29144642e01fSmrg if (rc != Success) { 291505b261ecSmrg client->errorValue = stuff->source; 29166747b715Smrg return rc; 291705b261ecSmrg } 29184642e01fSmrg 2919b86d567bSmrg rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client, 29204642e01fSmrg DixReadAccess); 29214642e01fSmrg if (rc != Success) 292205b261ecSmrg { 292305b261ecSmrg if (stuff->mask != None) 292405b261ecSmrg { 292505b261ecSmrg client->errorValue = stuff->mask; 29266747b715Smrg return rc; 292705b261ecSmrg } 292805b261ecSmrg } 292905b261ecSmrg else if ( src->drawable.width != msk->drawable.width 293005b261ecSmrg || src->drawable.height != msk->drawable.height 293105b261ecSmrg || src->drawable.depth != 1 293205b261ecSmrg || msk->drawable.depth != 1) 29336747b715Smrg return BadMatch; 293405b261ecSmrg 293505b261ecSmrg width = src->drawable.width; 293605b261ecSmrg height = src->drawable.height; 293705b261ecSmrg 293805b261ecSmrg if ( stuff->x > width 293905b261ecSmrg || stuff->y > height ) 29406747b715Smrg return BadMatch; 294105b261ecSmrg 294205b261ecSmrg n = BitmapBytePad(width)*height; 29436747b715Smrg srcbits = calloc(1, n); 294405b261ecSmrg if (!srcbits) 29456747b715Smrg return BadAlloc; 29466747b715Smrg mskbits = malloc(n); 294705b261ecSmrg if (!mskbits) 294805b261ecSmrg { 29496747b715Smrg free(srcbits); 29506747b715Smrg return BadAlloc; 295105b261ecSmrg } 295205b261ecSmrg 295305b261ecSmrg (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height, 295405b261ecSmrg XYPixmap, 1, (pointer)srcbits); 295505b261ecSmrg if ( msk == (PixmapPtr)NULL) 295605b261ecSmrg { 295705b261ecSmrg unsigned char *bits = mskbits; 295805b261ecSmrg while (--n >= 0) 295905b261ecSmrg *bits++ = ~0; 296005b261ecSmrg } 296105b261ecSmrg else 296205b261ecSmrg { 296305b261ecSmrg /* zeroing the (pad) bits helps some ddx cursor handling */ 29646747b715Smrg memset((char *)mskbits, 0, n); 296505b261ecSmrg (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width, 296605b261ecSmrg height, XYPixmap, 1, (pointer)mskbits); 296705b261ecSmrg } 296805b261ecSmrg cm.width = width; 296905b261ecSmrg cm.height = height; 297005b261ecSmrg cm.xhot = stuff->x; 297105b261ecSmrg cm.yhot = stuff->y; 29724642e01fSmrg rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 29734642e01fSmrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 29744642e01fSmrg stuff->backRed, stuff->backGreen, stuff->backBlue, 29754642e01fSmrg &pCursor, client, stuff->cid); 297605b261ecSmrg 29774642e01fSmrg if (rc != Success) 29784642e01fSmrg return rc; 29794642e01fSmrg if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 29804642e01fSmrg return BadAlloc; 29814642e01fSmrg 29826747b715Smrg return Success; 298305b261ecSmrg} 298405b261ecSmrg 298505b261ecSmrgint 298605b261ecSmrgProcCreateGlyphCursor (ClientPtr client) 298705b261ecSmrg{ 298805b261ecSmrg CursorPtr pCursor; 298905b261ecSmrg int res; 299005b261ecSmrg 299105b261ecSmrg REQUEST(xCreateGlyphCursorReq); 299205b261ecSmrg 299305b261ecSmrg REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 299405b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 299505b261ecSmrg 299605b261ecSmrg res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 299705b261ecSmrg stuff->mask, stuff->maskChar, 299805b261ecSmrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 299905b261ecSmrg stuff->backRed, stuff->backGreen, stuff->backBlue, 30004642e01fSmrg &pCursor, client, stuff->cid); 300105b261ecSmrg if (res != Success) 300205b261ecSmrg return res; 300305b261ecSmrg if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 30046747b715Smrg return Success; 300505b261ecSmrg return BadAlloc; 300605b261ecSmrg} 300705b261ecSmrg 300805b261ecSmrg 300905b261ecSmrgint 301005b261ecSmrgProcFreeCursor (ClientPtr client) 301105b261ecSmrg{ 301205b261ecSmrg CursorPtr pCursor; 30134642e01fSmrg int rc; 301405b261ecSmrg REQUEST(xResourceReq); 301505b261ecSmrg 301605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 3017b86d567bSmrg rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client, 30184642e01fSmrg DixDestroyAccess); 30194642e01fSmrg if (rc == Success) 302005b261ecSmrg { 302105b261ecSmrg FreeResource(stuff->id, RT_NONE); 30226747b715Smrg return Success; 302305b261ecSmrg } 302405b261ecSmrg else 302505b261ecSmrg { 302605b261ecSmrg client->errorValue = stuff->id; 30276747b715Smrg return rc; 302805b261ecSmrg } 302905b261ecSmrg} 303005b261ecSmrg 303105b261ecSmrgint 303205b261ecSmrgProcQueryBestSize (ClientPtr client) 303305b261ecSmrg{ 303405b261ecSmrg xQueryBestSizeReply reply; 303505b261ecSmrg DrawablePtr pDraw; 303605b261ecSmrg ScreenPtr pScreen; 303705b261ecSmrg int rc; 303805b261ecSmrg REQUEST(xQueryBestSizeReq); 303905b261ecSmrg REQUEST_SIZE_MATCH(xQueryBestSizeReq); 304005b261ecSmrg 304105b261ecSmrg if ((stuff->class != CursorShape) && 304205b261ecSmrg (stuff->class != TileShape) && 304305b261ecSmrg (stuff->class != StippleShape)) 304405b261ecSmrg { 304505b261ecSmrg client->errorValue = stuff->class; 30466747b715Smrg return BadValue; 304705b261ecSmrg } 304805b261ecSmrg 304905b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 30504642e01fSmrg DixGetAttrAccess); 305105b261ecSmrg if (rc != Success) 305205b261ecSmrg return rc; 305305b261ecSmrg if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 30546747b715Smrg return BadMatch; 305505b261ecSmrg pScreen = pDraw->pScreen; 30564642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 30574642e01fSmrg if (rc != Success) 30584642e01fSmrg return rc; 305905b261ecSmrg (* pScreen->QueryBestSize)(stuff->class, &stuff->width, 306005b261ecSmrg &stuff->height, pScreen); 30616747b715Smrg memset(&reply, 0, sizeof(xQueryBestSizeReply)); 306205b261ecSmrg reply.type = X_Reply; 306305b261ecSmrg reply.length = 0; 306405b261ecSmrg reply.sequenceNumber = client->sequence; 306505b261ecSmrg reply.width = stuff->width; 306605b261ecSmrg reply.height = stuff->height; 306705b261ecSmrg WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 30686747b715Smrg return Success; 306905b261ecSmrg} 307005b261ecSmrg 307105b261ecSmrg 307205b261ecSmrgint 307305b261ecSmrgProcSetScreenSaver (ClientPtr client) 307405b261ecSmrg{ 30754642e01fSmrg int rc, i, blankingOption, exposureOption; 307605b261ecSmrg REQUEST(xSetScreenSaverReq); 307705b261ecSmrg REQUEST_SIZE_MATCH(xSetScreenSaverReq); 30784642e01fSmrg 30794642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 30804642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 30814642e01fSmrg DixSetAttrAccess); 30824642e01fSmrg if (rc != Success) 30834642e01fSmrg return rc; 30844642e01fSmrg } 30854642e01fSmrg 308605b261ecSmrg blankingOption = stuff->preferBlank; 308705b261ecSmrg if ((blankingOption != DontPreferBlanking) && 308805b261ecSmrg (blankingOption != PreferBlanking) && 308905b261ecSmrg (blankingOption != DefaultBlanking)) 309005b261ecSmrg { 309105b261ecSmrg client->errorValue = blankingOption; 309205b261ecSmrg return BadValue; 309305b261ecSmrg } 309405b261ecSmrg exposureOption = stuff->allowExpose; 309505b261ecSmrg if ((exposureOption != DontAllowExposures) && 309605b261ecSmrg (exposureOption != AllowExposures) && 309705b261ecSmrg (exposureOption != DefaultExposures)) 309805b261ecSmrg { 309905b261ecSmrg client->errorValue = exposureOption; 310005b261ecSmrg return BadValue; 310105b261ecSmrg } 310205b261ecSmrg if (stuff->timeout < -1) 310305b261ecSmrg { 310405b261ecSmrg client->errorValue = stuff->timeout; 310505b261ecSmrg return BadValue; 310605b261ecSmrg } 310705b261ecSmrg if (stuff->interval < -1) 310805b261ecSmrg { 310905b261ecSmrg client->errorValue = stuff->interval; 311005b261ecSmrg return BadValue; 311105b261ecSmrg } 311205b261ecSmrg 311305b261ecSmrg if (blankingOption == DefaultBlanking) 311405b261ecSmrg ScreenSaverBlanking = defaultScreenSaverBlanking; 311505b261ecSmrg else 311605b261ecSmrg ScreenSaverBlanking = blankingOption; 311705b261ecSmrg if (exposureOption == DefaultExposures) 311805b261ecSmrg ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 311905b261ecSmrg else 312005b261ecSmrg ScreenSaverAllowExposures = exposureOption; 312105b261ecSmrg 312205b261ecSmrg if (stuff->timeout >= 0) 312305b261ecSmrg ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 312405b261ecSmrg else 312505b261ecSmrg ScreenSaverTime = defaultScreenSaverTime; 312605b261ecSmrg if (stuff->interval >= 0) 312705b261ecSmrg ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 312805b261ecSmrg else 312905b261ecSmrg ScreenSaverInterval = defaultScreenSaverInterval; 313005b261ecSmrg 313105b261ecSmrg SetScreenSaverTimer(); 31326747b715Smrg return Success; 313305b261ecSmrg} 313405b261ecSmrg 313505b261ecSmrgint 313605b261ecSmrgProcGetScreenSaver(ClientPtr client) 313705b261ecSmrg{ 313805b261ecSmrg xGetScreenSaverReply rep; 31394642e01fSmrg int rc, i; 314005b261ecSmrg REQUEST_SIZE_MATCH(xReq); 31414642e01fSmrg 31424642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 31434642e01fSmrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 31444642e01fSmrg DixGetAttrAccess); 31454642e01fSmrg if (rc != Success) 31464642e01fSmrg return rc; 31474642e01fSmrg } 31484642e01fSmrg 314905b261ecSmrg rep.type = X_Reply; 315005b261ecSmrg rep.length = 0; 315105b261ecSmrg rep.sequenceNumber = client->sequence; 315205b261ecSmrg rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; 315305b261ecSmrg rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; 315405b261ecSmrg rep.preferBlanking = ScreenSaverBlanking; 315505b261ecSmrg rep.allowExposures = ScreenSaverAllowExposures; 315605b261ecSmrg WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 31576747b715Smrg return Success; 315805b261ecSmrg} 315905b261ecSmrg 316005b261ecSmrgint 316105b261ecSmrgProcChangeHosts(ClientPtr client) 316205b261ecSmrg{ 316305b261ecSmrg REQUEST(xChangeHostsReq); 316405b261ecSmrg 316505b261ecSmrg REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 316605b261ecSmrg 316705b261ecSmrg if(stuff->mode == HostInsert) 31686747b715Smrg return AddHost(client, (int)stuff->hostFamily, 316905b261ecSmrg stuff->hostLength, (pointer)&stuff[1]); 31706747b715Smrg if (stuff->mode == HostDelete) 31716747b715Smrg return RemoveHost(client, (int)stuff->hostFamily, 317205b261ecSmrg stuff->hostLength, (pointer)&stuff[1]); 31736747b715Smrg client->errorValue = stuff->mode; 31746747b715Smrg return BadValue; 317505b261ecSmrg} 317605b261ecSmrg 317705b261ecSmrgint 317805b261ecSmrgProcListHosts(ClientPtr client) 317905b261ecSmrg{ 318005b261ecSmrg xListHostsReply reply; 318105b261ecSmrg int len, nHosts, result; 318205b261ecSmrg pointer pdata; 318305b261ecSmrg /* REQUEST(xListHostsReq); */ 318405b261ecSmrg 318505b261ecSmrg REQUEST_SIZE_MATCH(xListHostsReq); 318605b261ecSmrg 318705b261ecSmrg /* untrusted clients can't list hosts */ 31884642e01fSmrg result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); 31894642e01fSmrg if (result != Success) 31904642e01fSmrg return result; 319105b261ecSmrg 319205b261ecSmrg result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); 319305b261ecSmrg if (result != Success) 31946747b715Smrg return result; 319505b261ecSmrg reply.type = X_Reply; 319605b261ecSmrg reply.sequenceNumber = client->sequence; 319705b261ecSmrg reply.nHosts = nHosts; 31986747b715Smrg reply.length = bytes_to_int32(len); 319905b261ecSmrg WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 320005b261ecSmrg if (nHosts) 320105b261ecSmrg { 320205b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 320305b261ecSmrg WriteSwappedDataToClient(client, len, pdata); 320405b261ecSmrg } 32056747b715Smrg free(pdata); 32066747b715Smrg return Success; 320705b261ecSmrg} 320805b261ecSmrg 320905b261ecSmrgint 321005b261ecSmrgProcChangeAccessControl(ClientPtr client) 321105b261ecSmrg{ 321205b261ecSmrg REQUEST(xSetAccessControlReq); 321305b261ecSmrg 321405b261ecSmrg REQUEST_SIZE_MATCH(xSetAccessControlReq); 321505b261ecSmrg if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) 321605b261ecSmrg { 321705b261ecSmrg client->errorValue = stuff->mode; 321805b261ecSmrg return BadValue; 321905b261ecSmrg } 32206747b715Smrg return ChangeAccessControl(client, stuff->mode == EnableAccess); 322105b261ecSmrg} 322205b261ecSmrg 322305b261ecSmrg/********************* 322405b261ecSmrg * CloseDownRetainedResources 322505b261ecSmrg * 322605b261ecSmrg * Find all clients that are gone and have terminated in RetainTemporary 322705b261ecSmrg * and destroy their resources. 322805b261ecSmrg *********************/ 322905b261ecSmrg 323005b261ecSmrgstatic void 323105b261ecSmrgCloseDownRetainedResources(void) 323205b261ecSmrg{ 323305b261ecSmrg int i; 323405b261ecSmrg ClientPtr client; 323505b261ecSmrg 323605b261ecSmrg for (i=1; i<currentMaxClients; i++) 323705b261ecSmrg { 323805b261ecSmrg client = clients[i]; 323905b261ecSmrg if (client && (client->closeDownMode == RetainTemporary) 324005b261ecSmrg && (client->clientGone)) 324105b261ecSmrg CloseDownClient(client); 324205b261ecSmrg } 324305b261ecSmrg} 324405b261ecSmrg 324505b261ecSmrgint 324605b261ecSmrgProcKillClient(ClientPtr client) 324705b261ecSmrg{ 324805b261ecSmrg REQUEST(xResourceReq); 324905b261ecSmrg ClientPtr killclient; 325005b261ecSmrg int rc; 325105b261ecSmrg 325205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 325305b261ecSmrg if (stuff->id == AllTemporary) 325405b261ecSmrg { 325505b261ecSmrg CloseDownRetainedResources(); 32566747b715Smrg return Success; 325705b261ecSmrg } 325805b261ecSmrg 325905b261ecSmrg rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 326005b261ecSmrg if (rc == Success) { 326105b261ecSmrg CloseDownClient(killclient); 326205b261ecSmrg /* if an LBX proxy gets killed, isItTimeToYield will be set */ 326305b261ecSmrg if (isItTimeToYield || (client == killclient)) 326405b261ecSmrg { 326505b261ecSmrg /* force yield and return Success, so that Dispatch() 326605b261ecSmrg * doesn't try to touch client 326705b261ecSmrg */ 326805b261ecSmrg isItTimeToYield = TRUE; 32696747b715Smrg return Success; 327005b261ecSmrg } 32716747b715Smrg return Success; 327205b261ecSmrg } 327305b261ecSmrg else 327405b261ecSmrg return rc; 327505b261ecSmrg} 327605b261ecSmrg 327705b261ecSmrgint 327805b261ecSmrgProcSetFontPath(ClientPtr client) 327905b261ecSmrg{ 328005b261ecSmrg unsigned char *ptr; 328105b261ecSmrg unsigned long nbytes, total; 328205b261ecSmrg long nfonts; 32836747b715Smrg int n; 328405b261ecSmrg REQUEST(xSetFontPathReq); 328505b261ecSmrg 328605b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 328705b261ecSmrg 328805b261ecSmrg nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 328905b261ecSmrg total = nbytes; 329005b261ecSmrg ptr = (unsigned char *)&stuff[1]; 329105b261ecSmrg nfonts = stuff->nFonts; 329205b261ecSmrg while (--nfonts >= 0) 329305b261ecSmrg { 329405b261ecSmrg if ((total == 0) || (total < (n = (*ptr + 1)))) 32956747b715Smrg return BadLength; 329605b261ecSmrg total -= n; 329705b261ecSmrg ptr += n; 329805b261ecSmrg } 329905b261ecSmrg if (total >= 4) 33006747b715Smrg return BadLength; 33016747b715Smrg return SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]); 330205b261ecSmrg} 330305b261ecSmrg 330405b261ecSmrgint 330505b261ecSmrgProcGetFontPath(ClientPtr client) 330605b261ecSmrg{ 330705b261ecSmrg xGetFontPathReply reply; 33084642e01fSmrg int rc, stringLens, numpaths; 330905b261ecSmrg unsigned char *bufferStart; 331005b261ecSmrg /* REQUEST (xReq); */ 331105b261ecSmrg 331205b261ecSmrg REQUEST_SIZE_MATCH(xReq); 33134642e01fSmrg rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); 33144642e01fSmrg if (rc != Success) 33154642e01fSmrg return rc; 331605b261ecSmrg 331705b261ecSmrg reply.type = X_Reply; 331805b261ecSmrg reply.sequenceNumber = client->sequence; 33196747b715Smrg reply.length = bytes_to_int32(stringLens + numpaths); 332005b261ecSmrg reply.nPaths = numpaths; 332105b261ecSmrg 332205b261ecSmrg WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 332305b261ecSmrg if (stringLens || numpaths) 332405b261ecSmrg (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart); 33256747b715Smrg return Success; 332605b261ecSmrg} 332705b261ecSmrg 332805b261ecSmrgint 332905b261ecSmrgProcChangeCloseDownMode(ClientPtr client) 333005b261ecSmrg{ 33314642e01fSmrg int rc; 333205b261ecSmrg REQUEST(xSetCloseDownModeReq); 333305b261ecSmrg REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 33344642e01fSmrg 33354642e01fSmrg rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); 33364642e01fSmrg if (rc != Success) 33374642e01fSmrg return rc; 33384642e01fSmrg 333905b261ecSmrg if ((stuff->mode == AllTemporary) || 334005b261ecSmrg (stuff->mode == RetainPermanent) || 334105b261ecSmrg (stuff->mode == RetainTemporary)) 334205b261ecSmrg { 334305b261ecSmrg client->closeDownMode = stuff->mode; 33446747b715Smrg return Success; 334505b261ecSmrg } 334605b261ecSmrg else 334705b261ecSmrg { 334805b261ecSmrg client->errorValue = stuff->mode; 33496747b715Smrg return BadValue; 335005b261ecSmrg } 335105b261ecSmrg} 335205b261ecSmrg 335305b261ecSmrgint ProcForceScreenSaver(ClientPtr client) 335405b261ecSmrg{ 33554642e01fSmrg int rc; 335605b261ecSmrg REQUEST(xForceScreenSaverReq); 335705b261ecSmrg 335805b261ecSmrg REQUEST_SIZE_MATCH(xForceScreenSaverReq); 335905b261ecSmrg 336005b261ecSmrg if ((stuff->mode != ScreenSaverReset) && 336105b261ecSmrg (stuff->mode != ScreenSaverActive)) 336205b261ecSmrg { 336305b261ecSmrg client->errorValue = stuff->mode; 336405b261ecSmrg return BadValue; 336505b261ecSmrg } 33664642e01fSmrg rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode); 33674642e01fSmrg if (rc != Success) 33684642e01fSmrg return rc; 33696747b715Smrg return Success; 337005b261ecSmrg} 337105b261ecSmrg 337205b261ecSmrgint ProcNoOperation(ClientPtr client) 337305b261ecSmrg{ 337405b261ecSmrg REQUEST_AT_LEAST_SIZE(xReq); 337505b261ecSmrg 337605b261ecSmrg /* noop -- don't do anything */ 33776747b715Smrg return Success; 337805b261ecSmrg} 337905b261ecSmrg 338005b261ecSmrg/********************** 338105b261ecSmrg * CloseDownClient 338205b261ecSmrg * 338305b261ecSmrg * Client can either mark his resources destroy or retain. If retained and 338405b261ecSmrg * then killed again, the client is really destroyed. 338505b261ecSmrg *********************/ 338605b261ecSmrg 338705b261ecSmrgchar dispatchExceptionAtReset = DE_RESET; 338805b261ecSmrg 338905b261ecSmrgvoid 339005b261ecSmrgCloseDownClient(ClientPtr client) 339105b261ecSmrg{ 339205b261ecSmrg Bool really_close_down = client->clientGone || 339305b261ecSmrg client->closeDownMode == DestroyAll; 339405b261ecSmrg 339505b261ecSmrg if (!client->clientGone) 339605b261ecSmrg { 339705b261ecSmrg /* ungrab server if grabbing client dies */ 339805b261ecSmrg if (grabState != GrabNone && grabClient == client) 339905b261ecSmrg { 340005b261ecSmrg UngrabServer(client); 340105b261ecSmrg } 340205b261ecSmrg BITCLEAR(grabWaiters, client->index); 340305b261ecSmrg DeleteClientFromAnySelections(client); 340405b261ecSmrg ReleaseActiveGrabs(client); 340505b261ecSmrg DeleteClientFontStuff(client); 340605b261ecSmrg if (!really_close_down) 340705b261ecSmrg { 340805b261ecSmrg /* This frees resources that should never be retained 340905b261ecSmrg * no matter what the close down mode is. Actually we 341005b261ecSmrg * could do this unconditionally, but it's probably 341105b261ecSmrg * better not to traverse all the client's resources 341205b261ecSmrg * twice (once here, once a few lines down in 341305b261ecSmrg * FreeClientResources) in the common case of 341405b261ecSmrg * really_close_down == TRUE. 341505b261ecSmrg */ 341605b261ecSmrg FreeClientNeverRetainResources(client); 341705b261ecSmrg client->clientState = ClientStateRetained; 341805b261ecSmrg if (ClientStateCallback) 341905b261ecSmrg { 342005b261ecSmrg NewClientInfoRec clientinfo; 342105b261ecSmrg 342205b261ecSmrg clientinfo.client = client; 342305b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 342405b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 342505b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 342605b261ecSmrg } 342705b261ecSmrg } 342805b261ecSmrg client->clientGone = TRUE; /* so events aren't sent to client */ 342905b261ecSmrg if (ClientIsAsleep(client)) 343005b261ecSmrg ClientSignal (client); 343105b261ecSmrg ProcessWorkQueueZombies(); 343205b261ecSmrg CloseDownConnection(client); 343305b261ecSmrg 343405b261ecSmrg /* If the client made it to the Running stage, nClients has 343505b261ecSmrg * been incremented on its behalf, so we need to decrement it 343605b261ecSmrg * now. If it hasn't gotten to Running, nClients has *not* 343705b261ecSmrg * been incremented, so *don't* decrement it. 343805b261ecSmrg */ 343905b261ecSmrg if (client->clientState != ClientStateInitial && 344005b261ecSmrg client->clientState != ClientStateAuthenticating ) 344105b261ecSmrg { 344205b261ecSmrg --nClients; 344305b261ecSmrg } 344405b261ecSmrg } 344505b261ecSmrg 344605b261ecSmrg if (really_close_down) 344705b261ecSmrg { 344805b261ecSmrg if (client->clientState == ClientStateRunning && nClients == 0) 344905b261ecSmrg dispatchException |= dispatchExceptionAtReset; 345005b261ecSmrg 345105b261ecSmrg client->clientState = ClientStateGone; 345205b261ecSmrg if (ClientStateCallback) 345305b261ecSmrg { 345405b261ecSmrg NewClientInfoRec clientinfo; 345505b261ecSmrg 345605b261ecSmrg clientinfo.client = client; 345705b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 345805b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 345905b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 346005b261ecSmrg } 346105b261ecSmrg FreeClientResources(client); 346205b261ecSmrg#ifdef XSERVER_DTRACE 346305b261ecSmrg XSERVER_CLIENT_DISCONNECT(client->index); 346405b261ecSmrg#endif 346505b261ecSmrg if (client->index < nextFreeClientID) 346605b261ecSmrg nextFreeClientID = client->index; 346705b261ecSmrg clients[client->index] = NullClient; 346805b261ecSmrg SmartLastClient = NullClient; 34696747b715Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 347005b261ecSmrg 347105b261ecSmrg while (!clients[currentMaxClients-1]) 347205b261ecSmrg currentMaxClients--; 347305b261ecSmrg } 347405b261ecSmrg} 347505b261ecSmrg 347605b261ecSmrgstatic void 347705b261ecSmrgKillAllClients(void) 347805b261ecSmrg{ 347905b261ecSmrg int i; 348005b261ecSmrg for (i=1; i<currentMaxClients; i++) 348105b261ecSmrg if (clients[i]) { 348205b261ecSmrg /* Make sure Retained clients are released. */ 348305b261ecSmrg clients[i]->closeDownMode = DestroyAll; 348405b261ecSmrg CloseDownClient(clients[i]); 348505b261ecSmrg } 348605b261ecSmrg} 348705b261ecSmrg 348805b261ecSmrgvoid InitClient(ClientPtr client, int i, pointer ospriv) 348905b261ecSmrg{ 349005b261ecSmrg client->index = i; 349105b261ecSmrg client->clientAsMask = ((Mask)i) << CLIENTOFFSET; 34924642e01fSmrg client->closeDownMode = i ? DestroyAll : RetainPermanent; 349305b261ecSmrg client->requestVector = InitialVector; 349405b261ecSmrg client->osPrivate = ospriv; 34956747b715Smrg QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); 349605b261ecSmrg client->smart_start_tick = SmartScheduleTime; 349705b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 349805b261ecSmrg client->smart_check_tick = SmartScheduleTime; 349905b261ecSmrg} 350005b261ecSmrg 350105b261ecSmrg/************************ 350205b261ecSmrg * int NextAvailableClient(ospriv) 350305b261ecSmrg * 350405b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes. 350505b261ecSmrg * Returns NULL if there are no free clients. 350605b261ecSmrg *************************/ 350705b261ecSmrg 350805b261ecSmrgClientPtr NextAvailableClient(pointer ospriv) 350905b261ecSmrg{ 351005b261ecSmrg int i; 351105b261ecSmrg ClientPtr client; 351205b261ecSmrg xReq data; 351305b261ecSmrg 351405b261ecSmrg i = nextFreeClientID; 351505b261ecSmrg if (i == MAXCLIENTS) 351605b261ecSmrg return (ClientPtr)NULL; 35176747b715Smrg clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT); 351805b261ecSmrg if (!client) 351905b261ecSmrg return (ClientPtr)NULL; 352005b261ecSmrg InitClient(client, i, ospriv); 352105b261ecSmrg if (!InitClientResources(client)) 352205b261ecSmrg { 35236747b715Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 352405b261ecSmrg return (ClientPtr)NULL; 352505b261ecSmrg } 352605b261ecSmrg data.reqType = 1; 35276747b715Smrg data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); 352805b261ecSmrg if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) 352905b261ecSmrg { 353005b261ecSmrg FreeClientResources(client); 35316747b715Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 353205b261ecSmrg return (ClientPtr)NULL; 353305b261ecSmrg } 353405b261ecSmrg if (i == currentMaxClients) 353505b261ecSmrg currentMaxClients++; 353605b261ecSmrg while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) 353705b261ecSmrg nextFreeClientID++; 353805b261ecSmrg if (ClientStateCallback) 353905b261ecSmrg { 354005b261ecSmrg NewClientInfoRec clientinfo; 354105b261ecSmrg 354205b261ecSmrg clientinfo.client = client; 354305b261ecSmrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 354405b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 354505b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 354605b261ecSmrg } 35476747b715Smrg return client; 354805b261ecSmrg} 354905b261ecSmrg 355005b261ecSmrgint 355105b261ecSmrgProcInitialConnection(ClientPtr client) 355205b261ecSmrg{ 355305b261ecSmrg REQUEST(xReq); 355405b261ecSmrg xConnClientPrefix *prefix; 355505b261ecSmrg int whichbyte = 1; 355605b261ecSmrg 355705b261ecSmrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 355805b261ecSmrg if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) 35596747b715Smrg return client->noClientException = -1; 356005b261ecSmrg if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || 356105b261ecSmrg (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) 356205b261ecSmrg { 356305b261ecSmrg client->swapped = TRUE; 356405b261ecSmrg SwapConnClientPrefix(prefix); 356505b261ecSmrg } 356605b261ecSmrg stuff->reqType = 2; 35676747b715Smrg stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + 35686747b715Smrg bytes_to_int32(prefix->nbytesAuthString); 356905b261ecSmrg if (client->swapped) 357005b261ecSmrg { 357105b261ecSmrg swaps(&stuff->length, whichbyte); 357205b261ecSmrg } 357305b261ecSmrg ResetCurrentRequest(client); 35746747b715Smrg return Success; 357505b261ecSmrg} 357605b261ecSmrg 35774642e01fSmrgstatic int 357805b261ecSmrgSendConnSetup(ClientPtr client, char *reason) 357905b261ecSmrg{ 358005b261ecSmrg xWindowRoot *root; 358105b261ecSmrg int i; 358205b261ecSmrg int numScreens; 358305b261ecSmrg char* lConnectionInfo; 358405b261ecSmrg xConnSetupPrefix* lconnSetupPrefix; 358505b261ecSmrg 358605b261ecSmrg if (reason) 358705b261ecSmrg { 358805b261ecSmrg xConnSetupPrefix csp; 358905b261ecSmrg 359005b261ecSmrg csp.success = xFalse; 359105b261ecSmrg csp.lengthReason = strlen(reason); 35926747b715Smrg csp.length = bytes_to_int32(csp.lengthReason); 359305b261ecSmrg csp.majorVersion = X_PROTOCOL; 359405b261ecSmrg csp.minorVersion = X_PROTOCOL_REVISION; 359505b261ecSmrg if (client->swapped) 359605b261ecSmrg WriteSConnSetupPrefix(client, &csp); 359705b261ecSmrg else 359805b261ecSmrg (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); 359905b261ecSmrg (void)WriteToClient(client, (int)csp.lengthReason, reason); 36006747b715Smrg return client->noClientException = -1; 360105b261ecSmrg } 360205b261ecSmrg 360305b261ecSmrg numScreens = screenInfo.numScreens; 360405b261ecSmrg lConnectionInfo = ConnectionInfo; 360505b261ecSmrg lconnSetupPrefix = &connSetupPrefix; 360605b261ecSmrg 360705b261ecSmrg /* We're about to start speaking X protocol back to the client by 360805b261ecSmrg * sending the connection setup info. This means the authorization 360905b261ecSmrg * step is complete, and we can count the client as an 361005b261ecSmrg * authorized one. 361105b261ecSmrg */ 361205b261ecSmrg nClients++; 361305b261ecSmrg 361405b261ecSmrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 361505b261ecSmrg client->sequence = 0; 361605b261ecSmrg ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask; 361705b261ecSmrg ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 361805b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 361905b261ecSmrg ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client); 362005b261ecSmrg ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client); 362105b261ecSmrg#endif 362205b261ecSmrg /* fill in the "currentInputMask" */ 362305b261ecSmrg root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart); 362405b261ecSmrg#ifdef PANORAMIX 362505b261ecSmrg if (noPanoramiXExtension) 362605b261ecSmrg numScreens = screenInfo.numScreens; 362705b261ecSmrg else 362805b261ecSmrg numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; 362905b261ecSmrg#endif 363005b261ecSmrg 363105b261ecSmrg for (i=0; i<numScreens; i++) 363205b261ecSmrg { 363305b261ecSmrg unsigned int j; 363405b261ecSmrg xDepth *pDepth; 36356747b715Smrg WindowPtr pRoot = screenInfo.screens[i]->root; 363605b261ecSmrg 36376747b715Smrg root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot); 363805b261ecSmrg pDepth = (xDepth *)(root + 1); 363905b261ecSmrg for (j = 0; j < root->nDepths; j++) 364005b261ecSmrg { 364105b261ecSmrg pDepth = (xDepth *)(((char *)(pDepth + 1)) + 364205b261ecSmrg pDepth->nVisuals * sizeof(xVisualType)); 364305b261ecSmrg } 364405b261ecSmrg root = (xWindowRoot *)pDepth; 364505b261ecSmrg } 364605b261ecSmrg 364705b261ecSmrg if (client->swapped) 364805b261ecSmrg { 364905b261ecSmrg WriteSConnSetupPrefix(client, lconnSetupPrefix); 365005b261ecSmrg WriteSConnectionInfo(client, 365105b261ecSmrg (unsigned long)(lconnSetupPrefix->length << 2), 365205b261ecSmrg lConnectionInfo); 365305b261ecSmrg } 365405b261ecSmrg else 365505b261ecSmrg { 365605b261ecSmrg (void)WriteToClient(client, sizeof(xConnSetupPrefix), 365705b261ecSmrg (char *) lconnSetupPrefix); 365805b261ecSmrg (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2), 365905b261ecSmrg lConnectionInfo); 366005b261ecSmrg } 366105b261ecSmrg client->clientState = ClientStateRunning; 366205b261ecSmrg if (ClientStateCallback) 366305b261ecSmrg { 366405b261ecSmrg NewClientInfoRec clientinfo; 366505b261ecSmrg 366605b261ecSmrg clientinfo.client = client; 366705b261ecSmrg clientinfo.prefix = lconnSetupPrefix; 366805b261ecSmrg clientinfo.setup = (xConnSetup *)lConnectionInfo; 366905b261ecSmrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 367005b261ecSmrg } 36716747b715Smrg return Success; 367205b261ecSmrg} 367305b261ecSmrg 367405b261ecSmrgint 367505b261ecSmrgProcEstablishConnection(ClientPtr client) 367605b261ecSmrg{ 367705b261ecSmrg char *reason, *auth_proto, *auth_string; 367805b261ecSmrg xConnClientPrefix *prefix; 367905b261ecSmrg REQUEST(xReq); 368005b261ecSmrg 368105b261ecSmrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 368205b261ecSmrg auth_proto = (char *)prefix + sz_xConnClientPrefix; 36836747b715Smrg auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); 368405b261ecSmrg if ((prefix->majorVersion != X_PROTOCOL) || 368505b261ecSmrg (prefix->minorVersion != X_PROTOCOL_REVISION)) 368605b261ecSmrg reason = "Protocol version mismatch"; 368705b261ecSmrg else 368805b261ecSmrg reason = ClientAuthorized(client, 368905b261ecSmrg (unsigned short)prefix->nbytesAuthProto, 369005b261ecSmrg auth_proto, 369105b261ecSmrg (unsigned short)prefix->nbytesAuthString, 369205b261ecSmrg auth_string); 369305b261ecSmrg /* 369405b261ecSmrg * If Kerberos is being used for this client, the clientState 369505b261ecSmrg * will be set to ClientStateAuthenticating at this point. 369605b261ecSmrg * More messages need to be exchanged among the X server, Kerberos 369705b261ecSmrg * server, and client to figure out if everyone is authorized. 369805b261ecSmrg * So we don't want to send the connection setup info yet, since 369905b261ecSmrg * the auth step isn't really done. 370005b261ecSmrg */ 370105b261ecSmrg if (client->clientState == ClientStateCheckingSecurity) 370205b261ecSmrg client->clientState = ClientStateCheckedSecurity; 370305b261ecSmrg else if (client->clientState != ClientStateAuthenticating) 370405b261ecSmrg return(SendConnSetup(client, reason)); 37056747b715Smrg return Success; 370605b261ecSmrg} 370705b261ecSmrg 37086747b715Smrgvoid 370905b261ecSmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 371005b261ecSmrg XID resId, int errorCode) 371105b261ecSmrg{ 371205b261ecSmrg xError rep; 371305b261ecSmrg 37146747b715Smrg memset(&rep, 0, sizeof(xError)); 371505b261ecSmrg rep.type = X_Error; 371605b261ecSmrg rep.errorCode = errorCode; 371705b261ecSmrg rep.majorCode = majorCode; 371805b261ecSmrg rep.minorCode = minorCode; 371905b261ecSmrg rep.resourceID = resId; 372005b261ecSmrg 372105b261ecSmrg WriteEventsToClient (client, 1, (xEvent *)&rep); 372205b261ecSmrg} 372305b261ecSmrg 372405b261ecSmrgvoid 372505b261ecSmrgMarkClientException(ClientPtr client) 372605b261ecSmrg{ 372705b261ecSmrg client->noClientException = -1; 372805b261ecSmrg} 37296747b715Smrg 37306747b715Smrg/* 37316747b715Smrg * This array encodes the answer to the question "what is the log base 2 37326747b715Smrg * of the number of pixels that fit in a scanline pad unit?" 37336747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37346747b715Smrg */ 37356747b715Smrgstatic int answer[6][4] = { 37366747b715Smrg /* pad pad pad pad*/ 37376747b715Smrg /* 8 16 32 64 */ 37386747b715Smrg 37396747b715Smrg { 3, 4, 5 , 6 }, /* 1 bit per pixel */ 37406747b715Smrg { 1, 2, 3 , 4 }, /* 4 bits per pixel */ 37416747b715Smrg { 0, 1, 2 , 3 }, /* 8 bits per pixel */ 37426747b715Smrg { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ 37436747b715Smrg { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ 37446747b715Smrg { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ 37456747b715Smrg}; 37466747b715Smrg 37476747b715Smrg/* 37486747b715Smrg * This array gives the answer to the question "what is the first index for 37496747b715Smrg * the answer array above given the number of bits per pixel?" 37506747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37516747b715Smrg */ 37526747b715Smrgstatic int indexForBitsPerPixel[ 33 ] = { 37536747b715Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 37546747b715Smrg 1, ~0, ~0, ~0, /* 4 bits per pixel */ 37556747b715Smrg 2, ~0, ~0, ~0, /* 8 bits per pixel */ 37566747b715Smrg ~0,~0, ~0, ~0, 37576747b715Smrg 3, ~0, ~0, ~0, /* 16 bits per pixel */ 37586747b715Smrg ~0,~0, ~0, ~0, 37596747b715Smrg 4, ~0, ~0, ~0, /* 24 bits per pixel */ 37606747b715Smrg ~0,~0, ~0, ~0, 37616747b715Smrg 5 /* 32 bits per pixel */ 37626747b715Smrg}; 37636747b715Smrg 37646747b715Smrg/* 37656747b715Smrg * This array gives the bytesperPixel value for cases where the number 37666747b715Smrg * of bits per pixel is a multiple of 8 but not a power of 2. 37676747b715Smrg */ 37686747b715Smrgstatic int answerBytesPerPixel[ 33 ] = { 37696747b715Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 37706747b715Smrg 0, ~0, ~0, ~0, /* 4 bits per pixel */ 37716747b715Smrg 0, ~0, ~0, ~0, /* 8 bits per pixel */ 37726747b715Smrg ~0,~0, ~0, ~0, 37736747b715Smrg 0, ~0, ~0, ~0, /* 16 bits per pixel */ 37746747b715Smrg ~0,~0, ~0, ~0, 37756747b715Smrg 3, ~0, ~0, ~0, /* 24 bits per pixel */ 37766747b715Smrg ~0,~0, ~0, ~0, 37776747b715Smrg 0 /* 32 bits per pixel */ 37786747b715Smrg}; 37796747b715Smrg 37806747b715Smrg/* 37816747b715Smrg * This array gives the answer to the question "what is the second index for 37826747b715Smrg * the answer array above given the number of bits per scanline pad unit?" 37836747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37846747b715Smrg */ 37856747b715Smrgstatic int indexForScanlinePad[ 65 ] = { 37866747b715Smrg ~0, ~0, ~0, ~0, 37876747b715Smrg ~0, ~0, ~0, ~0, 37886747b715Smrg 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ 37896747b715Smrg ~0, ~0, ~0, ~0, 37906747b715Smrg 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ 37916747b715Smrg ~0, ~0, ~0, ~0, 37926747b715Smrg ~0, ~0, ~0, ~0, 37936747b715Smrg ~0, ~0, ~0, ~0, 37946747b715Smrg 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ 37956747b715Smrg ~0, ~0, ~0, ~0, 37966747b715Smrg ~0, ~0, ~0, ~0, 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 3 /* 64 bits per scanline pad unit */ 38036747b715Smrg}; 38046747b715Smrg 38056747b715Smrg/* 38066747b715Smrg grow the array of screenRecs if necessary. 38076747b715Smrg call the device-supplied initialization procedure 38086747b715Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv. 38096747b715Smrg return the number of successfully installed screens. 38106747b715Smrg 38116747b715Smrg*/ 38126747b715Smrg 38136747b715Smrgint 38146747b715SmrgAddScreen( 38156747b715Smrg Bool (* pfnInit)( 38166747b715Smrg int /*index*/, 38176747b715Smrg ScreenPtr /*pScreen*/, 38186747b715Smrg int /*argc*/, 38196747b715Smrg char ** /*argv*/ 38206747b715Smrg ), 38216747b715Smrg int argc, 38226747b715Smrg char **argv) 38236747b715Smrg{ 38246747b715Smrg 38256747b715Smrg int i; 38266747b715Smrg int scanlinepad, format, depth, bitsPerPixel, j, k; 38276747b715Smrg ScreenPtr pScreen; 38286747b715Smrg 38296747b715Smrg i = screenInfo.numScreens; 38306747b715Smrg if (i == MAXSCREENS) 38316747b715Smrg return -1; 38326747b715Smrg 38336747b715Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 38346747b715Smrg if (!pScreen) 38356747b715Smrg return -1; 38366747b715Smrg 38376747b715Smrg if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { 38386747b715Smrg free (pScreen); 38396747b715Smrg return -1; 38406747b715Smrg } 38416747b715Smrg pScreen->myNum = i; 38426747b715Smrg pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ 38436747b715Smrg pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ 38446747b715Smrg pScreen->CreateScreenResources = 0; 38456747b715Smrg 38466747b715Smrg /* 38476747b715Smrg * This loop gets run once for every Screen that gets added, 38486747b715Smrg * but thats ok. If the ddx layer initializes the formats 38496747b715Smrg * one at a time calling AddScreen() after each, then each 38506747b715Smrg * iteration will make it a little more accurate. Worst case 38516747b715Smrg * we do this loop N * numPixmapFormats where N is # of screens. 38526747b715Smrg * Anyway, this must be called after InitOutput and before the 38536747b715Smrg * screen init routine is called. 38546747b715Smrg */ 38556747b715Smrg for (format=0; format<screenInfo.numPixmapFormats; format++) 38566747b715Smrg { 38576747b715Smrg depth = screenInfo.formats[format].depth; 38586747b715Smrg bitsPerPixel = screenInfo.formats[format].bitsPerPixel; 38596747b715Smrg scanlinepad = screenInfo.formats[format].scanlinePad; 38606747b715Smrg j = indexForBitsPerPixel[ bitsPerPixel ]; 38616747b715Smrg k = indexForScanlinePad[ scanlinepad ]; 38626747b715Smrg PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k]; 38636747b715Smrg PixmapWidthPaddingInfo[ depth ].padRoundUp = 38646747b715Smrg (scanlinepad/bitsPerPixel) - 1; 38656747b715Smrg j = indexForBitsPerPixel[ 8 ]; /* bits per byte */ 38666747b715Smrg PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k]; 38676747b715Smrg PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel; 38686747b715Smrg if (answerBytesPerPixel[bitsPerPixel]) 38696747b715Smrg { 38706747b715Smrg PixmapWidthPaddingInfo[ depth ].notPower2 = 1; 38716747b715Smrg PixmapWidthPaddingInfo[ depth ].bytesPerPixel = 38726747b715Smrg answerBytesPerPixel[bitsPerPixel]; 38736747b715Smrg } 38746747b715Smrg else 38756747b715Smrg { 38766747b715Smrg PixmapWidthPaddingInfo[ depth ].notPower2 = 0; 38776747b715Smrg } 38786747b715Smrg } 38796747b715Smrg 38806747b715Smrg /* This is where screen specific stuff gets initialized. Load the 38816747b715Smrg screen structure, call the hardware, whatever. 38826747b715Smrg This is also where the default colormap should be allocated and 38836747b715Smrg also pixel values for blackPixel, whitePixel, and the cursor 38846747b715Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 38856747b715Smrg any of the strings pointed to by argv. They may be passed to 38866747b715Smrg multiple screens. 38876747b715Smrg */ 38886747b715Smrg screenInfo.screens[i] = pScreen; 38896747b715Smrg screenInfo.numScreens++; 38906747b715Smrg if (!(*pfnInit)(i, pScreen, argc, argv)) 38916747b715Smrg { 38926747b715Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 38936747b715Smrg free(pScreen); 38946747b715Smrg screenInfo.numScreens--; 38956747b715Smrg return -1; 38966747b715Smrg } 38976747b715Smrg 38986747b715Smrg dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0); 38996747b715Smrg 39006747b715Smrg return i; 39016747b715Smrg} 3902