1706f2543Smrg/************************************************************ 2706f2543Smrg 3706f2543SmrgCopyright 1987, 1989, 1998 The Open Group 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 7706f2543Smrgthe above copyright notice appear in all copies and that both that 8706f2543Smrgcopyright notice and this permission notice appear in supporting 9706f2543Smrgdocumentation. 10706f2543Smrg 11706f2543SmrgThe above copyright notice and this permission notice shall be included in 12706f2543Smrgall copies or substantial portions of the Software. 13706f2543Smrg 14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20706f2543Smrg 21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 23706f2543Smrgin this Software without prior written authorization from The Open Group. 24706f2543Smrg 25706f2543Smrg 26706f2543SmrgCopyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 27706f2543Smrg 28706f2543Smrg All Rights Reserved 29706f2543Smrg 30706f2543SmrgPermission to use, copy, modify, and distribute this software and its 31706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 32706f2543Smrgprovided that the above copyright notice appear in all copies and that 33706f2543Smrgboth that copyright notice and this permission notice appear in 34706f2543Smrgsupporting documentation, and that the name of Digital not be 35706f2543Smrgused in advertising or publicity pertaining to distribution of the 36706f2543Smrgsoftware without specific, written prior permission. 37706f2543Smrg 38706f2543SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40706f2543SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44706f2543SmrgSOFTWARE. 45706f2543Smrg 46706f2543Smrg********************************************************/ 47706f2543Smrg 48706f2543Smrg/* The panoramix components contained the following notice */ 49706f2543Smrg/***************************************************************** 50706f2543Smrg 51706f2543SmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 52706f2543Smrg 53706f2543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 54706f2543Smrgof this software and associated documentation files (the "Software"), to deal 55706f2543Smrgin the Software without restriction, including without limitation the rights 56706f2543Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 57706f2543Smrgcopies of the Software. 58706f2543Smrg 59706f2543SmrgThe above copyright notice and this permission notice shall be included in 60706f2543Smrgall copies or substantial portions of the Software. 61706f2543Smrg 62706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 64706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 65706f2543SmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 66706f2543SmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 67706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 68706f2543SmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 69706f2543Smrg 70706f2543SmrgExcept as contained in this notice, the name of Digital Equipment Corporation 71706f2543Smrgshall not be used in advertising or otherwise to promote the sale, use or other 72706f2543Smrgdealings in this Software without prior written authorization from Digital 73706f2543SmrgEquipment Corporation. 74706f2543Smrg 75706f2543Smrg******************************************************************/ 76706f2543Smrg 77706f2543Smrg/* XSERVER_DTRACE additions: 78706f2543Smrg * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. 79706f2543Smrg * 80706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 81706f2543Smrg * copy of this software and associated documentation files (the "Software"), 82706f2543Smrg * to deal in the Software without restriction, including without limitation 83706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 85706f2543Smrg * Software is furnished to do so, subject to the following conditions: 86706f2543Smrg * 87706f2543Smrg * The above copyright notice and this permission notice (including the next 88706f2543Smrg * paragraph) shall be included in all copies or substantial portions of the 89706f2543Smrg * Software. 90706f2543Smrg * 91706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 92706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 93706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 94706f2543Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 95706f2543Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 96706f2543Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 97706f2543Smrg * DEALINGS IN THE SOFTWARE. 98706f2543Smrg */ 99706f2543Smrg 100706f2543Smrg 101706f2543Smrg 102706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 103706f2543Smrg#include <dix-config.h> 104706f2543Smrg#include <version-config.h> 105706f2543Smrg#endif 106706f2543Smrg 107706f2543Smrg#ifdef PANORAMIX_DEBUG 108706f2543Smrg#include <stdio.h> 109706f2543Smrgint ProcInitialConnection(); 110706f2543Smrg#endif 111706f2543Smrg 112706f2543Smrg#include "windowstr.h" 113706f2543Smrg#include <X11/fonts/fontstruct.h> 114706f2543Smrg#include "dixfontstr.h" 115706f2543Smrg#include "gcstruct.h" 116706f2543Smrg#include "selection.h" 117706f2543Smrg#include "colormapst.h" 118706f2543Smrg#include "cursorstr.h" 119706f2543Smrg#include "scrnintstr.h" 120706f2543Smrg#include "opaque.h" 121706f2543Smrg#include "input.h" 122706f2543Smrg#include "servermd.h" 123706f2543Smrg#include "extnsionst.h" 124706f2543Smrg#include "dixfont.h" 125706f2543Smrg#include "dispatch.h" 126706f2543Smrg#include "swaprep.h" 127706f2543Smrg#include "swapreq.h" 128706f2543Smrg#include "privates.h" 129706f2543Smrg#include "xace.h" 130706f2543Smrg#include "inputstr.h" 131706f2543Smrg#include "xkbsrv.h" 132706f2543Smrg#include "site.h" 133706f2543Smrg 134706f2543Smrg#ifdef XSERVER_DTRACE 135706f2543Smrg#include "registry.h" 136706f2543Smrg#include <sys/types.h> 137706f2543Smrgtypedef const char *string; 138706f2543Smrg#include "Xserver-dtrace.h" 139706f2543Smrg#endif 140706f2543Smrg 141706f2543Smrg#define mskcnt ((MAXCLIENTS + 31) / 32) 142706f2543Smrg#define BITMASK(i) (1U << ((i) & 31)) 143706f2543Smrg#define MASKIDX(i) ((i) >> 5) 144706f2543Smrg#define MASKWORD(buf, i) buf[MASKIDX(i)] 145706f2543Smrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) 146706f2543Smrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) 147706f2543Smrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) 148706f2543Smrg 149706f2543SmrgxConnSetupPrefix connSetupPrefix; 150706f2543Smrg 151706f2543SmrgPaddingInfo PixmapWidthPaddingInfo[33]; 152706f2543Smrg 153706f2543Smrgstatic ClientPtr grabClient; 154706f2543Smrg#define GrabNone 0 155706f2543Smrg#define GrabActive 1 156706f2543Smrg#define GrabKickout 2 157706f2543Smrgstatic int grabState = GrabNone; 158706f2543Smrgstatic long grabWaiters[mskcnt]; 159706f2543SmrgCallbackListPtr ServerGrabCallback = NULL; 160706f2543SmrgHWEventQueuePtr checkForInput[2]; 161706f2543Smrgint connBlockScreenStart; 162706f2543Smrg 163706f2543Smrgstatic void KillAllClients(void); 164706f2543Smrg 165706f2543Smrgstatic int nextFreeClientID; /* always MIN free client ID */ 166706f2543Smrg 167706f2543Smrgstatic int nClients; /* number of authorized clients */ 168706f2543Smrg 169706f2543SmrgCallbackListPtr ClientStateCallback; 170706f2543Smrg 171706f2543Smrg/* dispatchException & isItTimeToYield must be declared volatile since they 172706f2543Smrg * are modified by signal handlers - otherwise optimizer may assume it doesn't 173706f2543Smrg * need to actually check value in memory when used and may miss changes from 174706f2543Smrg * signal handlers. 175706f2543Smrg */ 176706f2543Smrgvolatile char dispatchException = 0; 177706f2543Smrgvolatile char isItTimeToYield; 178706f2543Smrg 179706f2543Smrg#define SAME_SCREENS(a, b) (\ 180706f2543Smrg (a.pScreen == b.pScreen)) 181706f2543Smrg 182706f2543Smrgvoid 183706f2543SmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) 184706f2543Smrg{ 185706f2543Smrg checkForInput[0] = c0; 186706f2543Smrg checkForInput[1] = c1; 187706f2543Smrg} 188706f2543Smrg 189706f2543Smrgvoid 190706f2543SmrgUpdateCurrentTime(void) 191706f2543Smrg{ 192706f2543Smrg TimeStamp systime; 193706f2543Smrg 194706f2543Smrg /* To avoid time running backwards, we must call GetTimeInMillis before 195706f2543Smrg * calling ProcessInputEvents. 196706f2543Smrg */ 197706f2543Smrg systime.months = currentTime.months; 198706f2543Smrg systime.milliseconds = GetTimeInMillis(); 199706f2543Smrg if (systime.milliseconds < currentTime.milliseconds) 200706f2543Smrg systime.months++; 201706f2543Smrg if (*checkForInput[0] != *checkForInput[1]) 202706f2543Smrg ProcessInputEvents(); 203706f2543Smrg if (CompareTimeStamps(systime, currentTime) == LATER) 204706f2543Smrg currentTime = systime; 205706f2543Smrg} 206706f2543Smrg 207706f2543Smrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ 208706f2543Smrgvoid 209706f2543SmrgUpdateCurrentTimeIf(void) 210706f2543Smrg{ 211706f2543Smrg TimeStamp systime; 212706f2543Smrg 213706f2543Smrg systime.months = currentTime.months; 214706f2543Smrg systime.milliseconds = GetTimeInMillis(); 215706f2543Smrg if (systime.milliseconds < currentTime.milliseconds) 216706f2543Smrg systime.months++; 217706f2543Smrg if (*checkForInput[0] == *checkForInput[1]) 218706f2543Smrg currentTime = systime; 219706f2543Smrg} 220706f2543Smrg 221706f2543Smrg 222706f2543Smrg#undef SMART_DEBUG 223706f2543Smrg 224706f2543Smrg#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ 225706f2543Smrg#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ 226706f2543Smrg 227706f2543SmrgBool SmartScheduleDisable = FALSE; 228706f2543Smrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; 229706f2543Smrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; 230706f2543Smrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; 231706f2543Smrglong SmartScheduleTime; 232706f2543Smrgint SmartScheduleLatencyLimited = 0; 233706f2543Smrgstatic ClientPtr SmartLastClient; 234706f2543Smrgstatic int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; 235706f2543Smrg 236706f2543Smrg#ifdef SMART_DEBUG 237706f2543Smrglong SmartLastPrint; 238706f2543Smrg#endif 239706f2543Smrg 240706f2543Smrgvoid Dispatch(void); 241706f2543Smrg 242706f2543Smrgstatic int 243706f2543SmrgSmartScheduleClient (int *clientReady, int nready) 244706f2543Smrg{ 245706f2543Smrg ClientPtr pClient; 246706f2543Smrg int i; 247706f2543Smrg int client; 248706f2543Smrg int bestPrio, best = 0; 249706f2543Smrg int bestRobin, robin; 250706f2543Smrg long now = SmartScheduleTime; 251706f2543Smrg long idle; 252706f2543Smrg 253706f2543Smrg bestPrio = -0x7fffffff; 254706f2543Smrg bestRobin = 0; 255706f2543Smrg idle = 2 * SmartScheduleSlice; 256706f2543Smrg for (i = 0; i < nready; i++) 257706f2543Smrg { 258706f2543Smrg client = clientReady[i]; 259706f2543Smrg pClient = clients[client]; 260706f2543Smrg /* Praise clients which are idle */ 261706f2543Smrg if ((now - pClient->smart_check_tick) >= idle) 262706f2543Smrg { 263706f2543Smrg if (pClient->smart_priority < 0) 264706f2543Smrg pClient->smart_priority++; 265706f2543Smrg } 266706f2543Smrg pClient->smart_check_tick = now; 267706f2543Smrg 268706f2543Smrg /* check priority to select best client */ 269706f2543Smrg robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; 270706f2543Smrg if (pClient->smart_priority > bestPrio || 271706f2543Smrg (pClient->smart_priority == bestPrio && robin > bestRobin)) 272706f2543Smrg { 273706f2543Smrg bestPrio = pClient->smart_priority; 274706f2543Smrg bestRobin = robin; 275706f2543Smrg best = client; 276706f2543Smrg } 277706f2543Smrg#ifdef SMART_DEBUG 278706f2543Smrg if ((now - SmartLastPrint) >= 5000) 279706f2543Smrg fprintf (stderr, " %2d: %3d", client, pClient->smart_priority); 280706f2543Smrg#endif 281706f2543Smrg } 282706f2543Smrg#ifdef SMART_DEBUG 283706f2543Smrg if ((now - SmartLastPrint) >= 5000) 284706f2543Smrg { 285706f2543Smrg fprintf (stderr, " use %2d\n", best); 286706f2543Smrg SmartLastPrint = now; 287706f2543Smrg } 288706f2543Smrg#endif 289706f2543Smrg pClient = clients[best]; 290706f2543Smrg SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index; 291706f2543Smrg /* 292706f2543Smrg * Set current client pointer 293706f2543Smrg */ 294706f2543Smrg if (SmartLastClient != pClient) 295706f2543Smrg { 296706f2543Smrg pClient->smart_start_tick = now; 297706f2543Smrg SmartLastClient = pClient; 298706f2543Smrg } 299706f2543Smrg /* 300706f2543Smrg * Adjust slice 301706f2543Smrg */ 302706f2543Smrg if (nready == 1 && SmartScheduleLatencyLimited == 0) 303706f2543Smrg { 304706f2543Smrg /* 305706f2543Smrg * If it's been a long time since another client 306706f2543Smrg * has run, bump the slice up to get maximal 307706f2543Smrg * performance from a single client 308706f2543Smrg */ 309706f2543Smrg if ((now - pClient->smart_start_tick) > 1000 && 310706f2543Smrg SmartScheduleSlice < SmartScheduleMaxSlice) 311706f2543Smrg { 312706f2543Smrg SmartScheduleSlice += SmartScheduleInterval; 313706f2543Smrg } 314706f2543Smrg } 315706f2543Smrg else 316706f2543Smrg { 317706f2543Smrg SmartScheduleSlice = SmartScheduleInterval; 318706f2543Smrg } 319706f2543Smrg return best; 320706f2543Smrg} 321706f2543Smrg 322706f2543Smrgvoid 323706f2543SmrgEnableLimitedSchedulingLatency(void) 324706f2543Smrg{ 325706f2543Smrg ++SmartScheduleLatencyLimited; 326706f2543Smrg SmartScheduleSlice = SmartScheduleInterval; 327706f2543Smrg} 328706f2543Smrg 329706f2543Smrgvoid 330706f2543SmrgDisableLimitedSchedulingLatency(void) 331706f2543Smrg{ 332706f2543Smrg --SmartScheduleLatencyLimited; 333706f2543Smrg 334706f2543Smrg /* protect against bugs */ 335706f2543Smrg if (SmartScheduleLatencyLimited < 0) 336706f2543Smrg SmartScheduleLatencyLimited = 0; 337706f2543Smrg} 338706f2543Smrg 339706f2543Smrg#define MAJOROP ((xReq *)client->requestBuffer)->reqType 340706f2543Smrg 341706f2543Smrgvoid 342706f2543SmrgDispatch(void) 343706f2543Smrg{ 344706f2543Smrg int *clientReady; /* array of request ready clients */ 345706f2543Smrg int result; 346706f2543Smrg ClientPtr client; 347706f2543Smrg int nready; 348706f2543Smrg HWEventQueuePtr* icheck = checkForInput; 349706f2543Smrg long start_tick; 350706f2543Smrg 351706f2543Smrg nextFreeClientID = 1; 352706f2543Smrg nClients = 0; 353706f2543Smrg 354706f2543Smrg clientReady = malloc(sizeof(int) * MaxClients); 355706f2543Smrg if (!clientReady) 356706f2543Smrg return; 357706f2543Smrg 358706f2543Smrg SmartScheduleSlice = SmartScheduleInterval; 359706f2543Smrg while (!dispatchException) 360706f2543Smrg { 361706f2543Smrg if (*icheck[0] != *icheck[1]) 362706f2543Smrg { 363706f2543Smrg ProcessInputEvents(); 364706f2543Smrg FlushIfCriticalOutputPending(); 365706f2543Smrg } 366706f2543Smrg 367706f2543Smrg nready = WaitForSomething(clientReady); 368706f2543Smrg 369706f2543Smrg if (nready && !SmartScheduleDisable) 370706f2543Smrg { 371706f2543Smrg clientReady[0] = SmartScheduleClient (clientReady, nready); 372706f2543Smrg nready = 1; 373706f2543Smrg } 374706f2543Smrg /***************** 375706f2543Smrg * Handle events in round robin fashion, doing input between 376706f2543Smrg * each round 377706f2543Smrg *****************/ 378706f2543Smrg 379706f2543Smrg while (!dispatchException && (--nready >= 0)) 380706f2543Smrg { 381706f2543Smrg client = clients[clientReady[nready]]; 382706f2543Smrg if (! client) 383706f2543Smrg { 384706f2543Smrg /* KillClient can cause this to happen */ 385706f2543Smrg continue; 386706f2543Smrg } 387706f2543Smrg /* GrabServer activation can cause this to be true */ 388706f2543Smrg if (grabState == GrabKickout) 389706f2543Smrg { 390706f2543Smrg grabState = GrabActive; 391706f2543Smrg break; 392706f2543Smrg } 393706f2543Smrg isItTimeToYield = FALSE; 394706f2543Smrg 395706f2543Smrg start_tick = SmartScheduleTime; 396706f2543Smrg while (!isItTimeToYield) 397706f2543Smrg { 398706f2543Smrg if (*icheck[0] != *icheck[1]) 399706f2543Smrg ProcessInputEvents(); 400706f2543Smrg 401706f2543Smrg FlushIfCriticalOutputPending(); 402706f2543Smrg if (!SmartScheduleDisable && 403706f2543Smrg (SmartScheduleTime - start_tick) >= SmartScheduleSlice) 404706f2543Smrg { 405706f2543Smrg /* Penalize clients which consume ticks */ 406706f2543Smrg if (client->smart_priority > SMART_MIN_PRIORITY) 407706f2543Smrg client->smart_priority--; 408706f2543Smrg break; 409706f2543Smrg } 410706f2543Smrg /* now, finally, deal with client requests */ 411706f2543Smrg 412706f2543Smrg result = ReadRequestFromClient(client); 413706f2543Smrg if (result <= 0) 414706f2543Smrg { 415706f2543Smrg if (result < 0) 416706f2543Smrg CloseDownClient(client); 417706f2543Smrg break; 418706f2543Smrg } 419706f2543Smrg 420706f2543Smrg client->sequence++; 421706f2543Smrg#ifdef XSERVER_DTRACE 422706f2543Smrg XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP, 423706f2543Smrg ((xReq *)client->requestBuffer)->length, 424706f2543Smrg client->index, client->requestBuffer); 425706f2543Smrg#endif 426706f2543Smrg if (result > (maxBigRequestSize << 2)) 427706f2543Smrg result = BadLength; 428706f2543Smrg else { 429706f2543Smrg result = XaceHookDispatch(client, MAJOROP); 430706f2543Smrg if (result == Success) 431706f2543Smrg result = (* client->requestVector[MAJOROP])(client); 432706f2543Smrg XaceHookAuditEnd(client, result); 433706f2543Smrg } 434706f2543Smrg#ifdef XSERVER_DTRACE 435706f2543Smrg XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP, 436706f2543Smrg client->sequence, client->index, result); 437706f2543Smrg#endif 438706f2543Smrg 439706f2543Smrg if (client->noClientException != Success) 440706f2543Smrg { 441706f2543Smrg CloseDownClient(client); 442706f2543Smrg break; 443706f2543Smrg } 444706f2543Smrg else if (result != Success) 445706f2543Smrg { 446706f2543Smrg SendErrorToClient(client, MAJOROP, 447706f2543Smrg MinorOpcodeOfRequest(client), 448706f2543Smrg client->errorValue, result); 449706f2543Smrg break; 450706f2543Smrg } 451706f2543Smrg } 452706f2543Smrg FlushAllOutput(); 453706f2543Smrg client = clients[clientReady[nready]]; 454706f2543Smrg if (client) 455706f2543Smrg client->smart_stop_tick = SmartScheduleTime; 456706f2543Smrg } 457706f2543Smrg dispatchException &= ~DE_PRIORITYCHANGE; 458706f2543Smrg } 459706f2543Smrg#if defined(DDXBEFORERESET) 460706f2543Smrg ddxBeforeReset (); 461706f2543Smrg#endif 462706f2543Smrg KillAllClients(); 463706f2543Smrg free(clientReady); 464706f2543Smrg dispatchException &= ~DE_RESET; 465706f2543Smrg SmartScheduleLatencyLimited = 0; 466706f2543Smrg} 467706f2543Smrg 468706f2543Smrg#undef MAJOROP 469706f2543Smrg 470706f2543Smrgstatic int VendorRelease = VENDOR_RELEASE; 471706f2543Smrgstatic char *VendorString = VENDOR_NAME; 472706f2543Smrg 473706f2543Smrgstatic const int padlength[4] = {0, 3, 2, 1}; 474706f2543Smrg 475706f2543Smrgvoid 476706f2543SmrgSetVendorRelease(int release) 477706f2543Smrg{ 478706f2543Smrg VendorRelease = release; 479706f2543Smrg} 480706f2543Smrg 481706f2543Smrgvoid 482706f2543SmrgSetVendorString(char *string) 483706f2543Smrg{ 484706f2543Smrg VendorString = string; 485706f2543Smrg} 486706f2543Smrg 487706f2543SmrgBool 488706f2543SmrgCreateConnectionBlock(void) 489706f2543Smrg{ 490706f2543Smrg xConnSetup setup; 491706f2543Smrg xWindowRoot root; 492706f2543Smrg xDepth depth; 493706f2543Smrg xVisualType visual; 494706f2543Smrg xPixmapFormat format; 495706f2543Smrg unsigned long vid; 496706f2543Smrg int i, j, k, 497706f2543Smrg lenofblock, 498706f2543Smrg sizesofar = 0; 499706f2543Smrg char *pBuf; 500706f2543Smrg 501706f2543Smrg 502706f2543Smrg memset(&setup, 0, sizeof(xConnSetup)); 503706f2543Smrg /* Leave off the ridBase and ridMask, these must be sent with 504706f2543Smrg connection */ 505706f2543Smrg 506706f2543Smrg setup.release = VendorRelease; 507706f2543Smrg /* 508706f2543Smrg * per-server image and bitmap parameters are defined in Xmd.h 509706f2543Smrg */ 510706f2543Smrg setup.imageByteOrder = screenInfo.imageByteOrder; 511706f2543Smrg 512706f2543Smrg setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; 513706f2543Smrg setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; 514706f2543Smrg 515706f2543Smrg setup.bitmapBitOrder = screenInfo.bitmapBitOrder; 516706f2543Smrg setup.motionBufferSize = NumMotionEvents(); 517706f2543Smrg setup.numRoots = screenInfo.numScreens; 518706f2543Smrg setup.nbytesVendor = strlen(VendorString); 519706f2543Smrg setup.numFormats = screenInfo.numPixmapFormats; 520706f2543Smrg setup.maxRequestSize = MAX_REQUEST_SIZE; 521706f2543Smrg QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); 522706f2543Smrg 523706f2543Smrg lenofblock = sizeof(xConnSetup) + 524706f2543Smrg pad_to_int32(setup.nbytesVendor) + 525706f2543Smrg (setup.numFormats * sizeof(xPixmapFormat)) + 526706f2543Smrg (setup.numRoots * sizeof(xWindowRoot)); 527706f2543Smrg ConnectionInfo = malloc(lenofblock); 528706f2543Smrg if (!ConnectionInfo) 529706f2543Smrg return FALSE; 530706f2543Smrg 531706f2543Smrg memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup)); 532706f2543Smrg sizesofar = sizeof(xConnSetup); 533706f2543Smrg pBuf = ConnectionInfo + sizeof(xConnSetup); 534706f2543Smrg 535706f2543Smrg memmove(pBuf, VendorString, (int)setup.nbytesVendor); 536706f2543Smrg sizesofar += setup.nbytesVendor; 537706f2543Smrg pBuf += setup.nbytesVendor; 538706f2543Smrg i = padlength[setup.nbytesVendor & 3]; 539706f2543Smrg sizesofar += i; 540706f2543Smrg while (--i >= 0) 541706f2543Smrg *pBuf++ = 0; 542706f2543Smrg 543706f2543Smrg memset(&format, 0, sizeof(xPixmapFormat)); 544706f2543Smrg for (i=0; i<screenInfo.numPixmapFormats; i++) 545706f2543Smrg { 546706f2543Smrg format.depth = screenInfo.formats[i].depth; 547706f2543Smrg format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; 548706f2543Smrg format.scanLinePad = screenInfo.formats[i].scanlinePad; 549706f2543Smrg memmove(pBuf, (char *)&format, sizeof(xPixmapFormat)); 550706f2543Smrg pBuf += sizeof(xPixmapFormat); 551706f2543Smrg sizesofar += sizeof(xPixmapFormat); 552706f2543Smrg } 553706f2543Smrg 554706f2543Smrg connBlockScreenStart = sizesofar; 555706f2543Smrg memset(&depth, 0, sizeof(xDepth)); 556706f2543Smrg memset(&visual, 0, sizeof(xVisualType)); 557706f2543Smrg for (i=0; i<screenInfo.numScreens; i++) 558706f2543Smrg { 559706f2543Smrg ScreenPtr pScreen; 560706f2543Smrg DepthPtr pDepth; 561706f2543Smrg VisualPtr pVisual; 562706f2543Smrg 563706f2543Smrg pScreen = screenInfo.screens[i]; 564706f2543Smrg root.windowId = pScreen->root->drawable.id; 565706f2543Smrg root.defaultColormap = pScreen->defColormap; 566706f2543Smrg root.whitePixel = pScreen->whitePixel; 567706f2543Smrg root.blackPixel = pScreen->blackPixel; 568706f2543Smrg root.currentInputMask = 0; /* filled in when sent */ 569706f2543Smrg root.pixWidth = pScreen->width; 570706f2543Smrg root.pixHeight = pScreen->height; 571706f2543Smrg root.mmWidth = pScreen->mmWidth; 572706f2543Smrg root.mmHeight = pScreen->mmHeight; 573706f2543Smrg root.minInstalledMaps = pScreen->minInstalledCmaps; 574706f2543Smrg root.maxInstalledMaps = pScreen->maxInstalledCmaps; 575706f2543Smrg root.rootVisualID = pScreen->rootVisual; 576706f2543Smrg root.backingStore = pScreen->backingStoreSupport; 577706f2543Smrg root.saveUnders = FALSE; 578706f2543Smrg root.rootDepth = pScreen->rootDepth; 579706f2543Smrg root.nDepths = pScreen->numDepths; 580706f2543Smrg memmove(pBuf, (char *)&root, sizeof(xWindowRoot)); 581706f2543Smrg sizesofar += sizeof(xWindowRoot); 582706f2543Smrg pBuf += sizeof(xWindowRoot); 583706f2543Smrg 584706f2543Smrg pDepth = pScreen->allowedDepths; 585706f2543Smrg for(j = 0; j < pScreen->numDepths; j++, pDepth++) 586706f2543Smrg { 587706f2543Smrg lenofblock += sizeof(xDepth) + 588706f2543Smrg (pDepth->numVids * sizeof(xVisualType)); 589706f2543Smrg pBuf = (char *)realloc(ConnectionInfo, lenofblock); 590706f2543Smrg if (!pBuf) 591706f2543Smrg { 592706f2543Smrg free(ConnectionInfo); 593706f2543Smrg return FALSE; 594706f2543Smrg } 595706f2543Smrg ConnectionInfo = pBuf; 596706f2543Smrg pBuf += sizesofar; 597706f2543Smrg depth.depth = pDepth->depth; 598706f2543Smrg depth.nVisuals = pDepth->numVids; 599706f2543Smrg memmove(pBuf, (char *)&depth, sizeof(xDepth)); 600706f2543Smrg pBuf += sizeof(xDepth); 601706f2543Smrg sizesofar += sizeof(xDepth); 602706f2543Smrg for(k = 0; k < pDepth->numVids; k++) 603706f2543Smrg { 604706f2543Smrg vid = pDepth->vids[k]; 605706f2543Smrg for (pVisual = pScreen->visuals; 606706f2543Smrg pVisual->vid != vid; 607706f2543Smrg pVisual++) 608706f2543Smrg ; 609706f2543Smrg visual.visualID = vid; 610706f2543Smrg visual.class = pVisual->class; 611706f2543Smrg visual.bitsPerRGB = pVisual->bitsPerRGBValue; 612706f2543Smrg visual.colormapEntries = pVisual->ColormapEntries; 613706f2543Smrg visual.redMask = pVisual->redMask; 614706f2543Smrg visual.greenMask = pVisual->greenMask; 615706f2543Smrg visual.blueMask = pVisual->blueMask; 616706f2543Smrg memmove(pBuf, (char *)&visual, sizeof(xVisualType)); 617706f2543Smrg pBuf += sizeof(xVisualType); 618706f2543Smrg sizesofar += sizeof(xVisualType); 619706f2543Smrg } 620706f2543Smrg } 621706f2543Smrg } 622706f2543Smrg connSetupPrefix.success = xTrue; 623706f2543Smrg connSetupPrefix.length = lenofblock/4; 624706f2543Smrg connSetupPrefix.majorVersion = X_PROTOCOL; 625706f2543Smrg connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; 626706f2543Smrg return TRUE; 627706f2543Smrg} 628706f2543Smrg 629706f2543Smrg 630706f2543Smrgint 631706f2543SmrgProcBadRequest(ClientPtr client) 632706f2543Smrg{ 633706f2543Smrg return BadRequest; 634706f2543Smrg} 635706f2543Smrg 636706f2543Smrgint 637706f2543SmrgProcCreateWindow(ClientPtr client) 638706f2543Smrg{ 639706f2543Smrg WindowPtr pParent, pWin; 640706f2543Smrg REQUEST(xCreateWindowReq); 641706f2543Smrg int len, rc; 642706f2543Smrg 643706f2543Smrg REQUEST_AT_LEAST_SIZE(xCreateWindowReq); 644706f2543Smrg 645706f2543Smrg LEGAL_NEW_RESOURCE(stuff->wid, client); 646706f2543Smrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 647706f2543Smrg if (rc != Success) 648706f2543Smrg return rc; 649706f2543Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); 650706f2543Smrg if (Ones(stuff->mask) != len) 651706f2543Smrg return BadLength; 652706f2543Smrg if (!stuff->width || !stuff->height) 653706f2543Smrg { 654706f2543Smrg client->errorValue = 0; 655706f2543Smrg return BadValue; 656706f2543Smrg } 657706f2543Smrg pWin = CreateWindow(stuff->wid, pParent, stuff->x, 658706f2543Smrg stuff->y, stuff->width, stuff->height, 659706f2543Smrg stuff->borderWidth, stuff->class, 660706f2543Smrg stuff->mask, (XID *) &stuff[1], 661706f2543Smrg (int)stuff->depth, 662706f2543Smrg client, stuff->visual, &rc); 663706f2543Smrg if (pWin) 664706f2543Smrg { 665706f2543Smrg Mask mask = pWin->eventMask; 666706f2543Smrg 667706f2543Smrg pWin->eventMask = 0; /* subterfuge in case AddResource fails */ 668706f2543Smrg if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin)) 669706f2543Smrg return BadAlloc; 670706f2543Smrg pWin->eventMask = mask; 671706f2543Smrg } 672706f2543Smrg return rc; 673706f2543Smrg} 674706f2543Smrg 675706f2543Smrgint 676706f2543SmrgProcChangeWindowAttributes(ClientPtr client) 677706f2543Smrg{ 678706f2543Smrg WindowPtr pWin; 679706f2543Smrg REQUEST(xChangeWindowAttributesReq); 680706f2543Smrg int len, rc; 681706f2543Smrg Mask access_mode = 0; 682706f2543Smrg 683706f2543Smrg REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); 684706f2543Smrg access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; 685706f2543Smrg access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; 686706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); 687706f2543Smrg if (rc != Success) 688706f2543Smrg return rc; 689706f2543Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); 690706f2543Smrg if (len != Ones(stuff->valueMask)) 691706f2543Smrg return BadLength; 692706f2543Smrg return ChangeWindowAttributes(pWin, 693706f2543Smrg stuff->valueMask, 694706f2543Smrg (XID *) &stuff[1], 695706f2543Smrg client); 696706f2543Smrg} 697706f2543Smrg 698706f2543Smrgint 699706f2543SmrgProcGetWindowAttributes(ClientPtr client) 700706f2543Smrg{ 701706f2543Smrg WindowPtr pWin; 702706f2543Smrg REQUEST(xResourceReq); 703706f2543Smrg xGetWindowAttributesReply wa; 704706f2543Smrg int rc; 705706f2543Smrg 706706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 707706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 708706f2543Smrg if (rc != Success) 709706f2543Smrg return rc; 710706f2543Smrg memset(&wa, 0, sizeof(xGetWindowAttributesReply)); 711706f2543Smrg GetWindowAttributes(pWin, client, &wa); 712706f2543Smrg WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); 713706f2543Smrg return Success; 714706f2543Smrg} 715706f2543Smrg 716706f2543Smrgint 717706f2543SmrgProcDestroyWindow(ClientPtr client) 718706f2543Smrg{ 719706f2543Smrg WindowPtr pWin; 720706f2543Smrg REQUEST(xResourceReq); 721706f2543Smrg int rc; 722706f2543Smrg 723706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 724706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 725706f2543Smrg if (rc != Success) 726706f2543Smrg return rc; 727706f2543Smrg if (pWin->parent) { 728706f2543Smrg rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, 729706f2543Smrg DixRemoveAccess); 730706f2543Smrg if (rc != Success) 731706f2543Smrg return rc; 732706f2543Smrg FreeResource(stuff->id, RT_NONE); 733706f2543Smrg } 734706f2543Smrg return Success; 735706f2543Smrg} 736706f2543Smrg 737706f2543Smrgint 738706f2543SmrgProcDestroySubwindows(ClientPtr client) 739706f2543Smrg{ 740706f2543Smrg WindowPtr pWin; 741706f2543Smrg REQUEST(xResourceReq); 742706f2543Smrg int rc; 743706f2543Smrg 744706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 745706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); 746706f2543Smrg if (rc != Success) 747706f2543Smrg return rc; 748706f2543Smrg DestroySubwindows(pWin, client); 749706f2543Smrg return Success; 750706f2543Smrg} 751706f2543Smrg 752706f2543Smrgint 753706f2543SmrgProcChangeSaveSet(ClientPtr client) 754706f2543Smrg{ 755706f2543Smrg WindowPtr pWin; 756706f2543Smrg REQUEST(xChangeSaveSetReq); 757706f2543Smrg int rc; 758706f2543Smrg 759706f2543Smrg REQUEST_SIZE_MATCH(xChangeSaveSetReq); 760706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 761706f2543Smrg if (rc != Success) 762706f2543Smrg return rc; 763706f2543Smrg if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) 764706f2543Smrg return BadMatch; 765706f2543Smrg if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) 766706f2543Smrg return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); 767706f2543Smrg client->errorValue = stuff->mode; 768706f2543Smrg return BadValue; 769706f2543Smrg} 770706f2543Smrg 771706f2543Smrgint 772706f2543SmrgProcReparentWindow(ClientPtr client) 773706f2543Smrg{ 774706f2543Smrg WindowPtr pWin, pParent; 775706f2543Smrg REQUEST(xReparentWindowReq); 776706f2543Smrg int rc; 777706f2543Smrg 778706f2543Smrg REQUEST_SIZE_MATCH(xReparentWindowReq); 779706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 780706f2543Smrg if (rc != Success) 781706f2543Smrg return rc; 782706f2543Smrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 783706f2543Smrg if (rc != Success) 784706f2543Smrg return rc; 785706f2543Smrg if (!SAME_SCREENS(pWin->drawable, pParent->drawable)) 786706f2543Smrg return BadMatch; 787706f2543Smrg if ((pWin->backgroundState == ParentRelative) && 788706f2543Smrg (pParent->drawable.depth != pWin->drawable.depth)) 789706f2543Smrg return BadMatch; 790706f2543Smrg if ((pWin->drawable.class != InputOnly) && 791706f2543Smrg (pParent->drawable.class == InputOnly)) 792706f2543Smrg return BadMatch; 793706f2543Smrg return ReparentWindow(pWin, pParent, 794706f2543Smrg (short)stuff->x, (short)stuff->y, client); 795706f2543Smrg} 796706f2543Smrg 797706f2543Smrgint 798706f2543SmrgProcMapWindow(ClientPtr client) 799706f2543Smrg{ 800706f2543Smrg WindowPtr pWin; 801706f2543Smrg REQUEST(xResourceReq); 802706f2543Smrg int rc; 803706f2543Smrg 804706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 805706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); 806706f2543Smrg if (rc != Success) 807706f2543Smrg return rc; 808706f2543Smrg MapWindow(pWin, client); 809706f2543Smrg /* update cache to say it is mapped */ 810706f2543Smrg return Success; 811706f2543Smrg} 812706f2543Smrg 813706f2543Smrgint 814706f2543SmrgProcMapSubwindows(ClientPtr client) 815706f2543Smrg{ 816706f2543Smrg WindowPtr pWin; 817706f2543Smrg REQUEST(xResourceReq); 818706f2543Smrg int rc; 819706f2543Smrg 820706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 821706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 822706f2543Smrg if (rc != Success) 823706f2543Smrg return rc; 824706f2543Smrg MapSubwindows(pWin, client); 825706f2543Smrg /* update cache to say it is mapped */ 826706f2543Smrg return Success; 827706f2543Smrg} 828706f2543Smrg 829706f2543Smrgint 830706f2543SmrgProcUnmapWindow(ClientPtr client) 831706f2543Smrg{ 832706f2543Smrg WindowPtr pWin; 833706f2543Smrg REQUEST(xResourceReq); 834706f2543Smrg int rc; 835706f2543Smrg 836706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 837706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); 838706f2543Smrg if (rc != Success) 839706f2543Smrg return rc; 840706f2543Smrg UnmapWindow(pWin, FALSE); 841706f2543Smrg /* update cache to say it is mapped */ 842706f2543Smrg return Success; 843706f2543Smrg} 844706f2543Smrg 845706f2543Smrgint 846706f2543SmrgProcUnmapSubwindows(ClientPtr client) 847706f2543Smrg{ 848706f2543Smrg WindowPtr pWin; 849706f2543Smrg REQUEST(xResourceReq); 850706f2543Smrg int rc; 851706f2543Smrg 852706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 853706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 854706f2543Smrg if (rc != Success) 855706f2543Smrg return rc; 856706f2543Smrg UnmapSubwindows(pWin); 857706f2543Smrg return Success; 858706f2543Smrg} 859706f2543Smrg 860706f2543Smrgint 861706f2543SmrgProcConfigureWindow(ClientPtr client) 862706f2543Smrg{ 863706f2543Smrg WindowPtr pWin; 864706f2543Smrg REQUEST(xConfigureWindowReq); 865706f2543Smrg int len, rc; 866706f2543Smrg 867706f2543Smrg REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); 868706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, 869706f2543Smrg DixManageAccess|DixSetAttrAccess); 870706f2543Smrg if (rc != Success) 871706f2543Smrg return rc; 872706f2543Smrg len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); 873706f2543Smrg if (Ones((Mask)stuff->mask) != len) 874706f2543Smrg return BadLength; 875706f2543Smrg return ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], client); 876706f2543Smrg} 877706f2543Smrg 878706f2543Smrgint 879706f2543SmrgProcCirculateWindow(ClientPtr client) 880706f2543Smrg{ 881706f2543Smrg WindowPtr pWin; 882706f2543Smrg REQUEST(xCirculateWindowReq); 883706f2543Smrg int rc; 884706f2543Smrg 885706f2543Smrg REQUEST_SIZE_MATCH(xCirculateWindowReq); 886706f2543Smrg if ((stuff->direction != RaiseLowest) && 887706f2543Smrg (stuff->direction != LowerHighest)) 888706f2543Smrg { 889706f2543Smrg client->errorValue = stuff->direction; 890706f2543Smrg return BadValue; 891706f2543Smrg } 892706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 893706f2543Smrg if (rc != Success) 894706f2543Smrg return rc; 895706f2543Smrg CirculateWindow(pWin, (int)stuff->direction, client); 896706f2543Smrg return Success; 897706f2543Smrg} 898706f2543Smrg 899706f2543Smrgstatic int 900706f2543SmrgGetGeometry(ClientPtr client, xGetGeometryReply *rep) 901706f2543Smrg{ 902706f2543Smrg DrawablePtr pDraw; 903706f2543Smrg int rc; 904706f2543Smrg REQUEST(xResourceReq); 905706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 906706f2543Smrg 907706f2543Smrg rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); 908706f2543Smrg if (rc != Success) 909706f2543Smrg return rc; 910706f2543Smrg 911706f2543Smrg rep->type = X_Reply; 912706f2543Smrg rep->length = 0; 913706f2543Smrg rep->sequenceNumber = client->sequence; 914706f2543Smrg rep->root = pDraw->pScreen->root->drawable.id; 915706f2543Smrg rep->depth = pDraw->depth; 916706f2543Smrg rep->width = pDraw->width; 917706f2543Smrg rep->height = pDraw->height; 918706f2543Smrg 919706f2543Smrg if (WindowDrawable(pDraw->type)) 920706f2543Smrg { 921706f2543Smrg WindowPtr pWin = (WindowPtr)pDraw; 922706f2543Smrg rep->x = pWin->origin.x - wBorderWidth (pWin); 923706f2543Smrg rep->y = pWin->origin.y - wBorderWidth (pWin); 924706f2543Smrg rep->borderWidth = pWin->borderWidth; 925706f2543Smrg } 926706f2543Smrg else /* DRAWABLE_PIXMAP */ 927706f2543Smrg { 928706f2543Smrg rep->x = rep->y = rep->borderWidth = 0; 929706f2543Smrg } 930706f2543Smrg 931706f2543Smrg return Success; 932706f2543Smrg} 933706f2543Smrg 934706f2543Smrg 935706f2543Smrgint 936706f2543SmrgProcGetGeometry(ClientPtr client) 937706f2543Smrg{ 938706f2543Smrg xGetGeometryReply rep; 939706f2543Smrg int status; 940706f2543Smrg 941706f2543Smrg memset(&rep, 0, sizeof(xGetGeometryReply)); 942706f2543Smrg if ((status = GetGeometry(client, &rep)) != Success) 943706f2543Smrg return status; 944706f2543Smrg 945706f2543Smrg WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); 946706f2543Smrg return Success; 947706f2543Smrg} 948706f2543Smrg 949706f2543Smrg 950706f2543Smrgint 951706f2543SmrgProcQueryTree(ClientPtr client) 952706f2543Smrg{ 953706f2543Smrg xQueryTreeReply reply; 954706f2543Smrg int rc, numChildren = 0; 955706f2543Smrg WindowPtr pChild, pWin, pHead; 956706f2543Smrg Window *childIDs = (Window *)NULL; 957706f2543Smrg REQUEST(xResourceReq); 958706f2543Smrg 959706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 960706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 961706f2543Smrg if (rc != Success) 962706f2543Smrg return rc; 963706f2543Smrg memset(&reply, 0, sizeof(xQueryTreeReply)); 964706f2543Smrg reply.type = X_Reply; 965706f2543Smrg reply.root = pWin->drawable.pScreen->root->drawable.id; 966706f2543Smrg reply.sequenceNumber = client->sequence; 967706f2543Smrg if (pWin->parent) 968706f2543Smrg reply.parent = pWin->parent->drawable.id; 969706f2543Smrg else 970706f2543Smrg reply.parent = (Window)None; 971706f2543Smrg pHead = RealChildHead(pWin); 972706f2543Smrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 973706f2543Smrg numChildren++; 974706f2543Smrg if (numChildren) 975706f2543Smrg { 976706f2543Smrg int curChild = 0; 977706f2543Smrg 978706f2543Smrg childIDs = malloc(numChildren * sizeof(Window)); 979706f2543Smrg if (!childIDs) 980706f2543Smrg return BadAlloc; 981706f2543Smrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 982706f2543Smrg childIDs[curChild++] = pChild->drawable.id; 983706f2543Smrg } 984706f2543Smrg 985706f2543Smrg reply.nChildren = numChildren; 986706f2543Smrg reply.length = bytes_to_int32(numChildren * sizeof(Window)); 987706f2543Smrg 988706f2543Smrg WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); 989706f2543Smrg if (numChildren) 990706f2543Smrg { 991706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 992706f2543Smrg WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs); 993706f2543Smrg free(childIDs); 994706f2543Smrg } 995706f2543Smrg 996706f2543Smrg return Success; 997706f2543Smrg} 998706f2543Smrg 999706f2543Smrgint 1000706f2543SmrgProcInternAtom(ClientPtr client) 1001706f2543Smrg{ 1002706f2543Smrg Atom atom; 1003706f2543Smrg char *tchar; 1004706f2543Smrg REQUEST(xInternAtomReq); 1005706f2543Smrg 1006706f2543Smrg REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); 1007706f2543Smrg if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) 1008706f2543Smrg { 1009706f2543Smrg client->errorValue = stuff->onlyIfExists; 1010706f2543Smrg return BadValue; 1011706f2543Smrg } 1012706f2543Smrg tchar = (char *) &stuff[1]; 1013706f2543Smrg atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); 1014706f2543Smrg if (atom != BAD_RESOURCE) 1015706f2543Smrg { 1016706f2543Smrg xInternAtomReply reply; 1017706f2543Smrg memset(&reply, 0, sizeof(xInternAtomReply)); 1018706f2543Smrg reply.type = X_Reply; 1019706f2543Smrg reply.length = 0; 1020706f2543Smrg reply.sequenceNumber = client->sequence; 1021706f2543Smrg reply.atom = atom; 1022706f2543Smrg WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); 1023706f2543Smrg return Success; 1024706f2543Smrg } 1025706f2543Smrg else 1026706f2543Smrg return BadAlloc; 1027706f2543Smrg} 1028706f2543Smrg 1029706f2543Smrgint 1030706f2543SmrgProcGetAtomName(ClientPtr client) 1031706f2543Smrg{ 1032706f2543Smrg const char *str; 1033706f2543Smrg xGetAtomNameReply reply; 1034706f2543Smrg int len; 1035706f2543Smrg REQUEST(xResourceReq); 1036706f2543Smrg 1037706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 1038706f2543Smrg if ( (str = NameForAtom(stuff->id)) ) 1039706f2543Smrg { 1040706f2543Smrg len = strlen(str); 1041706f2543Smrg memset(&reply, 0, sizeof(xGetAtomNameReply)); 1042706f2543Smrg reply.type = X_Reply; 1043706f2543Smrg reply.length = bytes_to_int32(len); 1044706f2543Smrg reply.sequenceNumber = client->sequence; 1045706f2543Smrg reply.nameLength = len; 1046706f2543Smrg WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); 1047706f2543Smrg (void)WriteToClient(client, len, str); 1048706f2543Smrg return Success; 1049706f2543Smrg } 1050706f2543Smrg else 1051706f2543Smrg { 1052706f2543Smrg client->errorValue = stuff->id; 1053706f2543Smrg return BadAtom; 1054706f2543Smrg } 1055706f2543Smrg} 1056706f2543Smrg 1057706f2543Smrgint 1058706f2543SmrgProcGrabServer(ClientPtr client) 1059706f2543Smrg{ 1060706f2543Smrg int rc; 1061706f2543Smrg REQUEST_SIZE_MATCH(xReq); 1062706f2543Smrg if (grabState != GrabNone && client != grabClient) 1063706f2543Smrg { 1064706f2543Smrg ResetCurrentRequest(client); 1065706f2543Smrg client->sequence--; 1066706f2543Smrg BITSET(grabWaiters, client->index); 1067706f2543Smrg IgnoreClient(client); 1068706f2543Smrg return Success; 1069706f2543Smrg } 1070706f2543Smrg rc = OnlyListenToOneClient(client); 1071706f2543Smrg if (rc != Success) 1072706f2543Smrg return rc; 1073706f2543Smrg grabState = GrabKickout; 1074706f2543Smrg grabClient = client; 1075706f2543Smrg 1076706f2543Smrg if (ServerGrabCallback) 1077706f2543Smrg { 1078706f2543Smrg ServerGrabInfoRec grabinfo; 1079706f2543Smrg grabinfo.client = client; 1080706f2543Smrg grabinfo.grabstate = SERVER_GRABBED; 1081706f2543Smrg CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 1082706f2543Smrg } 1083706f2543Smrg 1084706f2543Smrg return Success; 1085706f2543Smrg} 1086706f2543Smrg 1087706f2543Smrgstatic void 1088706f2543SmrgUngrabServer(ClientPtr client) 1089706f2543Smrg{ 1090706f2543Smrg int i; 1091706f2543Smrg 1092706f2543Smrg grabState = GrabNone; 1093706f2543Smrg ListenToAllClients(); 1094706f2543Smrg for (i = mskcnt; --i >= 0 && !grabWaiters[i]; ) 1095706f2543Smrg ; 1096706f2543Smrg if (i >= 0) 1097706f2543Smrg { 1098706f2543Smrg i <<= 5; 1099706f2543Smrg while (!GETBIT(grabWaiters, i)) 1100706f2543Smrg i++; 1101706f2543Smrg BITCLEAR(grabWaiters, i); 1102706f2543Smrg AttendClient(clients[i]); 1103706f2543Smrg } 1104706f2543Smrg 1105706f2543Smrg if (ServerGrabCallback) 1106706f2543Smrg { 1107706f2543Smrg ServerGrabInfoRec grabinfo; 1108706f2543Smrg grabinfo.client = client; 1109706f2543Smrg grabinfo.grabstate = SERVER_UNGRABBED; 1110706f2543Smrg CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 1111706f2543Smrg } 1112706f2543Smrg} 1113706f2543Smrg 1114706f2543Smrgint 1115706f2543SmrgProcUngrabServer(ClientPtr client) 1116706f2543Smrg{ 1117706f2543Smrg REQUEST_SIZE_MATCH(xReq); 1118706f2543Smrg UngrabServer(client); 1119706f2543Smrg return Success; 1120706f2543Smrg} 1121706f2543Smrg 1122706f2543Smrgint 1123706f2543SmrgProcTranslateCoords(ClientPtr client) 1124706f2543Smrg{ 1125706f2543Smrg REQUEST(xTranslateCoordsReq); 1126706f2543Smrg 1127706f2543Smrg WindowPtr pWin, pDst; 1128706f2543Smrg xTranslateCoordsReply rep; 1129706f2543Smrg int rc; 1130706f2543Smrg 1131706f2543Smrg REQUEST_SIZE_MATCH(xTranslateCoordsReq); 1132706f2543Smrg rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); 1133706f2543Smrg if (rc != Success) 1134706f2543Smrg return rc; 1135706f2543Smrg rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); 1136706f2543Smrg if (rc != Success) 1137706f2543Smrg return rc; 1138706f2543Smrg memset(&rep, 0, sizeof(xTranslateCoordsReply)); 1139706f2543Smrg rep.type = X_Reply; 1140706f2543Smrg rep.length = 0; 1141706f2543Smrg rep.sequenceNumber = client->sequence; 1142706f2543Smrg if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) 1143706f2543Smrg { 1144706f2543Smrg rep.sameScreen = xFalse; 1145706f2543Smrg rep.child = None; 1146706f2543Smrg rep.dstX = rep.dstY = 0; 1147706f2543Smrg } 1148706f2543Smrg else 1149706f2543Smrg { 1150706f2543Smrg INT16 x, y; 1151706f2543Smrg rep.sameScreen = xTrue; 1152706f2543Smrg rep.child = None; 1153706f2543Smrg /* computing absolute coordinates -- adjust to destination later */ 1154706f2543Smrg x = pWin->drawable.x + stuff->srcX; 1155706f2543Smrg y = pWin->drawable.y + stuff->srcY; 1156706f2543Smrg pWin = pDst->firstChild; 1157706f2543Smrg while (pWin) 1158706f2543Smrg { 1159706f2543Smrg BoxRec box; 1160706f2543Smrg if ((pWin->mapped) && 1161706f2543Smrg (x >= pWin->drawable.x - wBorderWidth (pWin)) && 1162706f2543Smrg (x < pWin->drawable.x + (int)pWin->drawable.width + 1163706f2543Smrg wBorderWidth (pWin)) && 1164706f2543Smrg (y >= pWin->drawable.y - wBorderWidth (pWin)) && 1165706f2543Smrg (y < pWin->drawable.y + (int)pWin->drawable.height + 1166706f2543Smrg wBorderWidth (pWin)) 1167706f2543Smrg /* When a window is shaped, a further check 1168706f2543Smrg * is made to see if the point is inside 1169706f2543Smrg * borderSize 1170706f2543Smrg */ 1171706f2543Smrg && (!wBoundingShape(pWin) || 1172706f2543Smrg RegionContainsPoint(&pWin->borderSize, x, y, &box)) 1173706f2543Smrg 1174706f2543Smrg && (!wInputShape(pWin) || 1175706f2543Smrg RegionContainsPoint(wInputShape(pWin), 1176706f2543Smrg x - pWin->drawable.x, 1177706f2543Smrg y - pWin->drawable.y, &box)) 1178706f2543Smrg ) 1179706f2543Smrg { 1180706f2543Smrg rep.child = pWin->drawable.id; 1181706f2543Smrg pWin = (WindowPtr) NULL; 1182706f2543Smrg } 1183706f2543Smrg else 1184706f2543Smrg pWin = pWin->nextSib; 1185706f2543Smrg } 1186706f2543Smrg /* adjust to destination coordinates */ 1187706f2543Smrg rep.dstX = x - pDst->drawable.x; 1188706f2543Smrg rep.dstY = y - pDst->drawable.y; 1189706f2543Smrg } 1190706f2543Smrg WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); 1191706f2543Smrg return Success; 1192706f2543Smrg} 1193706f2543Smrg 1194706f2543Smrgint 1195706f2543SmrgProcOpenFont(ClientPtr client) 1196706f2543Smrg{ 1197706f2543Smrg int err; 1198706f2543Smrg REQUEST(xOpenFontReq); 1199706f2543Smrg 1200706f2543Smrg REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); 1201706f2543Smrg client->errorValue = stuff->fid; 1202706f2543Smrg LEGAL_NEW_RESOURCE(stuff->fid, client); 1203706f2543Smrg err = OpenFont(client, stuff->fid, (Mask) 0, 1204706f2543Smrg stuff->nbytes, (char *)&stuff[1]); 1205706f2543Smrg if (err == Success) 1206706f2543Smrg { 1207706f2543Smrg return Success; 1208706f2543Smrg } 1209706f2543Smrg else 1210706f2543Smrg return err; 1211706f2543Smrg} 1212706f2543Smrg 1213706f2543Smrgint 1214706f2543SmrgProcCloseFont(ClientPtr client) 1215706f2543Smrg{ 1216706f2543Smrg FontPtr pFont; 1217706f2543Smrg int rc; 1218706f2543Smrg REQUEST(xResourceReq); 1219706f2543Smrg 1220706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 1221706f2543Smrg rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, 1222706f2543Smrg client, DixDestroyAccess); 1223706f2543Smrg if (rc == Success) 1224706f2543Smrg { 1225706f2543Smrg FreeResource(stuff->id, RT_NONE); 1226706f2543Smrg return Success; 1227706f2543Smrg } 1228706f2543Smrg else 1229706f2543Smrg { 1230706f2543Smrg client->errorValue = stuff->id; 1231706f2543Smrg return rc; 1232706f2543Smrg } 1233706f2543Smrg} 1234706f2543Smrg 1235706f2543Smrgint 1236706f2543SmrgProcQueryFont(ClientPtr client) 1237706f2543Smrg{ 1238706f2543Smrg xQueryFontReply *reply; 1239706f2543Smrg FontPtr pFont; 1240706f2543Smrg int rc; 1241706f2543Smrg REQUEST(xResourceReq); 1242706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 1243706f2543Smrg 1244706f2543Smrg rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess); 1245706f2543Smrg if (rc != Success) 1246706f2543Smrg return rc; 1247706f2543Smrg 1248706f2543Smrg { 1249706f2543Smrg xCharInfo *pmax = FONTINKMAX(pFont); 1250706f2543Smrg xCharInfo *pmin = FONTINKMIN(pFont); 1251706f2543Smrg int nprotoxcistructs; 1252706f2543Smrg int rlength; 1253706f2543Smrg 1254706f2543Smrg nprotoxcistructs = ( 1255706f2543Smrg pmax->rightSideBearing == pmin->rightSideBearing && 1256706f2543Smrg pmax->leftSideBearing == pmin->leftSideBearing && 1257706f2543Smrg pmax->descent == pmin->descent && 1258706f2543Smrg pmax->ascent == pmin->ascent && 1259706f2543Smrg pmax->characterWidth == pmin->characterWidth) ? 1260706f2543Smrg 0 : N2dChars(pFont); 1261706f2543Smrg 1262706f2543Smrg rlength = sizeof(xQueryFontReply) + 1263706f2543Smrg FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + 1264706f2543Smrg nprotoxcistructs * sizeof(xCharInfo); 1265706f2543Smrg reply = calloc(1, rlength); 1266706f2543Smrg if(!reply) 1267706f2543Smrg { 1268706f2543Smrg return BadAlloc; 1269706f2543Smrg } 1270706f2543Smrg 1271706f2543Smrg reply->type = X_Reply; 1272706f2543Smrg reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); 1273706f2543Smrg reply->sequenceNumber = client->sequence; 1274706f2543Smrg QueryFont( pFont, reply, nprotoxcistructs); 1275706f2543Smrg 1276706f2543Smrg WriteReplyToClient(client, rlength, reply); 1277706f2543Smrg free(reply); 1278706f2543Smrg return Success; 1279706f2543Smrg } 1280706f2543Smrg} 1281706f2543Smrg 1282706f2543Smrgint 1283706f2543SmrgProcQueryTextExtents(ClientPtr client) 1284706f2543Smrg{ 1285706f2543Smrg xQueryTextExtentsReply reply; 1286706f2543Smrg FontPtr pFont; 1287706f2543Smrg ExtentInfoRec info; 1288706f2543Smrg unsigned long length; 1289706f2543Smrg int rc; 1290706f2543Smrg REQUEST(xQueryTextExtentsReq); 1291706f2543Smrg REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); 1292706f2543Smrg 1293706f2543Smrg rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess); 1294706f2543Smrg if (rc != Success) 1295706f2543Smrg return rc; 1296706f2543Smrg 1297706f2543Smrg length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); 1298706f2543Smrg length = length << 1; 1299706f2543Smrg if (stuff->oddLength) 1300706f2543Smrg { 1301706f2543Smrg if (length == 0) 1302706f2543Smrg return BadLength; 1303706f2543Smrg length--; 1304706f2543Smrg } 1305706f2543Smrg if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info)) 1306706f2543Smrg return BadAlloc; 1307706f2543Smrg reply.type = X_Reply; 1308706f2543Smrg reply.length = 0; 1309706f2543Smrg reply.sequenceNumber = client->sequence; 1310706f2543Smrg reply.drawDirection = info.drawDirection; 1311706f2543Smrg reply.fontAscent = info.fontAscent; 1312706f2543Smrg reply.fontDescent = info.fontDescent; 1313706f2543Smrg reply.overallAscent = info.overallAscent; 1314706f2543Smrg reply.overallDescent = info.overallDescent; 1315706f2543Smrg reply.overallWidth = info.overallWidth; 1316706f2543Smrg reply.overallLeft = info.overallLeft; 1317706f2543Smrg reply.overallRight = info.overallRight; 1318706f2543Smrg WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); 1319706f2543Smrg return Success; 1320706f2543Smrg} 1321706f2543Smrg 1322706f2543Smrgint 1323706f2543SmrgProcListFonts(ClientPtr client) 1324706f2543Smrg{ 1325706f2543Smrg REQUEST(xListFontsReq); 1326706f2543Smrg 1327706f2543Smrg REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); 1328706f2543Smrg 1329706f2543Smrg return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 1330706f2543Smrg stuff->maxNames); 1331706f2543Smrg} 1332706f2543Smrg 1333706f2543Smrgint 1334706f2543SmrgProcListFontsWithInfo(ClientPtr client) 1335706f2543Smrg{ 1336706f2543Smrg REQUEST(xListFontsWithInfoReq); 1337706f2543Smrg 1338706f2543Smrg REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); 1339706f2543Smrg 1340706f2543Smrg return StartListFontsWithInfo(client, stuff->nbytes, 1341706f2543Smrg (unsigned char *) &stuff[1], stuff->maxNames); 1342706f2543Smrg} 1343706f2543Smrg 1344706f2543Smrg/** 1345706f2543Smrg * 1346706f2543Smrg * \param value must conform to DeleteType 1347706f2543Smrg */ 1348706f2543Smrgint 1349706f2543SmrgdixDestroyPixmap(pointer value, XID pid) 1350706f2543Smrg{ 1351706f2543Smrg PixmapPtr pPixmap = (PixmapPtr)value; 1352706f2543Smrg return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 1353706f2543Smrg} 1354706f2543Smrg 1355706f2543Smrgint 1356706f2543SmrgProcCreatePixmap(ClientPtr client) 1357706f2543Smrg{ 1358706f2543Smrg PixmapPtr pMap; 1359706f2543Smrg DrawablePtr pDraw; 1360706f2543Smrg REQUEST(xCreatePixmapReq); 1361706f2543Smrg DepthPtr pDepth; 1362706f2543Smrg int i, rc; 1363706f2543Smrg 1364706f2543Smrg REQUEST_SIZE_MATCH(xCreatePixmapReq); 1365706f2543Smrg client->errorValue = stuff->pid; 1366706f2543Smrg LEGAL_NEW_RESOURCE(stuff->pid, client); 1367706f2543Smrg 1368706f2543Smrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 1369706f2543Smrg DixGetAttrAccess); 1370706f2543Smrg if (rc != Success) 1371706f2543Smrg return rc; 1372706f2543Smrg 1373706f2543Smrg if (!stuff->width || !stuff->height) 1374706f2543Smrg { 1375706f2543Smrg client->errorValue = 0; 1376706f2543Smrg return BadValue; 1377706f2543Smrg } 1378706f2543Smrg if (stuff->width > 32767 || stuff->height > 32767) 1379706f2543Smrg { 1380706f2543Smrg /* It is allowed to try and allocate a pixmap which is larger than 1381706f2543Smrg * 32767 in either dimension. However, all of the framebuffer code 1382706f2543Smrg * is buggy and does not reliably draw to such big pixmaps, basically 1383706f2543Smrg * because the Region data structure operates with signed shorts 1384706f2543Smrg * for the rectangles in it. 1385706f2543Smrg * 1386706f2543Smrg * Furthermore, several places in the X server computes the 1387706f2543Smrg * size in bytes of the pixmap and tries to store it in an 1388706f2543Smrg * integer. This integer can overflow and cause the allocated size 1389706f2543Smrg * to be much smaller. 1390706f2543Smrg * 1391706f2543Smrg * So, such big pixmaps are rejected here with a BadAlloc 1392706f2543Smrg */ 1393706f2543Smrg return BadAlloc; 1394706f2543Smrg } 1395706f2543Smrg if (stuff->depth != 1) 1396706f2543Smrg { 1397706f2543Smrg pDepth = pDraw->pScreen->allowedDepths; 1398706f2543Smrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 1399706f2543Smrg if (pDepth->depth == stuff->depth) 1400706f2543Smrg goto CreatePmap; 1401706f2543Smrg client->errorValue = stuff->depth; 1402706f2543Smrg return BadValue; 1403706f2543Smrg } 1404706f2543SmrgCreatePmap: 1405706f2543Smrg pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) 1406706f2543Smrg (pDraw->pScreen, stuff->width, 1407706f2543Smrg stuff->height, stuff->depth, 0); 1408706f2543Smrg if (pMap) 1409706f2543Smrg { 1410706f2543Smrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 1411706f2543Smrg pMap->drawable.id = stuff->pid; 1412706f2543Smrg /* security creation/labeling check */ 1413706f2543Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 1414706f2543Smrg pMap, RT_NONE, NULL, DixCreateAccess); 1415706f2543Smrg if (rc != Success) { 1416706f2543Smrg (*pDraw->pScreen->DestroyPixmap)(pMap); 1417706f2543Smrg return rc; 1418706f2543Smrg } 1419706f2543Smrg if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) 1420706f2543Smrg return Success; 1421706f2543Smrg } 1422706f2543Smrg return BadAlloc; 1423706f2543Smrg} 1424706f2543Smrg 1425706f2543Smrgint 1426706f2543SmrgProcFreePixmap(ClientPtr client) 1427706f2543Smrg{ 1428706f2543Smrg PixmapPtr pMap; 1429706f2543Smrg int rc; 1430706f2543Smrg REQUEST(xResourceReq); 1431706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 1432706f2543Smrg 1433706f2543Smrg rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client, 1434706f2543Smrg DixDestroyAccess); 1435706f2543Smrg if (rc == Success) 1436706f2543Smrg { 1437706f2543Smrg FreeResource(stuff->id, RT_NONE); 1438706f2543Smrg return Success; 1439706f2543Smrg } 1440706f2543Smrg else 1441706f2543Smrg { 1442706f2543Smrg client->errorValue = stuff->id; 1443706f2543Smrg return rc; 1444706f2543Smrg } 1445706f2543Smrg} 1446706f2543Smrg 1447706f2543Smrgint 1448706f2543SmrgProcCreateGC(ClientPtr client) 1449706f2543Smrg{ 1450706f2543Smrg int error, rc; 1451706f2543Smrg GC *pGC; 1452706f2543Smrg DrawablePtr pDraw; 1453706f2543Smrg unsigned len; 1454706f2543Smrg REQUEST(xCreateGCReq); 1455706f2543Smrg 1456706f2543Smrg REQUEST_AT_LEAST_SIZE(xCreateGCReq); 1457706f2543Smrg client->errorValue = stuff->gc; 1458706f2543Smrg LEGAL_NEW_RESOURCE(stuff->gc, client); 1459706f2543Smrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 1460706f2543Smrg DixGetAttrAccess); 1461706f2543Smrg if (rc != Success) 1462706f2543Smrg return rc; 1463706f2543Smrg 1464706f2543Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); 1465706f2543Smrg if (len != Ones(stuff->mask)) 1466706f2543Smrg return BadLength; 1467706f2543Smrg pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, 1468706f2543Smrg stuff->gc, client); 1469706f2543Smrg if (error != Success) 1470706f2543Smrg return error; 1471706f2543Smrg if (!AddResource(stuff->gc, RT_GC, (pointer)pGC)) 1472706f2543Smrg return BadAlloc; 1473706f2543Smrg return Success; 1474706f2543Smrg} 1475706f2543Smrg 1476706f2543Smrgint 1477706f2543SmrgProcChangeGC(ClientPtr client) 1478706f2543Smrg{ 1479706f2543Smrg GC *pGC; 1480706f2543Smrg int result; 1481706f2543Smrg unsigned len; 1482706f2543Smrg REQUEST(xChangeGCReq); 1483706f2543Smrg REQUEST_AT_LEAST_SIZE(xChangeGCReq); 1484706f2543Smrg 1485706f2543Smrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 1486706f2543Smrg if (result != Success) 1487706f2543Smrg return result; 1488706f2543Smrg 1489706f2543Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); 1490706f2543Smrg if (len != Ones(stuff->mask)) 1491706f2543Smrg return BadLength; 1492706f2543Smrg 1493706f2543Smrg return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]); 1494706f2543Smrg} 1495706f2543Smrg 1496706f2543Smrgint 1497706f2543SmrgProcCopyGC(ClientPtr client) 1498706f2543Smrg{ 1499706f2543Smrg GC *dstGC; 1500706f2543Smrg GC *pGC; 1501706f2543Smrg int result; 1502706f2543Smrg REQUEST(xCopyGCReq); 1503706f2543Smrg REQUEST_SIZE_MATCH(xCopyGCReq); 1504706f2543Smrg 1505706f2543Smrg result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); 1506706f2543Smrg if (result != Success) 1507706f2543Smrg return result; 1508706f2543Smrg result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); 1509706f2543Smrg if (result != Success) 1510706f2543Smrg return result; 1511706f2543Smrg if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 1512706f2543Smrg return BadMatch; 1513706f2543Smrg if (stuff->mask & ~GCAllBits) 1514706f2543Smrg { 1515706f2543Smrg client->errorValue = stuff->mask; 1516706f2543Smrg return BadValue; 1517706f2543Smrg } 1518706f2543Smrg return CopyGC(pGC, dstGC, stuff->mask); 1519706f2543Smrg} 1520706f2543Smrg 1521706f2543Smrgint 1522706f2543SmrgProcSetDashes(ClientPtr client) 1523706f2543Smrg{ 1524706f2543Smrg GC *pGC; 1525706f2543Smrg int result; 1526706f2543Smrg REQUEST(xSetDashesReq); 1527706f2543Smrg 1528706f2543Smrg REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 1529706f2543Smrg if (stuff->nDashes == 0) 1530706f2543Smrg { 1531706f2543Smrg client->errorValue = 0; 1532706f2543Smrg return BadValue; 1533706f2543Smrg } 1534706f2543Smrg 1535706f2543Smrg result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 1536706f2543Smrg if (result != Success) 1537706f2543Smrg return result; 1538706f2543Smrg 1539706f2543Smrg /* If there's an error, either there's no sensible errorValue, 1540706f2543Smrg * or there was a dash segment of 0. */ 1541706f2543Smrg client->errorValue = 0; 1542706f2543Smrg return SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 1543706f2543Smrg (unsigned char *)&stuff[1]); 1544706f2543Smrg} 1545706f2543Smrg 1546706f2543Smrgint 1547706f2543SmrgProcSetClipRectangles(ClientPtr client) 1548706f2543Smrg{ 1549706f2543Smrg int nr, result; 1550706f2543Smrg GC *pGC; 1551706f2543Smrg REQUEST(xSetClipRectanglesReq); 1552706f2543Smrg 1553706f2543Smrg REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 1554706f2543Smrg if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 1555706f2543Smrg (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) 1556706f2543Smrg { 1557706f2543Smrg client->errorValue = stuff->ordering; 1558706f2543Smrg return BadValue; 1559706f2543Smrg } 1560706f2543Smrg result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 1561706f2543Smrg if (result != Success) 1562706f2543Smrg return result; 1563706f2543Smrg 1564706f2543Smrg nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 1565706f2543Smrg if (nr & 4) 1566706f2543Smrg return BadLength; 1567706f2543Smrg nr >>= 3; 1568706f2543Smrg return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 1569706f2543Smrg nr, (xRectangle *)&stuff[1], (int)stuff->ordering); 1570706f2543Smrg} 1571706f2543Smrg 1572706f2543Smrgint 1573706f2543SmrgProcFreeGC(ClientPtr client) 1574706f2543Smrg{ 1575706f2543Smrg GC *pGC; 1576706f2543Smrg int rc; 1577706f2543Smrg REQUEST(xResourceReq); 1578706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 1579706f2543Smrg 1580706f2543Smrg rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 1581706f2543Smrg if (rc != Success) 1582706f2543Smrg return rc; 1583706f2543Smrg 1584706f2543Smrg FreeResource(stuff->id, RT_NONE); 1585706f2543Smrg return Success; 1586706f2543Smrg} 1587706f2543Smrg 1588706f2543Smrgint 1589706f2543SmrgProcClearToBackground(ClientPtr client) 1590706f2543Smrg{ 1591706f2543Smrg REQUEST(xClearAreaReq); 1592706f2543Smrg WindowPtr pWin; 1593706f2543Smrg int rc; 1594706f2543Smrg 1595706f2543Smrg REQUEST_SIZE_MATCH(xClearAreaReq); 1596706f2543Smrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 1597706f2543Smrg if (rc != Success) 1598706f2543Smrg return rc; 1599706f2543Smrg if (pWin->drawable.class == InputOnly) 1600706f2543Smrg { 1601706f2543Smrg client->errorValue = stuff->window; 1602706f2543Smrg return BadMatch; 1603706f2543Smrg } 1604706f2543Smrg if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) 1605706f2543Smrg { 1606706f2543Smrg client->errorValue = stuff->exposures; 1607706f2543Smrg return BadValue; 1608706f2543Smrg } 1609706f2543Smrg (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y, 1610706f2543Smrg stuff->width, stuff->height, 1611706f2543Smrg (Bool)stuff->exposures); 1612706f2543Smrg return Success; 1613706f2543Smrg} 1614706f2543Smrg 1615706f2543Smrgint 1616706f2543SmrgProcCopyArea(ClientPtr client) 1617706f2543Smrg{ 1618706f2543Smrg DrawablePtr pDst; 1619706f2543Smrg DrawablePtr pSrc; 1620706f2543Smrg GC *pGC; 1621706f2543Smrg REQUEST(xCopyAreaReq); 1622706f2543Smrg RegionPtr pRgn; 1623706f2543Smrg int rc; 1624706f2543Smrg 1625706f2543Smrg REQUEST_SIZE_MATCH(xCopyAreaReq); 1626706f2543Smrg 1627706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 1628706f2543Smrg if (stuff->dstDrawable != stuff->srcDrawable) 1629706f2543Smrg { 1630706f2543Smrg rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 1631706f2543Smrg DixReadAccess); 1632706f2543Smrg if (rc != Success) 1633706f2543Smrg return rc; 1634706f2543Smrg if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) 1635706f2543Smrg { 1636706f2543Smrg client->errorValue = stuff->dstDrawable; 1637706f2543Smrg return BadMatch; 1638706f2543Smrg } 1639706f2543Smrg } 1640706f2543Smrg else 1641706f2543Smrg pSrc = pDst; 1642706f2543Smrg 1643706f2543Smrg pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 1644706f2543Smrg stuff->width, stuff->height, 1645706f2543Smrg stuff->dstX, stuff->dstY); 1646706f2543Smrg if (pGC->graphicsExposures) 1647706f2543Smrg { 1648706f2543Smrg (*pDst->pScreen->SendGraphicsExpose) 1649706f2543Smrg (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 1650706f2543Smrg if (pRgn) 1651706f2543Smrg RegionDestroy(pRgn); 1652706f2543Smrg } 1653706f2543Smrg 1654706f2543Smrg return Success; 1655706f2543Smrg} 1656706f2543Smrg 1657706f2543Smrgint 1658706f2543SmrgProcCopyPlane(ClientPtr client) 1659706f2543Smrg{ 1660706f2543Smrg DrawablePtr psrcDraw, pdstDraw; 1661706f2543Smrg GC *pGC; 1662706f2543Smrg REQUEST(xCopyPlaneReq); 1663706f2543Smrg RegionPtr pRgn; 1664706f2543Smrg int rc; 1665706f2543Smrg 1666706f2543Smrg REQUEST_SIZE_MATCH(xCopyPlaneReq); 1667706f2543Smrg 1668706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); 1669706f2543Smrg if (stuff->dstDrawable != stuff->srcDrawable) 1670706f2543Smrg { 1671706f2543Smrg rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 1672706f2543Smrg DixReadAccess); 1673706f2543Smrg if (rc != Success) 1674706f2543Smrg return rc; 1675706f2543Smrg 1676706f2543Smrg if (pdstDraw->pScreen != psrcDraw->pScreen) 1677706f2543Smrg { 1678706f2543Smrg client->errorValue = stuff->dstDrawable; 1679706f2543Smrg return BadMatch; 1680706f2543Smrg } 1681706f2543Smrg } 1682706f2543Smrg else 1683706f2543Smrg psrcDraw = pdstDraw; 1684706f2543Smrg 1685706f2543Smrg /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 1686706f2543Smrg if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 1687706f2543Smrg (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) 1688706f2543Smrg { 1689706f2543Smrg client->errorValue = stuff->bitPlane; 1690706f2543Smrg return BadValue; 1691706f2543Smrg } 1692706f2543Smrg 1693706f2543Smrg pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, 1694706f2543Smrg stuff->width, stuff->height, 1695706f2543Smrg stuff->dstX, stuff->dstY, stuff->bitPlane); 1696706f2543Smrg if (pGC->graphicsExposures) 1697706f2543Smrg { 1698706f2543Smrg (*pdstDraw->pScreen->SendGraphicsExpose) 1699706f2543Smrg (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 1700706f2543Smrg if (pRgn) 1701706f2543Smrg RegionDestroy(pRgn); 1702706f2543Smrg } 1703706f2543Smrg return Success; 1704706f2543Smrg} 1705706f2543Smrg 1706706f2543Smrgint 1707706f2543SmrgProcPolyPoint(ClientPtr client) 1708706f2543Smrg{ 1709706f2543Smrg int npoint; 1710706f2543Smrg GC *pGC; 1711706f2543Smrg DrawablePtr pDraw; 1712706f2543Smrg REQUEST(xPolyPointReq); 1713706f2543Smrg 1714706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyPointReq); 1715706f2543Smrg if ((stuff->coordMode != CoordModeOrigin) && 1716706f2543Smrg (stuff->coordMode != CoordModePrevious)) 1717706f2543Smrg { 1718706f2543Smrg client->errorValue = stuff->coordMode; 1719706f2543Smrg return BadValue; 1720706f2543Smrg } 1721706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1722706f2543Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); 1723706f2543Smrg if (npoint) 1724706f2543Smrg (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, 1725706f2543Smrg (xPoint *) &stuff[1]); 1726706f2543Smrg return Success; 1727706f2543Smrg} 1728706f2543Smrg 1729706f2543Smrgint 1730706f2543SmrgProcPolyLine(ClientPtr client) 1731706f2543Smrg{ 1732706f2543Smrg int npoint; 1733706f2543Smrg GC *pGC; 1734706f2543Smrg DrawablePtr pDraw; 1735706f2543Smrg REQUEST(xPolyLineReq); 1736706f2543Smrg 1737706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyLineReq); 1738706f2543Smrg if ((stuff->coordMode != CoordModeOrigin) && 1739706f2543Smrg (stuff->coordMode != CoordModePrevious)) 1740706f2543Smrg { 1741706f2543Smrg client->errorValue = stuff->coordMode; 1742706f2543Smrg return BadValue; 1743706f2543Smrg } 1744706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1745706f2543Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); 1746706f2543Smrg if (npoint > 1) 1747706f2543Smrg (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 1748706f2543Smrg (DDXPointPtr) &stuff[1]); 1749706f2543Smrg return Success; 1750706f2543Smrg} 1751706f2543Smrg 1752706f2543Smrgint 1753706f2543SmrgProcPolySegment(ClientPtr client) 1754706f2543Smrg{ 1755706f2543Smrg int nsegs; 1756706f2543Smrg GC *pGC; 1757706f2543Smrg DrawablePtr pDraw; 1758706f2543Smrg REQUEST(xPolySegmentReq); 1759706f2543Smrg 1760706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 1761706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1762706f2543Smrg nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 1763706f2543Smrg if (nsegs & 4) 1764706f2543Smrg return BadLength; 1765706f2543Smrg nsegs >>= 3; 1766706f2543Smrg if (nsegs) 1767706f2543Smrg (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 1768706f2543Smrg return Success; 1769706f2543Smrg} 1770706f2543Smrg 1771706f2543Smrgint 1772706f2543SmrgProcPolyRectangle (ClientPtr client) 1773706f2543Smrg{ 1774706f2543Smrg int nrects; 1775706f2543Smrg GC *pGC; 1776706f2543Smrg DrawablePtr pDraw; 1777706f2543Smrg REQUEST(xPolyRectangleReq); 1778706f2543Smrg 1779706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 1780706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1781706f2543Smrg nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 1782706f2543Smrg if (nrects & 4) 1783706f2543Smrg return BadLength; 1784706f2543Smrg nrects >>= 3; 1785706f2543Smrg if (nrects) 1786706f2543Smrg (*pGC->ops->PolyRectangle)(pDraw, pGC, 1787706f2543Smrg nrects, (xRectangle *) &stuff[1]); 1788706f2543Smrg return Success; 1789706f2543Smrg} 1790706f2543Smrg 1791706f2543Smrgint 1792706f2543SmrgProcPolyArc(ClientPtr client) 1793706f2543Smrg{ 1794706f2543Smrg int narcs; 1795706f2543Smrg GC *pGC; 1796706f2543Smrg DrawablePtr pDraw; 1797706f2543Smrg REQUEST(xPolyArcReq); 1798706f2543Smrg 1799706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyArcReq); 1800706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1801706f2543Smrg narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 1802706f2543Smrg if (narcs % sizeof(xArc)) 1803706f2543Smrg return BadLength; 1804706f2543Smrg narcs /= sizeof(xArc); 1805706f2543Smrg if (narcs) 1806706f2543Smrg (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]); 1807706f2543Smrg return Success; 1808706f2543Smrg} 1809706f2543Smrg 1810706f2543Smrgint 1811706f2543SmrgProcFillPoly(ClientPtr client) 1812706f2543Smrg{ 1813706f2543Smrg int things; 1814706f2543Smrg GC *pGC; 1815706f2543Smrg DrawablePtr pDraw; 1816706f2543Smrg REQUEST(xFillPolyReq); 1817706f2543Smrg 1818706f2543Smrg REQUEST_AT_LEAST_SIZE(xFillPolyReq); 1819706f2543Smrg if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 1820706f2543Smrg (stuff->shape != Convex)) 1821706f2543Smrg { 1822706f2543Smrg client->errorValue = stuff->shape; 1823706f2543Smrg return BadValue; 1824706f2543Smrg } 1825706f2543Smrg if ((stuff->coordMode != CoordModeOrigin) && 1826706f2543Smrg (stuff->coordMode != CoordModePrevious)) 1827706f2543Smrg { 1828706f2543Smrg client->errorValue = stuff->coordMode; 1829706f2543Smrg return BadValue; 1830706f2543Smrg } 1831706f2543Smrg 1832706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1833706f2543Smrg things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); 1834706f2543Smrg if (things) 1835706f2543Smrg (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 1836706f2543Smrg stuff->coordMode, things, 1837706f2543Smrg (DDXPointPtr) &stuff[1]); 1838706f2543Smrg return Success; 1839706f2543Smrg} 1840706f2543Smrg 1841706f2543Smrgint 1842706f2543SmrgProcPolyFillRectangle(ClientPtr client) 1843706f2543Smrg{ 1844706f2543Smrg int things; 1845706f2543Smrg GC *pGC; 1846706f2543Smrg DrawablePtr pDraw; 1847706f2543Smrg REQUEST(xPolyFillRectangleReq); 1848706f2543Smrg 1849706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 1850706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1851706f2543Smrg things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 1852706f2543Smrg if (things & 4) 1853706f2543Smrg return BadLength; 1854706f2543Smrg things >>= 3; 1855706f2543Smrg 1856706f2543Smrg if (things) 1857706f2543Smrg (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 1858706f2543Smrg (xRectangle *) &stuff[1]); 1859706f2543Smrg return Success; 1860706f2543Smrg} 1861706f2543Smrg 1862706f2543Smrgint 1863706f2543SmrgProcPolyFillArc(ClientPtr client) 1864706f2543Smrg{ 1865706f2543Smrg int narcs; 1866706f2543Smrg GC *pGC; 1867706f2543Smrg DrawablePtr pDraw; 1868706f2543Smrg REQUEST(xPolyFillArcReq); 1869706f2543Smrg 1870706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 1871706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1872706f2543Smrg narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 1873706f2543Smrg if (narcs % sizeof(xArc)) 1874706f2543Smrg return BadLength; 1875706f2543Smrg narcs /= sizeof(xArc); 1876706f2543Smrg if (narcs) 1877706f2543Smrg (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 1878706f2543Smrg return Success; 1879706f2543Smrg} 1880706f2543Smrg 1881706f2543Smrg#ifdef MATCH_CLIENT_ENDIAN 1882706f2543Smrg 1883706f2543Smrgint 1884706f2543SmrgServerOrder (void) 1885706f2543Smrg{ 1886706f2543Smrg int whichbyte = 1; 1887706f2543Smrg 1888706f2543Smrg if (*((char *) &whichbyte)) 1889706f2543Smrg return LSBFirst; 1890706f2543Smrg return MSBFirst; 1891706f2543Smrg} 1892706f2543Smrg 1893706f2543Smrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 1894706f2543Smrg 1895706f2543Smrgvoid 1896706f2543SmrgReformatImage (char *base, int nbytes, int bpp, int order) 1897706f2543Smrg{ 1898706f2543Smrg switch (bpp) { 1899706f2543Smrg case 1: /* yuck */ 1900706f2543Smrg if (BITMAP_BIT_ORDER != order) 1901706f2543Smrg BitOrderInvert ((unsigned char *) base, nbytes); 1902706f2543Smrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 1903706f2543Smrg ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order); 1904706f2543Smrg#endif 1905706f2543Smrg break; 1906706f2543Smrg case 4: 1907706f2543Smrg break; /* yuck */ 1908706f2543Smrg case 8: 1909706f2543Smrg break; 1910706f2543Smrg case 16: 1911706f2543Smrg if (IMAGE_BYTE_ORDER != order) 1912706f2543Smrg TwoByteSwap ((unsigned char *) base, nbytes); 1913706f2543Smrg break; 1914706f2543Smrg case 32: 1915706f2543Smrg if (IMAGE_BYTE_ORDER != order) 1916706f2543Smrg FourByteSwap ((unsigned char *) base, nbytes); 1917706f2543Smrg break; 1918706f2543Smrg } 1919706f2543Smrg} 1920706f2543Smrg#else 1921706f2543Smrg#define ReformatImage(b,n,bpp,o) 1922706f2543Smrg#endif 1923706f2543Smrg 1924706f2543Smrg/* 64-bit server notes: the protocol restricts padding of images to 1925706f2543Smrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 1926706f2543Smrg * to use internally. Removes need for internal alignment checking. 1927706f2543Smrg * All of the PutImage functions could be changed individually, but 1928706f2543Smrg * as currently written, they call other routines which require things 1929706f2543Smrg * to be 64-bit padded on scanlines, so we changed things here. 1930706f2543Smrg * If an image would be padded differently for 64- versus 32-, then 1931706f2543Smrg * copy each scanline to a 64-bit padded scanline. 1932706f2543Smrg * Also, we need to make sure that the image is aligned on a 64-bit 1933706f2543Smrg * boundary, even if the scanlines are padded to our satisfaction. 1934706f2543Smrg */ 1935706f2543Smrgint 1936706f2543SmrgProcPutImage(ClientPtr client) 1937706f2543Smrg{ 1938706f2543Smrg GC *pGC; 1939706f2543Smrg DrawablePtr pDraw; 1940706f2543Smrg long length; /* length of scanline server padded */ 1941706f2543Smrg long lengthProto; /* length of scanline protocol padded */ 1942706f2543Smrg char *tmpImage; 1943706f2543Smrg REQUEST(xPutImageReq); 1944706f2543Smrg 1945706f2543Smrg REQUEST_AT_LEAST_SIZE(xPutImageReq); 1946706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1947706f2543Smrg if (stuff->format == XYBitmap) 1948706f2543Smrg { 1949706f2543Smrg if ((stuff->depth != 1) || 1950706f2543Smrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 1951706f2543Smrg return BadMatch; 1952706f2543Smrg length = BitmapBytePad(stuff->width + stuff->leftPad); 1953706f2543Smrg } 1954706f2543Smrg else if (stuff->format == XYPixmap) 1955706f2543Smrg { 1956706f2543Smrg if ((pDraw->depth != stuff->depth) || 1957706f2543Smrg (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 1958706f2543Smrg return BadMatch; 1959706f2543Smrg length = BitmapBytePad(stuff->width + stuff->leftPad); 1960706f2543Smrg length *= stuff->depth; 1961706f2543Smrg } 1962706f2543Smrg else if (stuff->format == ZPixmap) 1963706f2543Smrg { 1964706f2543Smrg if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 1965706f2543Smrg return BadMatch; 1966706f2543Smrg length = PixmapBytePad(stuff->width, stuff->depth); 1967706f2543Smrg } 1968706f2543Smrg else 1969706f2543Smrg { 1970706f2543Smrg client->errorValue = stuff->format; 1971706f2543Smrg return BadValue; 1972706f2543Smrg } 1973706f2543Smrg 1974706f2543Smrg tmpImage = (char *)&stuff[1]; 1975706f2543Smrg lengthProto = length; 1976706f2543Smrg 1977706f2543Smrg if (lengthProto >= (INT32_MAX / stuff->height)) 1978706f2543Smrg return BadLength; 1979706f2543Smrg 1980706f2543Smrg if ((bytes_to_int32(lengthProto * stuff->height) + 1981706f2543Smrg bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) 1982706f2543Smrg return BadLength; 1983706f2543Smrg 1984706f2543Smrg ReformatImage (tmpImage, lengthProto * stuff->height, 1985706f2543Smrg stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1, 1986706f2543Smrg ClientOrder(client)); 1987706f2543Smrg 1988706f2543Smrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 1989706f2543Smrg stuff->width, stuff->height, 1990706f2543Smrg stuff->leftPad, stuff->format, tmpImage); 1991706f2543Smrg 1992706f2543Smrg return Success; 1993706f2543Smrg} 1994706f2543Smrg 1995706f2543Smrgstatic int 1996706f2543SmrgDoGetImage(ClientPtr client, int format, Drawable drawable, 1997706f2543Smrg int x, int y, int width, int height, 1998706f2543Smrg Mask planemask, xGetImageReply **im_return) 1999706f2543Smrg{ 2000706f2543Smrg DrawablePtr pDraw, pBoundingDraw; 2001706f2543Smrg int nlines, linesPerBuf, rc; 2002706f2543Smrg int linesDone; 2003706f2543Smrg /* coordinates relative to the bounding drawable */ 2004706f2543Smrg int relx, rely; 2005706f2543Smrg long widthBytesLine, length; 2006706f2543Smrg Mask plane = 0; 2007706f2543Smrg char *pBuf; 2008706f2543Smrg xGetImageReply xgi; 2009706f2543Smrg RegionPtr pVisibleRegion = NULL; 2010706f2543Smrg 2011706f2543Smrg if ((format != XYPixmap) && (format != ZPixmap)) 2012706f2543Smrg { 2013706f2543Smrg client->errorValue = format; 2014706f2543Smrg return BadValue; 2015706f2543Smrg } 2016706f2543Smrg rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 2017706f2543Smrg if (rc != Success) 2018706f2543Smrg return rc; 2019706f2543Smrg 2020706f2543Smrg memset(&xgi, 0, sizeof(xGetImageReply)); 2021706f2543Smrg 2022706f2543Smrg relx = x; 2023706f2543Smrg rely = y; 2024706f2543Smrg 2025706f2543Smrg if(pDraw->type == DRAWABLE_WINDOW) 2026706f2543Smrg { 2027706f2543Smrg WindowPtr pWin = (WindowPtr)pDraw; 2028706f2543Smrg 2029706f2543Smrg /* "If the drawable is a window, the window must be viewable ... or a 2030706f2543Smrg * BadMatch error results" */ 2031706f2543Smrg if (!pWin->viewable) 2032706f2543Smrg return BadMatch; 2033706f2543Smrg 2034706f2543Smrg relx += pDraw->x; 2035706f2543Smrg rely += pDraw->y; 2036706f2543Smrg 2037706f2543Smrg if (pDraw->pScreen->GetWindowPixmap) { 2038706f2543Smrg PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); 2039706f2543Smrg 2040706f2543Smrg pBoundingDraw = &pPix->drawable; 2041706f2543Smrg#ifdef COMPOSITE 2042706f2543Smrg relx -= pPix->screen_x; 2043706f2543Smrg rely -= pPix->screen_y; 2044706f2543Smrg#endif 2045706f2543Smrg } 2046706f2543Smrg else 2047706f2543Smrg { 2048706f2543Smrg pBoundingDraw = (DrawablePtr)pDraw->pScreen->root; 2049706f2543Smrg } 2050706f2543Smrg 2051706f2543Smrg xgi.visual = wVisual (pWin); 2052706f2543Smrg } 2053706f2543Smrg else 2054706f2543Smrg { 2055706f2543Smrg pBoundingDraw = pDraw; 2056706f2543Smrg xgi.visual = None; 2057706f2543Smrg } 2058706f2543Smrg 2059706f2543Smrg /* "If the drawable is a pixmap, the given rectangle must be wholly 2060706f2543Smrg * contained within the pixmap, or a BadMatch error results. If the 2061706f2543Smrg * drawable is a window [...] it must be the case that if there were no 2062706f2543Smrg * inferiors or overlapping windows, the specified rectangle of the window 2063706f2543Smrg * would be fully visible on the screen and wholly contained within the 2064706f2543Smrg * outside edges of the window, or a BadMatch error results." 2065706f2543Smrg * 2066706f2543Smrg * We relax the window case slightly to mean that the rectangle must exist 2067706f2543Smrg * within the bounds of the window's backing pixmap. In particular, this 2068706f2543Smrg * means that a GetImage request may succeed or fail with BadMatch depending 2069706f2543Smrg * on whether any of its ancestor windows are redirected. */ 2070706f2543Smrg if(relx < 0 || relx + width > (int)pBoundingDraw->width || 2071706f2543Smrg rely < 0 || rely + height > (int)pBoundingDraw->height) 2072706f2543Smrg return BadMatch; 2073706f2543Smrg 2074706f2543Smrg xgi.type = X_Reply; 2075706f2543Smrg xgi.sequenceNumber = client->sequence; 2076706f2543Smrg xgi.depth = pDraw->depth; 2077706f2543Smrg if(format == ZPixmap) 2078706f2543Smrg { 2079706f2543Smrg widthBytesLine = PixmapBytePad(width, pDraw->depth); 2080706f2543Smrg length = widthBytesLine * height; 2081706f2543Smrg 2082706f2543Smrg } 2083706f2543Smrg else 2084706f2543Smrg { 2085706f2543Smrg widthBytesLine = BitmapBytePad(width); 2086706f2543Smrg plane = ((Mask)1) << (pDraw->depth - 1); 2087706f2543Smrg /* only planes asked for */ 2088706f2543Smrg length = widthBytesLine * height * 2089706f2543Smrg Ones(planemask & (plane | (plane - 1))); 2090706f2543Smrg 2091706f2543Smrg } 2092706f2543Smrg 2093706f2543Smrg xgi.length = length; 2094706f2543Smrg 2095706f2543Smrg if (im_return) { 2096706f2543Smrg pBuf = calloc(1, sz_xGetImageReply + length); 2097706f2543Smrg if (!pBuf) 2098706f2543Smrg return BadAlloc; 2099706f2543Smrg if (widthBytesLine == 0) 2100706f2543Smrg linesPerBuf = 0; 2101706f2543Smrg else 2102706f2543Smrg linesPerBuf = height; 2103706f2543Smrg *im_return = (xGetImageReply *)pBuf; 2104706f2543Smrg *(xGetImageReply *)pBuf = xgi; 2105706f2543Smrg pBuf += sz_xGetImageReply; 2106706f2543Smrg } else { 2107706f2543Smrg xgi.length = bytes_to_int32(xgi.length); 2108706f2543Smrg if (widthBytesLine == 0 || height == 0) 2109706f2543Smrg linesPerBuf = 0; 2110706f2543Smrg else if (widthBytesLine >= IMAGE_BUFSIZE) 2111706f2543Smrg linesPerBuf = 1; 2112706f2543Smrg else 2113706f2543Smrg { 2114706f2543Smrg linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 2115706f2543Smrg if (linesPerBuf > height) 2116706f2543Smrg linesPerBuf = height; 2117706f2543Smrg } 2118706f2543Smrg length = linesPerBuf * widthBytesLine; 2119706f2543Smrg if (linesPerBuf < height) 2120706f2543Smrg { 2121706f2543Smrg /* we have to make sure intermediate buffers don't need padding */ 2122706f2543Smrg while ((linesPerBuf > 1) && 2123706f2543Smrg (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))) 2124706f2543Smrg { 2125706f2543Smrg linesPerBuf--; 2126706f2543Smrg length -= widthBytesLine; 2127706f2543Smrg } 2128706f2543Smrg while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)) 2129706f2543Smrg { 2130706f2543Smrg linesPerBuf++; 2131706f2543Smrg length += widthBytesLine; 2132706f2543Smrg } 2133706f2543Smrg } 2134706f2543Smrg if(!(pBuf = calloc(1, length))) 2135706f2543Smrg return BadAlloc; 2136706f2543Smrg WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); 2137706f2543Smrg } 2138706f2543Smrg 2139706f2543Smrg if (pDraw->type == DRAWABLE_WINDOW) 2140706f2543Smrg { 2141706f2543Smrg pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); 2142706f2543Smrg if (pVisibleRegion) 2143706f2543Smrg { 2144706f2543Smrg RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y); 2145706f2543Smrg } 2146706f2543Smrg } 2147706f2543Smrg 2148706f2543Smrg if (linesPerBuf == 0) 2149706f2543Smrg { 2150706f2543Smrg /* nothing to do */ 2151706f2543Smrg } 2152706f2543Smrg else if (format == ZPixmap) 2153706f2543Smrg { 2154706f2543Smrg linesDone = 0; 2155706f2543Smrg while (height - linesDone > 0) 2156706f2543Smrg { 2157706f2543Smrg nlines = min(linesPerBuf, height - linesDone); 2158706f2543Smrg (*pDraw->pScreen->GetImage) (pDraw, 2159706f2543Smrg x, 2160706f2543Smrg y + linesDone, 2161706f2543Smrg width, 2162706f2543Smrg nlines, 2163706f2543Smrg format, 2164706f2543Smrg planemask, 2165706f2543Smrg (pointer) pBuf); 2166706f2543Smrg if (pVisibleRegion) 2167706f2543Smrg XaceCensorImage(client, pVisibleRegion, widthBytesLine, 2168706f2543Smrg pDraw, x, y + linesDone, width, 2169706f2543Smrg nlines, format, pBuf); 2170706f2543Smrg 2171706f2543Smrg /* Note that this is NOT a call to WriteSwappedDataToClient, 2172706f2543Smrg as we do NOT byte swap */ 2173706f2543Smrg if (!im_return) 2174706f2543Smrg { 2175706f2543Smrg ReformatImage (pBuf, (int)(nlines * widthBytesLine), 2176706f2543Smrg BitsPerPixel (pDraw->depth), 2177706f2543Smrg ClientOrder(client)); 2178706f2543Smrg 2179706f2543Smrg/* Don't split me, gcc pukes when you do */ 2180706f2543Smrg (void)WriteToClient(client, 2181706f2543Smrg (int)(nlines * widthBytesLine), 2182706f2543Smrg pBuf); 2183706f2543Smrg } 2184706f2543Smrg linesDone += nlines; 2185706f2543Smrg } 2186706f2543Smrg } 2187706f2543Smrg else /* XYPixmap */ 2188706f2543Smrg { 2189706f2543Smrg for (; plane; plane >>= 1) 2190706f2543Smrg { 2191706f2543Smrg if (planemask & plane) 2192706f2543Smrg { 2193706f2543Smrg linesDone = 0; 2194706f2543Smrg while (height - linesDone > 0) 2195706f2543Smrg { 2196706f2543Smrg nlines = min(linesPerBuf, height - linesDone); 2197706f2543Smrg (*pDraw->pScreen->GetImage) (pDraw, 2198706f2543Smrg x, 2199706f2543Smrg y + linesDone, 2200706f2543Smrg width, 2201706f2543Smrg nlines, 2202706f2543Smrg format, 2203706f2543Smrg plane, 2204706f2543Smrg (pointer)pBuf); 2205706f2543Smrg if (pVisibleRegion) 2206706f2543Smrg XaceCensorImage(client, pVisibleRegion, 2207706f2543Smrg widthBytesLine, 2208706f2543Smrg pDraw, x, y + linesDone, width, 2209706f2543Smrg nlines, format, pBuf); 2210706f2543Smrg 2211706f2543Smrg /* Note: NOT a call to WriteSwappedDataToClient, 2212706f2543Smrg as we do NOT byte swap */ 2213706f2543Smrg if (im_return) { 2214706f2543Smrg pBuf += nlines * widthBytesLine; 2215706f2543Smrg } else { 2216706f2543Smrg ReformatImage (pBuf, 2217706f2543Smrg (int)(nlines * widthBytesLine), 2218706f2543Smrg 1, 2219706f2543Smrg ClientOrder (client)); 2220706f2543Smrg 2221706f2543Smrg/* Don't split me, gcc pukes when you do */ 2222706f2543Smrg (void)WriteToClient(client, 2223706f2543Smrg (int)(nlines * widthBytesLine), 2224706f2543Smrg pBuf); 2225706f2543Smrg } 2226706f2543Smrg linesDone += nlines; 2227706f2543Smrg } 2228706f2543Smrg } 2229706f2543Smrg } 2230706f2543Smrg } 2231706f2543Smrg if (pVisibleRegion) 2232706f2543Smrg RegionDestroy(pVisibleRegion); 2233706f2543Smrg if (!im_return) 2234706f2543Smrg free(pBuf); 2235706f2543Smrg return Success; 2236706f2543Smrg} 2237706f2543Smrg 2238706f2543Smrgint 2239706f2543SmrgProcGetImage(ClientPtr client) 2240706f2543Smrg{ 2241706f2543Smrg REQUEST(xGetImageReq); 2242706f2543Smrg 2243706f2543Smrg REQUEST_SIZE_MATCH(xGetImageReq); 2244706f2543Smrg 2245706f2543Smrg return DoGetImage(client, stuff->format, stuff->drawable, 2246706f2543Smrg stuff->x, stuff->y, 2247706f2543Smrg (int)stuff->width, (int)stuff->height, 2248706f2543Smrg stuff->planeMask, (xGetImageReply **)NULL); 2249706f2543Smrg} 2250706f2543Smrg 2251706f2543Smrgint 2252706f2543SmrgProcPolyText(ClientPtr client) 2253706f2543Smrg{ 2254706f2543Smrg int err; 2255706f2543Smrg REQUEST(xPolyTextReq); 2256706f2543Smrg DrawablePtr pDraw; 2257706f2543Smrg GC *pGC; 2258706f2543Smrg 2259706f2543Smrg REQUEST_AT_LEAST_SIZE(xPolyTextReq); 2260706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2261706f2543Smrg 2262706f2543Smrg err = PolyText(client, 2263706f2543Smrg pDraw, 2264706f2543Smrg pGC, 2265706f2543Smrg (unsigned char *)&stuff[1], 2266706f2543Smrg ((unsigned char *) stuff) + (client->req_len << 2), 2267706f2543Smrg stuff->x, 2268706f2543Smrg stuff->y, 2269706f2543Smrg stuff->reqType, 2270706f2543Smrg stuff->drawable); 2271706f2543Smrg 2272706f2543Smrg if (err == Success) 2273706f2543Smrg { 2274706f2543Smrg return Success; 2275706f2543Smrg } 2276706f2543Smrg else 2277706f2543Smrg return err; 2278706f2543Smrg} 2279706f2543Smrg 2280706f2543Smrgint 2281706f2543SmrgProcImageText8(ClientPtr client) 2282706f2543Smrg{ 2283706f2543Smrg int err; 2284706f2543Smrg DrawablePtr pDraw; 2285706f2543Smrg GC *pGC; 2286706f2543Smrg 2287706f2543Smrg REQUEST(xImageTextReq); 2288706f2543Smrg 2289706f2543Smrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 2290706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2291706f2543Smrg 2292706f2543Smrg err = ImageText(client, 2293706f2543Smrg pDraw, 2294706f2543Smrg pGC, 2295706f2543Smrg stuff->nChars, 2296706f2543Smrg (unsigned char *)&stuff[1], 2297706f2543Smrg stuff->x, 2298706f2543Smrg stuff->y, 2299706f2543Smrg stuff->reqType, 2300706f2543Smrg stuff->drawable); 2301706f2543Smrg 2302706f2543Smrg if (err == Success) 2303706f2543Smrg { 2304706f2543Smrg return Success; 2305706f2543Smrg } 2306706f2543Smrg else 2307706f2543Smrg return err; 2308706f2543Smrg} 2309706f2543Smrg 2310706f2543Smrgint 2311706f2543SmrgProcImageText16(ClientPtr client) 2312706f2543Smrg{ 2313706f2543Smrg int err; 2314706f2543Smrg DrawablePtr pDraw; 2315706f2543Smrg GC *pGC; 2316706f2543Smrg 2317706f2543Smrg REQUEST(xImageTextReq); 2318706f2543Smrg 2319706f2543Smrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 2320706f2543Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2321706f2543Smrg 2322706f2543Smrg err = ImageText(client, 2323706f2543Smrg pDraw, 2324706f2543Smrg pGC, 2325706f2543Smrg stuff->nChars, 2326706f2543Smrg (unsigned char *)&stuff[1], 2327706f2543Smrg stuff->x, 2328706f2543Smrg stuff->y, 2329706f2543Smrg stuff->reqType, 2330706f2543Smrg stuff->drawable); 2331706f2543Smrg 2332706f2543Smrg if (err == Success) 2333706f2543Smrg { 2334706f2543Smrg return Success; 2335706f2543Smrg } 2336706f2543Smrg else 2337706f2543Smrg return err; 2338706f2543Smrg} 2339706f2543Smrg 2340706f2543Smrg 2341706f2543Smrgint 2342706f2543SmrgProcCreateColormap(ClientPtr client) 2343706f2543Smrg{ 2344706f2543Smrg VisualPtr pVisual; 2345706f2543Smrg ColormapPtr pmap; 2346706f2543Smrg Colormap mid; 2347706f2543Smrg WindowPtr pWin; 2348706f2543Smrg ScreenPtr pScreen; 2349706f2543Smrg REQUEST(xCreateColormapReq); 2350706f2543Smrg int i, result; 2351706f2543Smrg 2352706f2543Smrg REQUEST_SIZE_MATCH(xCreateColormapReq); 2353706f2543Smrg 2354706f2543Smrg if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) 2355706f2543Smrg { 2356706f2543Smrg client->errorValue = stuff->alloc; 2357706f2543Smrg return BadValue; 2358706f2543Smrg } 2359706f2543Smrg mid = stuff->mid; 2360706f2543Smrg LEGAL_NEW_RESOURCE(mid, client); 2361706f2543Smrg result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 2362706f2543Smrg if (result != Success) 2363706f2543Smrg return result; 2364706f2543Smrg 2365706f2543Smrg pScreen = pWin->drawable.pScreen; 2366706f2543Smrg for (i = 0, pVisual = pScreen->visuals; 2367706f2543Smrg i < pScreen->numVisuals; 2368706f2543Smrg i++, pVisual++) 2369706f2543Smrg { 2370706f2543Smrg if (pVisual->vid != stuff->visual) 2371706f2543Smrg continue; 2372706f2543Smrg return CreateColormap(mid, pScreen, pVisual, &pmap, 2373706f2543Smrg (int)stuff->alloc, client->index); 2374706f2543Smrg } 2375706f2543Smrg client->errorValue = stuff->visual; 2376706f2543Smrg return BadMatch; 2377706f2543Smrg} 2378706f2543Smrg 2379706f2543Smrgint 2380706f2543SmrgProcFreeColormap(ClientPtr client) 2381706f2543Smrg{ 2382706f2543Smrg ColormapPtr pmap; 2383706f2543Smrg int rc; 2384706f2543Smrg REQUEST(xResourceReq); 2385706f2543Smrg 2386706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 2387706f2543Smrg rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client, 2388706f2543Smrg DixDestroyAccess); 2389706f2543Smrg if (rc == Success) 2390706f2543Smrg { 2391706f2543Smrg /* Freeing a default colormap is a no-op */ 2392706f2543Smrg if (!(pmap->flags & IsDefault)) 2393706f2543Smrg FreeResource(stuff->id, RT_NONE); 2394706f2543Smrg return Success; 2395706f2543Smrg } 2396706f2543Smrg else 2397706f2543Smrg { 2398706f2543Smrg client->errorValue = stuff->id; 2399706f2543Smrg return rc; 2400706f2543Smrg } 2401706f2543Smrg} 2402706f2543Smrg 2403706f2543Smrg 2404706f2543Smrgint 2405706f2543SmrgProcCopyColormapAndFree(ClientPtr client) 2406706f2543Smrg{ 2407706f2543Smrg Colormap mid; 2408706f2543Smrg ColormapPtr pSrcMap; 2409706f2543Smrg REQUEST(xCopyColormapAndFreeReq); 2410706f2543Smrg int rc; 2411706f2543Smrg 2412706f2543Smrg REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 2413706f2543Smrg mid = stuff->mid; 2414706f2543Smrg LEGAL_NEW_RESOURCE(mid, client); 2415706f2543Smrg rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP, 2416706f2543Smrg client, DixReadAccess|DixRemoveAccess); 2417706f2543Smrg if (rc == Success) 2418706f2543Smrg return CopyColormapAndFree(mid, pSrcMap, client->index); 2419706f2543Smrg client->errorValue = stuff->srcCmap; 2420706f2543Smrg return rc; 2421706f2543Smrg} 2422706f2543Smrg 2423706f2543Smrgint 2424706f2543SmrgProcInstallColormap(ClientPtr client) 2425706f2543Smrg{ 2426706f2543Smrg ColormapPtr pcmp; 2427706f2543Smrg int rc; 2428706f2543Smrg REQUEST(xResourceReq); 2429706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 2430706f2543Smrg 2431706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 2432706f2543Smrg DixInstallAccess); 2433706f2543Smrg if (rc != Success) 2434706f2543Smrg goto out; 2435706f2543Smrg 2436706f2543Smrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 2437706f2543Smrg if (rc != Success) { 2438706f2543Smrg if (rc == BadValue) 2439706f2543Smrg rc = BadColor; 2440706f2543Smrg goto out; 2441706f2543Smrg } 2442706f2543Smrg 2443706f2543Smrg (*(pcmp->pScreen->InstallColormap)) (pcmp); 2444706f2543Smrg return Success; 2445706f2543Smrg 2446706f2543Smrgout: 2447706f2543Smrg client->errorValue = stuff->id; 2448706f2543Smrg return rc; 2449706f2543Smrg} 2450706f2543Smrg 2451706f2543Smrgint 2452706f2543SmrgProcUninstallColormap(ClientPtr client) 2453706f2543Smrg{ 2454706f2543Smrg ColormapPtr pcmp; 2455706f2543Smrg int rc; 2456706f2543Smrg REQUEST(xResourceReq); 2457706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 2458706f2543Smrg 2459706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 2460706f2543Smrg DixUninstallAccess); 2461706f2543Smrg if (rc != Success) 2462706f2543Smrg goto out; 2463706f2543Smrg 2464706f2543Smrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 2465706f2543Smrg if (rc != Success) { 2466706f2543Smrg if (rc == BadValue) 2467706f2543Smrg rc = BadColor; 2468706f2543Smrg goto out; 2469706f2543Smrg } 2470706f2543Smrg 2471706f2543Smrg if(pcmp->mid != pcmp->pScreen->defColormap) 2472706f2543Smrg (*(pcmp->pScreen->UninstallColormap)) (pcmp); 2473706f2543Smrg return Success; 2474706f2543Smrg 2475706f2543Smrgout: 2476706f2543Smrg client->errorValue = stuff->id; 2477706f2543Smrg return rc; 2478706f2543Smrg} 2479706f2543Smrg 2480706f2543Smrgint 2481706f2543SmrgProcListInstalledColormaps(ClientPtr client) 2482706f2543Smrg{ 2483706f2543Smrg xListInstalledColormapsReply *preply; 2484706f2543Smrg int nummaps, rc; 2485706f2543Smrg WindowPtr pWin; 2486706f2543Smrg REQUEST(xResourceReq); 2487706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 2488706f2543Smrg 2489706f2543Smrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 2490706f2543Smrg if (rc != Success) 2491706f2543Smrg return rc; 2492706f2543Smrg 2493706f2543Smrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 2494706f2543Smrg DixGetAttrAccess); 2495706f2543Smrg if (rc != Success) 2496706f2543Smrg return rc; 2497706f2543Smrg 2498706f2543Smrg preply = malloc(sizeof(xListInstalledColormapsReply) + 2499706f2543Smrg pWin->drawable.pScreen->maxInstalledCmaps * 2500706f2543Smrg sizeof(Colormap)); 2501706f2543Smrg if(!preply) 2502706f2543Smrg return BadAlloc; 2503706f2543Smrg 2504706f2543Smrg preply->type = X_Reply; 2505706f2543Smrg preply->sequenceNumber = client->sequence; 2506706f2543Smrg nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 2507706f2543Smrg (pWin->drawable.pScreen, (Colormap *)&preply[1]); 2508706f2543Smrg preply->nColormaps = nummaps; 2509706f2543Smrg preply->length = nummaps; 2510706f2543Smrg WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply); 2511706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2512706f2543Smrg WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 2513706f2543Smrg free(preply); 2514706f2543Smrg return Success; 2515706f2543Smrg} 2516706f2543Smrg 2517706f2543Smrgint 2518706f2543SmrgProcAllocColor (ClientPtr client) 2519706f2543Smrg{ 2520706f2543Smrg ColormapPtr pmap; 2521706f2543Smrg int rc; 2522706f2543Smrg xAllocColorReply acr; 2523706f2543Smrg REQUEST(xAllocColorReq); 2524706f2543Smrg 2525706f2543Smrg REQUEST_SIZE_MATCH(xAllocColorReq); 2526706f2543Smrg rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client, 2527706f2543Smrg DixAddAccess); 2528706f2543Smrg if (rc == Success) 2529706f2543Smrg { 2530706f2543Smrg acr.type = X_Reply; 2531706f2543Smrg acr.length = 0; 2532706f2543Smrg acr.sequenceNumber = client->sequence; 2533706f2543Smrg acr.red = stuff->red; 2534706f2543Smrg acr.green = stuff->green; 2535706f2543Smrg acr.blue = stuff->blue; 2536706f2543Smrg acr.pixel = 0; 2537706f2543Smrg if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 2538706f2543Smrg &acr.pixel, client->index)) ) 2539706f2543Smrg return rc; 2540706f2543Smrg#ifdef PANORAMIX 2541706f2543Smrg if (noPanoramiXExtension || !pmap->pScreen->myNum) 2542706f2543Smrg#endif 2543706f2543Smrg WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 2544706f2543Smrg return Success; 2545706f2543Smrg 2546706f2543Smrg } 2547706f2543Smrg else 2548706f2543Smrg { 2549706f2543Smrg client->errorValue = stuff->cmap; 2550706f2543Smrg return rc; 2551706f2543Smrg } 2552706f2543Smrg} 2553706f2543Smrg 2554706f2543Smrgint 2555706f2543SmrgProcAllocNamedColor (ClientPtr client) 2556706f2543Smrg{ 2557706f2543Smrg ColormapPtr pcmp; 2558706f2543Smrg int rc; 2559706f2543Smrg REQUEST(xAllocNamedColorReq); 2560706f2543Smrg 2561706f2543Smrg REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 2562706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2563706f2543Smrg DixAddAccess); 2564706f2543Smrg if (rc == Success) 2565706f2543Smrg { 2566706f2543Smrg xAllocNamedColorReply ancr; 2567706f2543Smrg 2568706f2543Smrg ancr.type = X_Reply; 2569706f2543Smrg ancr.length = 0; 2570706f2543Smrg ancr.sequenceNumber = client->sequence; 2571706f2543Smrg 2572706f2543Smrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 2573706f2543Smrg &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) 2574706f2543Smrg { 2575706f2543Smrg ancr.screenRed = ancr.exactRed; 2576706f2543Smrg ancr.screenGreen = ancr.exactGreen; 2577706f2543Smrg ancr.screenBlue = ancr.exactBlue; 2578706f2543Smrg ancr.pixel = 0; 2579706f2543Smrg if( (rc = AllocColor(pcmp, 2580706f2543Smrg &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, 2581706f2543Smrg &ancr.pixel, client->index)) ) 2582706f2543Smrg return rc; 2583706f2543Smrg#ifdef PANORAMIX 2584706f2543Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 2585706f2543Smrg#endif 2586706f2543Smrg WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr); 2587706f2543Smrg return Success; 2588706f2543Smrg } 2589706f2543Smrg else 2590706f2543Smrg return BadName; 2591706f2543Smrg 2592706f2543Smrg } 2593706f2543Smrg else 2594706f2543Smrg { 2595706f2543Smrg client->errorValue = stuff->cmap; 2596706f2543Smrg return rc; 2597706f2543Smrg } 2598706f2543Smrg} 2599706f2543Smrg 2600706f2543Smrgint 2601706f2543SmrgProcAllocColorCells (ClientPtr client) 2602706f2543Smrg{ 2603706f2543Smrg ColormapPtr pcmp; 2604706f2543Smrg int rc; 2605706f2543Smrg REQUEST(xAllocColorCellsReq); 2606706f2543Smrg 2607706f2543Smrg REQUEST_SIZE_MATCH(xAllocColorCellsReq); 2608706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2609706f2543Smrg DixAddAccess); 2610706f2543Smrg if (rc == Success) 2611706f2543Smrg { 2612706f2543Smrg xAllocColorCellsReply accr; 2613706f2543Smrg int npixels, nmasks; 2614706f2543Smrg long length; 2615706f2543Smrg Pixel *ppixels, *pmasks; 2616706f2543Smrg 2617706f2543Smrg npixels = stuff->colors; 2618706f2543Smrg if (!npixels) 2619706f2543Smrg { 2620706f2543Smrg client->errorValue = npixels; 2621706f2543Smrg return BadValue; 2622706f2543Smrg } 2623706f2543Smrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 2624706f2543Smrg { 2625706f2543Smrg client->errorValue = stuff->contiguous; 2626706f2543Smrg return BadValue; 2627706f2543Smrg } 2628706f2543Smrg nmasks = stuff->planes; 2629706f2543Smrg length = ((long)npixels + (long)nmasks) * sizeof(Pixel); 2630706f2543Smrg ppixels = malloc(length); 2631706f2543Smrg if(!ppixels) 2632706f2543Smrg return BadAlloc; 2633706f2543Smrg pmasks = ppixels + npixels; 2634706f2543Smrg 2635706f2543Smrg if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 2636706f2543Smrg (Bool)stuff->contiguous, ppixels, pmasks)) ) 2637706f2543Smrg { 2638706f2543Smrg free(ppixels); 2639706f2543Smrg return rc; 2640706f2543Smrg } 2641706f2543Smrg#ifdef PANORAMIX 2642706f2543Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 2643706f2543Smrg#endif 2644706f2543Smrg { 2645706f2543Smrg accr.type = X_Reply; 2646706f2543Smrg accr.length = bytes_to_int32(length); 2647706f2543Smrg accr.sequenceNumber = client->sequence; 2648706f2543Smrg accr.nPixels = npixels; 2649706f2543Smrg accr.nMasks = nmasks; 2650706f2543Smrg WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr); 2651706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2652706f2543Smrg WriteSwappedDataToClient(client, length, ppixels); 2653706f2543Smrg } 2654706f2543Smrg free(ppixels); 2655706f2543Smrg return Success; 2656706f2543Smrg } 2657706f2543Smrg else 2658706f2543Smrg { 2659706f2543Smrg client->errorValue = stuff->cmap; 2660706f2543Smrg return rc; 2661706f2543Smrg } 2662706f2543Smrg} 2663706f2543Smrg 2664706f2543Smrgint 2665706f2543SmrgProcAllocColorPlanes(ClientPtr client) 2666706f2543Smrg{ 2667706f2543Smrg ColormapPtr pcmp; 2668706f2543Smrg int rc; 2669706f2543Smrg REQUEST(xAllocColorPlanesReq); 2670706f2543Smrg 2671706f2543Smrg REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 2672706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2673706f2543Smrg DixAddAccess); 2674706f2543Smrg if (rc == Success) 2675706f2543Smrg { 2676706f2543Smrg xAllocColorPlanesReply acpr; 2677706f2543Smrg int npixels; 2678706f2543Smrg long length; 2679706f2543Smrg Pixel *ppixels; 2680706f2543Smrg 2681706f2543Smrg npixels = stuff->colors; 2682706f2543Smrg if (!npixels) 2683706f2543Smrg { 2684706f2543Smrg client->errorValue = npixels; 2685706f2543Smrg return BadValue; 2686706f2543Smrg } 2687706f2543Smrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 2688706f2543Smrg { 2689706f2543Smrg client->errorValue = stuff->contiguous; 2690706f2543Smrg return BadValue; 2691706f2543Smrg } 2692706f2543Smrg acpr.type = X_Reply; 2693706f2543Smrg acpr.sequenceNumber = client->sequence; 2694706f2543Smrg acpr.nPixels = npixels; 2695706f2543Smrg length = (long)npixels * sizeof(Pixel); 2696706f2543Smrg ppixels = malloc(length); 2697706f2543Smrg if(!ppixels) 2698706f2543Smrg return BadAlloc; 2699706f2543Smrg if( (rc = AllocColorPlanes(client->index, pcmp, npixels, 2700706f2543Smrg (int)stuff->red, (int)stuff->green, (int)stuff->blue, 2701706f2543Smrg (Bool)stuff->contiguous, ppixels, 2702706f2543Smrg &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) ) 2703706f2543Smrg { 2704706f2543Smrg free(ppixels); 2705706f2543Smrg return rc; 2706706f2543Smrg } 2707706f2543Smrg acpr.length = bytes_to_int32(length); 2708706f2543Smrg#ifdef PANORAMIX 2709706f2543Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 2710706f2543Smrg#endif 2711706f2543Smrg { 2712706f2543Smrg WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 2713706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2714706f2543Smrg WriteSwappedDataToClient(client, length, ppixels); 2715706f2543Smrg } 2716706f2543Smrg free(ppixels); 2717706f2543Smrg return Success; 2718706f2543Smrg } 2719706f2543Smrg else 2720706f2543Smrg { 2721706f2543Smrg client->errorValue = stuff->cmap; 2722706f2543Smrg return rc; 2723706f2543Smrg } 2724706f2543Smrg} 2725706f2543Smrg 2726706f2543Smrgint 2727706f2543SmrgProcFreeColors(ClientPtr client) 2728706f2543Smrg{ 2729706f2543Smrg ColormapPtr pcmp; 2730706f2543Smrg int rc; 2731706f2543Smrg REQUEST(xFreeColorsReq); 2732706f2543Smrg 2733706f2543Smrg REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 2734706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2735706f2543Smrg DixRemoveAccess); 2736706f2543Smrg if (rc == Success) 2737706f2543Smrg { 2738706f2543Smrg int count; 2739706f2543Smrg 2740706f2543Smrg if(pcmp->flags & AllAllocated) 2741706f2543Smrg return BadAccess; 2742706f2543Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); 2743706f2543Smrg return FreeColors(pcmp, client->index, count, 2744706f2543Smrg (Pixel *)&stuff[1], (Pixel)stuff->planeMask); 2745706f2543Smrg } 2746706f2543Smrg else 2747706f2543Smrg { 2748706f2543Smrg client->errorValue = stuff->cmap; 2749706f2543Smrg return rc; 2750706f2543Smrg } 2751706f2543Smrg} 2752706f2543Smrg 2753706f2543Smrgint 2754706f2543SmrgProcStoreColors (ClientPtr client) 2755706f2543Smrg{ 2756706f2543Smrg ColormapPtr pcmp; 2757706f2543Smrg int rc; 2758706f2543Smrg REQUEST(xStoreColorsReq); 2759706f2543Smrg 2760706f2543Smrg REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 2761706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2762706f2543Smrg DixWriteAccess); 2763706f2543Smrg if (rc == Success) 2764706f2543Smrg { 2765706f2543Smrg int count; 2766706f2543Smrg 2767706f2543Smrg count = (client->req_len << 2) - sizeof(xStoreColorsReq); 2768706f2543Smrg if (count % sizeof(xColorItem)) 2769706f2543Smrg return BadLength; 2770706f2543Smrg count /= sizeof(xColorItem); 2771706f2543Smrg return StoreColors(pcmp, count, (xColorItem *)&stuff[1], client); 2772706f2543Smrg } 2773706f2543Smrg else 2774706f2543Smrg { 2775706f2543Smrg client->errorValue = stuff->cmap; 2776706f2543Smrg return rc; 2777706f2543Smrg } 2778706f2543Smrg} 2779706f2543Smrg 2780706f2543Smrgint 2781706f2543SmrgProcStoreNamedColor (ClientPtr client) 2782706f2543Smrg{ 2783706f2543Smrg ColormapPtr pcmp; 2784706f2543Smrg int rc; 2785706f2543Smrg REQUEST(xStoreNamedColorReq); 2786706f2543Smrg 2787706f2543Smrg REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 2788706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2789706f2543Smrg DixWriteAccess); 2790706f2543Smrg if (rc == Success) 2791706f2543Smrg { 2792706f2543Smrg xColorItem def; 2793706f2543Smrg 2794706f2543Smrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], 2795706f2543Smrg stuff->nbytes, &def.red, &def.green, &def.blue)) 2796706f2543Smrg { 2797706f2543Smrg def.flags = stuff->flags; 2798706f2543Smrg def.pixel = stuff->pixel; 2799706f2543Smrg return StoreColors(pcmp, 1, &def, client); 2800706f2543Smrg } 2801706f2543Smrg return BadName; 2802706f2543Smrg } 2803706f2543Smrg else 2804706f2543Smrg { 2805706f2543Smrg client->errorValue = stuff->cmap; 2806706f2543Smrg return rc; 2807706f2543Smrg } 2808706f2543Smrg} 2809706f2543Smrg 2810706f2543Smrgint 2811706f2543SmrgProcQueryColors(ClientPtr client) 2812706f2543Smrg{ 2813706f2543Smrg ColormapPtr pcmp; 2814706f2543Smrg int rc; 2815706f2543Smrg REQUEST(xQueryColorsReq); 2816706f2543Smrg 2817706f2543Smrg REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 2818706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2819706f2543Smrg DixReadAccess); 2820706f2543Smrg if (rc == Success) 2821706f2543Smrg { 2822706f2543Smrg int count; 2823706f2543Smrg xrgb *prgbs; 2824706f2543Smrg xQueryColorsReply qcr; 2825706f2543Smrg 2826706f2543Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); 2827706f2543Smrg prgbs = calloc(1, count * sizeof(xrgb)); 2828706f2543Smrg if(!prgbs && count) 2829706f2543Smrg return BadAlloc; 2830706f2543Smrg if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs, client)) ) 2831706f2543Smrg { 2832706f2543Smrg free(prgbs); 2833706f2543Smrg return rc; 2834706f2543Smrg } 2835706f2543Smrg memset(&qcr, 0, sizeof(xQueryColorsReply)); 2836706f2543Smrg qcr.type = X_Reply; 2837706f2543Smrg qcr.length = bytes_to_int32(count * sizeof(xrgb)); 2838706f2543Smrg qcr.sequenceNumber = client->sequence; 2839706f2543Smrg qcr.nColors = count; 2840706f2543Smrg WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 2841706f2543Smrg if (count) 2842706f2543Smrg { 2843706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 2844706f2543Smrg WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 2845706f2543Smrg } 2846706f2543Smrg free(prgbs); 2847706f2543Smrg return Success; 2848706f2543Smrg 2849706f2543Smrg } 2850706f2543Smrg else 2851706f2543Smrg { 2852706f2543Smrg client->errorValue = stuff->cmap; 2853706f2543Smrg return rc; 2854706f2543Smrg } 2855706f2543Smrg} 2856706f2543Smrg 2857706f2543Smrgint 2858706f2543SmrgProcLookupColor(ClientPtr client) 2859706f2543Smrg{ 2860706f2543Smrg ColormapPtr pcmp; 2861706f2543Smrg int rc; 2862706f2543Smrg REQUEST(xLookupColorReq); 2863706f2543Smrg 2864706f2543Smrg REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 2865706f2543Smrg rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2866706f2543Smrg DixReadAccess); 2867706f2543Smrg if (rc == Success) 2868706f2543Smrg { 2869706f2543Smrg xLookupColorReply lcr; 2870706f2543Smrg 2871706f2543Smrg if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 2872706f2543Smrg &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) 2873706f2543Smrg { 2874706f2543Smrg lcr.type = X_Reply; 2875706f2543Smrg lcr.length = 0; 2876706f2543Smrg lcr.sequenceNumber = client->sequence; 2877706f2543Smrg lcr.screenRed = lcr.exactRed; 2878706f2543Smrg lcr.screenGreen = lcr.exactGreen; 2879706f2543Smrg lcr.screenBlue = lcr.exactBlue; 2880706f2543Smrg (*pcmp->pScreen->ResolveColor)(&lcr.screenRed, 2881706f2543Smrg &lcr.screenGreen, 2882706f2543Smrg &lcr.screenBlue, 2883706f2543Smrg pcmp->pVisual); 2884706f2543Smrg WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 2885706f2543Smrg return Success; 2886706f2543Smrg } 2887706f2543Smrg return BadName; 2888706f2543Smrg } 2889706f2543Smrg else 2890706f2543Smrg { 2891706f2543Smrg client->errorValue = stuff->cmap; 2892706f2543Smrg return rc; 2893706f2543Smrg } 2894706f2543Smrg} 2895706f2543Smrg 2896706f2543Smrgint 2897706f2543SmrgProcCreateCursor (ClientPtr client) 2898706f2543Smrg{ 2899706f2543Smrg CursorPtr pCursor; 2900706f2543Smrg PixmapPtr src; 2901706f2543Smrg PixmapPtr msk; 2902706f2543Smrg unsigned char * srcbits; 2903706f2543Smrg unsigned char * mskbits; 2904706f2543Smrg unsigned short width, height; 2905706f2543Smrg long n; 2906706f2543Smrg CursorMetricRec cm; 2907706f2543Smrg int rc; 2908706f2543Smrg 2909706f2543Smrg REQUEST(xCreateCursorReq); 2910706f2543Smrg 2911706f2543Smrg REQUEST_SIZE_MATCH(xCreateCursorReq); 2912706f2543Smrg LEGAL_NEW_RESOURCE(stuff->cid, client); 2913706f2543Smrg 2914706f2543Smrg rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client, 2915706f2543Smrg DixReadAccess); 2916706f2543Smrg if (rc != Success) { 2917706f2543Smrg client->errorValue = stuff->source; 2918706f2543Smrg return rc; 2919706f2543Smrg } 2920706f2543Smrg 2921706f2543Smrg rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client, 2922706f2543Smrg DixReadAccess); 2923706f2543Smrg if (rc != Success) 2924706f2543Smrg { 2925706f2543Smrg if (stuff->mask != None) 2926706f2543Smrg { 2927706f2543Smrg client->errorValue = stuff->mask; 2928706f2543Smrg return rc; 2929706f2543Smrg } 2930706f2543Smrg } 2931706f2543Smrg else if ( src->drawable.width != msk->drawable.width 2932706f2543Smrg || src->drawable.height != msk->drawable.height 2933706f2543Smrg || src->drawable.depth != 1 2934706f2543Smrg || msk->drawable.depth != 1) 2935706f2543Smrg return BadMatch; 2936706f2543Smrg 2937706f2543Smrg width = src->drawable.width; 2938706f2543Smrg height = src->drawable.height; 2939706f2543Smrg 2940706f2543Smrg if ( stuff->x > width 2941706f2543Smrg || stuff->y > height ) 2942706f2543Smrg return BadMatch; 2943706f2543Smrg 2944706f2543Smrg n = BitmapBytePad(width)*height; 2945706f2543Smrg srcbits = calloc(1, n); 2946706f2543Smrg if (!srcbits) 2947706f2543Smrg return BadAlloc; 2948706f2543Smrg mskbits = malloc(n); 2949706f2543Smrg if (!mskbits) 2950706f2543Smrg { 2951706f2543Smrg free(srcbits); 2952706f2543Smrg return BadAlloc; 2953706f2543Smrg } 2954706f2543Smrg 2955706f2543Smrg (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height, 2956706f2543Smrg XYPixmap, 1, (pointer)srcbits); 2957706f2543Smrg if ( msk == (PixmapPtr)NULL) 2958706f2543Smrg { 2959706f2543Smrg unsigned char *bits = mskbits; 2960706f2543Smrg while (--n >= 0) 2961706f2543Smrg *bits++ = ~0; 2962706f2543Smrg } 2963706f2543Smrg else 2964706f2543Smrg { 2965706f2543Smrg /* zeroing the (pad) bits helps some ddx cursor handling */ 2966706f2543Smrg memset((char *)mskbits, 0, n); 2967706f2543Smrg (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width, 2968706f2543Smrg height, XYPixmap, 1, (pointer)mskbits); 2969706f2543Smrg } 2970706f2543Smrg cm.width = width; 2971706f2543Smrg cm.height = height; 2972706f2543Smrg cm.xhot = stuff->x; 2973706f2543Smrg cm.yhot = stuff->y; 2974706f2543Smrg rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 2975706f2543Smrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 2976706f2543Smrg stuff->backRed, stuff->backGreen, stuff->backBlue, 2977706f2543Smrg &pCursor, client, stuff->cid); 2978706f2543Smrg 2979706f2543Smrg if (rc != Success) 2980706f2543Smrg return rc; 2981706f2543Smrg if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 2982706f2543Smrg return BadAlloc; 2983706f2543Smrg 2984706f2543Smrg return Success; 2985706f2543Smrg} 2986706f2543Smrg 2987706f2543Smrgint 2988706f2543SmrgProcCreateGlyphCursor (ClientPtr client) 2989706f2543Smrg{ 2990706f2543Smrg CursorPtr pCursor; 2991706f2543Smrg int res; 2992706f2543Smrg 2993706f2543Smrg REQUEST(xCreateGlyphCursorReq); 2994706f2543Smrg 2995706f2543Smrg REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 2996706f2543Smrg LEGAL_NEW_RESOURCE(stuff->cid, client); 2997706f2543Smrg 2998706f2543Smrg res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 2999706f2543Smrg stuff->mask, stuff->maskChar, 3000706f2543Smrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 3001706f2543Smrg stuff->backRed, stuff->backGreen, stuff->backBlue, 3002706f2543Smrg &pCursor, client, stuff->cid); 3003706f2543Smrg if (res != Success) 3004706f2543Smrg return res; 3005706f2543Smrg if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 3006706f2543Smrg return Success; 3007706f2543Smrg return BadAlloc; 3008706f2543Smrg} 3009706f2543Smrg 3010706f2543Smrg 3011706f2543Smrgint 3012706f2543SmrgProcFreeCursor (ClientPtr client) 3013706f2543Smrg{ 3014706f2543Smrg CursorPtr pCursor; 3015706f2543Smrg int rc; 3016706f2543Smrg REQUEST(xResourceReq); 3017706f2543Smrg 3018706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 3019706f2543Smrg rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client, 3020706f2543Smrg DixDestroyAccess); 3021706f2543Smrg if (rc == Success) 3022706f2543Smrg { 3023706f2543Smrg FreeResource(stuff->id, RT_NONE); 3024706f2543Smrg return Success; 3025706f2543Smrg } 3026706f2543Smrg else 3027706f2543Smrg { 3028706f2543Smrg client->errorValue = stuff->id; 3029706f2543Smrg return rc; 3030706f2543Smrg } 3031706f2543Smrg} 3032706f2543Smrg 3033706f2543Smrgint 3034706f2543SmrgProcQueryBestSize (ClientPtr client) 3035706f2543Smrg{ 3036706f2543Smrg xQueryBestSizeReply reply; 3037706f2543Smrg DrawablePtr pDraw; 3038706f2543Smrg ScreenPtr pScreen; 3039706f2543Smrg int rc; 3040706f2543Smrg REQUEST(xQueryBestSizeReq); 3041706f2543Smrg REQUEST_SIZE_MATCH(xQueryBestSizeReq); 3042706f2543Smrg 3043706f2543Smrg if ((stuff->class != CursorShape) && 3044706f2543Smrg (stuff->class != TileShape) && 3045706f2543Smrg (stuff->class != StippleShape)) 3046706f2543Smrg { 3047706f2543Smrg client->errorValue = stuff->class; 3048706f2543Smrg return BadValue; 3049706f2543Smrg } 3050706f2543Smrg 3051706f2543Smrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 3052706f2543Smrg DixGetAttrAccess); 3053706f2543Smrg if (rc != Success) 3054706f2543Smrg return rc; 3055706f2543Smrg if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 3056706f2543Smrg return BadMatch; 3057706f2543Smrg pScreen = pDraw->pScreen; 3058706f2543Smrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 3059706f2543Smrg if (rc != Success) 3060706f2543Smrg return rc; 3061706f2543Smrg (* pScreen->QueryBestSize)(stuff->class, &stuff->width, 3062706f2543Smrg &stuff->height, pScreen); 3063706f2543Smrg memset(&reply, 0, sizeof(xQueryBestSizeReply)); 3064706f2543Smrg reply.type = X_Reply; 3065706f2543Smrg reply.length = 0; 3066706f2543Smrg reply.sequenceNumber = client->sequence; 3067706f2543Smrg reply.width = stuff->width; 3068706f2543Smrg reply.height = stuff->height; 3069706f2543Smrg WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 3070706f2543Smrg return Success; 3071706f2543Smrg} 3072706f2543Smrg 3073706f2543Smrg 3074706f2543Smrgint 3075706f2543SmrgProcSetScreenSaver (ClientPtr client) 3076706f2543Smrg{ 3077706f2543Smrg int rc, i, blankingOption, exposureOption; 3078706f2543Smrg REQUEST(xSetScreenSaverReq); 3079706f2543Smrg REQUEST_SIZE_MATCH(xSetScreenSaverReq); 3080706f2543Smrg 3081706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) { 3082706f2543Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3083706f2543Smrg DixSetAttrAccess); 3084706f2543Smrg if (rc != Success) 3085706f2543Smrg return rc; 3086706f2543Smrg } 3087706f2543Smrg 3088706f2543Smrg blankingOption = stuff->preferBlank; 3089706f2543Smrg if ((blankingOption != DontPreferBlanking) && 3090706f2543Smrg (blankingOption != PreferBlanking) && 3091706f2543Smrg (blankingOption != DefaultBlanking)) 3092706f2543Smrg { 3093706f2543Smrg client->errorValue = blankingOption; 3094706f2543Smrg return BadValue; 3095706f2543Smrg } 3096706f2543Smrg exposureOption = stuff->allowExpose; 3097706f2543Smrg if ((exposureOption != DontAllowExposures) && 3098706f2543Smrg (exposureOption != AllowExposures) && 3099706f2543Smrg (exposureOption != DefaultExposures)) 3100706f2543Smrg { 3101706f2543Smrg client->errorValue = exposureOption; 3102706f2543Smrg return BadValue; 3103706f2543Smrg } 3104706f2543Smrg if (stuff->timeout < -1) 3105706f2543Smrg { 3106706f2543Smrg client->errorValue = stuff->timeout; 3107706f2543Smrg return BadValue; 3108706f2543Smrg } 3109706f2543Smrg if (stuff->interval < -1) 3110706f2543Smrg { 3111706f2543Smrg client->errorValue = stuff->interval; 3112706f2543Smrg return BadValue; 3113706f2543Smrg } 3114706f2543Smrg 3115706f2543Smrg if (blankingOption == DefaultBlanking) 3116706f2543Smrg ScreenSaverBlanking = defaultScreenSaverBlanking; 3117706f2543Smrg else 3118706f2543Smrg ScreenSaverBlanking = blankingOption; 3119706f2543Smrg if (exposureOption == DefaultExposures) 3120706f2543Smrg ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 3121706f2543Smrg else 3122706f2543Smrg ScreenSaverAllowExposures = exposureOption; 3123706f2543Smrg 3124706f2543Smrg if (stuff->timeout >= 0) 3125706f2543Smrg ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 3126706f2543Smrg else 3127706f2543Smrg ScreenSaverTime = defaultScreenSaverTime; 3128706f2543Smrg if (stuff->interval >= 0) 3129706f2543Smrg ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 3130706f2543Smrg else 3131706f2543Smrg ScreenSaverInterval = defaultScreenSaverInterval; 3132706f2543Smrg 3133706f2543Smrg SetScreenSaverTimer(); 3134706f2543Smrg return Success; 3135706f2543Smrg} 3136706f2543Smrg 3137706f2543Smrgint 3138706f2543SmrgProcGetScreenSaver(ClientPtr client) 3139706f2543Smrg{ 3140706f2543Smrg xGetScreenSaverReply rep; 3141706f2543Smrg int rc, i; 3142706f2543Smrg REQUEST_SIZE_MATCH(xReq); 3143706f2543Smrg 3144706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) { 3145706f2543Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3146706f2543Smrg DixGetAttrAccess); 3147706f2543Smrg if (rc != Success) 3148706f2543Smrg return rc; 3149706f2543Smrg } 3150706f2543Smrg 3151706f2543Smrg rep.type = X_Reply; 3152706f2543Smrg rep.length = 0; 3153706f2543Smrg rep.sequenceNumber = client->sequence; 3154706f2543Smrg rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; 3155706f2543Smrg rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; 3156706f2543Smrg rep.preferBlanking = ScreenSaverBlanking; 3157706f2543Smrg rep.allowExposures = ScreenSaverAllowExposures; 3158706f2543Smrg WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 3159706f2543Smrg return Success; 3160706f2543Smrg} 3161706f2543Smrg 3162706f2543Smrgint 3163706f2543SmrgProcChangeHosts(ClientPtr client) 3164706f2543Smrg{ 3165706f2543Smrg REQUEST(xChangeHostsReq); 3166706f2543Smrg 3167706f2543Smrg REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 3168706f2543Smrg 3169706f2543Smrg if(stuff->mode == HostInsert) 3170706f2543Smrg return AddHost(client, (int)stuff->hostFamily, 3171706f2543Smrg stuff->hostLength, (pointer)&stuff[1]); 3172706f2543Smrg if (stuff->mode == HostDelete) 3173706f2543Smrg return RemoveHost(client, (int)stuff->hostFamily, 3174706f2543Smrg stuff->hostLength, (pointer)&stuff[1]); 3175706f2543Smrg client->errorValue = stuff->mode; 3176706f2543Smrg return BadValue; 3177706f2543Smrg} 3178706f2543Smrg 3179706f2543Smrgint 3180706f2543SmrgProcListHosts(ClientPtr client) 3181706f2543Smrg{ 3182706f2543Smrg xListHostsReply reply; 3183706f2543Smrg int len, nHosts, result; 3184706f2543Smrg pointer pdata; 3185706f2543Smrg /* REQUEST(xListHostsReq); */ 3186706f2543Smrg 3187706f2543Smrg REQUEST_SIZE_MATCH(xListHostsReq); 3188706f2543Smrg 3189706f2543Smrg /* untrusted clients can't list hosts */ 3190706f2543Smrg result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); 3191706f2543Smrg if (result != Success) 3192706f2543Smrg return result; 3193706f2543Smrg 3194706f2543Smrg result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); 3195706f2543Smrg if (result != Success) 3196706f2543Smrg return result; 3197706f2543Smrg reply.type = X_Reply; 3198706f2543Smrg reply.sequenceNumber = client->sequence; 3199706f2543Smrg reply.nHosts = nHosts; 3200706f2543Smrg reply.length = bytes_to_int32(len); 3201706f2543Smrg WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 3202706f2543Smrg if (nHosts) 3203706f2543Smrg { 3204706f2543Smrg client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 3205706f2543Smrg WriteSwappedDataToClient(client, len, pdata); 3206706f2543Smrg } 3207706f2543Smrg free(pdata); 3208706f2543Smrg return Success; 3209706f2543Smrg} 3210706f2543Smrg 3211706f2543Smrgint 3212706f2543SmrgProcChangeAccessControl(ClientPtr client) 3213706f2543Smrg{ 3214706f2543Smrg REQUEST(xSetAccessControlReq); 3215706f2543Smrg 3216706f2543Smrg REQUEST_SIZE_MATCH(xSetAccessControlReq); 3217706f2543Smrg if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) 3218706f2543Smrg { 3219706f2543Smrg client->errorValue = stuff->mode; 3220706f2543Smrg return BadValue; 3221706f2543Smrg } 3222706f2543Smrg return ChangeAccessControl(client, stuff->mode == EnableAccess); 3223706f2543Smrg} 3224706f2543Smrg 3225706f2543Smrg/********************* 3226706f2543Smrg * CloseDownRetainedResources 3227706f2543Smrg * 3228706f2543Smrg * Find all clients that are gone and have terminated in RetainTemporary 3229706f2543Smrg * and destroy their resources. 3230706f2543Smrg *********************/ 3231706f2543Smrg 3232706f2543Smrgstatic void 3233706f2543SmrgCloseDownRetainedResources(void) 3234706f2543Smrg{ 3235706f2543Smrg int i; 3236706f2543Smrg ClientPtr client; 3237706f2543Smrg 3238706f2543Smrg for (i=1; i<currentMaxClients; i++) 3239706f2543Smrg { 3240706f2543Smrg client = clients[i]; 3241706f2543Smrg if (client && (client->closeDownMode == RetainTemporary) 3242706f2543Smrg && (client->clientGone)) 3243706f2543Smrg CloseDownClient(client); 3244706f2543Smrg } 3245706f2543Smrg} 3246706f2543Smrg 3247706f2543Smrgint 3248706f2543SmrgProcKillClient(ClientPtr client) 3249706f2543Smrg{ 3250706f2543Smrg REQUEST(xResourceReq); 3251706f2543Smrg ClientPtr killclient; 3252706f2543Smrg int rc; 3253706f2543Smrg 3254706f2543Smrg REQUEST_SIZE_MATCH(xResourceReq); 3255706f2543Smrg if (stuff->id == AllTemporary) 3256706f2543Smrg { 3257706f2543Smrg CloseDownRetainedResources(); 3258706f2543Smrg return Success; 3259706f2543Smrg } 3260706f2543Smrg 3261706f2543Smrg rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 3262706f2543Smrg if (rc == Success) { 3263706f2543Smrg CloseDownClient(killclient); 3264706f2543Smrg /* if an LBX proxy gets killed, isItTimeToYield will be set */ 3265706f2543Smrg if (isItTimeToYield || (client == killclient)) 3266706f2543Smrg { 3267706f2543Smrg /* force yield and return Success, so that Dispatch() 3268706f2543Smrg * doesn't try to touch client 3269706f2543Smrg */ 3270706f2543Smrg isItTimeToYield = TRUE; 3271706f2543Smrg return Success; 3272706f2543Smrg } 3273706f2543Smrg return Success; 3274706f2543Smrg } 3275706f2543Smrg else 3276706f2543Smrg return rc; 3277706f2543Smrg} 3278706f2543Smrg 3279706f2543Smrgint 3280706f2543SmrgProcSetFontPath(ClientPtr client) 3281706f2543Smrg{ 3282706f2543Smrg unsigned char *ptr; 3283706f2543Smrg unsigned long nbytes, total; 3284706f2543Smrg long nfonts; 3285706f2543Smrg int n; 3286706f2543Smrg REQUEST(xSetFontPathReq); 3287706f2543Smrg 3288706f2543Smrg REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 3289706f2543Smrg 3290706f2543Smrg nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 3291706f2543Smrg total = nbytes; 3292706f2543Smrg ptr = (unsigned char *)&stuff[1]; 3293706f2543Smrg nfonts = stuff->nFonts; 3294706f2543Smrg while (--nfonts >= 0) 3295706f2543Smrg { 3296706f2543Smrg if ((total == 0) || (total < (n = (*ptr + 1)))) 3297706f2543Smrg return BadLength; 3298706f2543Smrg total -= n; 3299706f2543Smrg ptr += n; 3300706f2543Smrg } 3301706f2543Smrg if (total >= 4) 3302706f2543Smrg return BadLength; 3303706f2543Smrg return SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]); 3304706f2543Smrg} 3305706f2543Smrg 3306706f2543Smrgint 3307706f2543SmrgProcGetFontPath(ClientPtr client) 3308706f2543Smrg{ 3309706f2543Smrg xGetFontPathReply reply; 3310706f2543Smrg int rc, stringLens, numpaths; 3311706f2543Smrg unsigned char *bufferStart; 3312706f2543Smrg /* REQUEST (xReq); */ 3313706f2543Smrg 3314706f2543Smrg REQUEST_SIZE_MATCH(xReq); 3315706f2543Smrg rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); 3316706f2543Smrg if (rc != Success) 3317706f2543Smrg return rc; 3318706f2543Smrg 3319706f2543Smrg reply.type = X_Reply; 3320706f2543Smrg reply.sequenceNumber = client->sequence; 3321706f2543Smrg reply.length = bytes_to_int32(stringLens + numpaths); 3322706f2543Smrg reply.nPaths = numpaths; 3323706f2543Smrg 3324706f2543Smrg WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 3325706f2543Smrg if (stringLens || numpaths) 3326706f2543Smrg (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart); 3327706f2543Smrg return Success; 3328706f2543Smrg} 3329706f2543Smrg 3330706f2543Smrgint 3331706f2543SmrgProcChangeCloseDownMode(ClientPtr client) 3332706f2543Smrg{ 3333706f2543Smrg int rc; 3334706f2543Smrg REQUEST(xSetCloseDownModeReq); 3335706f2543Smrg REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 3336706f2543Smrg 3337706f2543Smrg rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); 3338706f2543Smrg if (rc != Success) 3339706f2543Smrg return rc; 3340706f2543Smrg 3341706f2543Smrg if ((stuff->mode == AllTemporary) || 3342706f2543Smrg (stuff->mode == RetainPermanent) || 3343706f2543Smrg (stuff->mode == RetainTemporary)) 3344706f2543Smrg { 3345706f2543Smrg client->closeDownMode = stuff->mode; 3346706f2543Smrg return Success; 3347706f2543Smrg } 3348706f2543Smrg else 3349706f2543Smrg { 3350706f2543Smrg client->errorValue = stuff->mode; 3351706f2543Smrg return BadValue; 3352706f2543Smrg } 3353706f2543Smrg} 3354706f2543Smrg 3355706f2543Smrgint ProcForceScreenSaver(ClientPtr client) 3356706f2543Smrg{ 3357706f2543Smrg int rc; 3358706f2543Smrg REQUEST(xForceScreenSaverReq); 3359706f2543Smrg 3360706f2543Smrg REQUEST_SIZE_MATCH(xForceScreenSaverReq); 3361706f2543Smrg 3362706f2543Smrg if ((stuff->mode != ScreenSaverReset) && 3363706f2543Smrg (stuff->mode != ScreenSaverActive)) 3364706f2543Smrg { 3365706f2543Smrg client->errorValue = stuff->mode; 3366706f2543Smrg return BadValue; 3367706f2543Smrg } 3368706f2543Smrg rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode); 3369706f2543Smrg if (rc != Success) 3370706f2543Smrg return rc; 3371706f2543Smrg return Success; 3372706f2543Smrg} 3373706f2543Smrg 3374706f2543Smrgint ProcNoOperation(ClientPtr client) 3375706f2543Smrg{ 3376706f2543Smrg REQUEST_AT_LEAST_SIZE(xReq); 3377706f2543Smrg 3378706f2543Smrg /* noop -- don't do anything */ 3379706f2543Smrg return Success; 3380706f2543Smrg} 3381706f2543Smrg 3382706f2543Smrg/********************** 3383706f2543Smrg * CloseDownClient 3384706f2543Smrg * 3385706f2543Smrg * Client can either mark his resources destroy or retain. If retained and 3386706f2543Smrg * then killed again, the client is really destroyed. 3387706f2543Smrg *********************/ 3388706f2543Smrg 3389706f2543Smrgchar dispatchExceptionAtReset = DE_RESET; 3390706f2543Smrg 3391706f2543Smrgvoid 3392706f2543SmrgCloseDownClient(ClientPtr client) 3393706f2543Smrg{ 3394706f2543Smrg Bool really_close_down = client->clientGone || 3395706f2543Smrg client->closeDownMode == DestroyAll; 3396706f2543Smrg 3397706f2543Smrg if (!client->clientGone) 3398706f2543Smrg { 3399706f2543Smrg /* ungrab server if grabbing client dies */ 3400706f2543Smrg if (grabState != GrabNone && grabClient == client) 3401706f2543Smrg { 3402706f2543Smrg UngrabServer(client); 3403706f2543Smrg } 3404706f2543Smrg BITCLEAR(grabWaiters, client->index); 3405706f2543Smrg DeleteClientFromAnySelections(client); 3406706f2543Smrg ReleaseActiveGrabs(client); 3407706f2543Smrg DeleteClientFontStuff(client); 3408706f2543Smrg if (!really_close_down) 3409706f2543Smrg { 3410706f2543Smrg /* This frees resources that should never be retained 3411706f2543Smrg * no matter what the close down mode is. Actually we 3412706f2543Smrg * could do this unconditionally, but it's probably 3413706f2543Smrg * better not to traverse all the client's resources 3414706f2543Smrg * twice (once here, once a few lines down in 3415706f2543Smrg * FreeClientResources) in the common case of 3416706f2543Smrg * really_close_down == TRUE. 3417706f2543Smrg */ 3418706f2543Smrg FreeClientNeverRetainResources(client); 3419706f2543Smrg client->clientState = ClientStateRetained; 3420706f2543Smrg if (ClientStateCallback) 3421706f2543Smrg { 3422706f2543Smrg NewClientInfoRec clientinfo; 3423706f2543Smrg 3424706f2543Smrg clientinfo.client = client; 3425706f2543Smrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 3426706f2543Smrg clientinfo.setup = (xConnSetup *) NULL; 3427706f2543Smrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3428706f2543Smrg } 3429706f2543Smrg } 3430706f2543Smrg client->clientGone = TRUE; /* so events aren't sent to client */ 3431706f2543Smrg if (ClientIsAsleep(client)) 3432706f2543Smrg ClientSignal (client); 3433706f2543Smrg ProcessWorkQueueZombies(); 3434706f2543Smrg CloseDownConnection(client); 3435706f2543Smrg 3436706f2543Smrg /* If the client made it to the Running stage, nClients has 3437706f2543Smrg * been incremented on its behalf, so we need to decrement it 3438706f2543Smrg * now. If it hasn't gotten to Running, nClients has *not* 3439706f2543Smrg * been incremented, so *don't* decrement it. 3440706f2543Smrg */ 3441706f2543Smrg if (client->clientState != ClientStateInitial && 3442706f2543Smrg client->clientState != ClientStateAuthenticating ) 3443706f2543Smrg { 3444706f2543Smrg --nClients; 3445706f2543Smrg } 3446706f2543Smrg } 3447706f2543Smrg 3448706f2543Smrg if (really_close_down) 3449706f2543Smrg { 3450706f2543Smrg if (client->clientState == ClientStateRunning && nClients == 0) 3451706f2543Smrg dispatchException |= dispatchExceptionAtReset; 3452706f2543Smrg 3453706f2543Smrg client->clientState = ClientStateGone; 3454706f2543Smrg if (ClientStateCallback) 3455706f2543Smrg { 3456706f2543Smrg NewClientInfoRec clientinfo; 3457706f2543Smrg 3458706f2543Smrg clientinfo.client = client; 3459706f2543Smrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 3460706f2543Smrg clientinfo.setup = (xConnSetup *) NULL; 3461706f2543Smrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3462706f2543Smrg } 3463706f2543Smrg FreeClientResources(client); 3464706f2543Smrg#ifdef XSERVER_DTRACE 3465706f2543Smrg XSERVER_CLIENT_DISCONNECT(client->index); 3466706f2543Smrg#endif 3467706f2543Smrg if (client->index < nextFreeClientID) 3468706f2543Smrg nextFreeClientID = client->index; 3469706f2543Smrg clients[client->index] = NullClient; 3470706f2543Smrg SmartLastClient = NullClient; 3471706f2543Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3472706f2543Smrg 3473706f2543Smrg while (!clients[currentMaxClients-1]) 3474706f2543Smrg currentMaxClients--; 3475706f2543Smrg } 3476706f2543Smrg} 3477706f2543Smrg 3478706f2543Smrgstatic void 3479706f2543SmrgKillAllClients(void) 3480706f2543Smrg{ 3481706f2543Smrg int i; 3482706f2543Smrg for (i=1; i<currentMaxClients; i++) 3483706f2543Smrg if (clients[i]) { 3484706f2543Smrg /* Make sure Retained clients are released. */ 3485706f2543Smrg clients[i]->closeDownMode = DestroyAll; 3486706f2543Smrg CloseDownClient(clients[i]); 3487706f2543Smrg } 3488706f2543Smrg} 3489706f2543Smrg 3490706f2543Smrgvoid InitClient(ClientPtr client, int i, pointer ospriv) 3491706f2543Smrg{ 3492706f2543Smrg client->index = i; 3493706f2543Smrg client->clientAsMask = ((Mask)i) << CLIENTOFFSET; 3494706f2543Smrg client->closeDownMode = i ? DestroyAll : RetainPermanent; 3495706f2543Smrg client->requestVector = InitialVector; 3496706f2543Smrg client->osPrivate = ospriv; 3497706f2543Smrg QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); 3498706f2543Smrg client->smart_start_tick = SmartScheduleTime; 3499706f2543Smrg client->smart_stop_tick = SmartScheduleTime; 3500706f2543Smrg client->smart_check_tick = SmartScheduleTime; 3501706f2543Smrg} 3502706f2543Smrg 3503706f2543Smrg/************************ 3504706f2543Smrg * int NextAvailableClient(ospriv) 3505706f2543Smrg * 3506706f2543Smrg * OS dependent portion can't assign client id's because of CloseDownModes. 3507706f2543Smrg * Returns NULL if there are no free clients. 3508706f2543Smrg *************************/ 3509706f2543Smrg 3510706f2543SmrgClientPtr NextAvailableClient(pointer ospriv) 3511706f2543Smrg{ 3512706f2543Smrg int i; 3513706f2543Smrg ClientPtr client; 3514706f2543Smrg xReq data; 3515706f2543Smrg 3516706f2543Smrg i = nextFreeClientID; 3517706f2543Smrg if (i == MAXCLIENTS) 3518706f2543Smrg return (ClientPtr)NULL; 3519706f2543Smrg clients[i] = client = dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT); 3520706f2543Smrg if (!client) 3521706f2543Smrg return (ClientPtr)NULL; 3522706f2543Smrg InitClient(client, i, ospriv); 3523706f2543Smrg if (!InitClientResources(client)) 3524706f2543Smrg { 3525706f2543Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3526706f2543Smrg return (ClientPtr)NULL; 3527706f2543Smrg } 3528706f2543Smrg data.reqType = 1; 3529706f2543Smrg data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); 3530706f2543Smrg if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) 3531706f2543Smrg { 3532706f2543Smrg FreeClientResources(client); 3533706f2543Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3534706f2543Smrg return (ClientPtr)NULL; 3535706f2543Smrg } 3536706f2543Smrg if (i == currentMaxClients) 3537706f2543Smrg currentMaxClients++; 3538706f2543Smrg while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) 3539706f2543Smrg nextFreeClientID++; 3540706f2543Smrg if (ClientStateCallback) 3541706f2543Smrg { 3542706f2543Smrg NewClientInfoRec clientinfo; 3543706f2543Smrg 3544706f2543Smrg clientinfo.client = client; 3545706f2543Smrg clientinfo.prefix = (xConnSetupPrefix *)NULL; 3546706f2543Smrg clientinfo.setup = (xConnSetup *) NULL; 3547706f2543Smrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3548706f2543Smrg } 3549706f2543Smrg return client; 3550706f2543Smrg} 3551706f2543Smrg 3552706f2543Smrgint 3553706f2543SmrgProcInitialConnection(ClientPtr client) 3554706f2543Smrg{ 3555706f2543Smrg REQUEST(xReq); 3556706f2543Smrg xConnClientPrefix *prefix; 3557706f2543Smrg int whichbyte = 1; 3558706f2543Smrg 3559706f2543Smrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 3560706f2543Smrg if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) 3561706f2543Smrg return client->noClientException = -1; 3562706f2543Smrg if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || 3563706f2543Smrg (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) 3564706f2543Smrg { 3565706f2543Smrg client->swapped = TRUE; 3566706f2543Smrg SwapConnClientPrefix(prefix); 3567706f2543Smrg } 3568706f2543Smrg stuff->reqType = 2; 3569706f2543Smrg stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + 3570706f2543Smrg bytes_to_int32(prefix->nbytesAuthString); 3571706f2543Smrg if (client->swapped) 3572706f2543Smrg { 3573706f2543Smrg swaps(&stuff->length, whichbyte); 3574706f2543Smrg } 3575706f2543Smrg ResetCurrentRequest(client); 3576706f2543Smrg return Success; 3577706f2543Smrg} 3578706f2543Smrg 3579706f2543Smrgstatic int 3580706f2543SmrgSendConnSetup(ClientPtr client, char *reason) 3581706f2543Smrg{ 3582706f2543Smrg xWindowRoot *root; 3583706f2543Smrg int i; 3584706f2543Smrg int numScreens; 3585706f2543Smrg char* lConnectionInfo; 3586706f2543Smrg xConnSetupPrefix* lconnSetupPrefix; 3587706f2543Smrg 3588706f2543Smrg if (reason) 3589706f2543Smrg { 3590706f2543Smrg xConnSetupPrefix csp; 3591706f2543Smrg 3592706f2543Smrg csp.success = xFalse; 3593706f2543Smrg csp.lengthReason = strlen(reason); 3594706f2543Smrg csp.length = bytes_to_int32(csp.lengthReason); 3595706f2543Smrg csp.majorVersion = X_PROTOCOL; 3596706f2543Smrg csp.minorVersion = X_PROTOCOL_REVISION; 3597706f2543Smrg if (client->swapped) 3598706f2543Smrg WriteSConnSetupPrefix(client, &csp); 3599706f2543Smrg else 3600706f2543Smrg (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); 3601706f2543Smrg (void)WriteToClient(client, (int)csp.lengthReason, reason); 3602706f2543Smrg return client->noClientException = -1; 3603706f2543Smrg } 3604706f2543Smrg 3605706f2543Smrg numScreens = screenInfo.numScreens; 3606706f2543Smrg lConnectionInfo = ConnectionInfo; 3607706f2543Smrg lconnSetupPrefix = &connSetupPrefix; 3608706f2543Smrg 3609706f2543Smrg /* We're about to start speaking X protocol back to the client by 3610706f2543Smrg * sending the connection setup info. This means the authorization 3611706f2543Smrg * step is complete, and we can count the client as an 3612706f2543Smrg * authorized one. 3613706f2543Smrg */ 3614706f2543Smrg nClients++; 3615706f2543Smrg 3616706f2543Smrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 3617706f2543Smrg client->sequence = 0; 3618706f2543Smrg ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask; 3619706f2543Smrg ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 3620706f2543Smrg#ifdef MATCH_CLIENT_ENDIAN 3621706f2543Smrg ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client); 3622706f2543Smrg ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client); 3623706f2543Smrg#endif 3624706f2543Smrg /* fill in the "currentInputMask" */ 3625706f2543Smrg root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart); 3626706f2543Smrg#ifdef PANORAMIX 3627706f2543Smrg if (noPanoramiXExtension) 3628706f2543Smrg numScreens = screenInfo.numScreens; 3629706f2543Smrg else 3630706f2543Smrg numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; 3631706f2543Smrg#endif 3632706f2543Smrg 3633706f2543Smrg for (i=0; i<numScreens; i++) 3634706f2543Smrg { 3635706f2543Smrg unsigned int j; 3636706f2543Smrg xDepth *pDepth; 3637706f2543Smrg WindowPtr pRoot = screenInfo.screens[i]->root; 3638706f2543Smrg 3639706f2543Smrg root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot); 3640706f2543Smrg pDepth = (xDepth *)(root + 1); 3641706f2543Smrg for (j = 0; j < root->nDepths; j++) 3642706f2543Smrg { 3643706f2543Smrg pDepth = (xDepth *)(((char *)(pDepth + 1)) + 3644706f2543Smrg pDepth->nVisuals * sizeof(xVisualType)); 3645706f2543Smrg } 3646706f2543Smrg root = (xWindowRoot *)pDepth; 3647706f2543Smrg } 3648706f2543Smrg 3649706f2543Smrg if (client->swapped) 3650706f2543Smrg { 3651706f2543Smrg WriteSConnSetupPrefix(client, lconnSetupPrefix); 3652706f2543Smrg WriteSConnectionInfo(client, 3653706f2543Smrg (unsigned long)(lconnSetupPrefix->length << 2), 3654706f2543Smrg lConnectionInfo); 3655706f2543Smrg } 3656706f2543Smrg else 3657706f2543Smrg { 3658706f2543Smrg (void)WriteToClient(client, sizeof(xConnSetupPrefix), 3659706f2543Smrg (char *) lconnSetupPrefix); 3660706f2543Smrg (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2), 3661706f2543Smrg lConnectionInfo); 3662706f2543Smrg } 3663706f2543Smrg client->clientState = ClientStateRunning; 3664706f2543Smrg if (ClientStateCallback) 3665706f2543Smrg { 3666706f2543Smrg NewClientInfoRec clientinfo; 3667706f2543Smrg 3668706f2543Smrg clientinfo.client = client; 3669706f2543Smrg clientinfo.prefix = lconnSetupPrefix; 3670706f2543Smrg clientinfo.setup = (xConnSetup *)lConnectionInfo; 3671706f2543Smrg CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3672706f2543Smrg } 3673706f2543Smrg return Success; 3674706f2543Smrg} 3675706f2543Smrg 3676706f2543Smrgint 3677706f2543SmrgProcEstablishConnection(ClientPtr client) 3678706f2543Smrg{ 3679706f2543Smrg char *reason, *auth_proto, *auth_string; 3680706f2543Smrg xConnClientPrefix *prefix; 3681706f2543Smrg REQUEST(xReq); 3682706f2543Smrg 3683706f2543Smrg prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 3684706f2543Smrg auth_proto = (char *)prefix + sz_xConnClientPrefix; 3685706f2543Smrg auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); 368648a68b89Smrg 368748a68b89Smrg if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix + 368848a68b89Smrg pad_to_int32(prefix->nbytesAuthProto) + 368948a68b89Smrg pad_to_int32(prefix->nbytesAuthString)) 369048a68b89Smrg reason = "Bad length"; 369148a68b89Smrg else if ((prefix->majorVersion != X_PROTOCOL) || 3692706f2543Smrg (prefix->minorVersion != X_PROTOCOL_REVISION)) 3693706f2543Smrg reason = "Protocol version mismatch"; 3694706f2543Smrg else 3695706f2543Smrg reason = ClientAuthorized(client, 3696706f2543Smrg (unsigned short)prefix->nbytesAuthProto, 3697706f2543Smrg auth_proto, 3698706f2543Smrg (unsigned short)prefix->nbytesAuthString, 3699706f2543Smrg auth_string); 3700706f2543Smrg /* 3701706f2543Smrg * If Kerberos is being used for this client, the clientState 3702706f2543Smrg * will be set to ClientStateAuthenticating at this point. 3703706f2543Smrg * More messages need to be exchanged among the X server, Kerberos 3704706f2543Smrg * server, and client to figure out if everyone is authorized. 3705706f2543Smrg * So we don't want to send the connection setup info yet, since 3706706f2543Smrg * the auth step isn't really done. 3707706f2543Smrg */ 3708706f2543Smrg if (client->clientState == ClientStateCheckingSecurity) 3709706f2543Smrg client->clientState = ClientStateCheckedSecurity; 3710706f2543Smrg else if (client->clientState != ClientStateAuthenticating) 3711706f2543Smrg return(SendConnSetup(client, reason)); 3712706f2543Smrg return Success; 3713706f2543Smrg} 3714706f2543Smrg 3715706f2543Smrgvoid 3716706f2543SmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 3717706f2543Smrg XID resId, int errorCode) 3718706f2543Smrg{ 3719706f2543Smrg xError rep; 3720706f2543Smrg 3721706f2543Smrg memset(&rep, 0, sizeof(xError)); 3722706f2543Smrg rep.type = X_Error; 3723706f2543Smrg rep.errorCode = errorCode; 3724706f2543Smrg rep.majorCode = majorCode; 3725706f2543Smrg rep.minorCode = minorCode; 3726706f2543Smrg rep.resourceID = resId; 3727706f2543Smrg 3728706f2543Smrg WriteEventsToClient (client, 1, (xEvent *)&rep); 3729706f2543Smrg} 3730706f2543Smrg 3731706f2543Smrgvoid 3732706f2543SmrgMarkClientException(ClientPtr client) 3733706f2543Smrg{ 3734706f2543Smrg client->noClientException = -1; 3735706f2543Smrg} 3736706f2543Smrg 3737706f2543Smrg/* 3738706f2543Smrg * This array encodes the answer to the question "what is the log base 2 3739706f2543Smrg * of the number of pixels that fit in a scanline pad unit?" 3740706f2543Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 3741706f2543Smrg */ 3742706f2543Smrgstatic int answer[6][4] = { 3743706f2543Smrg /* pad pad pad pad*/ 3744706f2543Smrg /* 8 16 32 64 */ 3745706f2543Smrg 3746706f2543Smrg { 3, 4, 5 , 6 }, /* 1 bit per pixel */ 3747706f2543Smrg { 1, 2, 3 , 4 }, /* 4 bits per pixel */ 3748706f2543Smrg { 0, 1, 2 , 3 }, /* 8 bits per pixel */ 3749706f2543Smrg { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ 3750706f2543Smrg { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ 3751706f2543Smrg { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ 3752706f2543Smrg}; 3753706f2543Smrg 3754706f2543Smrg/* 3755706f2543Smrg * This array gives the answer to the question "what is the first index for 3756706f2543Smrg * the answer array above given the number of bits per pixel?" 3757706f2543Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 3758706f2543Smrg */ 3759706f2543Smrgstatic int indexForBitsPerPixel[ 33 ] = { 3760706f2543Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 3761706f2543Smrg 1, ~0, ~0, ~0, /* 4 bits per pixel */ 3762706f2543Smrg 2, ~0, ~0, ~0, /* 8 bits per pixel */ 3763706f2543Smrg ~0,~0, ~0, ~0, 3764706f2543Smrg 3, ~0, ~0, ~0, /* 16 bits per pixel */ 3765706f2543Smrg ~0,~0, ~0, ~0, 3766706f2543Smrg 4, ~0, ~0, ~0, /* 24 bits per pixel */ 3767706f2543Smrg ~0,~0, ~0, ~0, 3768706f2543Smrg 5 /* 32 bits per pixel */ 3769706f2543Smrg}; 3770706f2543Smrg 3771706f2543Smrg/* 3772706f2543Smrg * This array gives the bytesperPixel value for cases where the number 3773706f2543Smrg * of bits per pixel is a multiple of 8 but not a power of 2. 3774706f2543Smrg */ 3775706f2543Smrgstatic int answerBytesPerPixel[ 33 ] = { 3776706f2543Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 3777706f2543Smrg 0, ~0, ~0, ~0, /* 4 bits per pixel */ 3778706f2543Smrg 0, ~0, ~0, ~0, /* 8 bits per pixel */ 3779706f2543Smrg ~0,~0, ~0, ~0, 3780706f2543Smrg 0, ~0, ~0, ~0, /* 16 bits per pixel */ 3781706f2543Smrg ~0,~0, ~0, ~0, 3782706f2543Smrg 3, ~0, ~0, ~0, /* 24 bits per pixel */ 3783706f2543Smrg ~0,~0, ~0, ~0, 3784706f2543Smrg 0 /* 32 bits per pixel */ 3785706f2543Smrg}; 3786706f2543Smrg 3787706f2543Smrg/* 3788706f2543Smrg * This array gives the answer to the question "what is the second index for 3789706f2543Smrg * the answer array above given the number of bits per scanline pad unit?" 3790706f2543Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 3791706f2543Smrg */ 3792706f2543Smrgstatic int indexForScanlinePad[ 65 ] = { 3793706f2543Smrg ~0, ~0, ~0, ~0, 3794706f2543Smrg ~0, ~0, ~0, ~0, 3795706f2543Smrg 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ 3796706f2543Smrg ~0, ~0, ~0, ~0, 3797706f2543Smrg 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ 3798706f2543Smrg ~0, ~0, ~0, ~0, 3799706f2543Smrg ~0, ~0, ~0, ~0, 3800706f2543Smrg ~0, ~0, ~0, ~0, 3801706f2543Smrg 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ 3802706f2543Smrg ~0, ~0, ~0, ~0, 3803706f2543Smrg ~0, ~0, ~0, ~0, 3804706f2543Smrg ~0, ~0, ~0, ~0, 3805706f2543Smrg ~0, ~0, ~0, ~0, 3806706f2543Smrg ~0, ~0, ~0, ~0, 3807706f2543Smrg ~0, ~0, ~0, ~0, 3808706f2543Smrg ~0, ~0, ~0, ~0, 3809706f2543Smrg 3 /* 64 bits per scanline pad unit */ 3810706f2543Smrg}; 3811706f2543Smrg 3812706f2543Smrg/* 3813706f2543Smrg grow the array of screenRecs if necessary. 3814706f2543Smrg call the device-supplied initialization procedure 3815706f2543Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv. 3816706f2543Smrg return the number of successfully installed screens. 3817706f2543Smrg 3818706f2543Smrg*/ 3819706f2543Smrg 3820706f2543Smrgint 3821706f2543SmrgAddScreen( 3822706f2543Smrg Bool (* pfnInit)( 3823706f2543Smrg int /*index*/, 3824706f2543Smrg ScreenPtr /*pScreen*/, 3825706f2543Smrg int /*argc*/, 3826706f2543Smrg char ** /*argv*/ 3827706f2543Smrg ), 3828706f2543Smrg int argc, 3829706f2543Smrg char **argv) 3830706f2543Smrg{ 3831706f2543Smrg 3832706f2543Smrg int i; 3833706f2543Smrg int scanlinepad, format, depth, bitsPerPixel, j, k; 3834706f2543Smrg ScreenPtr pScreen; 3835706f2543Smrg 3836706f2543Smrg i = screenInfo.numScreens; 3837706f2543Smrg if (i == MAXSCREENS) 3838706f2543Smrg return -1; 3839706f2543Smrg 3840706f2543Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 3841706f2543Smrg if (!pScreen) 3842706f2543Smrg return -1; 3843706f2543Smrg 3844706f2543Smrg if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { 3845706f2543Smrg free (pScreen); 3846706f2543Smrg return -1; 3847706f2543Smrg } 3848706f2543Smrg pScreen->myNum = i; 3849706f2543Smrg pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ 3850706f2543Smrg pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ 3851706f2543Smrg pScreen->CreateScreenResources = 0; 3852706f2543Smrg 3853706f2543Smrg /* 3854706f2543Smrg * This loop gets run once for every Screen that gets added, 3855706f2543Smrg * but thats ok. If the ddx layer initializes the formats 3856706f2543Smrg * one at a time calling AddScreen() after each, then each 3857706f2543Smrg * iteration will make it a little more accurate. Worst case 3858706f2543Smrg * we do this loop N * numPixmapFormats where N is # of screens. 3859706f2543Smrg * Anyway, this must be called after InitOutput and before the 3860706f2543Smrg * screen init routine is called. 3861706f2543Smrg */ 3862706f2543Smrg for (format=0; format<screenInfo.numPixmapFormats; format++) 3863706f2543Smrg { 3864706f2543Smrg depth = screenInfo.formats[format].depth; 3865706f2543Smrg bitsPerPixel = screenInfo.formats[format].bitsPerPixel; 3866706f2543Smrg scanlinepad = screenInfo.formats[format].scanlinePad; 3867706f2543Smrg j = indexForBitsPerPixel[ bitsPerPixel ]; 3868706f2543Smrg k = indexForScanlinePad[ scanlinepad ]; 3869706f2543Smrg PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k]; 3870706f2543Smrg PixmapWidthPaddingInfo[ depth ].padRoundUp = 3871706f2543Smrg (scanlinepad/bitsPerPixel) - 1; 3872706f2543Smrg j = indexForBitsPerPixel[ 8 ]; /* bits per byte */ 3873706f2543Smrg PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k]; 3874706f2543Smrg PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel; 3875706f2543Smrg if (answerBytesPerPixel[bitsPerPixel]) 3876706f2543Smrg { 3877706f2543Smrg PixmapWidthPaddingInfo[ depth ].notPower2 = 1; 3878706f2543Smrg PixmapWidthPaddingInfo[ depth ].bytesPerPixel = 3879706f2543Smrg answerBytesPerPixel[bitsPerPixel]; 3880706f2543Smrg } 3881706f2543Smrg else 3882706f2543Smrg { 3883706f2543Smrg PixmapWidthPaddingInfo[ depth ].notPower2 = 0; 3884706f2543Smrg } 3885706f2543Smrg } 3886706f2543Smrg 3887706f2543Smrg /* This is where screen specific stuff gets initialized. Load the 3888706f2543Smrg screen structure, call the hardware, whatever. 3889706f2543Smrg This is also where the default colormap should be allocated and 3890706f2543Smrg also pixel values for blackPixel, whitePixel, and the cursor 3891706f2543Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 3892706f2543Smrg any of the strings pointed to by argv. They may be passed to 3893706f2543Smrg multiple screens. 3894706f2543Smrg */ 3895706f2543Smrg screenInfo.screens[i] = pScreen; 3896706f2543Smrg screenInfo.numScreens++; 3897706f2543Smrg if (!(*pfnInit)(i, pScreen, argc, argv)) 3898706f2543Smrg { 3899706f2543Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 3900706f2543Smrg free(pScreen); 3901706f2543Smrg screenInfo.numScreens--; 3902706f2543Smrg return -1; 3903706f2543Smrg } 3904706f2543Smrg 3905706f2543Smrg dixRegisterPrivateKey(&cursorScreenDevPriv[i], PRIVATE_CURSOR, 0); 3906706f2543Smrg 3907706f2543Smrg return i; 3908706f2543Smrg} 3909