dispatch.c revision f7df2e56
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 2505b261ecSmrgCopyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 29f7df2e56SmrgPermission to use, copy, modify, and distribute this software and its 30f7df2e56Smrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 32f7df2e56Smrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Digital not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 35f7df2e56Smrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg********************************************************/ 4605b261ecSmrg 4705b261ecSmrg/* The panoramix components contained the following notice */ 4805b261ecSmrg/***************************************************************** 4905b261ecSmrg 5005b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 5105b261ecSmrg 5205b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 5305b261ecSmrgof this software and associated documentation files (the "Software"), to deal 5405b261ecSmrgin the Software without restriction, including without limitation the rights 5505b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5605b261ecSmrgcopies of the Software. 5705b261ecSmrg 5805b261ecSmrgThe above copyright notice and this permission notice shall be included in 5905b261ecSmrgall copies or substantial portions of the Software. 6005b261ecSmrg 6105b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6205b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6305b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 6405b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 6505b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 6605b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 6705b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6805b261ecSmrg 6905b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation 7005b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other 7105b261ecSmrgdealings in this Software without prior written authorization from Digital 7205b261ecSmrgEquipment Corporation. 7305b261ecSmrg 7405b261ecSmrg******************************************************************/ 7505b261ecSmrg 7605b261ecSmrg/* XSERVER_DTRACE additions: 779ace9065Smrg * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. 7805b261ecSmrg * 7905b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 806747b715Smrg * copy of this software and associated documentation files (the "Software"), 816747b715Smrg * to deal in the Software without restriction, including without limitation 826747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 836747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 846747b715Smrg * Software is furnished to do so, subject to the following conditions: 856747b715Smrg * 866747b715Smrg * The above copyright notice and this permission notice (including the next 876747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 886747b715Smrg * Software. 896747b715Smrg * 906747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 916747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 926747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 936747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 946747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 956747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 966747b715Smrg * DEALINGS IN THE SOFTWARE. 9705b261ecSmrg */ 9805b261ecSmrg 9905b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 10005b261ecSmrg#include <dix-config.h> 1016747b715Smrg#include <version-config.h> 10205b261ecSmrg#endif 10305b261ecSmrg 10405b261ecSmrg#ifdef PANORAMIX_DEBUG 10505b261ecSmrg#include <stdio.h> 10605b261ecSmrgint ProcInitialConnection(); 10705b261ecSmrg#endif 10805b261ecSmrg 10905b261ecSmrg#include "windowstr.h" 11005b261ecSmrg#include <X11/fonts/fontstruct.h> 111f7df2e56Smrg#include <X11/fonts/fontutil.h> 11205b261ecSmrg#include "dixfontstr.h" 11305b261ecSmrg#include "gcstruct.h" 11405b261ecSmrg#include "selection.h" 11505b261ecSmrg#include "colormapst.h" 11605b261ecSmrg#include "cursorstr.h" 11705b261ecSmrg#include "scrnintstr.h" 11805b261ecSmrg#include "opaque.h" 11905b261ecSmrg#include "input.h" 12005b261ecSmrg#include "servermd.h" 12105b261ecSmrg#include "extnsionst.h" 12205b261ecSmrg#include "dixfont.h" 12305b261ecSmrg#include "dispatch.h" 12405b261ecSmrg#include "swaprep.h" 12505b261ecSmrg#include "swapreq.h" 1264642e01fSmrg#include "privates.h" 12705b261ecSmrg#include "xace.h" 12805b261ecSmrg#include "inputstr.h" 1296747b715Smrg#include "xkbsrv.h" 1306747b715Smrg#include "site.h" 131f7df2e56Smrg#include "client.h" 13205b261ecSmrg 13305b261ecSmrg#ifdef XSERVER_DTRACE 1344642e01fSmrg#include "registry.h" 135f7df2e56Smrg#include "probes.h" 13605b261ecSmrg#endif 13705b261ecSmrg 13805b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32) 13905b261ecSmrg#define BITMASK(i) (1U << ((i) & 31)) 14005b261ecSmrg#define MASKIDX(i) ((i) >> 5) 14105b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)] 14205b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) 14305b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) 14405b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) 14505b261ecSmrg 1466747b715SmrgxConnSetupPrefix connSetupPrefix; 1476747b715Smrg 1486747b715SmrgPaddingInfo PixmapWidthPaddingInfo[33]; 14905b261ecSmrg 15005b261ecSmrgstatic ClientPtr grabClient; 151f7df2e56Smrg 15205b261ecSmrg#define GrabNone 0 15305b261ecSmrg#define GrabActive 1 15405b261ecSmrg#define GrabKickout 2 15505b261ecSmrgstatic int grabState = GrabNone; 15605b261ecSmrgstatic long grabWaiters[mskcnt]; 1576747b715SmrgCallbackListPtr ServerGrabCallback = NULL; 15805b261ecSmrgHWEventQueuePtr checkForInput[2]; 1596747b715Smrgint connBlockScreenStart; 16005b261ecSmrg 16105b261ecSmrgstatic void KillAllClients(void); 16205b261ecSmrg 163f7df2e56Smrgstatic int nextFreeClientID; /* always MIN free client ID */ 16405b261ecSmrg 165f7df2e56Smrgstatic int nClients; /* number of authorized clients */ 16605b261ecSmrg 1676747b715SmrgCallbackListPtr ClientStateCallback; 16805b261ecSmrg 16905b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they 17005b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't 17105b261ecSmrg * need to actually check value in memory when used and may miss changes from 17205b261ecSmrg * signal handlers. 17305b261ecSmrg */ 1746747b715Smrgvolatile char dispatchException = 0; 1756747b715Smrgvolatile char isItTimeToYield; 17605b261ecSmrg 17705b261ecSmrg#define SAME_SCREENS(a, b) (\ 17805b261ecSmrg (a.pScreen == b.pScreen)) 17905b261ecSmrg 1804642e01fSmrgvoid 18105b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) 18205b261ecSmrg{ 18305b261ecSmrg checkForInput[0] = c0; 18405b261ecSmrg checkForInput[1] = c1; 18505b261ecSmrg} 18605b261ecSmrg 1876747b715Smrgvoid 18805b261ecSmrgUpdateCurrentTime(void) 18905b261ecSmrg{ 19005b261ecSmrg TimeStamp systime; 19105b261ecSmrg 19205b261ecSmrg /* To avoid time running backwards, we must call GetTimeInMillis before 19305b261ecSmrg * calling ProcessInputEvents. 19405b261ecSmrg */ 19505b261ecSmrg systime.months = currentTime.months; 19605b261ecSmrg systime.milliseconds = GetTimeInMillis(); 19705b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 198f7df2e56Smrg systime.months++; 19905b261ecSmrg if (*checkForInput[0] != *checkForInput[1]) 200f7df2e56Smrg ProcessInputEvents(); 20105b261ecSmrg if (CompareTimeStamps(systime, currentTime) == LATER) 202f7df2e56Smrg currentTime = systime; 20305b261ecSmrg} 20405b261ecSmrg 20505b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ 2066747b715Smrgvoid 20705b261ecSmrgUpdateCurrentTimeIf(void) 20805b261ecSmrg{ 20905b261ecSmrg TimeStamp systime; 21005b261ecSmrg 21105b261ecSmrg systime.months = currentTime.months; 21205b261ecSmrg systime.milliseconds = GetTimeInMillis(); 21305b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 214f7df2e56Smrg systime.months++; 215f7df2e56Smrg if (CompareTimeStamps(systime, currentTime) == LATER) 216f7df2e56Smrg currentTime = systime; 21705b261ecSmrg} 21805b261ecSmrg 21905b261ecSmrg#undef SMART_DEBUG 22005b261ecSmrg 221f7df2e56Smrg/* in milliseconds */ 222f7df2e56Smrg#define SMART_SCHEDULE_DEFAULT_INTERVAL 5 223f7df2e56Smrg#define SMART_SCHEDULE_MAX_SLICE 15 22405b261ecSmrg 225f7df2e56Smrg#if defined(WIN32) && !defined(__CYGWIN__) 226f7df2e56SmrgBool SmartScheduleDisable = TRUE; 227f7df2e56Smrg#else 2286747b715SmrgBool SmartScheduleDisable = FALSE; 229f7df2e56Smrg#endif 2306747b715Smrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; 2316747b715Smrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; 2326747b715Smrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; 2336747b715Smrglong SmartScheduleTime; 2346747b715Smrgint SmartScheduleLatencyLimited = 0; 235f7df2e56Smrgstatic ClientPtr SmartLastClient; 236f7df2e56Smrgstatic int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1]; 23705b261ecSmrg 23805b261ecSmrg#ifdef SMART_DEBUG 239f7df2e56Smrglong SmartLastPrint; 24005b261ecSmrg#endif 24105b261ecSmrg 242f7df2e56Smrgvoid Dispatch(void); 24305b261ecSmrg 24405b261ecSmrgstatic int 245f7df2e56SmrgSmartScheduleClient(int *clientReady, int nready) 24605b261ecSmrg{ 247f7df2e56Smrg ClientPtr pClient; 248f7df2e56Smrg int i; 249f7df2e56Smrg int client; 250f7df2e56Smrg int bestPrio, best = 0; 251f7df2e56Smrg int bestRobin, robin; 252f7df2e56Smrg long now = SmartScheduleTime; 253f7df2e56Smrg long idle; 25405b261ecSmrg 25505b261ecSmrg bestPrio = -0x7fffffff; 25605b261ecSmrg bestRobin = 0; 25705b261ecSmrg idle = 2 * SmartScheduleSlice; 258f7df2e56Smrg for (i = 0; i < nready; i++) { 259f7df2e56Smrg client = clientReady[i]; 260f7df2e56Smrg pClient = clients[client]; 261f7df2e56Smrg /* Praise clients which haven't run in a while */ 262f7df2e56Smrg if ((now - pClient->smart_stop_tick) >= idle) { 263f7df2e56Smrg if (pClient->smart_priority < 0) 264f7df2e56Smrg pClient->smart_priority++; 265f7df2e56Smrg } 266f7df2e56Smrg 267f7df2e56Smrg /* check priority to select best client */ 268f7df2e56Smrg robin = 269f7df2e56Smrg (pClient->index - 270f7df2e56Smrg SmartLastIndex[pClient->smart_priority - 271f7df2e56Smrg SMART_MIN_PRIORITY]) & 0xff; 272f7df2e56Smrg if (pClient->smart_priority > bestPrio || 273f7df2e56Smrg (pClient->smart_priority == bestPrio && robin > bestRobin)) { 274f7df2e56Smrg bestPrio = pClient->smart_priority; 275f7df2e56Smrg bestRobin = robin; 276f7df2e56Smrg best = client; 277f7df2e56Smrg } 27805b261ecSmrg#ifdef SMART_DEBUG 279f7df2e56Smrg if ((now - SmartLastPrint) >= 5000) 280f7df2e56Smrg fprintf(stderr, " %2d: %3d", client, pClient->smart_priority); 28105b261ecSmrg#endif 28205b261ecSmrg } 28305b261ecSmrg#ifdef SMART_DEBUG 284f7df2e56Smrg if ((now - SmartLastPrint) >= 5000) { 285f7df2e56Smrg fprintf(stderr, " use %2d\n", best); 286f7df2e56Smrg SmartLastPrint = now; 28705b261ecSmrg } 28805b261ecSmrg#endif 28905b261ecSmrg pClient = clients[best]; 290f7df2e56Smrg SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index; 29105b261ecSmrg /* 29205b261ecSmrg * Set current client pointer 29305b261ecSmrg */ 294f7df2e56Smrg if (SmartLastClient != pClient) { 295f7df2e56Smrg pClient->smart_start_tick = now; 296f7df2e56Smrg SmartLastClient = pClient; 29705b261ecSmrg } 29805b261ecSmrg /* 29905b261ecSmrg * Adjust slice 30005b261ecSmrg */ 301f7df2e56Smrg if (nready == 1 && SmartScheduleLatencyLimited == 0) { 302f7df2e56Smrg /* 303f7df2e56Smrg * If it's been a long time since another client 304f7df2e56Smrg * has run, bump the slice up to get maximal 305f7df2e56Smrg * performance from a single client 306f7df2e56Smrg */ 307f7df2e56Smrg if ((now - pClient->smart_start_tick) > 1000 && 308f7df2e56Smrg SmartScheduleSlice < SmartScheduleMaxSlice) { 309f7df2e56Smrg SmartScheduleSlice += SmartScheduleInterval; 310f7df2e56Smrg } 31105b261ecSmrg } 312f7df2e56Smrg else { 313f7df2e56Smrg SmartScheduleSlice = SmartScheduleInterval; 31405b261ecSmrg } 31505b261ecSmrg return best; 31605b261ecSmrg} 31705b261ecSmrg 318b1d344b3Smrgvoid 319b1d344b3SmrgEnableLimitedSchedulingLatency(void) 320b1d344b3Smrg{ 321b1d344b3Smrg ++SmartScheduleLatencyLimited; 322b1d344b3Smrg SmartScheduleSlice = SmartScheduleInterval; 323b1d344b3Smrg} 324b1d344b3Smrg 325b1d344b3Smrgvoid 326b1d344b3SmrgDisableLimitedSchedulingLatency(void) 327b1d344b3Smrg{ 328b1d344b3Smrg --SmartScheduleLatencyLimited; 329b1d344b3Smrg 330b1d344b3Smrg /* protect against bugs */ 331b1d344b3Smrg if (SmartScheduleLatencyLimited < 0) 332f7df2e56Smrg SmartScheduleLatencyLimited = 0; 333b1d344b3Smrg} 334b1d344b3Smrg 33505b261ecSmrgvoid 33605b261ecSmrgDispatch(void) 33705b261ecSmrg{ 338f7df2e56Smrg int *clientReady; /* array of request ready clients */ 339f7df2e56Smrg int result; 340f7df2e56Smrg ClientPtr client; 341f7df2e56Smrg int nready; 342f7df2e56Smrg HWEventQueuePtr *icheck = checkForInput; 343f7df2e56Smrg long start_tick; 34405b261ecSmrg 34505b261ecSmrg nextFreeClientID = 1; 34605b261ecSmrg nClients = 0; 34705b261ecSmrg 348f7df2e56Smrg clientReady = xallocarray(MaxClients, sizeof(int)); 34905b261ecSmrg if (!clientReady) 350f7df2e56Smrg return; 35105b261ecSmrg 352b1d344b3Smrg SmartScheduleSlice = SmartScheduleInterval; 353f7df2e56Smrg while (!dispatchException) { 354f7df2e56Smrg if (*icheck[0] != *icheck[1]) { 355f7df2e56Smrg ProcessInputEvents(); 356f7df2e56Smrg FlushIfCriticalOutputPending(); 357f7df2e56Smrg } 358f7df2e56Smrg 359f7df2e56Smrg nready = WaitForSomething(clientReady); 360f7df2e56Smrg 361f7df2e56Smrg if (nready && !SmartScheduleDisable) { 362f7df2e56Smrg clientReady[0] = SmartScheduleClient(clientReady, nready); 363f7df2e56Smrg nready = 1; 364f7df2e56Smrg } 365f7df2e56Smrg /***************** 366f7df2e56Smrg * Handle events in round robin fashion, doing input between 367f7df2e56Smrg * each round 36805b261ecSmrg *****************/ 36905b261ecSmrg 370f7df2e56Smrg while (!dispatchException && (--nready >= 0)) { 371f7df2e56Smrg client = clients[clientReady[nready]]; 372f7df2e56Smrg if (!client) { 373f7df2e56Smrg /* KillClient can cause this to happen */ 374f7df2e56Smrg continue; 375f7df2e56Smrg } 376f7df2e56Smrg /* GrabServer activation can cause this to be true */ 377f7df2e56Smrg if (grabState == GrabKickout) { 378f7df2e56Smrg grabState = GrabActive; 379f7df2e56Smrg break; 380f7df2e56Smrg } 381f7df2e56Smrg isItTimeToYield = FALSE; 382f7df2e56Smrg 383f7df2e56Smrg start_tick = SmartScheduleTime; 384f7df2e56Smrg while (!isItTimeToYield) { 385f7df2e56Smrg if (*icheck[0] != *icheck[1]) 386f7df2e56Smrg ProcessInputEvents(); 387f7df2e56Smrg 388f7df2e56Smrg FlushIfCriticalOutputPending(); 389f7df2e56Smrg if (!SmartScheduleDisable && 390f7df2e56Smrg (SmartScheduleTime - start_tick) >= SmartScheduleSlice) { 391f7df2e56Smrg /* Penalize clients which consume ticks */ 392f7df2e56Smrg if (client->smart_priority > SMART_MIN_PRIORITY) 393f7df2e56Smrg client->smart_priority--; 394f7df2e56Smrg break; 395f7df2e56Smrg } 396f7df2e56Smrg /* now, finally, deal with client requests */ 397f7df2e56Smrg 398f7df2e56Smrg /* Update currentTime so request time checks, such as for input 399f7df2e56Smrg * device grabs, are calculated correctly */ 400f7df2e56Smrg UpdateCurrentTimeIf(); 401f7df2e56Smrg result = ReadRequestFromClient(client); 402f7df2e56Smrg if (result <= 0) { 403f7df2e56Smrg if (result < 0) 404f7df2e56Smrg CloseDownClient(client); 405f7df2e56Smrg break; 406f7df2e56Smrg } 407f7df2e56Smrg 408f7df2e56Smrg client->sequence++; 409f7df2e56Smrg client->majorOp = ((xReq *) client->requestBuffer)->reqType; 410f7df2e56Smrg client->minorOp = 0; 411f7df2e56Smrg if (client->majorOp >= EXTENSION_BASE) { 412f7df2e56Smrg ExtensionEntry *ext = GetExtensionEntry(client->majorOp); 413f7df2e56Smrg 414f7df2e56Smrg if (ext) 415f7df2e56Smrg client->minorOp = ext->MinorOpcode(client); 416f7df2e56Smrg } 41705b261ecSmrg#ifdef XSERVER_DTRACE 418f7df2e56Smrg if (XSERVER_REQUEST_START_ENABLED()) 419f7df2e56Smrg XSERVER_REQUEST_START(LookupMajorName(client->majorOp), 420f7df2e56Smrg client->majorOp, 421f7df2e56Smrg ((xReq *) client->requestBuffer)->length, 422f7df2e56Smrg client->index, 423f7df2e56Smrg client->requestBuffer); 42405b261ecSmrg#endif 425f7df2e56Smrg if (result > (maxBigRequestSize << 2)) 426f7df2e56Smrg result = BadLength; 427f7df2e56Smrg else { 428f7df2e56Smrg result = XaceHookDispatch(client, client->majorOp); 429f7df2e56Smrg if (result == Success) 430f7df2e56Smrg result = 431f7df2e56Smrg (*client->requestVector[client->majorOp]) (client); 432f7df2e56Smrg XaceHookAuditEnd(client, result); 433f7df2e56Smrg } 43405b261ecSmrg#ifdef XSERVER_DTRACE 435f7df2e56Smrg if (XSERVER_REQUEST_DONE_ENABLED()) 436f7df2e56Smrg XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), 437f7df2e56Smrg client->majorOp, client->sequence, 438f7df2e56Smrg client->index, result); 43905b261ecSmrg#endif 44005b261ecSmrg 441f7df2e56Smrg if (client->noClientException != Success) { 442f7df2e56Smrg CloseDownClient(client); 443f7df2e56Smrg break; 444f7df2e56Smrg } 445f7df2e56Smrg else if (result != Success) { 446f7df2e56Smrg SendErrorToClient(client, client->majorOp, 447f7df2e56Smrg client->minorOp, 448f7df2e56Smrg client->errorValue, result); 449f7df2e56Smrg break; 450f7df2e56Smrg } 451f7df2e56Smrg } 452f7df2e56Smrg FlushAllOutput(); 453f7df2e56Smrg client = clients[clientReady[nready]]; 454f7df2e56Smrg if (client) 455f7df2e56Smrg client->smart_stop_tick = SmartScheduleTime; 456f7df2e56Smrg } 457f7df2e56Smrg dispatchException &= ~DE_PRIORITYCHANGE; 45805b261ecSmrg } 45905b261ecSmrg#if defined(DDXBEFORERESET) 460f7df2e56Smrg ddxBeforeReset(); 46105b261ecSmrg#endif 46205b261ecSmrg KillAllClients(); 4636747b715Smrg free(clientReady); 46405b261ecSmrg dispatchException &= ~DE_RESET; 465b1d344b3Smrg SmartScheduleLatencyLimited = 0; 466f7df2e56Smrg ResetOsBuffers(); 46705b261ecSmrg} 46805b261ecSmrg 469f7df2e56Smrgstatic int VendorRelease = VENDOR_RELEASE; 470f7df2e56Smrgstatic const char *VendorString = VENDOR_NAME; 4716747b715Smrg 4726747b715Smrgvoid 4736747b715SmrgSetVendorRelease(int release) 4746747b715Smrg{ 4756747b715Smrg VendorRelease = release; 4766747b715Smrg} 4776747b715Smrg 4786747b715Smrgvoid 479f7df2e56SmrgSetVendorString(const char *vendor) 4806747b715Smrg{ 481f7df2e56Smrg VendorString = vendor; 4826747b715Smrg} 4836747b715Smrg 4846747b715SmrgBool 4856747b715SmrgCreateConnectionBlock(void) 4866747b715Smrg{ 4876747b715Smrg xConnSetup setup; 4886747b715Smrg xWindowRoot root; 489f7df2e56Smrg xDepth depth; 4906747b715Smrg xVisualType visual; 4916747b715Smrg xPixmapFormat format; 4926747b715Smrg unsigned long vid; 493f7df2e56Smrg int i, j, k, lenofblock, sizesofar = 0; 4946747b715Smrg char *pBuf; 4956747b715Smrg 4966747b715Smrg memset(&setup, 0, sizeof(xConnSetup)); 4976747b715Smrg /* Leave off the ridBase and ridMask, these must be sent with 4986747b715Smrg connection */ 4996747b715Smrg 5006747b715Smrg setup.release = VendorRelease; 5016747b715Smrg /* 5026747b715Smrg * per-server image and bitmap parameters are defined in Xmd.h 5036747b715Smrg */ 5046747b715Smrg setup.imageByteOrder = screenInfo.imageByteOrder; 5056747b715Smrg 5066747b715Smrg setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; 5076747b715Smrg setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; 5086747b715Smrg 5096747b715Smrg setup.bitmapBitOrder = screenInfo.bitmapBitOrder; 5106747b715Smrg setup.motionBufferSize = NumMotionEvents(); 5116747b715Smrg setup.numRoots = screenInfo.numScreens; 5126747b715Smrg setup.nbytesVendor = strlen(VendorString); 5136747b715Smrg setup.numFormats = screenInfo.numPixmapFormats; 5146747b715Smrg setup.maxRequestSize = MAX_REQUEST_SIZE; 5156747b715Smrg QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); 5166747b715Smrg 5176747b715Smrg lenofblock = sizeof(xConnSetup) + 518f7df2e56Smrg pad_to_int32(setup.nbytesVendor) + 519f7df2e56Smrg (setup.numFormats * sizeof(xPixmapFormat)) + 520f7df2e56Smrg (setup.numRoots * sizeof(xWindowRoot)); 5216747b715Smrg ConnectionInfo = malloc(lenofblock); 5226747b715Smrg if (!ConnectionInfo) 523f7df2e56Smrg return FALSE; 5246747b715Smrg 525f7df2e56Smrg memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup)); 5266747b715Smrg sizesofar = sizeof(xConnSetup); 5276747b715Smrg pBuf = ConnectionInfo + sizeof(xConnSetup); 5286747b715Smrg 529f7df2e56Smrg memmove(pBuf, VendorString, (int) setup.nbytesVendor); 5306747b715Smrg sizesofar += setup.nbytesVendor; 5316747b715Smrg pBuf += setup.nbytesVendor; 532f7df2e56Smrg i = padding_for_int32(setup.nbytesVendor); 5336747b715Smrg sizesofar += i; 5346747b715Smrg while (--i >= 0) 535f7df2e56Smrg *pBuf++ = 0; 5366747b715Smrg 5376747b715Smrg memset(&format, 0, sizeof(xPixmapFormat)); 538f7df2e56Smrg for (i = 0; i < screenInfo.numPixmapFormats; i++) { 539f7df2e56Smrg format.depth = screenInfo.formats[i].depth; 540f7df2e56Smrg format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; 541f7df2e56Smrg format.scanLinePad = screenInfo.formats[i].scanlinePad; 542f7df2e56Smrg memmove(pBuf, (char *) &format, sizeof(xPixmapFormat)); 543f7df2e56Smrg pBuf += sizeof(xPixmapFormat); 544f7df2e56Smrg sizesofar += sizeof(xPixmapFormat); 5456747b715Smrg } 5466747b715Smrg 5476747b715Smrg connBlockScreenStart = sizesofar; 5486747b715Smrg memset(&depth, 0, sizeof(xDepth)); 5496747b715Smrg memset(&visual, 0, sizeof(xVisualType)); 550f7df2e56Smrg for (i = 0; i < screenInfo.numScreens; i++) { 551f7df2e56Smrg ScreenPtr pScreen; 552f7df2e56Smrg DepthPtr pDepth; 553f7df2e56Smrg VisualPtr pVisual; 554f7df2e56Smrg 555f7df2e56Smrg pScreen = screenInfo.screens[i]; 556f7df2e56Smrg root.windowId = pScreen->root->drawable.id; 557f7df2e56Smrg root.defaultColormap = pScreen->defColormap; 558f7df2e56Smrg root.whitePixel = pScreen->whitePixel; 559f7df2e56Smrg root.blackPixel = pScreen->blackPixel; 560f7df2e56Smrg root.currentInputMask = 0; /* filled in when sent */ 561f7df2e56Smrg root.pixWidth = pScreen->width; 562f7df2e56Smrg root.pixHeight = pScreen->height; 563f7df2e56Smrg root.mmWidth = pScreen->mmWidth; 564f7df2e56Smrg root.mmHeight = pScreen->mmHeight; 565f7df2e56Smrg root.minInstalledMaps = pScreen->minInstalledCmaps; 566f7df2e56Smrg root.maxInstalledMaps = pScreen->maxInstalledCmaps; 567f7df2e56Smrg root.rootVisualID = pScreen->rootVisual; 568f7df2e56Smrg root.backingStore = pScreen->backingStoreSupport; 569f7df2e56Smrg root.saveUnders = FALSE; 570f7df2e56Smrg root.rootDepth = pScreen->rootDepth; 571f7df2e56Smrg root.nDepths = pScreen->numDepths; 572f7df2e56Smrg memmove(pBuf, (char *) &root, sizeof(xWindowRoot)); 573f7df2e56Smrg sizesofar += sizeof(xWindowRoot); 574f7df2e56Smrg pBuf += sizeof(xWindowRoot); 575f7df2e56Smrg 576f7df2e56Smrg pDepth = pScreen->allowedDepths; 577f7df2e56Smrg for (j = 0; j < pScreen->numDepths; j++, pDepth++) { 578f7df2e56Smrg lenofblock += sizeof(xDepth) + 579f7df2e56Smrg (pDepth->numVids * sizeof(xVisualType)); 580f7df2e56Smrg pBuf = (char *) realloc(ConnectionInfo, lenofblock); 581f7df2e56Smrg if (!pBuf) { 582f7df2e56Smrg free(ConnectionInfo); 583f7df2e56Smrg return FALSE; 584f7df2e56Smrg } 585f7df2e56Smrg ConnectionInfo = pBuf; 586f7df2e56Smrg pBuf += sizesofar; 587f7df2e56Smrg depth.depth = pDepth->depth; 588f7df2e56Smrg depth.nVisuals = pDepth->numVids; 589f7df2e56Smrg memmove(pBuf, (char *) &depth, sizeof(xDepth)); 590f7df2e56Smrg pBuf += sizeof(xDepth); 591f7df2e56Smrg sizesofar += sizeof(xDepth); 592f7df2e56Smrg for (k = 0; k < pDepth->numVids; k++) { 593f7df2e56Smrg vid = pDepth->vids[k]; 594f7df2e56Smrg for (pVisual = pScreen->visuals; 595f7df2e56Smrg pVisual->vid != vid; pVisual++); 596f7df2e56Smrg visual.visualID = vid; 597f7df2e56Smrg visual.class = pVisual->class; 598f7df2e56Smrg visual.bitsPerRGB = pVisual->bitsPerRGBValue; 599f7df2e56Smrg visual.colormapEntries = pVisual->ColormapEntries; 600f7df2e56Smrg visual.redMask = pVisual->redMask; 601f7df2e56Smrg visual.greenMask = pVisual->greenMask; 602f7df2e56Smrg visual.blueMask = pVisual->blueMask; 603f7df2e56Smrg memmove(pBuf, (char *) &visual, sizeof(xVisualType)); 604f7df2e56Smrg pBuf += sizeof(xVisualType); 605f7df2e56Smrg sizesofar += sizeof(xVisualType); 606f7df2e56Smrg } 607f7df2e56Smrg } 6086747b715Smrg } 6096747b715Smrg connSetupPrefix.success = xTrue; 610f7df2e56Smrg connSetupPrefix.length = lenofblock / 4; 6116747b715Smrg connSetupPrefix.majorVersion = X_PROTOCOL; 6126747b715Smrg connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; 6136747b715Smrg return TRUE; 6146747b715Smrg} 6156747b715Smrg 6166747b715Smrgint 61705b261ecSmrgProcBadRequest(ClientPtr client) 61805b261ecSmrg{ 6196747b715Smrg return BadRequest; 62005b261ecSmrg} 62105b261ecSmrg 62205b261ecSmrgint 62305b261ecSmrgProcCreateWindow(ClientPtr client) 62405b261ecSmrg{ 62505b261ecSmrg WindowPtr pParent, pWin; 626f7df2e56Smrg 62705b261ecSmrg REQUEST(xCreateWindowReq); 6284642e01fSmrg int len, rc; 62905b261ecSmrg 63005b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateWindowReq); 631f7df2e56Smrg 63205b261ecSmrg LEGAL_NEW_RESOURCE(stuff->wid, client); 6334642e01fSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 63405b261ecSmrg if (rc != Success) 63505b261ecSmrg return rc; 6366747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); 63705b261ecSmrg if (Ones(stuff->mask) != len) 63805b261ecSmrg return BadLength; 639f7df2e56Smrg if (!stuff->width || !stuff->height) { 640f7df2e56Smrg client->errorValue = 0; 64105b261ecSmrg return BadValue; 64205b261ecSmrg } 64305b261ecSmrg pWin = CreateWindow(stuff->wid, pParent, stuff->x, 644f7df2e56Smrg stuff->y, stuff->width, stuff->height, 645f7df2e56Smrg stuff->borderWidth, stuff->class, 646f7df2e56Smrg stuff->mask, (XID *) &stuff[1], 647f7df2e56Smrg (int) stuff->depth, client, stuff->visual, &rc); 648f7df2e56Smrg if (pWin) { 649f7df2e56Smrg Mask mask = pWin->eventMask; 650f7df2e56Smrg 651f7df2e56Smrg pWin->eventMask = 0; /* subterfuge in case AddResource fails */ 652f7df2e56Smrg if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin)) 653f7df2e56Smrg return BadAlloc; 654f7df2e56Smrg pWin->eventMask = mask; 65505b261ecSmrg } 6566747b715Smrg return rc; 65705b261ecSmrg} 65805b261ecSmrg 65905b261ecSmrgint 66005b261ecSmrgProcChangeWindowAttributes(ClientPtr client) 66105b261ecSmrg{ 66205b261ecSmrg WindowPtr pWin; 663f7df2e56Smrg 66405b261ecSmrg REQUEST(xChangeWindowAttributesReq); 6656747b715Smrg int len, rc; 6664642e01fSmrg Mask access_mode = 0; 66705b261ecSmrg 66805b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); 6694642e01fSmrg access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; 6704642e01fSmrg access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; 6714642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); 67205b261ecSmrg if (rc != Success) 67305b261ecSmrg return rc; 6746747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); 67505b261ecSmrg if (len != Ones(stuff->valueMask)) 67605b261ecSmrg return BadLength; 6776747b715Smrg return ChangeWindowAttributes(pWin, 678f7df2e56Smrg stuff->valueMask, (XID *) &stuff[1], client); 67905b261ecSmrg} 68005b261ecSmrg 68105b261ecSmrgint 68205b261ecSmrgProcGetWindowAttributes(ClientPtr client) 68305b261ecSmrg{ 68405b261ecSmrg WindowPtr pWin; 685f7df2e56Smrg 68605b261ecSmrg REQUEST(xResourceReq); 68705b261ecSmrg xGetWindowAttributesReply wa; 68805b261ecSmrg int rc; 68905b261ecSmrg 69005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 6914642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 69205b261ecSmrg if (rc != Success) 693f7df2e56Smrg return rc; 6946747b715Smrg memset(&wa, 0, sizeof(xGetWindowAttributesReply)); 69505b261ecSmrg GetWindowAttributes(pWin, client, &wa); 69605b261ecSmrg WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); 6976747b715Smrg return Success; 69805b261ecSmrg} 69905b261ecSmrg 70005b261ecSmrgint 70105b261ecSmrgProcDestroyWindow(ClientPtr client) 70205b261ecSmrg{ 70305b261ecSmrg WindowPtr pWin; 704f7df2e56Smrg 70505b261ecSmrg REQUEST(xResourceReq); 70605b261ecSmrg int rc; 70705b261ecSmrg 70805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 70905b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 71005b261ecSmrg if (rc != Success) 711f7df2e56Smrg return rc; 7124642e01fSmrg if (pWin->parent) { 713f7df2e56Smrg rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, 714f7df2e56Smrg DixRemoveAccess); 715f7df2e56Smrg if (rc != Success) 716f7df2e56Smrg return rc; 717f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 7184642e01fSmrg } 7196747b715Smrg return Success; 72005b261ecSmrg} 72105b261ecSmrg 72205b261ecSmrgint 72305b261ecSmrgProcDestroySubwindows(ClientPtr client) 72405b261ecSmrg{ 72505b261ecSmrg WindowPtr pWin; 726f7df2e56Smrg 72705b261ecSmrg REQUEST(xResourceReq); 72805b261ecSmrg int rc; 72905b261ecSmrg 73005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 7314642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); 73205b261ecSmrg if (rc != Success) 733f7df2e56Smrg return rc; 73405b261ecSmrg DestroySubwindows(pWin, client); 7356747b715Smrg return Success; 73605b261ecSmrg} 73705b261ecSmrg 73805b261ecSmrgint 73905b261ecSmrgProcChangeSaveSet(ClientPtr client) 74005b261ecSmrg{ 74105b261ecSmrg WindowPtr pWin; 742f7df2e56Smrg 74305b261ecSmrg REQUEST(xChangeSaveSetReq); 7446747b715Smrg int rc; 745f7df2e56Smrg 74605b261ecSmrg REQUEST_SIZE_MATCH(xChangeSaveSetReq); 7474642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 74805b261ecSmrg if (rc != Success) 74905b261ecSmrg return rc; 75005b261ecSmrg if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) 75105b261ecSmrg return BadMatch; 75205b261ecSmrg if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) 7536747b715Smrg return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); 7546747b715Smrg client->errorValue = stuff->mode; 7556747b715Smrg return BadValue; 75605b261ecSmrg} 75705b261ecSmrg 75805b261ecSmrgint 75905b261ecSmrgProcReparentWindow(ClientPtr client) 76005b261ecSmrg{ 76105b261ecSmrg WindowPtr pWin, pParent; 762f7df2e56Smrg 76305b261ecSmrg REQUEST(xReparentWindowReq); 7646747b715Smrg int rc; 76505b261ecSmrg 76605b261ecSmrg REQUEST_SIZE_MATCH(xReparentWindowReq); 7674642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 76805b261ecSmrg if (rc != Success) 76905b261ecSmrg return rc; 7704642e01fSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 77105b261ecSmrg if (rc != Success) 77205b261ecSmrg return rc; 7736747b715Smrg if (!SAME_SCREENS(pWin->drawable, pParent->drawable)) 774f7df2e56Smrg return BadMatch; 7756747b715Smrg if ((pWin->backgroundState == ParentRelative) && 776f7df2e56Smrg (pParent->drawable.depth != pWin->drawable.depth)) 777f7df2e56Smrg return BadMatch; 7786747b715Smrg if ((pWin->drawable.class != InputOnly) && 779f7df2e56Smrg (pParent->drawable.class == InputOnly)) 780f7df2e56Smrg return BadMatch; 7816747b715Smrg return ReparentWindow(pWin, pParent, 782f7df2e56Smrg (short) stuff->x, (short) stuff->y, client); 78305b261ecSmrg} 78405b261ecSmrg 78505b261ecSmrgint 78605b261ecSmrgProcMapWindow(ClientPtr client) 78705b261ecSmrg{ 78805b261ecSmrg WindowPtr pWin; 789f7df2e56Smrg 79005b261ecSmrg REQUEST(xResourceReq); 79105b261ecSmrg int rc; 79205b261ecSmrg 79305b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 7944642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); 79505b261ecSmrg if (rc != Success) 79605b261ecSmrg return rc; 79705b261ecSmrg MapWindow(pWin, client); 798f7df2e56Smrg /* update cache to say it is mapped */ 7996747b715Smrg return Success; 80005b261ecSmrg} 80105b261ecSmrg 80205b261ecSmrgint 80305b261ecSmrgProcMapSubwindows(ClientPtr client) 80405b261ecSmrg{ 80505b261ecSmrg WindowPtr pWin; 806f7df2e56Smrg 80705b261ecSmrg REQUEST(xResourceReq); 80805b261ecSmrg int rc; 80905b261ecSmrg 81005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8114642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 81205b261ecSmrg if (rc != Success) 81305b261ecSmrg return rc; 81405b261ecSmrg MapSubwindows(pWin, client); 815f7df2e56Smrg /* update cache to say it is mapped */ 8166747b715Smrg return Success; 81705b261ecSmrg} 81805b261ecSmrg 81905b261ecSmrgint 82005b261ecSmrgProcUnmapWindow(ClientPtr client) 82105b261ecSmrg{ 82205b261ecSmrg WindowPtr pWin; 823f7df2e56Smrg 82405b261ecSmrg REQUEST(xResourceReq); 82505b261ecSmrg int rc; 82605b261ecSmrg 82705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8284642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); 82905b261ecSmrg if (rc != Success) 83005b261ecSmrg return rc; 83105b261ecSmrg UnmapWindow(pWin, FALSE); 832f7df2e56Smrg /* update cache to say it is mapped */ 8336747b715Smrg return Success; 83405b261ecSmrg} 83505b261ecSmrg 83605b261ecSmrgint 83705b261ecSmrgProcUnmapSubwindows(ClientPtr client) 83805b261ecSmrg{ 83905b261ecSmrg WindowPtr pWin; 840f7df2e56Smrg 84105b261ecSmrg REQUEST(xResourceReq); 84205b261ecSmrg int rc; 84305b261ecSmrg 84405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8454642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 84605b261ecSmrg if (rc != Success) 84705b261ecSmrg return rc; 84805b261ecSmrg UnmapSubwindows(pWin); 8496747b715Smrg return Success; 85005b261ecSmrg} 85105b261ecSmrg 85205b261ecSmrgint 85305b261ecSmrgProcConfigureWindow(ClientPtr client) 85405b261ecSmrg{ 85505b261ecSmrg WindowPtr pWin; 856f7df2e56Smrg 85705b261ecSmrg REQUEST(xConfigureWindowReq); 85805b261ecSmrg int len, rc; 85905b261ecSmrg 86005b261ecSmrg REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); 8614642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, 862f7df2e56Smrg DixManageAccess | DixSetAttrAccess); 86305b261ecSmrg if (rc != Success) 86405b261ecSmrg return rc; 8656747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); 866f7df2e56Smrg if (Ones((Mask) stuff->mask) != len) 86705b261ecSmrg return BadLength; 868f7df2e56Smrg return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client); 86905b261ecSmrg} 87005b261ecSmrg 87105b261ecSmrgint 87205b261ecSmrgProcCirculateWindow(ClientPtr client) 87305b261ecSmrg{ 87405b261ecSmrg WindowPtr pWin; 875f7df2e56Smrg 87605b261ecSmrg REQUEST(xCirculateWindowReq); 87705b261ecSmrg int rc; 87805b261ecSmrg 87905b261ecSmrg REQUEST_SIZE_MATCH(xCirculateWindowReq); 880f7df2e56Smrg if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) { 881f7df2e56Smrg client->errorValue = stuff->direction; 88205b261ecSmrg return BadValue; 88305b261ecSmrg } 8844642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 88505b261ecSmrg if (rc != Success) 88605b261ecSmrg return rc; 887f7df2e56Smrg CirculateWindow(pWin, (int) stuff->direction, client); 8886747b715Smrg return Success; 88905b261ecSmrg} 89005b261ecSmrg 89105b261ecSmrgstatic int 892f7df2e56SmrgGetGeometry(ClientPtr client, xGetGeometryReply * rep) 89305b261ecSmrg{ 89405b261ecSmrg DrawablePtr pDraw; 89505b261ecSmrg int rc; 896f7df2e56Smrg 89705b261ecSmrg REQUEST(xResourceReq); 89805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 89905b261ecSmrg 9004642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); 90105b261ecSmrg if (rc != Success) 902f7df2e56Smrg return rc; 90305b261ecSmrg 90405b261ecSmrg rep->type = X_Reply; 90505b261ecSmrg rep->length = 0; 90605b261ecSmrg rep->sequenceNumber = client->sequence; 9076747b715Smrg rep->root = pDraw->pScreen->root->drawable.id; 90805b261ecSmrg rep->depth = pDraw->depth; 90905b261ecSmrg rep->width = pDraw->width; 91005b261ecSmrg rep->height = pDraw->height; 91105b261ecSmrg 912f7df2e56Smrg if (WindowDrawable(pDraw->type)) { 913f7df2e56Smrg WindowPtr pWin = (WindowPtr) pDraw; 914f7df2e56Smrg 915f7df2e56Smrg rep->x = pWin->origin.x - wBorderWidth(pWin); 916f7df2e56Smrg rep->y = pWin->origin.y - wBorderWidth(pWin); 917f7df2e56Smrg rep->borderWidth = pWin->borderWidth; 91805b261ecSmrg } 919f7df2e56Smrg else { /* DRAWABLE_PIXMAP */ 920f7df2e56Smrg 921f7df2e56Smrg rep->x = rep->y = rep->borderWidth = 0; 92205b261ecSmrg } 92305b261ecSmrg 92405b261ecSmrg return Success; 92505b261ecSmrg} 92605b261ecSmrg 92705b261ecSmrgint 92805b261ecSmrgProcGetGeometry(ClientPtr client) 92905b261ecSmrg{ 930f7df2e56Smrg xGetGeometryReply rep = { .type = X_Reply }; 93105b261ecSmrg int status; 93205b261ecSmrg 93305b261ecSmrg if ((status = GetGeometry(client, &rep)) != Success) 934f7df2e56Smrg return status; 93505b261ecSmrg 93605b261ecSmrg WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); 9376747b715Smrg return Success; 93805b261ecSmrg} 93905b261ecSmrg 94005b261ecSmrgint 94105b261ecSmrgProcQueryTree(ClientPtr client) 94205b261ecSmrg{ 94305b261ecSmrg xQueryTreeReply reply; 94405b261ecSmrg int rc, numChildren = 0; 94505b261ecSmrg WindowPtr pChild, pWin, pHead; 946f7df2e56Smrg Window *childIDs = (Window *) NULL; 947f7df2e56Smrg 94805b261ecSmrg REQUEST(xResourceReq); 94905b261ecSmrg 95005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 9514642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 95205b261ecSmrg if (rc != Success) 95305b261ecSmrg return rc; 954f7df2e56Smrg 955f7df2e56Smrg reply = (xQueryTreeReply) { 956f7df2e56Smrg .type = X_Reply, 957f7df2e56Smrg .sequenceNumber = client->sequence, 958f7df2e56Smrg .root = pWin->drawable.pScreen->root->drawable.id, 959f7df2e56Smrg .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None 960f7df2e56Smrg }; 96105b261ecSmrg pHead = RealChildHead(pWin); 96205b261ecSmrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 963f7df2e56Smrg numChildren++; 964f7df2e56Smrg if (numChildren) { 965f7df2e56Smrg int curChild = 0; 96605b261ecSmrg 967f7df2e56Smrg childIDs = xallocarray(numChildren, sizeof(Window)); 968f7df2e56Smrg if (!childIDs) 969f7df2e56Smrg return BadAlloc; 970f7df2e56Smrg for (pChild = pWin->lastChild; pChild != pHead; 971f7df2e56Smrg pChild = pChild->prevSib) 972f7df2e56Smrg childIDs[curChild++] = pChild->drawable.id; 97305b261ecSmrg } 974f7df2e56Smrg 97505b261ecSmrg reply.nChildren = numChildren; 9766747b715Smrg reply.length = bytes_to_int32(numChildren * sizeof(Window)); 977f7df2e56Smrg 97805b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); 979f7df2e56Smrg if (numChildren) { 980f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 981f7df2e56Smrg WriteSwappedDataToClient(client, numChildren * sizeof(Window), 982f7df2e56Smrg childIDs); 983f7df2e56Smrg free(childIDs); 98405b261ecSmrg } 98505b261ecSmrg 9866747b715Smrg return Success; 98705b261ecSmrg} 98805b261ecSmrg 98905b261ecSmrgint 99005b261ecSmrgProcInternAtom(ClientPtr client) 99105b261ecSmrg{ 99205b261ecSmrg Atom atom; 99305b261ecSmrg char *tchar; 994f7df2e56Smrg 99505b261ecSmrg REQUEST(xInternAtomReq); 99605b261ecSmrg 99705b261ecSmrg REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); 998f7df2e56Smrg if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) { 999f7df2e56Smrg client->errorValue = stuff->onlyIfExists; 10006747b715Smrg return BadValue; 100105b261ecSmrg } 100205b261ecSmrg tchar = (char *) &stuff[1]; 100305b261ecSmrg atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); 1004f7df2e56Smrg if (atom != BAD_RESOURCE) { 1005f7df2e56Smrg xInternAtomReply reply = { 1006f7df2e56Smrg .type = X_Reply, 1007f7df2e56Smrg .sequenceNumber = client->sequence, 1008f7df2e56Smrg .length = 0, 1009f7df2e56Smrg .atom = atom 1010f7df2e56Smrg }; 1011f7df2e56Smrg WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); 1012f7df2e56Smrg return Success; 101305b261ecSmrg } 101405b261ecSmrg else 1015f7df2e56Smrg return BadAlloc; 101605b261ecSmrg} 101705b261ecSmrg 101805b261ecSmrgint 101905b261ecSmrgProcGetAtomName(ClientPtr client) 102005b261ecSmrg{ 10216747b715Smrg const char *str; 1022f7df2e56Smrg 102305b261ecSmrg REQUEST(xResourceReq); 102405b261ecSmrg 102505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 1026f7df2e56Smrg if ((str = NameForAtom(stuff->id))) { 1027f7df2e56Smrg int len = strlen(str); 1028f7df2e56Smrg xGetAtomNameReply reply = { 1029f7df2e56Smrg .type = X_Reply, 1030f7df2e56Smrg .sequenceNumber = client->sequence, 1031f7df2e56Smrg .length = bytes_to_int32(len), 1032f7df2e56Smrg .nameLength = len 1033f7df2e56Smrg }; 1034f7df2e56Smrg 1035f7df2e56Smrg WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); 1036f7df2e56Smrg WriteToClient(client, len, str); 1037f7df2e56Smrg return Success; 103805b261ecSmrg } 1039f7df2e56Smrg else { 1040f7df2e56Smrg client->errorValue = stuff->id; 1041f7df2e56Smrg return BadAtom; 104205b261ecSmrg } 104305b261ecSmrg} 104405b261ecSmrg 104505b261ecSmrgint 104605b261ecSmrgProcGrabServer(ClientPtr client) 104705b261ecSmrg{ 10484642e01fSmrg int rc; 1049f7df2e56Smrg 105005b261ecSmrg REQUEST_SIZE_MATCH(xReq); 1051f7df2e56Smrg if (grabState != GrabNone && client != grabClient) { 1052f7df2e56Smrg ResetCurrentRequest(client); 1053f7df2e56Smrg client->sequence--; 1054f7df2e56Smrg BITSET(grabWaiters, client->index); 1055f7df2e56Smrg IgnoreClient(client); 1056f7df2e56Smrg return Success; 105705b261ecSmrg } 10584642e01fSmrg rc = OnlyListenToOneClient(client); 10594642e01fSmrg if (rc != Success) 1060f7df2e56Smrg return rc; 106105b261ecSmrg grabState = GrabKickout; 106205b261ecSmrg grabClient = client; 106305b261ecSmrg 1064f7df2e56Smrg if (ServerGrabCallback) { 1065f7df2e56Smrg ServerGrabInfoRec grabinfo; 1066f7df2e56Smrg 1067f7df2e56Smrg grabinfo.client = client; 1068f7df2e56Smrg grabinfo.grabstate = SERVER_GRABBED; 1069f7df2e56Smrg CallCallbacks(&ServerGrabCallback, (void *) &grabinfo); 107005b261ecSmrg } 107105b261ecSmrg 10726747b715Smrg return Success; 107305b261ecSmrg} 107405b261ecSmrg 107505b261ecSmrgstatic void 107605b261ecSmrgUngrabServer(ClientPtr client) 107705b261ecSmrg{ 107805b261ecSmrg int i; 107905b261ecSmrg 108005b261ecSmrg grabState = GrabNone; 108105b261ecSmrg ListenToAllClients(); 1082f7df2e56Smrg for (i = mskcnt; --i >= 0 && !grabWaiters[i];); 1083f7df2e56Smrg if (i >= 0) { 1084f7df2e56Smrg i <<= 5; 1085f7df2e56Smrg while (!GETBIT(grabWaiters, i)) 1086f7df2e56Smrg i++; 1087f7df2e56Smrg BITCLEAR(grabWaiters, i); 1088f7df2e56Smrg AttendClient(clients[i]); 108905b261ecSmrg } 109005b261ecSmrg 1091f7df2e56Smrg if (ServerGrabCallback) { 1092f7df2e56Smrg ServerGrabInfoRec grabinfo; 1093f7df2e56Smrg 1094f7df2e56Smrg grabinfo.client = client; 1095f7df2e56Smrg grabinfo.grabstate = SERVER_UNGRABBED; 1096f7df2e56Smrg CallCallbacks(&ServerGrabCallback, (void *) &grabinfo); 109705b261ecSmrg } 109805b261ecSmrg} 109905b261ecSmrg 110005b261ecSmrgint 110105b261ecSmrgProcUngrabServer(ClientPtr client) 110205b261ecSmrg{ 110305b261ecSmrg REQUEST_SIZE_MATCH(xReq); 110405b261ecSmrg UngrabServer(client); 11056747b715Smrg return Success; 110605b261ecSmrg} 110705b261ecSmrg 110805b261ecSmrgint 110905b261ecSmrgProcTranslateCoords(ClientPtr client) 111005b261ecSmrg{ 111105b261ecSmrg REQUEST(xTranslateCoordsReq); 111205b261ecSmrg 111305b261ecSmrg WindowPtr pWin, pDst; 111405b261ecSmrg xTranslateCoordsReply rep; 111505b261ecSmrg int rc; 111605b261ecSmrg 111705b261ecSmrg REQUEST_SIZE_MATCH(xTranslateCoordsReq); 11184642e01fSmrg rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); 111905b261ecSmrg if (rc != Success) 112005b261ecSmrg return rc; 11214642e01fSmrg rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); 112205b261ecSmrg if (rc != Success) 112305b261ecSmrg return rc; 1124f7df2e56Smrg 1125f7df2e56Smrg rep = (xTranslateCoordsReply) { 1126f7df2e56Smrg .type = X_Reply, 1127f7df2e56Smrg .sequenceNumber = client->sequence, 1128f7df2e56Smrg .length = 0 1129f7df2e56Smrg }; 1130f7df2e56Smrg if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) { 1131f7df2e56Smrg rep.sameScreen = xFalse; 113205b261ecSmrg rep.child = None; 1133f7df2e56Smrg rep.dstX = rep.dstY = 0; 113405b261ecSmrg } 1135f7df2e56Smrg else { 1136f7df2e56Smrg INT16 x, y; 1137f7df2e56Smrg 1138f7df2e56Smrg rep.sameScreen = xTrue; 1139f7df2e56Smrg rep.child = None; 1140f7df2e56Smrg /* computing absolute coordinates -- adjust to destination later */ 1141f7df2e56Smrg x = pWin->drawable.x + stuff->srcX; 1142f7df2e56Smrg y = pWin->drawable.y + stuff->srcY; 1143f7df2e56Smrg pWin = pDst->firstChild; 1144f7df2e56Smrg while (pWin) { 1145f7df2e56Smrg BoxRec box; 1146f7df2e56Smrg 1147f7df2e56Smrg if ((pWin->mapped) && 1148f7df2e56Smrg (x >= pWin->drawable.x - wBorderWidth(pWin)) && 1149f7df2e56Smrg (x < pWin->drawable.x + (int) pWin->drawable.width + 1150f7df2e56Smrg wBorderWidth(pWin)) && 1151f7df2e56Smrg (y >= pWin->drawable.y - wBorderWidth(pWin)) && 1152f7df2e56Smrg (y < pWin->drawable.y + (int) pWin->drawable.height + 1153f7df2e56Smrg wBorderWidth(pWin)) 1154f7df2e56Smrg /* When a window is shaped, a further check 1155f7df2e56Smrg * is made to see if the point is inside 1156f7df2e56Smrg * borderSize 1157f7df2e56Smrg */ 1158f7df2e56Smrg && (!wBoundingShape(pWin) || 1159f7df2e56Smrg RegionContainsPoint(&pWin->borderSize, x, y, &box)) 1160f7df2e56Smrg 1161f7df2e56Smrg && (!wInputShape(pWin) || 1162f7df2e56Smrg RegionContainsPoint(wInputShape(pWin), 1163f7df2e56Smrg x - pWin->drawable.x, 1164f7df2e56Smrg y - pWin->drawable.y, &box)) 1165f7df2e56Smrg ) { 1166f7df2e56Smrg rep.child = pWin->drawable.id; 1167f7df2e56Smrg pWin = (WindowPtr) NULL; 1168f7df2e56Smrg } 1169f7df2e56Smrg else 1170f7df2e56Smrg pWin = pWin->nextSib; 1171f7df2e56Smrg } 1172f7df2e56Smrg /* adjust to destination coordinates */ 1173f7df2e56Smrg rep.dstX = x - pDst->drawable.x; 1174f7df2e56Smrg rep.dstY = y - pDst->drawable.y; 117505b261ecSmrg } 117605b261ecSmrg WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); 11776747b715Smrg return Success; 117805b261ecSmrg} 117905b261ecSmrg 118005b261ecSmrgint 118105b261ecSmrgProcOpenFont(ClientPtr client) 118205b261ecSmrg{ 1183f7df2e56Smrg int err; 1184f7df2e56Smrg 118505b261ecSmrg REQUEST(xOpenFontReq); 118605b261ecSmrg 118705b261ecSmrg REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); 118805b261ecSmrg client->errorValue = stuff->fid; 118905b261ecSmrg LEGAL_NEW_RESOURCE(stuff->fid, client); 119005b261ecSmrg err = OpenFont(client, stuff->fid, (Mask) 0, 1191f7df2e56Smrg stuff->nbytes, (char *) &stuff[1]); 1192f7df2e56Smrg if (err == Success) { 1193f7df2e56Smrg return Success; 119405b261ecSmrg } 119505b261ecSmrg else 1196f7df2e56Smrg return err; 119705b261ecSmrg} 119805b261ecSmrg 119905b261ecSmrgint 120005b261ecSmrgProcCloseFont(ClientPtr client) 120105b261ecSmrg{ 120205b261ecSmrg FontPtr pFont; 12036747b715Smrg int rc; 1204f7df2e56Smrg 120505b261ecSmrg REQUEST(xResourceReq); 120605b261ecSmrg 120705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 1208f7df2e56Smrg rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT, 1209f7df2e56Smrg client, DixDestroyAccess); 1210f7df2e56Smrg if (rc == Success) { 121105b261ecSmrg FreeResource(stuff->id, RT_NONE); 1212f7df2e56Smrg return Success; 121305b261ecSmrg } 1214f7df2e56Smrg else { 1215f7df2e56Smrg client->errorValue = stuff->id; 12166747b715Smrg return rc; 121705b261ecSmrg } 121805b261ecSmrg} 121905b261ecSmrg 122005b261ecSmrgint 122105b261ecSmrgProcQueryFont(ClientPtr client) 122205b261ecSmrg{ 1223f7df2e56Smrg xQueryFontReply *reply; 122405b261ecSmrg FontPtr pFont; 12254642e01fSmrg int rc; 1226f7df2e56Smrg 122705b261ecSmrg REQUEST(xResourceReq); 122805b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 12294642e01fSmrg 12306747b715Smrg rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess); 12314642e01fSmrg if (rc != Success) 1232f7df2e56Smrg return rc; 123305b261ecSmrg 123405b261ecSmrg { 1235f7df2e56Smrg xCharInfo *pmax = FONTINKMAX(pFont); 1236f7df2e56Smrg xCharInfo *pmin = FONTINKMIN(pFont); 1237f7df2e56Smrg int nprotoxcistructs; 1238f7df2e56Smrg int rlength; 1239f7df2e56Smrg 1240f7df2e56Smrg nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing && 1241f7df2e56Smrg pmax->leftSideBearing == pmin->leftSideBearing && 1242f7df2e56Smrg pmax->descent == pmin->descent && 1243f7df2e56Smrg pmax->ascent == pmin->ascent && 1244f7df2e56Smrg pmax->characterWidth == pmin->characterWidth) ? 1245f7df2e56Smrg 0 : N2dChars(pFont); 1246f7df2e56Smrg 1247f7df2e56Smrg rlength = sizeof(xQueryFontReply) + 1248f7df2e56Smrg FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + 1249f7df2e56Smrg nprotoxcistructs * sizeof(xCharInfo); 1250f7df2e56Smrg reply = calloc(1, rlength); 1251f7df2e56Smrg if (!reply) { 1252f7df2e56Smrg return BadAlloc; 1253f7df2e56Smrg } 1254f7df2e56Smrg 1255f7df2e56Smrg reply->type = X_Reply; 1256f7df2e56Smrg reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); 1257f7df2e56Smrg reply->sequenceNumber = client->sequence; 1258f7df2e56Smrg QueryFont(pFont, reply, nprotoxcistructs); 125905b261ecSmrg 126005b261ecSmrg WriteReplyToClient(client, rlength, reply); 1261f7df2e56Smrg free(reply); 1262f7df2e56Smrg return Success; 126305b261ecSmrg } 126405b261ecSmrg} 126505b261ecSmrg 126605b261ecSmrgint 126705b261ecSmrgProcQueryTextExtents(ClientPtr client) 126805b261ecSmrg{ 126905b261ecSmrg xQueryTextExtentsReply reply; 127005b261ecSmrg FontPtr pFont; 127105b261ecSmrg ExtentInfoRec info; 127205b261ecSmrg unsigned long length; 12734642e01fSmrg int rc; 1274f7df2e56Smrg 12754642e01fSmrg REQUEST(xQueryTextExtentsReq); 127605b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); 1277f7df2e56Smrg 12786747b715Smrg rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess); 12794642e01fSmrg if (rc != Success) 1280f7df2e56Smrg return rc; 12814642e01fSmrg 12826747b715Smrg length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); 128305b261ecSmrg length = length << 1; 1284f7df2e56Smrg if (stuff->oddLength) { 1285f7df2e56Smrg if (length == 0) 1286f7df2e56Smrg return BadLength; 128705b261ecSmrg length--; 128805b261ecSmrg } 1289f7df2e56Smrg if (!QueryTextExtents(pFont, length, (unsigned char *) &stuff[1], &info)) 1290f7df2e56Smrg return BadAlloc; 1291f7df2e56Smrg reply = (xQueryTextExtentsReply) { 1292f7df2e56Smrg .type = X_Reply, 1293f7df2e56Smrg .drawDirection = info.drawDirection, 1294f7df2e56Smrg .sequenceNumber = client->sequence, 1295f7df2e56Smrg .length = 0, 1296f7df2e56Smrg .fontAscent = info.fontAscent, 1297f7df2e56Smrg .fontDescent = info.fontDescent, 1298f7df2e56Smrg .overallAscent = info.overallAscent, 1299f7df2e56Smrg .overallDescent = info.overallDescent, 1300f7df2e56Smrg .overallWidth = info.overallWidth, 1301f7df2e56Smrg .overallLeft = info.overallLeft, 1302f7df2e56Smrg .overallRight = info.overallRight 1303f7df2e56Smrg }; 130405b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); 13056747b715Smrg return Success; 130605b261ecSmrg} 130705b261ecSmrg 130805b261ecSmrgint 130905b261ecSmrgProcListFonts(ClientPtr client) 131005b261ecSmrg{ 131105b261ecSmrg REQUEST(xListFontsReq); 131205b261ecSmrg 131305b261ecSmrg REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); 131405b261ecSmrg 1315f7df2e56Smrg return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 1316f7df2e56Smrg stuff->maxNames); 131705b261ecSmrg} 131805b261ecSmrg 131905b261ecSmrgint 132005b261ecSmrgProcListFontsWithInfo(ClientPtr client) 132105b261ecSmrg{ 132205b261ecSmrg REQUEST(xListFontsWithInfoReq); 132305b261ecSmrg 132405b261ecSmrg REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); 132505b261ecSmrg 132605b261ecSmrg return StartListFontsWithInfo(client, stuff->nbytes, 1327f7df2e56Smrg (unsigned char *) &stuff[1], stuff->maxNames); 132805b261ecSmrg} 132905b261ecSmrg 133005b261ecSmrg/** 133105b261ecSmrg * 133205b261ecSmrg * \param value must conform to DeleteType 133305b261ecSmrg */ 133405b261ecSmrgint 1335f7df2e56SmrgdixDestroyPixmap(void *value, XID pid) 133605b261ecSmrg{ 1337f7df2e56Smrg PixmapPtr pPixmap = (PixmapPtr) value; 1338f7df2e56Smrg 1339f7df2e56Smrg return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); 134005b261ecSmrg} 134105b261ecSmrg 134205b261ecSmrgint 134305b261ecSmrgProcCreatePixmap(ClientPtr client) 134405b261ecSmrg{ 134505b261ecSmrg PixmapPtr pMap; 134605b261ecSmrg DrawablePtr pDraw; 1347f7df2e56Smrg 134805b261ecSmrg REQUEST(xCreatePixmapReq); 134905b261ecSmrg DepthPtr pDepth; 135005b261ecSmrg int i, rc; 135105b261ecSmrg 135205b261ecSmrg REQUEST_SIZE_MATCH(xCreatePixmapReq); 135305b261ecSmrg client->errorValue = stuff->pid; 135405b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 1355f7df2e56Smrg 135605b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 1357f7df2e56Smrg DixGetAttrAccess); 135805b261ecSmrg if (rc != Success) 1359f7df2e56Smrg return rc; 136005b261ecSmrg 1361f7df2e56Smrg if (!stuff->width || !stuff->height) { 1362f7df2e56Smrg client->errorValue = 0; 136305b261ecSmrg return BadValue; 136405b261ecSmrg } 1365f7df2e56Smrg if (stuff->width > 32767 || stuff->height > 32767) { 1366f7df2e56Smrg /* It is allowed to try and allocate a pixmap which is larger than 1367f7df2e56Smrg * 32767 in either dimension. However, all of the framebuffer code 1368f7df2e56Smrg * is buggy and does not reliably draw to such big pixmaps, basically 1369f7df2e56Smrg * because the Region data structure operates with signed shorts 1370f7df2e56Smrg * for the rectangles in it. 1371f7df2e56Smrg * 1372f7df2e56Smrg * Furthermore, several places in the X server computes the 1373f7df2e56Smrg * size in bytes of the pixmap and tries to store it in an 1374f7df2e56Smrg * integer. This integer can overflow and cause the allocated size 1375f7df2e56Smrg * to be much smaller. 1376f7df2e56Smrg * 1377f7df2e56Smrg * So, such big pixmaps are rejected here with a BadAlloc 1378f7df2e56Smrg */ 1379f7df2e56Smrg return BadAlloc; 1380f7df2e56Smrg } 1381f7df2e56Smrg if (stuff->depth != 1) { 138205b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 1383f7df2e56Smrg for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++) 1384f7df2e56Smrg if (pDepth->depth == stuff->depth) 1385f7df2e56Smrg goto CreatePmap; 1386f7df2e56Smrg client->errorValue = stuff->depth; 138705b261ecSmrg return BadValue; 138805b261ecSmrg } 1389f7df2e56Smrg CreatePmap: 1390f7df2e56Smrg pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap) 1391f7df2e56Smrg (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0); 1392f7df2e56Smrg if (pMap) { 1393f7df2e56Smrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 1394f7df2e56Smrg pMap->drawable.id = stuff->pid; 1395f7df2e56Smrg /* security creation/labeling check */ 1396f7df2e56Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 1397f7df2e56Smrg pMap, RT_NONE, NULL, DixCreateAccess); 1398f7df2e56Smrg if (rc != Success) { 1399f7df2e56Smrg (*pDraw->pScreen->DestroyPixmap) (pMap); 1400f7df2e56Smrg return rc; 1401f7df2e56Smrg } 1402f7df2e56Smrg if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap)) 1403f7df2e56Smrg return Success; 140405b261ecSmrg } 14056747b715Smrg return BadAlloc; 140605b261ecSmrg} 140705b261ecSmrg 140805b261ecSmrgint 140905b261ecSmrgProcFreePixmap(ClientPtr client) 141005b261ecSmrg{ 141105b261ecSmrg PixmapPtr pMap; 14124642e01fSmrg int rc; 1413f7df2e56Smrg 141405b261ecSmrg REQUEST(xResourceReq); 141505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 14164642e01fSmrg 1417f7df2e56Smrg rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP, 1418f7df2e56Smrg client, DixDestroyAccess); 1419f7df2e56Smrg if (rc == Success) { 1420f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 1421f7df2e56Smrg return Success; 142205b261ecSmrg } 1423f7df2e56Smrg else { 1424f7df2e56Smrg client->errorValue = stuff->id; 1425f7df2e56Smrg return rc; 142605b261ecSmrg } 142705b261ecSmrg} 142805b261ecSmrg 142905b261ecSmrgint 143005b261ecSmrgProcCreateGC(ClientPtr client) 143105b261ecSmrg{ 143205b261ecSmrg int error, rc; 143305b261ecSmrg GC *pGC; 143405b261ecSmrg DrawablePtr pDraw; 143505b261ecSmrg unsigned len; 1436f7df2e56Smrg 143705b261ecSmrg REQUEST(xCreateGCReq); 143805b261ecSmrg 143905b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateGCReq); 144005b261ecSmrg client->errorValue = stuff->gc; 144105b261ecSmrg LEGAL_NEW_RESOURCE(stuff->gc, client); 14424642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 1443f7df2e56Smrg DixGetAttrAccess); 144405b261ecSmrg if (rc != Success) 1445f7df2e56Smrg return rc; 144605b261ecSmrg 1447f7df2e56Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); 144805b261ecSmrg if (len != Ones(stuff->mask)) 144905b261ecSmrg return BadLength; 1450f7df2e56Smrg pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, 1451f7df2e56Smrg stuff->gc, client); 145205b261ecSmrg if (error != Success) 145305b261ecSmrg return error; 1454f7df2e56Smrg if (!AddResource(stuff->gc, RT_GC, (void *) pGC)) 1455f7df2e56Smrg return BadAlloc; 14566747b715Smrg return Success; 145705b261ecSmrg} 145805b261ecSmrg 145905b261ecSmrgint 146005b261ecSmrgProcChangeGC(ClientPtr client) 146105b261ecSmrg{ 146205b261ecSmrg GC *pGC; 146305b261ecSmrg int result; 146405b261ecSmrg unsigned len; 1465f7df2e56Smrg 146605b261ecSmrg REQUEST(xChangeGCReq); 146705b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeGCReq); 146805b261ecSmrg 14694642e01fSmrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 147005b261ecSmrg if (result != Success) 1471f7df2e56Smrg return result; 147205b261ecSmrg 1473f7df2e56Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); 147405b261ecSmrg if (len != Ones(stuff->mask)) 147505b261ecSmrg return BadLength; 147605b261ecSmrg 14776747b715Smrg return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]); 147805b261ecSmrg} 147905b261ecSmrg 148005b261ecSmrgint 148105b261ecSmrgProcCopyGC(ClientPtr client) 148205b261ecSmrg{ 148305b261ecSmrg GC *dstGC; 148405b261ecSmrg GC *pGC; 148505b261ecSmrg int result; 1486f7df2e56Smrg 148705b261ecSmrg REQUEST(xCopyGCReq); 148805b261ecSmrg REQUEST_SIZE_MATCH(xCopyGCReq); 148905b261ecSmrg 14904642e01fSmrg result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); 149105b261ecSmrg if (result != Success) 1492f7df2e56Smrg return result; 14934642e01fSmrg result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); 149405b261ecSmrg if (result != Success) 1495f7df2e56Smrg return result; 149605b261ecSmrg if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 14976747b715Smrg return BadMatch; 1498f7df2e56Smrg if (stuff->mask & ~GCAllBits) { 1499f7df2e56Smrg client->errorValue = stuff->mask; 1500f7df2e56Smrg return BadValue; 150105b261ecSmrg } 15026747b715Smrg return CopyGC(pGC, dstGC, stuff->mask); 150305b261ecSmrg} 150405b261ecSmrg 150505b261ecSmrgint 150605b261ecSmrgProcSetDashes(ClientPtr client) 150705b261ecSmrg{ 150805b261ecSmrg GC *pGC; 150905b261ecSmrg int result; 1510f7df2e56Smrg 151105b261ecSmrg REQUEST(xSetDashesReq); 151205b261ecSmrg 151305b261ecSmrg REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 1514f7df2e56Smrg if (stuff->nDashes == 0) { 1515f7df2e56Smrg client->errorValue = 0; 1516f7df2e56Smrg return BadValue; 151705b261ecSmrg } 151805b261ecSmrg 1519f7df2e56Smrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 152005b261ecSmrg if (result != Success) 1521f7df2e56Smrg return result; 152205b261ecSmrg 15236747b715Smrg /* If there's an error, either there's no sensible errorValue, 15246747b715Smrg * or there was a dash segment of 0. */ 15256747b715Smrg client->errorValue = 0; 15266747b715Smrg return SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 1527f7df2e56Smrg (unsigned char *) &stuff[1]); 152805b261ecSmrg} 152905b261ecSmrg 153005b261ecSmrgint 153105b261ecSmrgProcSetClipRectangles(ClientPtr client) 153205b261ecSmrg{ 1533f7df2e56Smrg int nr, result; 153405b261ecSmrg GC *pGC; 1535f7df2e56Smrg 153605b261ecSmrg REQUEST(xSetClipRectanglesReq); 153705b261ecSmrg 153805b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 153905b261ecSmrg if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 1540f7df2e56Smrg (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) { 1541f7df2e56Smrg client->errorValue = stuff->ordering; 154205b261ecSmrg return BadValue; 154305b261ecSmrg } 1544f7df2e56Smrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 154505b261ecSmrg if (result != Success) 1546f7df2e56Smrg return result; 1547f7df2e56Smrg 154805b261ecSmrg nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 154905b261ecSmrg if (nr & 4) 1550f7df2e56Smrg return BadLength; 155105b261ecSmrg nr >>= 3; 15526747b715Smrg return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 1553f7df2e56Smrg nr, (xRectangle *) &stuff[1], (int) stuff->ordering); 155405b261ecSmrg} 155505b261ecSmrg 155605b261ecSmrgint 155705b261ecSmrgProcFreeGC(ClientPtr client) 155805b261ecSmrg{ 155905b261ecSmrg GC *pGC; 156005b261ecSmrg int rc; 1561f7df2e56Smrg 156205b261ecSmrg REQUEST(xResourceReq); 156305b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 156405b261ecSmrg 156505b261ecSmrg rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 156605b261ecSmrg if (rc != Success) 1567f7df2e56Smrg return rc; 156805b261ecSmrg 156905b261ecSmrg FreeResource(stuff->id, RT_NONE); 15706747b715Smrg return Success; 157105b261ecSmrg} 157205b261ecSmrg 157305b261ecSmrgint 157405b261ecSmrgProcClearToBackground(ClientPtr client) 157505b261ecSmrg{ 157605b261ecSmrg REQUEST(xClearAreaReq); 157705b261ecSmrg WindowPtr pWin; 157805b261ecSmrg int rc; 157905b261ecSmrg 158005b261ecSmrg REQUEST_SIZE_MATCH(xClearAreaReq); 158105b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 158205b261ecSmrg if (rc != Success) 158305b261ecSmrg return rc; 1584f7df2e56Smrg if (pWin->drawable.class == InputOnly) { 1585f7df2e56Smrg client->errorValue = stuff->window; 1586f7df2e56Smrg return BadMatch; 1587f7df2e56Smrg } 1588f7df2e56Smrg if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) { 1589f7df2e56Smrg client->errorValue = stuff->exposures; 15906747b715Smrg return BadValue; 159105b261ecSmrg } 1592f7df2e56Smrg (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y, 1593f7df2e56Smrg stuff->width, stuff->height, 1594f7df2e56Smrg (Bool) stuff->exposures); 15956747b715Smrg return Success; 159605b261ecSmrg} 159705b261ecSmrg 1598f7df2e56Smrg/* send GraphicsExpose events, or a NoExpose event, based on the region */ 1599f7df2e56Smrgvoid 1600f7df2e56SmrgSendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable, 1601f7df2e56Smrg int major, int minor) 1602f7df2e56Smrg{ 1603f7df2e56Smrg if (pRgn && !RegionNil(pRgn)) { 1604f7df2e56Smrg xEvent *pEvent; 1605f7df2e56Smrg xEvent *pe; 1606f7df2e56Smrg BoxPtr pBox; 1607f7df2e56Smrg int i; 1608f7df2e56Smrg int numRects; 1609f7df2e56Smrg 1610f7df2e56Smrg numRects = RegionNumRects(pRgn); 1611f7df2e56Smrg pBox = RegionRects(pRgn); 1612f7df2e56Smrg if (!(pEvent = calloc(numRects, sizeof(xEvent)))) 1613f7df2e56Smrg return; 1614f7df2e56Smrg pe = pEvent; 1615f7df2e56Smrg 1616f7df2e56Smrg for (i = 1; i <= numRects; i++, pe++, pBox++) { 1617f7df2e56Smrg pe->u.u.type = GraphicsExpose; 1618f7df2e56Smrg pe->u.graphicsExposure.drawable = drawable; 1619f7df2e56Smrg pe->u.graphicsExposure.x = pBox->x1; 1620f7df2e56Smrg pe->u.graphicsExposure.y = pBox->y1; 1621f7df2e56Smrg pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; 1622f7df2e56Smrg pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; 1623f7df2e56Smrg pe->u.graphicsExposure.count = numRects - i; 1624f7df2e56Smrg pe->u.graphicsExposure.majorEvent = major; 1625f7df2e56Smrg pe->u.graphicsExposure.minorEvent = minor; 1626f7df2e56Smrg } 1627f7df2e56Smrg /* GraphicsExpose is a "critical event", which TryClientEvents 1628f7df2e56Smrg * handles specially. */ 1629f7df2e56Smrg TryClientEvents(client, NULL, pEvent, numRects, 1630f7df2e56Smrg (Mask) 0, NoEventMask, NullGrab); 1631f7df2e56Smrg free(pEvent); 1632f7df2e56Smrg } 1633f7df2e56Smrg else { 1634f7df2e56Smrg xEvent event = { 1635f7df2e56Smrg .u.noExposure.drawable = drawable, 1636f7df2e56Smrg .u.noExposure.majorEvent = major, 1637f7df2e56Smrg .u.noExposure.minorEvent = minor 1638f7df2e56Smrg }; 1639f7df2e56Smrg event.u.u.type = NoExpose; 1640f7df2e56Smrg WriteEventsToClient(client, 1, &event); 1641f7df2e56Smrg } 1642f7df2e56Smrg} 1643f7df2e56Smrg 164405b261ecSmrgint 164505b261ecSmrgProcCopyArea(ClientPtr client) 164605b261ecSmrg{ 164705b261ecSmrg DrawablePtr pDst; 164805b261ecSmrg DrawablePtr pSrc; 164905b261ecSmrg GC *pGC; 1650f7df2e56Smrg 165105b261ecSmrg REQUEST(xCopyAreaReq); 165205b261ecSmrg RegionPtr pRgn; 165305b261ecSmrg int rc; 165405b261ecSmrg 165505b261ecSmrg REQUEST_SIZE_MATCH(xCopyAreaReq); 165605b261ecSmrg 1657f7df2e56Smrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 1658f7df2e56Smrg if (stuff->dstDrawable != stuff->srcDrawable) { 1659f7df2e56Smrg rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 1660f7df2e56Smrg DixReadAccess); 1661f7df2e56Smrg if (rc != Success) 1662f7df2e56Smrg return rc; 1663f7df2e56Smrg if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) { 1664f7df2e56Smrg client->errorValue = stuff->dstDrawable; 1665f7df2e56Smrg return BadMatch; 1666f7df2e56Smrg } 166705b261ecSmrg } 166805b261ecSmrg else 166905b261ecSmrg pSrc = pDst; 167005b261ecSmrg 1671f7df2e56Smrg pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 1672f7df2e56Smrg stuff->width, stuff->height, 1673f7df2e56Smrg stuff->dstX, stuff->dstY); 1674f7df2e56Smrg if (pGC->graphicsExposures) { 1675f7df2e56Smrg SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 1676f7df2e56Smrg if (pRgn) 1677f7df2e56Smrg RegionDestroy(pRgn); 167805b261ecSmrg } 167905b261ecSmrg 16806747b715Smrg return Success; 168105b261ecSmrg} 168205b261ecSmrg 168305b261ecSmrgint 168405b261ecSmrgProcCopyPlane(ClientPtr client) 168505b261ecSmrg{ 168605b261ecSmrg DrawablePtr psrcDraw, pdstDraw; 168705b261ecSmrg GC *pGC; 1688f7df2e56Smrg 168905b261ecSmrg REQUEST(xCopyPlaneReq); 169005b261ecSmrg RegionPtr pRgn; 169105b261ecSmrg int rc; 169205b261ecSmrg 169305b261ecSmrg REQUEST_SIZE_MATCH(xCopyPlaneReq); 169405b261ecSmrg 16954642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); 1696f7df2e56Smrg if (stuff->dstDrawable != stuff->srcDrawable) { 1697f7df2e56Smrg rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 1698f7df2e56Smrg DixReadAccess); 1699f7df2e56Smrg if (rc != Success) 1700f7df2e56Smrg return rc; 1701f7df2e56Smrg 1702f7df2e56Smrg if (pdstDraw->pScreen != psrcDraw->pScreen) { 1703f7df2e56Smrg client->errorValue = stuff->dstDrawable; 1704f7df2e56Smrg return BadMatch; 1705f7df2e56Smrg } 170605b261ecSmrg } 170705b261ecSmrg else 170805b261ecSmrg psrcDraw = pdstDraw; 170905b261ecSmrg 171005b261ecSmrg /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 1711f7df2e56Smrg if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 1712f7df2e56Smrg (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) { 1713f7df2e56Smrg client->errorValue = stuff->bitPlane; 1714f7df2e56Smrg return BadValue; 171505b261ecSmrg } 171605b261ecSmrg 1717f7df2e56Smrg pRgn = 1718f7df2e56Smrg (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX, 1719f7df2e56Smrg stuff->srcY, stuff->width, stuff->height, 1720f7df2e56Smrg stuff->dstX, stuff->dstY, stuff->bitPlane); 1721f7df2e56Smrg if (pGC->graphicsExposures) { 1722f7df2e56Smrg SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 1723f7df2e56Smrg if (pRgn) 1724f7df2e56Smrg RegionDestroy(pRgn); 172505b261ecSmrg } 17266747b715Smrg return Success; 172705b261ecSmrg} 172805b261ecSmrg 172905b261ecSmrgint 173005b261ecSmrgProcPolyPoint(ClientPtr client) 173105b261ecSmrg{ 173205b261ecSmrg int npoint; 173305b261ecSmrg GC *pGC; 173405b261ecSmrg DrawablePtr pDraw; 1735f7df2e56Smrg 173605b261ecSmrg REQUEST(xPolyPointReq); 173705b261ecSmrg 173805b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyPointReq); 1739f7df2e56Smrg if ((stuff->coordMode != CoordModeOrigin) && 1740f7df2e56Smrg (stuff->coordMode != CoordModePrevious)) { 1741f7df2e56Smrg client->errorValue = stuff->coordMode; 174205b261ecSmrg return BadValue; 174305b261ecSmrg } 1744f7df2e56Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 17456747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); 174605b261ecSmrg if (npoint) 1747f7df2e56Smrg (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint, 1748f7df2e56Smrg (xPoint *) &stuff[1]); 17496747b715Smrg return Success; 175005b261ecSmrg} 175105b261ecSmrg 175205b261ecSmrgint 175305b261ecSmrgProcPolyLine(ClientPtr client) 175405b261ecSmrg{ 175505b261ecSmrg int npoint; 175605b261ecSmrg GC *pGC; 175705b261ecSmrg DrawablePtr pDraw; 1758f7df2e56Smrg 175905b261ecSmrg REQUEST(xPolyLineReq); 176005b261ecSmrg 176105b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyLineReq); 1762f7df2e56Smrg if ((stuff->coordMode != CoordModeOrigin) && 1763f7df2e56Smrg (stuff->coordMode != CoordModePrevious)) { 1764f7df2e56Smrg client->errorValue = stuff->coordMode; 176505b261ecSmrg return BadValue; 176605b261ecSmrg } 17674642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 17686747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); 176905b261ecSmrg if (npoint > 1) 1770f7df2e56Smrg (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint, 1771f7df2e56Smrg (DDXPointPtr) &stuff[1]); 17726747b715Smrg return Success; 177305b261ecSmrg} 177405b261ecSmrg 177505b261ecSmrgint 177605b261ecSmrgProcPolySegment(ClientPtr client) 177705b261ecSmrg{ 177805b261ecSmrg int nsegs; 177905b261ecSmrg GC *pGC; 178005b261ecSmrg DrawablePtr pDraw; 1781f7df2e56Smrg 178205b261ecSmrg REQUEST(xPolySegmentReq); 178305b261ecSmrg 178405b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 17854642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 178605b261ecSmrg nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 178705b261ecSmrg if (nsegs & 4) 1788f7df2e56Smrg return BadLength; 178905b261ecSmrg nsegs >>= 3; 179005b261ecSmrg if (nsegs) 1791f7df2e56Smrg (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 17926747b715Smrg return Success; 179305b261ecSmrg} 179405b261ecSmrg 179505b261ecSmrgint 1796f7df2e56SmrgProcPolyRectangle(ClientPtr client) 179705b261ecSmrg{ 179805b261ecSmrg int nrects; 179905b261ecSmrg GC *pGC; 180005b261ecSmrg DrawablePtr pDraw; 1801f7df2e56Smrg 180205b261ecSmrg REQUEST(xPolyRectangleReq); 180305b261ecSmrg 180405b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 18054642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 180605b261ecSmrg nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 180705b261ecSmrg if (nrects & 4) 1808f7df2e56Smrg return BadLength; 180905b261ecSmrg nrects >>= 3; 181005b261ecSmrg if (nrects) 1811f7df2e56Smrg (*pGC->ops->PolyRectangle) (pDraw, pGC, 1812f7df2e56Smrg nrects, (xRectangle *) &stuff[1]); 18136747b715Smrg return Success; 181405b261ecSmrg} 181505b261ecSmrg 181605b261ecSmrgint 181705b261ecSmrgProcPolyArc(ClientPtr client) 181805b261ecSmrg{ 1819f7df2e56Smrg int narcs; 182005b261ecSmrg GC *pGC; 182105b261ecSmrg DrawablePtr pDraw; 1822f7df2e56Smrg 182305b261ecSmrg REQUEST(xPolyArcReq); 182405b261ecSmrg 182505b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyArcReq); 18264642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 182705b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 182805b261ecSmrg if (narcs % sizeof(xArc)) 1829f7df2e56Smrg return BadLength; 183005b261ecSmrg narcs /= sizeof(xArc); 183105b261ecSmrg if (narcs) 1832f7df2e56Smrg (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 18336747b715Smrg return Success; 183405b261ecSmrg} 183505b261ecSmrg 183605b261ecSmrgint 183705b261ecSmrgProcFillPoly(ClientPtr client) 183805b261ecSmrg{ 1839f7df2e56Smrg int things; 184005b261ecSmrg GC *pGC; 184105b261ecSmrg DrawablePtr pDraw; 1842f7df2e56Smrg 184305b261ecSmrg REQUEST(xFillPolyReq); 184405b261ecSmrg 184505b261ecSmrg REQUEST_AT_LEAST_SIZE(xFillPolyReq); 1846f7df2e56Smrg if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 1847f7df2e56Smrg (stuff->shape != Convex)) { 1848f7df2e56Smrg client->errorValue = stuff->shape; 184905b261ecSmrg return BadValue; 185005b261ecSmrg } 1851f7df2e56Smrg if ((stuff->coordMode != CoordModeOrigin) && 1852f7df2e56Smrg (stuff->coordMode != CoordModePrevious)) { 1853f7df2e56Smrg client->errorValue = stuff->coordMode; 185405b261ecSmrg return BadValue; 185505b261ecSmrg } 185605b261ecSmrg 18574642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 18586747b715Smrg things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); 185905b261ecSmrg if (things) 186005b261ecSmrg (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 1861f7df2e56Smrg stuff->coordMode, things, 1862f7df2e56Smrg (DDXPointPtr) &stuff[1]); 18636747b715Smrg return Success; 186405b261ecSmrg} 186505b261ecSmrg 186605b261ecSmrgint 186705b261ecSmrgProcPolyFillRectangle(ClientPtr client) 186805b261ecSmrg{ 1869f7df2e56Smrg int things; 187005b261ecSmrg GC *pGC; 187105b261ecSmrg DrawablePtr pDraw; 1872f7df2e56Smrg 187305b261ecSmrg REQUEST(xPolyFillRectangleReq); 187405b261ecSmrg 187505b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 18764642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 187705b261ecSmrg things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 187805b261ecSmrg if (things & 4) 1879f7df2e56Smrg return BadLength; 188005b261ecSmrg things >>= 3; 188105b261ecSmrg 188205b261ecSmrg if (things) 188305b261ecSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 1884f7df2e56Smrg (xRectangle *) &stuff[1]); 18856747b715Smrg return Success; 188605b261ecSmrg} 188705b261ecSmrg 188805b261ecSmrgint 188905b261ecSmrgProcPolyFillArc(ClientPtr client) 189005b261ecSmrg{ 1891f7df2e56Smrg int narcs; 189205b261ecSmrg GC *pGC; 189305b261ecSmrg DrawablePtr pDraw; 1894f7df2e56Smrg 189505b261ecSmrg REQUEST(xPolyFillArcReq); 189605b261ecSmrg 189705b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 18984642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 189905b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 190005b261ecSmrg if (narcs % sizeof(xArc)) 1901f7df2e56Smrg return BadLength; 190205b261ecSmrg narcs /= sizeof(xArc); 190305b261ecSmrg if (narcs) 190405b261ecSmrg (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 19056747b715Smrg return Success; 190605b261ecSmrg} 190705b261ecSmrg 190805b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 190905b261ecSmrg 191005b261ecSmrgint 1911f7df2e56SmrgServerOrder(void) 191205b261ecSmrg{ 1913f7df2e56Smrg int whichbyte = 1; 191405b261ecSmrg 191505b261ecSmrg if (*((char *) &whichbyte)) 1916f7df2e56Smrg return LSBFirst; 191705b261ecSmrg return MSBFirst; 191805b261ecSmrg} 191905b261ecSmrg 192005b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 192105b261ecSmrg 192205b261ecSmrgvoid 1923f7df2e56SmrgReformatImage(char *base, int nbytes, int bpp, int order) 192405b261ecSmrg{ 192505b261ecSmrg switch (bpp) { 1926f7df2e56Smrg case 1: /* yuck */ 1927f7df2e56Smrg if (BITMAP_BIT_ORDER != order) 1928f7df2e56Smrg BitOrderInvert((unsigned char *) base, nbytes); 192905b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 1930f7df2e56Smrg ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order); 193105b261ecSmrg#endif 1932f7df2e56Smrg break; 193305b261ecSmrg case 4: 1934f7df2e56Smrg break; /* yuck */ 193505b261ecSmrg case 8: 1936f7df2e56Smrg break; 193705b261ecSmrg case 16: 1938f7df2e56Smrg if (IMAGE_BYTE_ORDER != order) 1939f7df2e56Smrg TwoByteSwap((unsigned char *) base, nbytes); 1940f7df2e56Smrg break; 194105b261ecSmrg case 32: 1942f7df2e56Smrg if (IMAGE_BYTE_ORDER != order) 1943f7df2e56Smrg FourByteSwap((unsigned char *) base, nbytes); 1944f7df2e56Smrg break; 194505b261ecSmrg } 194605b261ecSmrg} 194705b261ecSmrg#else 194805b261ecSmrg#define ReformatImage(b,n,bpp,o) 194905b261ecSmrg#endif 195005b261ecSmrg 195105b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to 195205b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 195305b261ecSmrg * to use internally. Removes need for internal alignment checking. 195405b261ecSmrg * All of the PutImage functions could be changed individually, but 195505b261ecSmrg * as currently written, they call other routines which require things 195605b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here. 195705b261ecSmrg * If an image would be padded differently for 64- versus 32-, then 195805b261ecSmrg * copy each scanline to a 64-bit padded scanline. 195905b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit 196005b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction. 196105b261ecSmrg */ 196205b261ecSmrgint 196305b261ecSmrgProcPutImage(ClientPtr client) 196405b261ecSmrg{ 196505b261ecSmrg GC *pGC; 196605b261ecSmrg DrawablePtr pDraw; 1967f7df2e56Smrg long length; /* length of scanline server padded */ 1968f7df2e56Smrg long lengthProto; /* length of scanline protocol padded */ 1969f7df2e56Smrg char *tmpImage; 1970f7df2e56Smrg 197105b261ecSmrg REQUEST(xPutImageReq); 197205b261ecSmrg 197305b261ecSmrg REQUEST_AT_LEAST_SIZE(xPutImageReq); 19744642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1975f7df2e56Smrg if (stuff->format == XYBitmap) { 197605b261ecSmrg if ((stuff->depth != 1) || 1977f7df2e56Smrg (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad)) 197805b261ecSmrg return BadMatch; 1979f7df2e56Smrg length = BitmapBytePad(stuff->width + stuff->leftPad); 198005b261ecSmrg } 1981f7df2e56Smrg else if (stuff->format == XYPixmap) { 1982f7df2e56Smrg if ((pDraw->depth != stuff->depth) || 1983f7df2e56Smrg (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad)) 198405b261ecSmrg return BadMatch; 1985f7df2e56Smrg length = BitmapBytePad(stuff->width + stuff->leftPad); 1986f7df2e56Smrg length *= stuff->depth; 198705b261ecSmrg } 1988f7df2e56Smrg else if (stuff->format == ZPixmap) { 198905b261ecSmrg if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 199005b261ecSmrg return BadMatch; 1991f7df2e56Smrg length = PixmapBytePad(stuff->width, stuff->depth); 199205b261ecSmrg } 1993f7df2e56Smrg else { 1994f7df2e56Smrg client->errorValue = stuff->format; 199505b261ecSmrg return BadValue; 199605b261ecSmrg } 199705b261ecSmrg 1998f7df2e56Smrg tmpImage = (char *) &stuff[1]; 199905b261ecSmrg lengthProto = length; 20000b0d8713Smrg 2001f7df2e56Smrg if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height)) 20020b0d8713Smrg return BadLength; 2003f7df2e56Smrg 20046747b715Smrg if ((bytes_to_int32(lengthProto * stuff->height) + 2005f7df2e56Smrg bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) 2006f7df2e56Smrg return BadLength; 2007f7df2e56Smrg 2008f7df2e56Smrg ReformatImage(tmpImage, lengthProto * stuff->height, 2009f7df2e56Smrg stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1, 2010f7df2e56Smrg ClientOrder(client)); 201105b261ecSmrg 201205b261ecSmrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 2013f7df2e56Smrg stuff->width, stuff->height, 2014f7df2e56Smrg stuff->leftPad, stuff->format, tmpImage); 201505b261ecSmrg 2016f7df2e56Smrg return Success; 201705b261ecSmrg} 201805b261ecSmrg 201905b261ecSmrgstatic int 2020f7df2e56SmrgDoGetImage(ClientPtr client, int format, Drawable drawable, 2021f7df2e56Smrg int x, int y, int width, int height, 2022f7df2e56Smrg Mask planemask) 202305b261ecSmrg{ 2024f7df2e56Smrg DrawablePtr pDraw, pBoundingDraw; 2025f7df2e56Smrg int nlines, linesPerBuf, rc; 2026f7df2e56Smrg int linesDone; 2027f7df2e56Smrg 20286747b715Smrg /* coordinates relative to the bounding drawable */ 2029f7df2e56Smrg int relx, rely; 2030f7df2e56Smrg long widthBytesLine, length; 2031f7df2e56Smrg Mask plane = 0; 2032f7df2e56Smrg char *pBuf; 2033f7df2e56Smrg xGetImageReply xgi; 203405b261ecSmrg RegionPtr pVisibleRegion = NULL; 203505b261ecSmrg 2036f7df2e56Smrg if ((format != XYPixmap) && (format != ZPixmap)) { 2037f7df2e56Smrg client->errorValue = format; 20386747b715Smrg return BadValue; 203905b261ecSmrg } 204005b261ecSmrg rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 204105b261ecSmrg if (rc != Success) 2042f7df2e56Smrg return rc; 204305b261ecSmrg 20446747b715Smrg memset(&xgi, 0, sizeof(xGetImageReply)); 20456747b715Smrg 20466747b715Smrg relx = x; 20476747b715Smrg rely = y; 20486747b715Smrg 2049f7df2e56Smrg if (pDraw->type == DRAWABLE_WINDOW) { 2050f7df2e56Smrg WindowPtr pWin = (WindowPtr) pDraw; 2051f7df2e56Smrg 2052f7df2e56Smrg /* "If the drawable is a window, the window must be viewable ... or a 2053f7df2e56Smrg * BadMatch error results" */ 2054f7df2e56Smrg if (!pWin->viewable) 2055f7df2e56Smrg return BadMatch; 20566747b715Smrg 2057f7df2e56Smrg /* If the drawable is a window, the rectangle must be contained within 2058f7df2e56Smrg * its bounds (including the border). */ 2059f7df2e56Smrg if (x < -wBorderWidth(pWin) || 2060f7df2e56Smrg x + width > wBorderWidth(pWin) + (int) pDraw->width || 2061f7df2e56Smrg y < -wBorderWidth(pWin) || 2062f7df2e56Smrg y + height > wBorderWidth(pWin) + (int) pDraw->height) 2063f7df2e56Smrg return BadMatch; 20646747b715Smrg 2065f7df2e56Smrg relx += pDraw->x; 2066f7df2e56Smrg rely += pDraw->y; 20676747b715Smrg 2068f7df2e56Smrg if (pDraw->pScreen->GetWindowPixmap) { 2069f7df2e56Smrg PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); 20706747b715Smrg 2071f7df2e56Smrg pBoundingDraw = &pPix->drawable; 20726747b715Smrg#ifdef COMPOSITE 2073f7df2e56Smrg relx -= pPix->screen_x; 2074f7df2e56Smrg rely -= pPix->screen_y; 20756747b715Smrg#endif 2076f7df2e56Smrg } 2077f7df2e56Smrg else { 2078f7df2e56Smrg pBoundingDraw = (DrawablePtr) pDraw->pScreen->root; 2079f7df2e56Smrg } 20806747b715Smrg 2081f7df2e56Smrg xgi.visual = wVisual(pWin); 208205b261ecSmrg } 2083f7df2e56Smrg else { 2084f7df2e56Smrg pBoundingDraw = pDraw; 2085f7df2e56Smrg xgi.visual = None; 208605b261ecSmrg } 208705b261ecSmrg 20886747b715Smrg /* "If the drawable is a pixmap, the given rectangle must be wholly 20896747b715Smrg * contained within the pixmap, or a BadMatch error results. If the 20906747b715Smrg * drawable is a window [...] it must be the case that if there were no 20916747b715Smrg * inferiors or overlapping windows, the specified rectangle of the window 20926747b715Smrg * would be fully visible on the screen and wholly contained within the 20936747b715Smrg * outside edges of the window, or a BadMatch error results." 20946747b715Smrg * 20956747b715Smrg * We relax the window case slightly to mean that the rectangle must exist 20966747b715Smrg * within the bounds of the window's backing pixmap. In particular, this 20976747b715Smrg * means that a GetImage request may succeed or fail with BadMatch depending 20986747b715Smrg * on whether any of its ancestor windows are redirected. */ 2099f7df2e56Smrg if (relx < 0 || relx + width > (int) pBoundingDraw->width || 2100f7df2e56Smrg rely < 0 || rely + height > (int) pBoundingDraw->height) 2101f7df2e56Smrg return BadMatch; 21026747b715Smrg 210305b261ecSmrg xgi.type = X_Reply; 210405b261ecSmrg xgi.sequenceNumber = client->sequence; 210505b261ecSmrg xgi.depth = pDraw->depth; 2106f7df2e56Smrg if (format == ZPixmap) { 2107f7df2e56Smrg widthBytesLine = PixmapBytePad(width, pDraw->depth); 2108f7df2e56Smrg length = widthBytesLine * height; 210905b261ecSmrg 211005b261ecSmrg } 2111f7df2e56Smrg else { 2112f7df2e56Smrg widthBytesLine = BitmapBytePad(width); 2113f7df2e56Smrg plane = ((Mask) 1) << (pDraw->depth - 1); 2114f7df2e56Smrg /* only planes asked for */ 2115f7df2e56Smrg length = widthBytesLine * height * 2116f7df2e56Smrg Ones(planemask & (plane | (plane - 1))); 211705b261ecSmrg 211805b261ecSmrg } 211905b261ecSmrg 212005b261ecSmrg xgi.length = length; 212105b261ecSmrg 2122f7df2e56Smrg xgi.length = bytes_to_int32(xgi.length); 2123f7df2e56Smrg if (widthBytesLine == 0 || height == 0) 2124f7df2e56Smrg linesPerBuf = 0; 2125f7df2e56Smrg else if (widthBytesLine >= IMAGE_BUFSIZE) 2126f7df2e56Smrg linesPerBuf = 1; 2127f7df2e56Smrg else { 2128f7df2e56Smrg linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 2129f7df2e56Smrg if (linesPerBuf > height) 2130f7df2e56Smrg linesPerBuf = height; 2131f7df2e56Smrg } 2132f7df2e56Smrg length = linesPerBuf * widthBytesLine; 2133f7df2e56Smrg if (linesPerBuf < height) { 2134f7df2e56Smrg /* we have to make sure intermediate buffers don't need padding */ 2135f7df2e56Smrg while ((linesPerBuf > 1) && 2136f7df2e56Smrg (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) { 2137f7df2e56Smrg linesPerBuf--; 2138f7df2e56Smrg length -= widthBytesLine; 2139f7df2e56Smrg } 2140f7df2e56Smrg while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) { 2141f7df2e56Smrg linesPerBuf++; 2142f7df2e56Smrg length += widthBytesLine; 2143f7df2e56Smrg } 214405b261ecSmrg } 2145f7df2e56Smrg if (!(pBuf = calloc(1, length))) 2146f7df2e56Smrg return BadAlloc; 2147f7df2e56Smrg WriteReplyToClient(client, sizeof(xGetImageReply), &xgi); 214805b261ecSmrg 2149f7df2e56Smrg if (pDraw->type == DRAWABLE_WINDOW) { 2150f7df2e56Smrg pVisibleRegion = NotClippedByChildren((WindowPtr) pDraw); 2151f7df2e56Smrg if (pVisibleRegion) { 2152f7df2e56Smrg RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y); 2153f7df2e56Smrg } 215405b261ecSmrg } 2155f7df2e56Smrg 2156f7df2e56Smrg if (linesPerBuf == 0) { 2157f7df2e56Smrg /* nothing to do */ 2158f7df2e56Smrg } 2159f7df2e56Smrg else if (format == ZPixmap) { 216005b261ecSmrg linesDone = 0; 2161f7df2e56Smrg while (height - linesDone > 0) { 2162f7df2e56Smrg nlines = min(linesPerBuf, height - linesDone); 2163f7df2e56Smrg (*pDraw->pScreen->GetImage) (pDraw, 2164f7df2e56Smrg x, 2165f7df2e56Smrg y + linesDone, 2166f7df2e56Smrg width, 2167f7df2e56Smrg nlines, 2168f7df2e56Smrg format, planemask, (void *) pBuf); 2169f7df2e56Smrg if (pVisibleRegion) 2170f7df2e56Smrg XaceCensorImage(client, pVisibleRegion, widthBytesLine, 2171f7df2e56Smrg pDraw, x, y + linesDone, width, 2172f7df2e56Smrg nlines, format, pBuf); 2173f7df2e56Smrg 2174f7df2e56Smrg /* Note that this is NOT a call to WriteSwappedDataToClient, 217505b261ecSmrg as we do NOT byte swap */ 2176f7df2e56Smrg ReformatImage(pBuf, (int) (nlines * widthBytesLine), 2177f7df2e56Smrg BitsPerPixel(pDraw->depth), ClientOrder(client)); 2178f7df2e56Smrg 2179f7df2e56Smrg WriteToClient(client, (int) (nlines * widthBytesLine), pBuf); 2180f7df2e56Smrg linesDone += nlines; 218105b261ecSmrg } 218205b261ecSmrg } 2183f7df2e56Smrg else { /* XYPixmap */ 2184f7df2e56Smrg 2185f7df2e56Smrg for (; plane; plane >>= 1) { 2186f7df2e56Smrg if (planemask & plane) { 2187f7df2e56Smrg linesDone = 0; 2188f7df2e56Smrg while (height - linesDone > 0) { 2189f7df2e56Smrg nlines = min(linesPerBuf, height - linesDone); 2190f7df2e56Smrg (*pDraw->pScreen->GetImage) (pDraw, 2191f7df2e56Smrg x, 2192f7df2e56Smrg y + linesDone, 2193f7df2e56Smrg width, 2194f7df2e56Smrg nlines, 2195f7df2e56Smrg format, plane, (void *) pBuf); 2196f7df2e56Smrg if (pVisibleRegion) 2197f7df2e56Smrg XaceCensorImage(client, pVisibleRegion, 2198f7df2e56Smrg widthBytesLine, 2199f7df2e56Smrg pDraw, x, y + linesDone, width, 2200f7df2e56Smrg nlines, format, pBuf); 2201f7df2e56Smrg 2202f7df2e56Smrg /* Note: NOT a call to WriteSwappedDataToClient, 2203f7df2e56Smrg as we do NOT byte swap */ 2204f7df2e56Smrg ReformatImage(pBuf, (int) (nlines * widthBytesLine), 2205f7df2e56Smrg 1, ClientOrder(client)); 2206f7df2e56Smrg 2207f7df2e56Smrg WriteToClient(client, (int)(nlines * widthBytesLine), pBuf); 2208f7df2e56Smrg linesDone += nlines; 2209f7df2e56Smrg } 221005b261ecSmrg } 2211f7df2e56Smrg } 221205b261ecSmrg } 221305b261ecSmrg if (pVisibleRegion) 2214f7df2e56Smrg RegionDestroy(pVisibleRegion); 2215f7df2e56Smrg free(pBuf); 22166747b715Smrg return Success; 221705b261ecSmrg} 221805b261ecSmrg 221905b261ecSmrgint 222005b261ecSmrgProcGetImage(ClientPtr client) 222105b261ecSmrg{ 222205b261ecSmrg REQUEST(xGetImageReq); 222305b261ecSmrg 222405b261ecSmrg REQUEST_SIZE_MATCH(xGetImageReq); 222505b261ecSmrg 222605b261ecSmrg return DoGetImage(client, stuff->format, stuff->drawable, 2227f7df2e56Smrg stuff->x, stuff->y, 2228f7df2e56Smrg (int) stuff->width, (int) stuff->height, 2229f7df2e56Smrg stuff->planeMask); 223005b261ecSmrg} 223105b261ecSmrg 223205b261ecSmrgint 223305b261ecSmrgProcPolyText(ClientPtr client) 223405b261ecSmrg{ 2235f7df2e56Smrg int err; 2236f7df2e56Smrg 223705b261ecSmrg REQUEST(xPolyTextReq); 223805b261ecSmrg DrawablePtr pDraw; 223905b261ecSmrg GC *pGC; 224005b261ecSmrg 224105b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyTextReq); 22424642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 224305b261ecSmrg 224405b261ecSmrg err = PolyText(client, 2245f7df2e56Smrg pDraw, 2246f7df2e56Smrg pGC, 2247f7df2e56Smrg (unsigned char *) &stuff[1], 2248f7df2e56Smrg ((unsigned char *) stuff) + (client->req_len << 2), 2249f7df2e56Smrg stuff->x, stuff->y, stuff->reqType, stuff->drawable); 2250f7df2e56Smrg 2251f7df2e56Smrg if (err == Success) { 2252f7df2e56Smrg return Success; 225305b261ecSmrg } 225405b261ecSmrg else 2255f7df2e56Smrg return err; 225605b261ecSmrg} 225705b261ecSmrg 225805b261ecSmrgint 225905b261ecSmrgProcImageText8(ClientPtr client) 226005b261ecSmrg{ 2261f7df2e56Smrg int err; 226205b261ecSmrg DrawablePtr pDraw; 226305b261ecSmrg GC *pGC; 226405b261ecSmrg 226505b261ecSmrg REQUEST(xImageTextReq); 226605b261ecSmrg 226705b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 22684642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 226905b261ecSmrg 227005b261ecSmrg err = ImageText(client, 2271f7df2e56Smrg pDraw, 2272f7df2e56Smrg pGC, 2273f7df2e56Smrg stuff->nChars, 2274f7df2e56Smrg (unsigned char *) &stuff[1], 2275f7df2e56Smrg stuff->x, stuff->y, stuff->reqType, stuff->drawable); 2276f7df2e56Smrg 2277f7df2e56Smrg if (err == Success) { 2278f7df2e56Smrg return Success; 227905b261ecSmrg } 228005b261ecSmrg else 2281f7df2e56Smrg return err; 228205b261ecSmrg} 228305b261ecSmrg 228405b261ecSmrgint 228505b261ecSmrgProcImageText16(ClientPtr client) 228605b261ecSmrg{ 2287f7df2e56Smrg int err; 228805b261ecSmrg DrawablePtr pDraw; 228905b261ecSmrg GC *pGC; 229005b261ecSmrg 229105b261ecSmrg REQUEST(xImageTextReq); 229205b261ecSmrg 229305b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 22944642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 229505b261ecSmrg 229605b261ecSmrg err = ImageText(client, 2297f7df2e56Smrg pDraw, 2298f7df2e56Smrg pGC, 2299f7df2e56Smrg stuff->nChars, 2300f7df2e56Smrg (unsigned char *) &stuff[1], 2301f7df2e56Smrg stuff->x, stuff->y, stuff->reqType, stuff->drawable); 2302f7df2e56Smrg 2303f7df2e56Smrg if (err == Success) { 2304f7df2e56Smrg return Success; 230505b261ecSmrg } 230605b261ecSmrg else 2307f7df2e56Smrg return err; 230805b261ecSmrg} 230905b261ecSmrg 231005b261ecSmrgint 231105b261ecSmrgProcCreateColormap(ClientPtr client) 231205b261ecSmrg{ 2313f7df2e56Smrg VisualPtr pVisual; 2314f7df2e56Smrg ColormapPtr pmap; 2315f7df2e56Smrg Colormap mid; 2316f7df2e56Smrg WindowPtr pWin; 231705b261ecSmrg ScreenPtr pScreen; 2318f7df2e56Smrg 231905b261ecSmrg REQUEST(xCreateColormapReq); 232005b261ecSmrg int i, result; 232105b261ecSmrg 232205b261ecSmrg REQUEST_SIZE_MATCH(xCreateColormapReq); 232305b261ecSmrg 2324f7df2e56Smrg if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) { 2325f7df2e56Smrg client->errorValue = stuff->alloc; 23266747b715Smrg return BadValue; 232705b261ecSmrg } 232805b261ecSmrg mid = stuff->mid; 232905b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 23304642e01fSmrg result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 233105b261ecSmrg if (result != Success) 233205b261ecSmrg return result; 233305b261ecSmrg 233405b261ecSmrg pScreen = pWin->drawable.pScreen; 233505b261ecSmrg for (i = 0, pVisual = pScreen->visuals; 2336f7df2e56Smrg i < pScreen->numVisuals; i++, pVisual++) { 2337f7df2e56Smrg if (pVisual->vid != stuff->visual) 2338f7df2e56Smrg continue; 2339f7df2e56Smrg return CreateColormap(mid, pScreen, pVisual, &pmap, 2340f7df2e56Smrg (int) stuff->alloc, client->index); 234105b261ecSmrg } 234205b261ecSmrg client->errorValue = stuff->visual; 23436747b715Smrg return BadMatch; 234405b261ecSmrg} 234505b261ecSmrg 234605b261ecSmrgint 234705b261ecSmrgProcFreeColormap(ClientPtr client) 234805b261ecSmrg{ 234905b261ecSmrg ColormapPtr pmap; 23504642e01fSmrg int rc; 2351f7df2e56Smrg 235205b261ecSmrg REQUEST(xResourceReq); 235305b261ecSmrg 235405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 2355f7df2e56Smrg rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP, 2356f7df2e56Smrg client, DixDestroyAccess); 2357f7df2e56Smrg if (rc == Success) { 2358f7df2e56Smrg /* Freeing a default colormap is a no-op */ 2359f7df2e56Smrg if (!(pmap->flags & IsDefault)) 2360f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 2361f7df2e56Smrg return Success; 236205b261ecSmrg } 2363f7df2e56Smrg else { 2364f7df2e56Smrg client->errorValue = stuff->id; 2365f7df2e56Smrg return rc; 236605b261ecSmrg } 236705b261ecSmrg} 236805b261ecSmrg 236905b261ecSmrgint 237005b261ecSmrgProcCopyColormapAndFree(ClientPtr client) 237105b261ecSmrg{ 2372f7df2e56Smrg Colormap mid; 2373f7df2e56Smrg ColormapPtr pSrcMap; 2374f7df2e56Smrg 237505b261ecSmrg REQUEST(xCopyColormapAndFreeReq); 23764642e01fSmrg int rc; 237705b261ecSmrg 237805b261ecSmrg REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 237905b261ecSmrg mid = stuff->mid; 238005b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 2381f7df2e56Smrg rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap, 2382f7df2e56Smrg RT_COLORMAP, client, 2383f7df2e56Smrg DixReadAccess | DixRemoveAccess); 23844642e01fSmrg if (rc == Success) 2385f7df2e56Smrg return CopyColormapAndFree(mid, pSrcMap, client->index); 23866747b715Smrg client->errorValue = stuff->srcCmap; 23876747b715Smrg return rc; 238805b261ecSmrg} 238905b261ecSmrg 239005b261ecSmrgint 239105b261ecSmrgProcInstallColormap(ClientPtr client) 239205b261ecSmrg{ 239305b261ecSmrg ColormapPtr pcmp; 23944642e01fSmrg int rc; 2395f7df2e56Smrg 239605b261ecSmrg REQUEST(xResourceReq); 239705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 23984642e01fSmrg 2399f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, 2400f7df2e56Smrg client, DixInstallAccess); 24014642e01fSmrg if (rc != Success) 2402f7df2e56Smrg goto out; 24034642e01fSmrg 24044642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 24056747b715Smrg if (rc != Success) { 2406f7df2e56Smrg if (rc == BadValue) 2407f7df2e56Smrg rc = BadColor; 2408f7df2e56Smrg goto out; 24096747b715Smrg } 24104642e01fSmrg 24114642e01fSmrg (*(pcmp->pScreen->InstallColormap)) (pcmp); 24126747b715Smrg return Success; 24134642e01fSmrg 2414f7df2e56Smrg out: 24154642e01fSmrg client->errorValue = stuff->id; 24166747b715Smrg return rc; 241705b261ecSmrg} 241805b261ecSmrg 241905b261ecSmrgint 242005b261ecSmrgProcUninstallColormap(ClientPtr client) 242105b261ecSmrg{ 242205b261ecSmrg ColormapPtr pcmp; 24234642e01fSmrg int rc; 2424f7df2e56Smrg 242505b261ecSmrg REQUEST(xResourceReq); 242605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24274642e01fSmrg 2428f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, 2429f7df2e56Smrg client, DixUninstallAccess); 24304642e01fSmrg if (rc != Success) 2431f7df2e56Smrg goto out; 24324642e01fSmrg 24334642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 24346747b715Smrg if (rc != Success) { 2435f7df2e56Smrg if (rc == BadValue) 2436f7df2e56Smrg rc = BadColor; 2437f7df2e56Smrg goto out; 24386747b715Smrg } 24394642e01fSmrg 2440f7df2e56Smrg if (pcmp->mid != pcmp->pScreen->defColormap) 2441f7df2e56Smrg (*(pcmp->pScreen->UninstallColormap)) (pcmp); 24426747b715Smrg return Success; 24434642e01fSmrg 2444f7df2e56Smrg out: 24454642e01fSmrg client->errorValue = stuff->id; 24466747b715Smrg return rc; 244705b261ecSmrg} 244805b261ecSmrg 244905b261ecSmrgint 245005b261ecSmrgProcListInstalledColormaps(ClientPtr client) 245105b261ecSmrg{ 2452f7df2e56Smrg xListInstalledColormapsReply *preply; 245305b261ecSmrg int nummaps, rc; 245405b261ecSmrg WindowPtr pWin; 2455f7df2e56Smrg 245605b261ecSmrg REQUEST(xResourceReq); 245705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 24584642e01fSmrg 24594642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 246005b261ecSmrg if (rc != Success) 2461f7df2e56Smrg return rc; 24624642e01fSmrg 24634642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 2464f7df2e56Smrg DixGetAttrAccess); 24654642e01fSmrg if (rc != Success) 2466f7df2e56Smrg return rc; 246705b261ecSmrg 24686747b715Smrg preply = malloc(sizeof(xListInstalledColormapsReply) + 2469f7df2e56Smrg pWin->drawable.pScreen->maxInstalledCmaps * 2470f7df2e56Smrg sizeof(Colormap)); 2471f7df2e56Smrg if (!preply) 24726747b715Smrg return BadAlloc; 247305b261ecSmrg 247405b261ecSmrg preply->type = X_Reply; 247505b261ecSmrg preply->sequenceNumber = client->sequence; 247605b261ecSmrg nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 2477f7df2e56Smrg (pWin->drawable.pScreen, (Colormap *) &preply[1]); 247805b261ecSmrg preply->nColormaps = nummaps; 247905b261ecSmrg preply->length = nummaps; 2480f7df2e56Smrg WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply); 248105b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 248205b261ecSmrg WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 24836747b715Smrg free(preply); 24846747b715Smrg return Success; 248505b261ecSmrg} 248605b261ecSmrg 248705b261ecSmrgint 2488f7df2e56SmrgProcAllocColor(ClientPtr client) 248905b261ecSmrg{ 249005b261ecSmrg ColormapPtr pmap; 24914642e01fSmrg int rc; 2492f7df2e56Smrg 249305b261ecSmrg REQUEST(xAllocColorReq); 249405b261ecSmrg 249505b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorReq); 2496f7df2e56Smrg rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP, 2497f7df2e56Smrg client, DixAddAccess); 2498f7df2e56Smrg if (rc == Success) { 2499f7df2e56Smrg xAllocColorReply acr = { 2500f7df2e56Smrg .type = X_Reply, 2501f7df2e56Smrg .sequenceNumber = client->sequence, 2502f7df2e56Smrg .length = 0, 2503f7df2e56Smrg .red = stuff->red, 2504f7df2e56Smrg .green = stuff->green, 2505f7df2e56Smrg .blue = stuff->blue, 2506f7df2e56Smrg .pixel = 0 2507f7df2e56Smrg }; 2508f7df2e56Smrg if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 2509f7df2e56Smrg &acr.pixel, client->index))) 2510f7df2e56Smrg return rc; 251105b261ecSmrg#ifdef PANORAMIX 2512f7df2e56Smrg if (noPanoramiXExtension || !pmap->pScreen->myNum) 251305b261ecSmrg#endif 2514f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 2515f7df2e56Smrg return Success; 251605b261ecSmrg 251705b261ecSmrg } 2518f7df2e56Smrg else { 251905b261ecSmrg client->errorValue = stuff->cmap; 25206747b715Smrg return rc; 252105b261ecSmrg } 252205b261ecSmrg} 252305b261ecSmrg 252405b261ecSmrgint 2525f7df2e56SmrgProcAllocNamedColor(ClientPtr client) 252605b261ecSmrg{ 252705b261ecSmrg ColormapPtr pcmp; 25284642e01fSmrg int rc; 2529f7df2e56Smrg 253005b261ecSmrg REQUEST(xAllocNamedColorReq); 253105b261ecSmrg 253205b261ecSmrg REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 2533f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2534f7df2e56Smrg client, DixAddAccess); 2535f7df2e56Smrg if (rc == Success) { 2536f7df2e56Smrg xAllocNamedColorReply ancr = { 2537f7df2e56Smrg .type = X_Reply, 2538f7df2e56Smrg .sequenceNumber = client->sequence, 2539f7df2e56Smrg .length = 0 2540f7df2e56Smrg }; 2541f7df2e56Smrg if (OsLookupColor 2542f7df2e56Smrg (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, 2543f7df2e56Smrg &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) { 2544f7df2e56Smrg ancr.screenRed = ancr.exactRed; 2545f7df2e56Smrg ancr.screenGreen = ancr.exactGreen; 2546f7df2e56Smrg ancr.screenBlue = ancr.exactBlue; 2547f7df2e56Smrg ancr.pixel = 0; 2548f7df2e56Smrg if ((rc = AllocColor(pcmp, 2549f7df2e56Smrg &ancr.screenRed, &ancr.screenGreen, 2550f7df2e56Smrg &ancr.screenBlue, &ancr.pixel, client->index))) 2551f7df2e56Smrg return rc; 255205b261ecSmrg#ifdef PANORAMIX 2553f7df2e56Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 255405b261ecSmrg#endif 2555f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocNamedColorReply), 2556f7df2e56Smrg &ancr); 2557f7df2e56Smrg return Success; 2558f7df2e56Smrg } 2559f7df2e56Smrg else 2560f7df2e56Smrg return BadName; 2561f7df2e56Smrg 256205b261ecSmrg } 2563f7df2e56Smrg else { 256405b261ecSmrg client->errorValue = stuff->cmap; 25656747b715Smrg return rc; 256605b261ecSmrg } 256705b261ecSmrg} 256805b261ecSmrg 256905b261ecSmrgint 2570f7df2e56SmrgProcAllocColorCells(ClientPtr client) 257105b261ecSmrg{ 257205b261ecSmrg ColormapPtr pcmp; 25734642e01fSmrg int rc; 2574f7df2e56Smrg 257505b261ecSmrg REQUEST(xAllocColorCellsReq); 257605b261ecSmrg 257705b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorCellsReq); 2578f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2579f7df2e56Smrg client, DixAddAccess); 2580f7df2e56Smrg if (rc == Success) { 2581f7df2e56Smrg int npixels, nmasks; 2582f7df2e56Smrg long length; 2583f7df2e56Smrg Pixel *ppixels, *pmasks; 2584f7df2e56Smrg 2585f7df2e56Smrg npixels = stuff->colors; 2586f7df2e56Smrg if (!npixels) { 2587f7df2e56Smrg client->errorValue = npixels; 2588f7df2e56Smrg return BadValue; 2589f7df2e56Smrg } 2590f7df2e56Smrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) { 2591f7df2e56Smrg client->errorValue = stuff->contiguous; 2592f7df2e56Smrg return BadValue; 2593f7df2e56Smrg } 2594f7df2e56Smrg nmasks = stuff->planes; 2595f7df2e56Smrg length = ((long) npixels + (long) nmasks) * sizeof(Pixel); 2596f7df2e56Smrg ppixels = malloc(length); 2597f7df2e56Smrg if (!ppixels) 25986747b715Smrg return BadAlloc; 2599f7df2e56Smrg pmasks = ppixels + npixels; 2600f7df2e56Smrg 2601f7df2e56Smrg if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 2602f7df2e56Smrg (Bool) stuff->contiguous, ppixels, pmasks))) { 2603f7df2e56Smrg free(ppixels); 2604f7df2e56Smrg return rc; 2605f7df2e56Smrg } 260605b261ecSmrg#ifdef PANORAMIX 2607f7df2e56Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 260805b261ecSmrg#endif 2609f7df2e56Smrg { 2610f7df2e56Smrg xAllocColorCellsReply accr = { 2611f7df2e56Smrg .type = X_Reply, 2612f7df2e56Smrg .sequenceNumber = client->sequence, 2613f7df2e56Smrg .length = bytes_to_int32(length), 2614f7df2e56Smrg .nPixels = npixels, 2615f7df2e56Smrg .nMasks = nmasks 2616f7df2e56Smrg }; 2617f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr); 2618f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2619f7df2e56Smrg WriteSwappedDataToClient(client, length, ppixels); 2620f7df2e56Smrg } 2621f7df2e56Smrg free(ppixels); 26226747b715Smrg return Success; 262305b261ecSmrg } 2624f7df2e56Smrg else { 262505b261ecSmrg client->errorValue = stuff->cmap; 26266747b715Smrg return rc; 262705b261ecSmrg } 262805b261ecSmrg} 262905b261ecSmrg 263005b261ecSmrgint 263105b261ecSmrgProcAllocColorPlanes(ClientPtr client) 263205b261ecSmrg{ 263305b261ecSmrg ColormapPtr pcmp; 26344642e01fSmrg int rc; 2635f7df2e56Smrg 263605b261ecSmrg REQUEST(xAllocColorPlanesReq); 263705b261ecSmrg 263805b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 2639f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2640f7df2e56Smrg client, DixAddAccess); 2641f7df2e56Smrg if (rc == Success) { 2642f7df2e56Smrg xAllocColorPlanesReply acpr; 2643f7df2e56Smrg int npixels; 2644f7df2e56Smrg long length; 2645f7df2e56Smrg Pixel *ppixels; 2646f7df2e56Smrg 2647f7df2e56Smrg npixels = stuff->colors; 2648f7df2e56Smrg if (!npixels) { 2649f7df2e56Smrg client->errorValue = npixels; 2650f7df2e56Smrg return BadValue; 2651f7df2e56Smrg } 2652f7df2e56Smrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) { 2653f7df2e56Smrg client->errorValue = stuff->contiguous; 2654f7df2e56Smrg return BadValue; 2655f7df2e56Smrg } 2656f7df2e56Smrg acpr = (xAllocColorPlanesReply) { 2657f7df2e56Smrg .type = X_Reply, 2658f7df2e56Smrg .sequenceNumber = client->sequence, 2659f7df2e56Smrg .nPixels = npixels 2660f7df2e56Smrg }; 2661f7df2e56Smrg length = (long) npixels *sizeof(Pixel); 2662f7df2e56Smrg 2663f7df2e56Smrg ppixels = malloc(length); 2664f7df2e56Smrg if (!ppixels) 26656747b715Smrg return BadAlloc; 2666f7df2e56Smrg if ((rc = AllocColorPlanes(client->index, pcmp, npixels, 2667f7df2e56Smrg (int) stuff->red, (int) stuff->green, 2668f7df2e56Smrg (int) stuff->blue, (Bool) stuff->contiguous, 2669f7df2e56Smrg ppixels, &acpr.redMask, &acpr.greenMask, 2670f7df2e56Smrg &acpr.blueMask))) { 26716747b715Smrg free(ppixels); 2672f7df2e56Smrg return rc; 2673f7df2e56Smrg } 2674f7df2e56Smrg acpr.length = bytes_to_int32(length); 267505b261ecSmrg#ifdef PANORAMIX 2676f7df2e56Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 267705b261ecSmrg#endif 2678f7df2e56Smrg { 2679f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 2680f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2681f7df2e56Smrg WriteSwappedDataToClient(client, length, ppixels); 2682f7df2e56Smrg } 2683f7df2e56Smrg free(ppixels); 26846747b715Smrg return Success; 268505b261ecSmrg } 2686f7df2e56Smrg else { 268705b261ecSmrg client->errorValue = stuff->cmap; 26886747b715Smrg return rc; 268905b261ecSmrg } 269005b261ecSmrg} 269105b261ecSmrg 269205b261ecSmrgint 269305b261ecSmrgProcFreeColors(ClientPtr client) 269405b261ecSmrg{ 269505b261ecSmrg ColormapPtr pcmp; 26964642e01fSmrg int rc; 2697f7df2e56Smrg 269805b261ecSmrg REQUEST(xFreeColorsReq); 269905b261ecSmrg 270005b261ecSmrg REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 2701f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2702f7df2e56Smrg client, DixRemoveAccess); 2703f7df2e56Smrg if (rc == Success) { 2704f7df2e56Smrg int count; 270505b261ecSmrg 2706f7df2e56Smrg if (pcmp->flags & AllAllocated) 2707f7df2e56Smrg return BadAccess; 2708f7df2e56Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); 2709f7df2e56Smrg return FreeColors(pcmp, client->index, count, 2710f7df2e56Smrg (Pixel *) &stuff[1], (Pixel) stuff->planeMask); 271105b261ecSmrg } 2712f7df2e56Smrg else { 271305b261ecSmrg client->errorValue = stuff->cmap; 27146747b715Smrg return rc; 271505b261ecSmrg } 271605b261ecSmrg} 271705b261ecSmrg 271805b261ecSmrgint 2719f7df2e56SmrgProcStoreColors(ClientPtr client) 272005b261ecSmrg{ 272105b261ecSmrg ColormapPtr pcmp; 27224642e01fSmrg int rc; 2723f7df2e56Smrg 272405b261ecSmrg REQUEST(xStoreColorsReq); 272505b261ecSmrg 272605b261ecSmrg REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 2727f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2728f7df2e56Smrg client, DixWriteAccess); 2729f7df2e56Smrg if (rc == Success) { 2730f7df2e56Smrg int count; 273105b261ecSmrg 273205b261ecSmrg count = (client->req_len << 2) - sizeof(xStoreColorsReq); 2733f7df2e56Smrg if (count % sizeof(xColorItem)) 2734f7df2e56Smrg return BadLength; 2735f7df2e56Smrg count /= sizeof(xColorItem); 2736f7df2e56Smrg return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client); 273705b261ecSmrg } 2738f7df2e56Smrg else { 273905b261ecSmrg client->errorValue = stuff->cmap; 27406747b715Smrg return rc; 274105b261ecSmrg } 274205b261ecSmrg} 274305b261ecSmrg 274405b261ecSmrgint 2745f7df2e56SmrgProcStoreNamedColor(ClientPtr client) 274605b261ecSmrg{ 274705b261ecSmrg ColormapPtr pcmp; 27484642e01fSmrg int rc; 2749f7df2e56Smrg 275005b261ecSmrg REQUEST(xStoreNamedColorReq); 275105b261ecSmrg 275205b261ecSmrg REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 2753f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2754f7df2e56Smrg client, DixWriteAccess); 2755f7df2e56Smrg if (rc == Success) { 2756f7df2e56Smrg xColorItem def; 2757f7df2e56Smrg 2758f7df2e56Smrg if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1], 2759f7df2e56Smrg stuff->nbytes, &def.red, &def.green, &def.blue)) { 2760f7df2e56Smrg def.flags = stuff->flags; 2761f7df2e56Smrg def.pixel = stuff->pixel; 2762f7df2e56Smrg return StoreColors(pcmp, 1, &def, client); 2763f7df2e56Smrg } 27646747b715Smrg return BadName; 276505b261ecSmrg } 2766f7df2e56Smrg else { 276705b261ecSmrg client->errorValue = stuff->cmap; 27686747b715Smrg return rc; 276905b261ecSmrg } 277005b261ecSmrg} 277105b261ecSmrg 277205b261ecSmrgint 277305b261ecSmrgProcQueryColors(ClientPtr client) 277405b261ecSmrg{ 277505b261ecSmrg ColormapPtr pcmp; 27764642e01fSmrg int rc; 2777f7df2e56Smrg 277805b261ecSmrg REQUEST(xQueryColorsReq); 277905b261ecSmrg 278005b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 2781f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2782f7df2e56Smrg client, DixReadAccess); 2783f7df2e56Smrg if (rc == Success) { 2784f7df2e56Smrg int count; 2785f7df2e56Smrg xrgb *prgbs; 2786f7df2e56Smrg xQueryColorsReply qcr; 2787f7df2e56Smrg 2788f7df2e56Smrg count = 2789f7df2e56Smrg bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); 2790f7df2e56Smrg prgbs = calloc(count, sizeof(xrgb)); 2791f7df2e56Smrg if (!prgbs && count) 27926747b715Smrg return BadAlloc; 2793f7df2e56Smrg if ((rc = 2794f7df2e56Smrg QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) { 2795f7df2e56Smrg free(prgbs); 2796f7df2e56Smrg return rc; 2797f7df2e56Smrg } 2798f7df2e56Smrg qcr = (xQueryColorsReply) { 2799f7df2e56Smrg .type = X_Reply, 2800f7df2e56Smrg .sequenceNumber = client->sequence, 2801f7df2e56Smrg .length = bytes_to_int32(count * sizeof(xrgb)), 2802f7df2e56Smrg .nColors = count 2803f7df2e56Smrg }; 2804f7df2e56Smrg WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 2805f7df2e56Smrg if (count) { 2806f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 2807f7df2e56Smrg WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 2808f7df2e56Smrg } 2809f7df2e56Smrg free(prgbs); 2810f7df2e56Smrg return Success; 2811f7df2e56Smrg 281205b261ecSmrg } 2813f7df2e56Smrg else { 281405b261ecSmrg client->errorValue = stuff->cmap; 28156747b715Smrg return rc; 281605b261ecSmrg } 2817f7df2e56Smrg} 281805b261ecSmrg 281905b261ecSmrgint 282005b261ecSmrgProcLookupColor(ClientPtr client) 282105b261ecSmrg{ 282205b261ecSmrg ColormapPtr pcmp; 28234642e01fSmrg int rc; 2824f7df2e56Smrg 282505b261ecSmrg REQUEST(xLookupColorReq); 282605b261ecSmrg 282705b261ecSmrg REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 2828f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2829f7df2e56Smrg client, DixReadAccess); 2830f7df2e56Smrg if (rc == Success) { 2831f7df2e56Smrg CARD16 exactRed, exactGreen, exactBlue; 2832f7df2e56Smrg 2833f7df2e56Smrg if (OsLookupColor 2834f7df2e56Smrg (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, 2835f7df2e56Smrg &exactRed, &exactGreen, &exactBlue)) { 2836f7df2e56Smrg xLookupColorReply lcr = { 2837f7df2e56Smrg .type = X_Reply, 2838f7df2e56Smrg .sequenceNumber = client->sequence, 2839f7df2e56Smrg .length = 0, 2840f7df2e56Smrg .exactRed = exactRed, 2841f7df2e56Smrg .exactGreen = exactGreen, 2842f7df2e56Smrg .exactBlue = exactBlue, 2843f7df2e56Smrg .screenRed = exactRed, 2844f7df2e56Smrg .screenGreen = exactGreen, 2845f7df2e56Smrg .screenBlue = exactBlue 2846f7df2e56Smrg }; 2847f7df2e56Smrg (*pcmp->pScreen->ResolveColor) (&lcr.screenRed, 2848f7df2e56Smrg &lcr.screenGreen, 2849f7df2e56Smrg &lcr.screenBlue, pcmp->pVisual); 2850f7df2e56Smrg WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 2851f7df2e56Smrg return Success; 2852f7df2e56Smrg } 28536747b715Smrg return BadName; 285405b261ecSmrg } 2855f7df2e56Smrg else { 285605b261ecSmrg client->errorValue = stuff->cmap; 28576747b715Smrg return rc; 285805b261ecSmrg } 285905b261ecSmrg} 286005b261ecSmrg 286105b261ecSmrgint 2862f7df2e56SmrgProcCreateCursor(ClientPtr client) 286305b261ecSmrg{ 2864f7df2e56Smrg CursorPtr pCursor; 2865f7df2e56Smrg PixmapPtr src; 2866f7df2e56Smrg PixmapPtr msk; 2867f7df2e56Smrg unsigned char *srcbits; 2868f7df2e56Smrg unsigned char *mskbits; 2869f7df2e56Smrg unsigned short width, height; 2870f7df2e56Smrg long n; 2871f7df2e56Smrg CursorMetricRec cm; 28724642e01fSmrg int rc; 287305b261ecSmrg 287405b261ecSmrg REQUEST(xCreateCursorReq); 287505b261ecSmrg 287605b261ecSmrg REQUEST_SIZE_MATCH(xCreateCursorReq); 287705b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 287805b261ecSmrg 2879f7df2e56Smrg rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP, 2880f7df2e56Smrg client, DixReadAccess); 28814642e01fSmrg if (rc != Success) { 2882f7df2e56Smrg client->errorValue = stuff->source; 2883f7df2e56Smrg return rc; 288405b261ecSmrg } 28854642e01fSmrg 2886f7df2e56Smrg if (src->drawable.depth != 1) 2887f7df2e56Smrg return (BadMatch); 2888f7df2e56Smrg 2889f7df2e56Smrg /* Find and validate cursor mask pixmap, if one is provided */ 2890f7df2e56Smrg if (stuff->mask != None) { 2891f7df2e56Smrg rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP, 2892f7df2e56Smrg client, DixReadAccess); 2893f7df2e56Smrg if (rc != Success) { 2894f7df2e56Smrg client->errorValue = stuff->mask; 2895f7df2e56Smrg return rc; 2896f7df2e56Smrg } 2897f7df2e56Smrg 2898f7df2e56Smrg if (src->drawable.width != msk->drawable.width 2899f7df2e56Smrg || src->drawable.height != msk->drawable.height 2900f7df2e56Smrg || src->drawable.depth != 1 || msk->drawable.depth != 1) 2901f7df2e56Smrg return BadMatch; 2902f7df2e56Smrg } 2903f7df2e56Smrg else 2904f7df2e56Smrg msk = NULL; 290505b261ecSmrg 290605b261ecSmrg width = src->drawable.width; 290705b261ecSmrg height = src->drawable.height; 290805b261ecSmrg 2909f7df2e56Smrg if (stuff->x > width || stuff->y > height) 2910f7df2e56Smrg return BadMatch; 291105b261ecSmrg 2912f7df2e56Smrg srcbits = calloc(BitmapBytePad(width), height); 291305b261ecSmrg if (!srcbits) 2914f7df2e56Smrg return BadAlloc; 2915f7df2e56Smrg n = BitmapBytePad(width) * height; 29166747b715Smrg mskbits = malloc(n); 2917f7df2e56Smrg if (!mskbits) { 2918f7df2e56Smrg free(srcbits); 2919f7df2e56Smrg return BadAlloc; 292005b261ecSmrg } 292105b261ecSmrg 2922f7df2e56Smrg (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height, 2923f7df2e56Smrg XYPixmap, 1, (void *) srcbits); 2924f7df2e56Smrg if (msk == (PixmapPtr) NULL) { 2925f7df2e56Smrg unsigned char *bits = mskbits; 2926f7df2e56Smrg 2927f7df2e56Smrg while (--n >= 0) 2928f7df2e56Smrg *bits++ = ~0; 292905b261ecSmrg } 2930f7df2e56Smrg else { 2931f7df2e56Smrg /* zeroing the (pad) bits helps some ddx cursor handling */ 2932f7df2e56Smrg memset((char *) mskbits, 0, n); 2933f7df2e56Smrg (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width, 2934f7df2e56Smrg height, XYPixmap, 1, 2935f7df2e56Smrg (void *) mskbits); 293605b261ecSmrg } 293705b261ecSmrg cm.width = width; 293805b261ecSmrg cm.height = height; 293905b261ecSmrg cm.xhot = stuff->x; 294005b261ecSmrg cm.yhot = stuff->y; 29414642e01fSmrg rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 2942f7df2e56Smrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 2943f7df2e56Smrg stuff->backRed, stuff->backGreen, stuff->backBlue, 2944f7df2e56Smrg &pCursor, client, stuff->cid); 294505b261ecSmrg 29464642e01fSmrg if (rc != Success) 2947f7df2e56Smrg goto bail; 2948f7df2e56Smrg if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) { 2949f7df2e56Smrg rc = BadAlloc; 2950f7df2e56Smrg goto bail; 2951f7df2e56Smrg } 29524642e01fSmrg 29536747b715Smrg return Success; 2954f7df2e56Smrg bail: 2955f7df2e56Smrg free(srcbits); 2956f7df2e56Smrg free(mskbits); 2957f7df2e56Smrg return rc; 295805b261ecSmrg} 295905b261ecSmrg 296005b261ecSmrgint 2961f7df2e56SmrgProcCreateGlyphCursor(ClientPtr client) 296205b261ecSmrg{ 296305b261ecSmrg CursorPtr pCursor; 296405b261ecSmrg int res; 296505b261ecSmrg 296605b261ecSmrg REQUEST(xCreateGlyphCursorReq); 296705b261ecSmrg 296805b261ecSmrg REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 296905b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 297005b261ecSmrg 297105b261ecSmrg res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 2972f7df2e56Smrg stuff->mask, stuff->maskChar, 2973f7df2e56Smrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 2974f7df2e56Smrg stuff->backRed, stuff->backGreen, stuff->backBlue, 2975f7df2e56Smrg &pCursor, client, stuff->cid); 297605b261ecSmrg if (res != Success) 2977f7df2e56Smrg return res; 2978f7df2e56Smrg if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) 2979f7df2e56Smrg return Success; 298005b261ecSmrg return BadAlloc; 298105b261ecSmrg} 298205b261ecSmrg 298305b261ecSmrgint 2984f7df2e56SmrgProcFreeCursor(ClientPtr client) 298505b261ecSmrg{ 298605b261ecSmrg CursorPtr pCursor; 29874642e01fSmrg int rc; 2988f7df2e56Smrg 298905b261ecSmrg REQUEST(xResourceReq); 299005b261ecSmrg 299105b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 2992f7df2e56Smrg rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR, 2993f7df2e56Smrg client, DixDestroyAccess); 2994f7df2e56Smrg if (rc == Success) { 2995f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 2996f7df2e56Smrg return Success; 299705b261ecSmrg } 2998f7df2e56Smrg else { 2999f7df2e56Smrg client->errorValue = stuff->id; 3000f7df2e56Smrg return rc; 300105b261ecSmrg } 300205b261ecSmrg} 300305b261ecSmrg 300405b261ecSmrgint 3005f7df2e56SmrgProcQueryBestSize(ClientPtr client) 300605b261ecSmrg{ 3007f7df2e56Smrg xQueryBestSizeReply reply; 300805b261ecSmrg DrawablePtr pDraw; 300905b261ecSmrg ScreenPtr pScreen; 301005b261ecSmrg int rc; 3011f7df2e56Smrg 301205b261ecSmrg REQUEST(xQueryBestSizeReq); 301305b261ecSmrg REQUEST_SIZE_MATCH(xQueryBestSizeReq); 301405b261ecSmrg 3015f7df2e56Smrg if ((stuff->class != CursorShape) && 3016f7df2e56Smrg (stuff->class != TileShape) && (stuff->class != StippleShape)) { 3017f7df2e56Smrg client->errorValue = stuff->class; 30186747b715Smrg return BadValue; 301905b261ecSmrg } 302005b261ecSmrg 302105b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 3022f7df2e56Smrg DixGetAttrAccess); 302305b261ecSmrg if (rc != Success) 3024f7df2e56Smrg return rc; 302505b261ecSmrg if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 3026f7df2e56Smrg return BadMatch; 302705b261ecSmrg pScreen = pDraw->pScreen; 30284642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 30294642e01fSmrg if (rc != Success) 3030f7df2e56Smrg return rc; 3031f7df2e56Smrg (*pScreen->QueryBestSize) (stuff->class, &stuff->width, 3032f7df2e56Smrg &stuff->height, pScreen); 3033f7df2e56Smrg reply = (xQueryBestSizeReply) { 3034f7df2e56Smrg .type = X_Reply, 3035f7df2e56Smrg .sequenceNumber = client->sequence, 3036f7df2e56Smrg .length = 0, 3037f7df2e56Smrg .width = stuff->width, 3038f7df2e56Smrg .height = stuff->height 3039f7df2e56Smrg }; 304005b261ecSmrg WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 30416747b715Smrg return Success; 304205b261ecSmrg} 304305b261ecSmrg 304405b261ecSmrgint 3045f7df2e56SmrgProcSetScreenSaver(ClientPtr client) 304605b261ecSmrg{ 30474642e01fSmrg int rc, i, blankingOption, exposureOption; 3048f7df2e56Smrg 304905b261ecSmrg REQUEST(xSetScreenSaverReq); 305005b261ecSmrg REQUEST_SIZE_MATCH(xSetScreenSaverReq); 30514642e01fSmrg 30524642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 3053f7df2e56Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3054f7df2e56Smrg DixSetAttrAccess); 3055f7df2e56Smrg if (rc != Success) 3056f7df2e56Smrg return rc; 30574642e01fSmrg } 30584642e01fSmrg 305905b261ecSmrg blankingOption = stuff->preferBlank; 306005b261ecSmrg if ((blankingOption != DontPreferBlanking) && 306105b261ecSmrg (blankingOption != PreferBlanking) && 3062f7df2e56Smrg (blankingOption != DefaultBlanking)) { 3063f7df2e56Smrg client->errorValue = blankingOption; 306405b261ecSmrg return BadValue; 306505b261ecSmrg } 306605b261ecSmrg exposureOption = stuff->allowExpose; 306705b261ecSmrg if ((exposureOption != DontAllowExposures) && 306805b261ecSmrg (exposureOption != AllowExposures) && 3069f7df2e56Smrg (exposureOption != DefaultExposures)) { 3070f7df2e56Smrg client->errorValue = exposureOption; 307105b261ecSmrg return BadValue; 307205b261ecSmrg } 3073f7df2e56Smrg if (stuff->timeout < -1) { 3074f7df2e56Smrg client->errorValue = stuff->timeout; 307505b261ecSmrg return BadValue; 307605b261ecSmrg } 3077f7df2e56Smrg if (stuff->interval < -1) { 3078f7df2e56Smrg client->errorValue = stuff->interval; 307905b261ecSmrg return BadValue; 308005b261ecSmrg } 308105b261ecSmrg 308205b261ecSmrg if (blankingOption == DefaultBlanking) 3083f7df2e56Smrg ScreenSaverBlanking = defaultScreenSaverBlanking; 308405b261ecSmrg else 3085f7df2e56Smrg ScreenSaverBlanking = blankingOption; 308605b261ecSmrg if (exposureOption == DefaultExposures) 3087f7df2e56Smrg ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 308805b261ecSmrg else 3089f7df2e56Smrg ScreenSaverAllowExposures = exposureOption; 309005b261ecSmrg 309105b261ecSmrg if (stuff->timeout >= 0) 3092f7df2e56Smrg ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 3093f7df2e56Smrg else 3094f7df2e56Smrg ScreenSaverTime = defaultScreenSaverTime; 309505b261ecSmrg if (stuff->interval >= 0) 3096f7df2e56Smrg ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 309705b261ecSmrg else 3098f7df2e56Smrg ScreenSaverInterval = defaultScreenSaverInterval; 309905b261ecSmrg 310005b261ecSmrg SetScreenSaverTimer(); 31016747b715Smrg return Success; 310205b261ecSmrg} 310305b261ecSmrg 310405b261ecSmrgint 310505b261ecSmrgProcGetScreenSaver(ClientPtr client) 310605b261ecSmrg{ 310705b261ecSmrg xGetScreenSaverReply rep; 31084642e01fSmrg int rc, i; 3109f7df2e56Smrg 311005b261ecSmrg REQUEST_SIZE_MATCH(xReq); 31114642e01fSmrg 31124642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 3113f7df2e56Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3114f7df2e56Smrg DixGetAttrAccess); 3115f7df2e56Smrg if (rc != Success) 3116f7df2e56Smrg return rc; 3117f7df2e56Smrg } 3118f7df2e56Smrg 3119f7df2e56Smrg rep = (xGetScreenSaverReply) { 3120f7df2e56Smrg .type = X_Reply, 3121f7df2e56Smrg .sequenceNumber = client->sequence, 3122f7df2e56Smrg .length = 0, 3123f7df2e56Smrg .timeout = ScreenSaverTime / MILLI_PER_SECOND, 3124f7df2e56Smrg .interval = ScreenSaverInterval / MILLI_PER_SECOND, 3125f7df2e56Smrg .preferBlanking = ScreenSaverBlanking, 3126f7df2e56Smrg .allowExposures = ScreenSaverAllowExposures 3127f7df2e56Smrg }; 312805b261ecSmrg WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 31296747b715Smrg return Success; 313005b261ecSmrg} 313105b261ecSmrg 313205b261ecSmrgint 313305b261ecSmrgProcChangeHosts(ClientPtr client) 313405b261ecSmrg{ 313505b261ecSmrg REQUEST(xChangeHostsReq); 313605b261ecSmrg 313705b261ecSmrg REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 313805b261ecSmrg 3139f7df2e56Smrg if (stuff->mode == HostInsert) 3140f7df2e56Smrg return AddHost(client, (int) stuff->hostFamily, 3141f7df2e56Smrg stuff->hostLength, (void *) &stuff[1]); 31426747b715Smrg if (stuff->mode == HostDelete) 3143f7df2e56Smrg return RemoveHost(client, (int) stuff->hostFamily, 3144f7df2e56Smrg stuff->hostLength, (void *) &stuff[1]); 31456747b715Smrg client->errorValue = stuff->mode; 31466747b715Smrg return BadValue; 314705b261ecSmrg} 314805b261ecSmrg 314905b261ecSmrgint 315005b261ecSmrgProcListHosts(ClientPtr client) 315105b261ecSmrg{ 315205b261ecSmrg xListHostsReply reply; 3153f7df2e56Smrg int len, nHosts, result; 3154f7df2e56Smrg BOOL enabled; 3155f7df2e56Smrg void *pdata; 3156f7df2e56Smrg 315705b261ecSmrg /* REQUEST(xListHostsReq); */ 315805b261ecSmrg 315905b261ecSmrg REQUEST_SIZE_MATCH(xListHostsReq); 316005b261ecSmrg 316105b261ecSmrg /* untrusted clients can't list hosts */ 31624642e01fSmrg result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); 31634642e01fSmrg if (result != Success) 3164f7df2e56Smrg return result; 316505b261ecSmrg 3166f7df2e56Smrg result = GetHosts(&pdata, &nHosts, &len, &enabled); 316705b261ecSmrg if (result != Success) 3168f7df2e56Smrg return result; 3169f7df2e56Smrg 3170f7df2e56Smrg reply = (xListHostsReply) { 3171f7df2e56Smrg .type = X_Reply, 3172f7df2e56Smrg .enabled = enabled, 3173f7df2e56Smrg .sequenceNumber = client->sequence, 3174f7df2e56Smrg .length = bytes_to_int32(len), 3175f7df2e56Smrg .nHosts = nHosts 3176f7df2e56Smrg }; 317705b261ecSmrg WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 3178f7df2e56Smrg if (nHosts) { 3179f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 3180f7df2e56Smrg WriteSwappedDataToClient(client, len, pdata); 318105b261ecSmrg } 31826747b715Smrg free(pdata); 31836747b715Smrg return Success; 318405b261ecSmrg} 318505b261ecSmrg 318605b261ecSmrgint 318705b261ecSmrgProcChangeAccessControl(ClientPtr client) 318805b261ecSmrg{ 318905b261ecSmrg REQUEST(xSetAccessControlReq); 319005b261ecSmrg 319105b261ecSmrg REQUEST_SIZE_MATCH(xSetAccessControlReq); 3192f7df2e56Smrg if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) { 3193f7df2e56Smrg client->errorValue = stuff->mode; 319405b261ecSmrg return BadValue; 319505b261ecSmrg } 31966747b715Smrg return ChangeAccessControl(client, stuff->mode == EnableAccess); 319705b261ecSmrg} 319805b261ecSmrg 319905b261ecSmrg/********************* 320005b261ecSmrg * CloseDownRetainedResources 320105b261ecSmrg * 3202f7df2e56Smrg * Find all clients that are gone and have terminated in RetainTemporary 320305b261ecSmrg * and destroy their resources. 320405b261ecSmrg *********************/ 320505b261ecSmrg 320605b261ecSmrgstatic void 320705b261ecSmrgCloseDownRetainedResources(void) 320805b261ecSmrg{ 320905b261ecSmrg int i; 321005b261ecSmrg ClientPtr client; 321105b261ecSmrg 3212f7df2e56Smrg for (i = 1; i < currentMaxClients; i++) { 321305b261ecSmrg client = clients[i]; 321405b261ecSmrg if (client && (client->closeDownMode == RetainTemporary) 3215f7df2e56Smrg && (client->clientGone)) 3216f7df2e56Smrg CloseDownClient(client); 321705b261ecSmrg } 321805b261ecSmrg} 321905b261ecSmrg 322005b261ecSmrgint 322105b261ecSmrgProcKillClient(ClientPtr client) 322205b261ecSmrg{ 322305b261ecSmrg REQUEST(xResourceReq); 322405b261ecSmrg ClientPtr killclient; 322505b261ecSmrg int rc; 322605b261ecSmrg 322705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 3228f7df2e56Smrg if (stuff->id == AllTemporary) { 3229f7df2e56Smrg CloseDownRetainedResources(); 32306747b715Smrg return Success; 323105b261ecSmrg } 323205b261ecSmrg 323305b261ecSmrg rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 323405b261ecSmrg if (rc == Success) { 3235f7df2e56Smrg CloseDownClient(killclient); 3236f7df2e56Smrg if (client == killclient) { 3237f7df2e56Smrg /* force yield and return Success, so that Dispatch() 3238f7df2e56Smrg * doesn't try to touch client 3239f7df2e56Smrg */ 3240f7df2e56Smrg isItTimeToYield = TRUE; 3241f7df2e56Smrg } 3242f7df2e56Smrg return Success; 324305b261ecSmrg } 324405b261ecSmrg else 3245f7df2e56Smrg return rc; 324605b261ecSmrg} 324705b261ecSmrg 324805b261ecSmrgint 324905b261ecSmrgProcSetFontPath(ClientPtr client) 325005b261ecSmrg{ 325105b261ecSmrg unsigned char *ptr; 325205b261ecSmrg unsigned long nbytes, total; 325305b261ecSmrg long nfonts; 32546747b715Smrg int n; 3255f7df2e56Smrg 325605b261ecSmrg REQUEST(xSetFontPathReq); 3257f7df2e56Smrg 325805b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 3259f7df2e56Smrg 326005b261ecSmrg nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 326105b261ecSmrg total = nbytes; 3262f7df2e56Smrg ptr = (unsigned char *) &stuff[1]; 326305b261ecSmrg nfonts = stuff->nFonts; 3264f7df2e56Smrg while (--nfonts >= 0) { 3265f7df2e56Smrg if ((total == 0) || (total < (n = (*ptr + 1)))) 3266f7df2e56Smrg return BadLength; 3267f7df2e56Smrg total -= n; 3268f7df2e56Smrg ptr += n; 326905b261ecSmrg } 327005b261ecSmrg if (total >= 4) 3271f7df2e56Smrg return BadLength; 3272f7df2e56Smrg return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]); 327305b261ecSmrg} 327405b261ecSmrg 327505b261ecSmrgint 327605b261ecSmrgProcGetFontPath(ClientPtr client) 327705b261ecSmrg{ 327805b261ecSmrg xGetFontPathReply reply; 32794642e01fSmrg int rc, stringLens, numpaths; 328005b261ecSmrg unsigned char *bufferStart; 3281f7df2e56Smrg 328205b261ecSmrg /* REQUEST (xReq); */ 328305b261ecSmrg 328405b261ecSmrg REQUEST_SIZE_MATCH(xReq); 32854642e01fSmrg rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); 32864642e01fSmrg if (rc != Success) 3287f7df2e56Smrg return rc; 328805b261ecSmrg 3289f7df2e56Smrg reply = (xGetFontPathReply) { 3290f7df2e56Smrg .type = X_Reply, 3291f7df2e56Smrg .sequenceNumber = client->sequence, 3292f7df2e56Smrg .length = bytes_to_int32(stringLens + numpaths), 3293f7df2e56Smrg .nPaths = numpaths 3294f7df2e56Smrg }; 329505b261ecSmrg 329605b261ecSmrg WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 329705b261ecSmrg if (stringLens || numpaths) 3298f7df2e56Smrg WriteToClient(client, stringLens + numpaths, bufferStart); 32996747b715Smrg return Success; 330005b261ecSmrg} 330105b261ecSmrg 330205b261ecSmrgint 330305b261ecSmrgProcChangeCloseDownMode(ClientPtr client) 330405b261ecSmrg{ 33054642e01fSmrg int rc; 3306f7df2e56Smrg 330705b261ecSmrg REQUEST(xSetCloseDownModeReq); 330805b261ecSmrg REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 33094642e01fSmrg 33104642e01fSmrg rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); 33114642e01fSmrg if (rc != Success) 3312f7df2e56Smrg return rc; 33134642e01fSmrg 331405b261ecSmrg if ((stuff->mode == AllTemporary) || 3315f7df2e56Smrg (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) { 3316f7df2e56Smrg client->closeDownMode = stuff->mode; 3317f7df2e56Smrg return Success; 331805b261ecSmrg } 3319f7df2e56Smrg else { 3320f7df2e56Smrg client->errorValue = stuff->mode; 3321f7df2e56Smrg return BadValue; 332205b261ecSmrg } 332305b261ecSmrg} 332405b261ecSmrg 3325f7df2e56Smrgint 3326f7df2e56SmrgProcForceScreenSaver(ClientPtr client) 3327f7df2e56Smrg{ 33284642e01fSmrg int rc; 3329f7df2e56Smrg 333005b261ecSmrg REQUEST(xForceScreenSaverReq); 333105b261ecSmrg 333205b261ecSmrg REQUEST_SIZE_MATCH(xForceScreenSaverReq); 3333f7df2e56Smrg 3334f7df2e56Smrg if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) { 3335f7df2e56Smrg client->errorValue = stuff->mode; 333605b261ecSmrg return BadValue; 333705b261ecSmrg } 3338f7df2e56Smrg rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode); 33394642e01fSmrg if (rc != Success) 3340f7df2e56Smrg return rc; 33416747b715Smrg return Success; 334205b261ecSmrg} 334305b261ecSmrg 3344f7df2e56Smrgint 3345f7df2e56SmrgProcNoOperation(ClientPtr client) 334605b261ecSmrg{ 334705b261ecSmrg REQUEST_AT_LEAST_SIZE(xReq); 3348f7df2e56Smrg 334905b261ecSmrg /* noop -- don't do anything */ 33506747b715Smrg return Success; 335105b261ecSmrg} 335205b261ecSmrg 335305b261ecSmrg/********************** 335405b261ecSmrg * CloseDownClient 335505b261ecSmrg * 335605b261ecSmrg * Client can either mark his resources destroy or retain. If retained and 335705b261ecSmrg * then killed again, the client is really destroyed. 335805b261ecSmrg *********************/ 335905b261ecSmrg 336005b261ecSmrgchar dispatchExceptionAtReset = DE_RESET; 336105b261ecSmrg 336205b261ecSmrgvoid 336305b261ecSmrgCloseDownClient(ClientPtr client) 336405b261ecSmrg{ 336505b261ecSmrg Bool really_close_down = client->clientGone || 3366f7df2e56Smrg client->closeDownMode == DestroyAll; 336705b261ecSmrg 3368f7df2e56Smrg if (!client->clientGone) { 3369f7df2e56Smrg /* ungrab server if grabbing client dies */ 3370f7df2e56Smrg if (grabState != GrabNone && grabClient == client) { 3371f7df2e56Smrg UngrabServer(client); 3372f7df2e56Smrg } 3373f7df2e56Smrg BITCLEAR(grabWaiters, client->index); 3374f7df2e56Smrg DeleteClientFromAnySelections(client); 3375f7df2e56Smrg ReleaseActiveGrabs(client); 3376f7df2e56Smrg DeleteClientFontStuff(client); 3377f7df2e56Smrg if (!really_close_down) { 3378f7df2e56Smrg /* This frees resources that should never be retained 3379f7df2e56Smrg * no matter what the close down mode is. Actually we 3380f7df2e56Smrg * could do this unconditionally, but it's probably 3381f7df2e56Smrg * better not to traverse all the client's resources 3382f7df2e56Smrg * twice (once here, once a few lines down in 3383f7df2e56Smrg * FreeClientResources) in the common case of 3384f7df2e56Smrg * really_close_down == TRUE. 3385f7df2e56Smrg */ 3386f7df2e56Smrg FreeClientNeverRetainResources(client); 3387f7df2e56Smrg client->clientState = ClientStateRetained; 3388f7df2e56Smrg if (ClientStateCallback) { 3389f7df2e56Smrg NewClientInfoRec clientinfo; 3390f7df2e56Smrg 3391f7df2e56Smrg clientinfo.client = client; 3392f7df2e56Smrg clientinfo.prefix = (xConnSetupPrefix *) NULL; 3393f7df2e56Smrg clientinfo.setup = (xConnSetup *) NULL; 3394f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3395f7df2e56Smrg } 3396f7df2e56Smrg } 3397f7df2e56Smrg client->clientGone = TRUE; /* so events aren't sent to client */ 3398f7df2e56Smrg if (ClientIsAsleep(client)) 3399f7df2e56Smrg ClientSignal(client); 3400f7df2e56Smrg ProcessWorkQueueZombies(); 3401f7df2e56Smrg CloseDownConnection(client); 3402f7df2e56Smrg 3403f7df2e56Smrg /* If the client made it to the Running stage, nClients has 3404f7df2e56Smrg * been incremented on its behalf, so we need to decrement it 3405f7df2e56Smrg * now. If it hasn't gotten to Running, nClients has *not* 3406f7df2e56Smrg * been incremented, so *don't* decrement it. 3407f7df2e56Smrg */ 3408f7df2e56Smrg if (client->clientState != ClientStateInitial) { 3409f7df2e56Smrg --nClients; 3410f7df2e56Smrg } 3411f7df2e56Smrg } 3412f7df2e56Smrg 3413f7df2e56Smrg if (really_close_down) { 3414f7df2e56Smrg if (client->clientState == ClientStateRunning && nClients == 0) 3415f7df2e56Smrg dispatchException |= dispatchExceptionAtReset; 3416f7df2e56Smrg 3417f7df2e56Smrg client->clientState = ClientStateGone; 3418f7df2e56Smrg if (ClientStateCallback) { 3419f7df2e56Smrg NewClientInfoRec clientinfo; 3420f7df2e56Smrg 3421f7df2e56Smrg clientinfo.client = client; 3422f7df2e56Smrg clientinfo.prefix = (xConnSetupPrefix *) NULL; 3423f7df2e56Smrg clientinfo.setup = (xConnSetup *) NULL; 3424f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3425f7df2e56Smrg } 3426f7df2e56Smrg TouchListenerGone(client->clientAsMask); 3427f7df2e56Smrg FreeClientResources(client); 3428f7df2e56Smrg /* Disable client ID tracking. This must be done after 3429f7df2e56Smrg * ClientStateCallback. */ 3430f7df2e56Smrg ReleaseClientIds(client); 343105b261ecSmrg#ifdef XSERVER_DTRACE 3432f7df2e56Smrg XSERVER_CLIENT_DISCONNECT(client->index); 3433f7df2e56Smrg#endif 3434f7df2e56Smrg if (client->index < nextFreeClientID) 3435f7df2e56Smrg nextFreeClientID = client->index; 3436f7df2e56Smrg clients[client->index] = NullClient; 3437f7df2e56Smrg SmartLastClient = NullClient; 3438f7df2e56Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 343905b261ecSmrg 3440f7df2e56Smrg while (!clients[currentMaxClients - 1]) 3441f7df2e56Smrg currentMaxClients--; 344205b261ecSmrg } 344305b261ecSmrg} 344405b261ecSmrg 344505b261ecSmrgstatic void 344605b261ecSmrgKillAllClients(void) 344705b261ecSmrg{ 344805b261ecSmrg int i; 3449f7df2e56Smrg 3450f7df2e56Smrg for (i = 1; i < currentMaxClients; i++) 345105b261ecSmrg if (clients[i]) { 345205b261ecSmrg /* Make sure Retained clients are released. */ 345305b261ecSmrg clients[i]->closeDownMode = DestroyAll; 3454f7df2e56Smrg CloseDownClient(clients[i]); 345505b261ecSmrg } 345605b261ecSmrg} 345705b261ecSmrg 3458f7df2e56Smrgvoid 3459f7df2e56SmrgInitClient(ClientPtr client, int i, void *ospriv) 346005b261ecSmrg{ 346105b261ecSmrg client->index = i; 3462f7df2e56Smrg client->clientAsMask = ((Mask) i) << CLIENTOFFSET; 34634642e01fSmrg client->closeDownMode = i ? DestroyAll : RetainPermanent; 346405b261ecSmrg client->requestVector = InitialVector; 346505b261ecSmrg client->osPrivate = ospriv; 3466f7df2e56Smrg QueryMinMaxKeyCodes(&client->minKC, &client->maxKC); 346705b261ecSmrg client->smart_start_tick = SmartScheduleTime; 346805b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 3469f7df2e56Smrg client->clientIds = NULL; 347005b261ecSmrg} 347105b261ecSmrg 347205b261ecSmrg/************************ 347305b261ecSmrg * int NextAvailableClient(ospriv) 347405b261ecSmrg * 347505b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes. 347605b261ecSmrg * Returns NULL if there are no free clients. 347705b261ecSmrg *************************/ 347805b261ecSmrg 3479f7df2e56SmrgClientPtr 3480f7df2e56SmrgNextAvailableClient(void *ospriv) 348105b261ecSmrg{ 348205b261ecSmrg int i; 348305b261ecSmrg ClientPtr client; 348405b261ecSmrg xReq data; 348505b261ecSmrg 348605b261ecSmrg i = nextFreeClientID; 3487f7df2e56Smrg if (i == LimitClients) 3488f7df2e56Smrg return (ClientPtr) NULL; 3489f7df2e56Smrg clients[i] = client = 3490f7df2e56Smrg dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT); 349105b261ecSmrg if (!client) 3492f7df2e56Smrg return (ClientPtr) NULL; 349305b261ecSmrg InitClient(client, i, ospriv); 3494f7df2e56Smrg if (!InitClientResources(client)) { 3495f7df2e56Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3496f7df2e56Smrg return (ClientPtr) NULL; 349705b261ecSmrg } 349805b261ecSmrg data.reqType = 1; 34996747b715Smrg data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); 3500f7df2e56Smrg if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) { 3501f7df2e56Smrg FreeClientResources(client); 3502f7df2e56Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3503f7df2e56Smrg return (ClientPtr) NULL; 350405b261ecSmrg } 350505b261ecSmrg if (i == currentMaxClients) 3506f7df2e56Smrg currentMaxClients++; 3507f7df2e56Smrg while ((nextFreeClientID < LimitClients) && clients[nextFreeClientID]) 3508f7df2e56Smrg nextFreeClientID++; 3509f7df2e56Smrg 3510f7df2e56Smrg /* Enable client ID tracking. This must be done before 3511f7df2e56Smrg * ClientStateCallback. */ 3512f7df2e56Smrg ReserveClientIds(client); 3513f7df2e56Smrg 3514f7df2e56Smrg if (ClientStateCallback) { 3515f7df2e56Smrg NewClientInfoRec clientinfo; 351605b261ecSmrg 3517f7df2e56Smrg clientinfo.client = client; 3518f7df2e56Smrg clientinfo.prefix = (xConnSetupPrefix *) NULL; 351905b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 3520f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3521f7df2e56Smrg } 35226747b715Smrg return client; 352305b261ecSmrg} 352405b261ecSmrg 352505b261ecSmrgint 352605b261ecSmrgProcInitialConnection(ClientPtr client) 352705b261ecSmrg{ 352805b261ecSmrg REQUEST(xReq); 352905b261ecSmrg xConnClientPrefix *prefix; 353005b261ecSmrg int whichbyte = 1; 3531f7df2e56Smrg char order; 353205b261ecSmrg 3533f7df2e56Smrg prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq); 3534f7df2e56Smrg order = prefix->byteOrder; 3535f7df2e56Smrg if (order != 'l' && order != 'B' && order != 'r' && order != 'R') 35366747b715Smrg return client->noClientException = -1; 3537f7df2e56Smrg if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || 3538f7df2e56Smrg (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { 353905b261ecSmrg client->swapped = TRUE; 354005b261ecSmrg SwapConnClientPrefix(prefix); 354105b261ecSmrg } 354205b261ecSmrg stuff->reqType = 2; 35436747b715Smrg stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + 3544f7df2e56Smrg bytes_to_int32(prefix->nbytesAuthString); 3545f7df2e56Smrg if (client->swapped) { 3546f7df2e56Smrg swaps(&stuff->length); 3547f7df2e56Smrg } 3548f7df2e56Smrg if (order == 'r' || order == 'R') { 3549f7df2e56Smrg client->local = FALSE; 355005b261ecSmrg } 355105b261ecSmrg ResetCurrentRequest(client); 35526747b715Smrg return Success; 355305b261ecSmrg} 355405b261ecSmrg 35554642e01fSmrgstatic int 3556f7df2e56SmrgSendConnSetup(ClientPtr client, const char *reason) 355705b261ecSmrg{ 355805b261ecSmrg xWindowRoot *root; 355905b261ecSmrg int i; 356005b261ecSmrg int numScreens; 3561f7df2e56Smrg char *lConnectionInfo; 3562f7df2e56Smrg xConnSetupPrefix *lconnSetupPrefix; 356305b261ecSmrg 3564f7df2e56Smrg if (reason) { 3565f7df2e56Smrg xConnSetupPrefix csp; 3566f7df2e56Smrg 3567f7df2e56Smrg csp.success = xFalse; 3568f7df2e56Smrg csp.lengthReason = strlen(reason); 3569f7df2e56Smrg csp.length = bytes_to_int32(csp.lengthReason); 3570f7df2e56Smrg csp.majorVersion = X_PROTOCOL; 3571f7df2e56Smrg csp.minorVersion = X_PROTOCOL_REVISION; 3572f7df2e56Smrg if (client->swapped) 3573f7df2e56Smrg WriteSConnSetupPrefix(client, &csp); 3574f7df2e56Smrg else 3575f7df2e56Smrg WriteToClient(client, sz_xConnSetupPrefix, &csp); 3576f7df2e56Smrg WriteToClient(client, (int) csp.lengthReason, reason); 3577f7df2e56Smrg return client->noClientException = -1; 357805b261ecSmrg } 357905b261ecSmrg 358005b261ecSmrg numScreens = screenInfo.numScreens; 358105b261ecSmrg lConnectionInfo = ConnectionInfo; 358205b261ecSmrg lconnSetupPrefix = &connSetupPrefix; 358305b261ecSmrg 358405b261ecSmrg /* We're about to start speaking X protocol back to the client by 358505b261ecSmrg * sending the connection setup info. This means the authorization 358605b261ecSmrg * step is complete, and we can count the client as an 358705b261ecSmrg * authorized one. 358805b261ecSmrg */ 358905b261ecSmrg nClients++; 359005b261ecSmrg 359105b261ecSmrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 359205b261ecSmrg client->sequence = 0; 3593f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask; 3594f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 359505b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 3596f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client); 3597f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client); 359805b261ecSmrg#endif 359905b261ecSmrg /* fill in the "currentInputMask" */ 3600f7df2e56Smrg root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart); 360105b261ecSmrg#ifdef PANORAMIX 360205b261ecSmrg if (noPanoramiXExtension) 3603f7df2e56Smrg numScreens = screenInfo.numScreens; 3604f7df2e56Smrg else 3605f7df2e56Smrg numScreens = ((xConnSetup *) ConnectionInfo)->numRoots; 360605b261ecSmrg#endif 360705b261ecSmrg 3608f7df2e56Smrg for (i = 0; i < numScreens; i++) { 3609f7df2e56Smrg unsigned int j; 3610f7df2e56Smrg xDepth *pDepth; 3611f7df2e56Smrg WindowPtr pRoot = screenInfo.screens[i]->root; 361205b261ecSmrg 36136747b715Smrg root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot); 3614f7df2e56Smrg pDepth = (xDepth *) (root + 1); 3615f7df2e56Smrg for (j = 0; j < root->nDepths; j++) { 3616f7df2e56Smrg pDepth = (xDepth *) (((char *) (pDepth + 1)) + 3617f7df2e56Smrg pDepth->nVisuals * sizeof(xVisualType)); 3618f7df2e56Smrg } 3619f7df2e56Smrg root = (xWindowRoot *) pDepth; 362005b261ecSmrg } 362105b261ecSmrg 3622f7df2e56Smrg if (client->swapped) { 3623f7df2e56Smrg WriteSConnSetupPrefix(client, lconnSetupPrefix); 3624f7df2e56Smrg WriteSConnectionInfo(client, 3625f7df2e56Smrg (unsigned long) (lconnSetupPrefix->length << 2), 3626f7df2e56Smrg lConnectionInfo); 362705b261ecSmrg } 3628f7df2e56Smrg else { 3629f7df2e56Smrg WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix); 3630f7df2e56Smrg WriteToClient(client, (int) (lconnSetupPrefix->length << 2), 3631f7df2e56Smrg lConnectionInfo); 363205b261ecSmrg } 363305b261ecSmrg client->clientState = ClientStateRunning; 3634f7df2e56Smrg if (ClientStateCallback) { 3635f7df2e56Smrg NewClientInfoRec clientinfo; 363605b261ecSmrg 3637f7df2e56Smrg clientinfo.client = client; 3638f7df2e56Smrg clientinfo.prefix = lconnSetupPrefix; 3639f7df2e56Smrg clientinfo.setup = (xConnSetup *) lConnectionInfo; 3640f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3641f7df2e56Smrg } 36426747b715Smrg return Success; 364305b261ecSmrg} 364405b261ecSmrg 364505b261ecSmrgint 364605b261ecSmrgProcEstablishConnection(ClientPtr client) 364705b261ecSmrg{ 3648f7df2e56Smrg const char *reason; 3649f7df2e56Smrg char *auth_proto, *auth_string; 365005b261ecSmrg xConnClientPrefix *prefix; 3651f7df2e56Smrg 365205b261ecSmrg REQUEST(xReq); 365305b261ecSmrg 3654f7df2e56Smrg prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq); 3655f7df2e56Smrg auth_proto = (char *) prefix + sz_xConnClientPrefix; 36566747b715Smrg auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); 365705b261ecSmrg if ((prefix->majorVersion != X_PROTOCOL) || 3658f7df2e56Smrg (prefix->minorVersion != X_PROTOCOL_REVISION)) 3659f7df2e56Smrg reason = "Protocol version mismatch"; 366005b261ecSmrg else 3661f7df2e56Smrg reason = ClientAuthorized(client, 3662f7df2e56Smrg (unsigned short) prefix->nbytesAuthProto, 3663f7df2e56Smrg auth_proto, 3664f7df2e56Smrg (unsigned short) prefix->nbytesAuthString, 3665f7df2e56Smrg auth_string); 3666f7df2e56Smrg 3667f7df2e56Smrg return (SendConnSetup(client, reason)); 366805b261ecSmrg} 366905b261ecSmrg 36706747b715Smrgvoid 3671f7df2e56SmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 367205b261ecSmrg XID resId, int errorCode) 367305b261ecSmrg{ 3674f7df2e56Smrg xError rep = { 3675f7df2e56Smrg .type = X_Error, 3676f7df2e56Smrg .errorCode = errorCode, 3677f7df2e56Smrg .resourceID = resId, 3678f7df2e56Smrg .minorCode = minorCode, 3679f7df2e56Smrg .majorCode = majorCode 3680f7df2e56Smrg }; 368105b261ecSmrg 3682f7df2e56Smrg WriteEventsToClient(client, 1, (xEvent *) &rep); 368305b261ecSmrg} 368405b261ecSmrg 368505b261ecSmrgvoid 368605b261ecSmrgMarkClientException(ClientPtr client) 368705b261ecSmrg{ 368805b261ecSmrg client->noClientException = -1; 368905b261ecSmrg} 36906747b715Smrg 36916747b715Smrg/* 36926747b715Smrg * This array encodes the answer to the question "what is the log base 2 36936747b715Smrg * of the number of pixels that fit in a scanline pad unit?" 36946747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 36956747b715Smrg */ 36966747b715Smrgstatic int answer[6][4] = { 3697f7df2e56Smrg /* pad pad pad pad */ 3698f7df2e56Smrg /* 8 16 32 64 */ 3699f7df2e56Smrg 3700f7df2e56Smrg {3, 4, 5, 6}, /* 1 bit per pixel */ 3701f7df2e56Smrg {1, 2, 3, 4}, /* 4 bits per pixel */ 3702f7df2e56Smrg {0, 1, 2, 3}, /* 8 bits per pixel */ 3703f7df2e56Smrg {~0, 0, 1, 2}, /* 16 bits per pixel */ 3704f7df2e56Smrg {~0, ~0, 0, 1}, /* 24 bits per pixel */ 3705f7df2e56Smrg {~0, ~0, 0, 1} /* 32 bits per pixel */ 37066747b715Smrg}; 37076747b715Smrg 37086747b715Smrg/* 37096747b715Smrg * This array gives the answer to the question "what is the first index for 37106747b715Smrg * the answer array above given the number of bits per pixel?" 37116747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37126747b715Smrg */ 3713f7df2e56Smrgstatic int indexForBitsPerPixel[33] = { 3714f7df2e56Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 3715f7df2e56Smrg 1, ~0, ~0, ~0, /* 4 bits per pixel */ 3716f7df2e56Smrg 2, ~0, ~0, ~0, /* 8 bits per pixel */ 3717f7df2e56Smrg ~0, ~0, ~0, ~0, 3718f7df2e56Smrg 3, ~0, ~0, ~0, /* 16 bits per pixel */ 3719f7df2e56Smrg ~0, ~0, ~0, ~0, 3720f7df2e56Smrg 4, ~0, ~0, ~0, /* 24 bits per pixel */ 3721f7df2e56Smrg ~0, ~0, ~0, ~0, 3722f7df2e56Smrg 5 /* 32 bits per pixel */ 37236747b715Smrg}; 37246747b715Smrg 37256747b715Smrg/* 37266747b715Smrg * This array gives the bytesperPixel value for cases where the number 37276747b715Smrg * of bits per pixel is a multiple of 8 but not a power of 2. 37286747b715Smrg */ 3729f7df2e56Smrgstatic int answerBytesPerPixel[33] = { 3730f7df2e56Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 3731f7df2e56Smrg 0, ~0, ~0, ~0, /* 4 bits per pixel */ 3732f7df2e56Smrg 0, ~0, ~0, ~0, /* 8 bits per pixel */ 3733f7df2e56Smrg ~0, ~0, ~0, ~0, 3734f7df2e56Smrg 0, ~0, ~0, ~0, /* 16 bits per pixel */ 3735f7df2e56Smrg ~0, ~0, ~0, ~0, 3736f7df2e56Smrg 3, ~0, ~0, ~0, /* 24 bits per pixel */ 3737f7df2e56Smrg ~0, ~0, ~0, ~0, 3738f7df2e56Smrg 0 /* 32 bits per pixel */ 37396747b715Smrg}; 37406747b715Smrg 37416747b715Smrg/* 37426747b715Smrg * This array gives the answer to the question "what is the second index for 37436747b715Smrg * the answer array above given the number of bits per scanline pad unit?" 37446747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 37456747b715Smrg */ 3746f7df2e56Smrgstatic int indexForScanlinePad[65] = { 3747f7df2e56Smrg ~0, ~0, ~0, ~0, 3748f7df2e56Smrg ~0, ~0, ~0, ~0, 3749f7df2e56Smrg 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ 3750f7df2e56Smrg ~0, ~0, ~0, ~0, 3751f7df2e56Smrg 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ 3752f7df2e56Smrg ~0, ~0, ~0, ~0, 3753f7df2e56Smrg ~0, ~0, ~0, ~0, 3754f7df2e56Smrg ~0, ~0, ~0, ~0, 3755f7df2e56Smrg 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ 3756f7df2e56Smrg ~0, ~0, ~0, ~0, 3757f7df2e56Smrg ~0, ~0, ~0, ~0, 3758f7df2e56Smrg ~0, ~0, ~0, ~0, 3759f7df2e56Smrg ~0, ~0, ~0, ~0, 3760f7df2e56Smrg ~0, ~0, ~0, ~0, 3761f7df2e56Smrg ~0, ~0, ~0, ~0, 3762f7df2e56Smrg ~0, ~0, ~0, ~0, 3763f7df2e56Smrg 3 /* 64 bits per scanline pad unit */ 37646747b715Smrg}; 37656747b715Smrg 37666747b715Smrg/* 37676747b715Smrg grow the array of screenRecs if necessary. 37686747b715Smrg call the device-supplied initialization procedure 37696747b715Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv. 37706747b715Smrg return the number of successfully installed screens. 37716747b715Smrg 37726747b715Smrg*/ 37736747b715Smrg 3774f7df2e56Smrgstatic int init_screen(ScreenPtr pScreen, int i, Bool gpu) 37756747b715Smrg{ 37766747b715Smrg int scanlinepad, format, depth, bitsPerPixel, j, k; 37776747b715Smrg 3778f7df2e56Smrg dixInitScreenSpecificPrivates(pScreen); 37796747b715Smrg 37806747b715Smrg if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { 3781f7df2e56Smrg return -1; 37826747b715Smrg } 37836747b715Smrg pScreen->myNum = i; 3784f7df2e56Smrg if (gpu) { 3785f7df2e56Smrg pScreen->myNum += GPU_SCREEN_OFFSET; 3786f7df2e56Smrg pScreen->isGPU = TRUE; 3787f7df2e56Smrg } 3788f7df2e56Smrg pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ 3789f7df2e56Smrg pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ 37906747b715Smrg pScreen->CreateScreenResources = 0; 37916747b715Smrg 3792f7df2e56Smrg xorg_list_init(&pScreen->pixmap_dirty_list); 3793f7df2e56Smrg xorg_list_init(&pScreen->unattached_list); 3794f7df2e56Smrg xorg_list_init(&pScreen->output_slave_list); 3795f7df2e56Smrg xorg_list_init(&pScreen->offload_slave_list); 3796f7df2e56Smrg 37976747b715Smrg /* 37986747b715Smrg * This loop gets run once for every Screen that gets added, 37996747b715Smrg * but thats ok. If the ddx layer initializes the formats 38006747b715Smrg * one at a time calling AddScreen() after each, then each 38016747b715Smrg * iteration will make it a little more accurate. Worst case 38026747b715Smrg * we do this loop N * numPixmapFormats where N is # of screens. 38036747b715Smrg * Anyway, this must be called after InitOutput and before the 38046747b715Smrg * screen init routine is called. 38056747b715Smrg */ 3806f7df2e56Smrg for (format = 0; format < screenInfo.numPixmapFormats; format++) { 3807f7df2e56Smrg depth = screenInfo.formats[format].depth; 3808f7df2e56Smrg bitsPerPixel = screenInfo.formats[format].bitsPerPixel; 3809f7df2e56Smrg scanlinepad = screenInfo.formats[format].scanlinePad; 3810f7df2e56Smrg j = indexForBitsPerPixel[bitsPerPixel]; 3811f7df2e56Smrg k = indexForScanlinePad[scanlinepad]; 3812f7df2e56Smrg PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k]; 3813f7df2e56Smrg PixmapWidthPaddingInfo[depth].padRoundUp = 3814f7df2e56Smrg (scanlinepad / bitsPerPixel) - 1; 3815f7df2e56Smrg j = indexForBitsPerPixel[8]; /* bits per byte */ 3816f7df2e56Smrg PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k]; 3817f7df2e56Smrg PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel; 3818f7df2e56Smrg if (answerBytesPerPixel[bitsPerPixel]) { 3819f7df2e56Smrg PixmapWidthPaddingInfo[depth].notPower2 = 1; 3820f7df2e56Smrg PixmapWidthPaddingInfo[depth].bytesPerPixel = 3821f7df2e56Smrg answerBytesPerPixel[bitsPerPixel]; 3822f7df2e56Smrg } 3823f7df2e56Smrg else { 3824f7df2e56Smrg PixmapWidthPaddingInfo[depth].notPower2 = 0; 3825f7df2e56Smrg } 38266747b715Smrg } 3827f7df2e56Smrg return 0; 3828f7df2e56Smrg} 3829f7df2e56Smrg 3830f7df2e56Smrgint 3831f7df2e56SmrgAddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , 3832f7df2e56Smrg int /*argc */ , 3833f7df2e56Smrg char ** /*argv */ 3834f7df2e56Smrg ), int argc, char **argv) 3835f7df2e56Smrg{ 3836f7df2e56Smrg 3837f7df2e56Smrg int i; 3838f7df2e56Smrg ScreenPtr pScreen; 3839f7df2e56Smrg Bool ret; 3840f7df2e56Smrg 3841f7df2e56Smrg i = screenInfo.numScreens; 3842f7df2e56Smrg if (i == MAXSCREENS) 3843f7df2e56Smrg return -1; 3844f7df2e56Smrg 3845f7df2e56Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 3846f7df2e56Smrg if (!pScreen) 3847f7df2e56Smrg return -1; 38486747b715Smrg 3849f7df2e56Smrg ret = init_screen(pScreen, i, FALSE); 3850f7df2e56Smrg if (ret != 0) { 3851f7df2e56Smrg free(pScreen); 3852f7df2e56Smrg return ret; 3853f7df2e56Smrg } 38546747b715Smrg /* This is where screen specific stuff gets initialized. Load the 38556747b715Smrg screen structure, call the hardware, whatever. 38566747b715Smrg This is also where the default colormap should be allocated and 38576747b715Smrg also pixel values for blackPixel, whitePixel, and the cursor 38586747b715Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 38596747b715Smrg any of the strings pointed to by argv. They may be passed to 38606747b715Smrg multiple screens. 3861f7df2e56Smrg */ 38626747b715Smrg screenInfo.screens[i] = pScreen; 38636747b715Smrg screenInfo.numScreens++; 3864f7df2e56Smrg if (!(*pfnInit) (pScreen, argc, argv)) { 3865f7df2e56Smrg dixFreeScreenSpecificPrivates(pScreen); 3866f7df2e56Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 3867f7df2e56Smrg free(pScreen); 3868f7df2e56Smrg screenInfo.numScreens--; 3869f7df2e56Smrg return -1; 38706747b715Smrg } 38716747b715Smrg 3872f7df2e56Smrg update_desktop_dimensions(); 3873f7df2e56Smrg 3874f7df2e56Smrg dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR, 3875f7df2e56Smrg 0); 38766747b715Smrg 38776747b715Smrg return i; 38786747b715Smrg} 3879f7df2e56Smrg 3880f7df2e56Smrgint 3881f7df2e56SmrgAddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , 3882f7df2e56Smrg int /*argc */ , 3883f7df2e56Smrg char ** /*argv */ 3884f7df2e56Smrg ), 3885f7df2e56Smrg int argc, char **argv) 3886f7df2e56Smrg{ 3887f7df2e56Smrg int i; 3888f7df2e56Smrg ScreenPtr pScreen; 3889f7df2e56Smrg Bool ret; 3890f7df2e56Smrg 3891f7df2e56Smrg i = screenInfo.numGPUScreens; 3892f7df2e56Smrg if (i == MAXGPUSCREENS) 3893f7df2e56Smrg return -1; 3894f7df2e56Smrg 3895f7df2e56Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 3896f7df2e56Smrg if (!pScreen) 3897f7df2e56Smrg return -1; 3898f7df2e56Smrg 3899f7df2e56Smrg ret = init_screen(pScreen, i, TRUE); 3900f7df2e56Smrg if (ret != 0) { 3901f7df2e56Smrg free(pScreen); 3902f7df2e56Smrg return ret; 3903f7df2e56Smrg } 3904f7df2e56Smrg 3905f7df2e56Smrg /* This is where screen specific stuff gets initialized. Load the 3906f7df2e56Smrg screen structure, call the hardware, whatever. 3907f7df2e56Smrg This is also where the default colormap should be allocated and 3908f7df2e56Smrg also pixel values for blackPixel, whitePixel, and the cursor 3909f7df2e56Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 3910f7df2e56Smrg any of the strings pointed to by argv. They may be passed to 3911f7df2e56Smrg multiple screens. 3912f7df2e56Smrg */ 3913f7df2e56Smrg screenInfo.gpuscreens[i] = pScreen; 3914f7df2e56Smrg screenInfo.numGPUScreens++; 3915f7df2e56Smrg if (!(*pfnInit) (pScreen, argc, argv)) { 3916f7df2e56Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 3917f7df2e56Smrg free(pScreen); 3918f7df2e56Smrg screenInfo.numGPUScreens--; 3919f7df2e56Smrg return -1; 3920f7df2e56Smrg } 3921f7df2e56Smrg 3922f7df2e56Smrg update_desktop_dimensions(); 3923f7df2e56Smrg 3924f7df2e56Smrg return i; 3925f7df2e56Smrg} 3926f7df2e56Smrg 3927f7df2e56Smrgvoid 3928f7df2e56SmrgRemoveGPUScreen(ScreenPtr pScreen) 3929f7df2e56Smrg{ 3930f7df2e56Smrg int idx, j; 3931f7df2e56Smrg if (!pScreen->isGPU) 3932f7df2e56Smrg return; 3933f7df2e56Smrg 3934f7df2e56Smrg idx = pScreen->myNum - GPU_SCREEN_OFFSET; 3935f7df2e56Smrg for (j = idx; j < screenInfo.numGPUScreens - 1; j++) { 3936f7df2e56Smrg screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1]; 3937f7df2e56Smrg screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET; 3938f7df2e56Smrg } 3939f7df2e56Smrg screenInfo.numGPUScreens--; 3940f7df2e56Smrg 3941f7df2e56Smrg /* this gets freed later in the resource list, but without 3942f7df2e56Smrg * the screen existing it causes crashes - so remove it here */ 3943f7df2e56Smrg if (pScreen->defColormap) 3944f7df2e56Smrg FreeResource(pScreen->defColormap, RT_COLORMAP); 3945f7df2e56Smrg free(pScreen); 3946f7df2e56Smrg 3947f7df2e56Smrg} 3948f7df2e56Smrg 3949f7df2e56Smrgvoid 3950f7df2e56SmrgAttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new) 3951f7df2e56Smrg{ 3952f7df2e56Smrg assert(new->isGPU); 3953f7df2e56Smrg assert(!new->current_master); 3954f7df2e56Smrg xorg_list_add(&new->unattached_head, &pScreen->unattached_list); 3955f7df2e56Smrg new->current_master = pScreen; 3956f7df2e56Smrg} 3957f7df2e56Smrg 3958f7df2e56Smrgvoid 3959f7df2e56SmrgDetachUnboundGPU(ScreenPtr slave) 3960f7df2e56Smrg{ 3961f7df2e56Smrg assert(slave->isGPU); 3962f7df2e56Smrg xorg_list_del(&slave->unattached_head); 3963f7df2e56Smrg slave->current_master = NULL; 3964f7df2e56Smrg} 3965f7df2e56Smrg 3966f7df2e56Smrgvoid 3967f7df2e56SmrgAttachOutputGPU(ScreenPtr pScreen, ScreenPtr new) 3968f7df2e56Smrg{ 3969f7df2e56Smrg assert(new->isGPU); 3970f7df2e56Smrg xorg_list_add(&new->output_head, &pScreen->output_slave_list); 3971f7df2e56Smrg new->current_master = pScreen; 3972f7df2e56Smrg} 3973f7df2e56Smrg 3974f7df2e56Smrgvoid 3975f7df2e56SmrgDetachOutputGPU(ScreenPtr slave) 3976f7df2e56Smrg{ 3977f7df2e56Smrg assert(slave->isGPU); 3978f7df2e56Smrg xorg_list_del(&slave->output_head); 3979f7df2e56Smrg slave->current_master = NULL; 3980f7df2e56Smrg} 3981f7df2e56Smrg 3982f7df2e56Smrgvoid 3983f7df2e56SmrgAttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new) 3984f7df2e56Smrg{ 3985f7df2e56Smrg assert(new->isGPU); 3986f7df2e56Smrg xorg_list_add(&new->offload_head, &pScreen->offload_slave_list); 3987f7df2e56Smrg new->current_master = pScreen; 3988f7df2e56Smrg} 3989f7df2e56Smrg 3990f7df2e56Smrgvoid 3991f7df2e56SmrgDetachOffloadGPU(ScreenPtr slave) 3992f7df2e56Smrg{ 3993f7df2e56Smrg assert(slave->isGPU); 3994f7df2e56Smrg xorg_list_del(&slave->offload_head); 3995f7df2e56Smrg slave->current_master = NULL; 3996f7df2e56Smrg} 3997f7df2e56Smrg 3998