105b261ecSmrg/************************************************************ 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1989, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrgCopyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 29f7df2e56SmrgPermission to use, copy, modify, and distribute this software and its 30f7df2e56Smrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 32f7df2e56Smrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Digital not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 35f7df2e56Smrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg********************************************************/ 4605b261ecSmrg 4705b261ecSmrg/* The panoramix components contained the following notice */ 4805b261ecSmrg/***************************************************************** 4905b261ecSmrg 5005b261ecSmrgCopyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 5105b261ecSmrg 5205b261ecSmrgPermission is hereby granted, free of charge, to any person obtaining a copy 5305b261ecSmrgof this software and associated documentation files (the "Software"), to deal 5405b261ecSmrgin the Software without restriction, including without limitation the rights 5505b261ecSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5605b261ecSmrgcopies of the Software. 5705b261ecSmrg 5805b261ecSmrgThe above copyright notice and this permission notice shall be included in 5905b261ecSmrgall copies or substantial portions of the Software. 6005b261ecSmrg 6105b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6205b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6305b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 6405b261ecSmrgDIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 6505b261ecSmrgBUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 6605b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 6705b261ecSmrgIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6805b261ecSmrg 6905b261ecSmrgExcept as contained in this notice, the name of Digital Equipment Corporation 7005b261ecSmrgshall not be used in advertising or otherwise to promote the sale, use or other 7105b261ecSmrgdealings in this Software without prior written authorization from Digital 7205b261ecSmrgEquipment Corporation. 7305b261ecSmrg 7405b261ecSmrg******************************************************************/ 7505b261ecSmrg 7605b261ecSmrg/* XSERVER_DTRACE additions: 779ace9065Smrg * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved. 7805b261ecSmrg * 7905b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 806747b715Smrg * copy of this software and associated documentation files (the "Software"), 816747b715Smrg * to deal in the Software without restriction, including without limitation 826747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 836747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 846747b715Smrg * Software is furnished to do so, subject to the following conditions: 856747b715Smrg * 866747b715Smrg * The above copyright notice and this permission notice (including the next 876747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 886747b715Smrg * Software. 896747b715Smrg * 906747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 916747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 926747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 936747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 946747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 956747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 966747b715Smrg * DEALINGS IN THE SOFTWARE. 9705b261ecSmrg */ 9805b261ecSmrg 9905b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 10005b261ecSmrg#include <dix-config.h> 1016747b715Smrg#include <version-config.h> 10205b261ecSmrg#endif 10305b261ecSmrg 10405b261ecSmrg#ifdef PANORAMIX_DEBUG 10505b261ecSmrg#include <stdio.h> 10605b261ecSmrgint ProcInitialConnection(); 10705b261ecSmrg#endif 10805b261ecSmrg 10905b261ecSmrg#include "windowstr.h" 11005b261ecSmrg#include <X11/fonts/fontstruct.h> 1117e31ba66Smrg#include <X11/fonts/libxfont2.h> 11205b261ecSmrg#include "dixfontstr.h" 11305b261ecSmrg#include "gcstruct.h" 11405b261ecSmrg#include "selection.h" 11505b261ecSmrg#include "colormapst.h" 11605b261ecSmrg#include "cursorstr.h" 11705b261ecSmrg#include "scrnintstr.h" 11805b261ecSmrg#include "opaque.h" 11905b261ecSmrg#include "input.h" 12005b261ecSmrg#include "servermd.h" 12105b261ecSmrg#include "extnsionst.h" 12205b261ecSmrg#include "dixfont.h" 12305b261ecSmrg#include "dispatch.h" 12405b261ecSmrg#include "swaprep.h" 12505b261ecSmrg#include "swapreq.h" 1264642e01fSmrg#include "privates.h" 12705b261ecSmrg#include "xace.h" 12805b261ecSmrg#include "inputstr.h" 1296747b715Smrg#include "xkbsrv.h" 130f7df2e56Smrg#include "client.h" 1315a112b11Smrg#include "xfixesint.h" 13205b261ecSmrg 13305b261ecSmrg#ifdef XSERVER_DTRACE 1344642e01fSmrg#include "registry.h" 135f7df2e56Smrg#include "probes.h" 13605b261ecSmrg#endif 13705b261ecSmrg 13805b261ecSmrg#define mskcnt ((MAXCLIENTS + 31) / 32) 13905b261ecSmrg#define BITMASK(i) (1U << ((i) & 31)) 14005b261ecSmrg#define MASKIDX(i) ((i) >> 5) 14105b261ecSmrg#define MASKWORD(buf, i) buf[MASKIDX(i)] 14205b261ecSmrg#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) 14305b261ecSmrg#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) 14405b261ecSmrg#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) 14505b261ecSmrg 1466747b715SmrgxConnSetupPrefix connSetupPrefix; 1476747b715Smrg 1486747b715SmrgPaddingInfo PixmapWidthPaddingInfo[33]; 14905b261ecSmrg 15005b261ecSmrgstatic ClientPtr grabClient; 1515a112b11Smrgstatic ClientPtr currentClient; /* Client for the request currently being dispatched */ 152f7df2e56Smrg 15305b261ecSmrg#define GrabNone 0 15405b261ecSmrg#define GrabActive 1 15505b261ecSmrgstatic int grabState = GrabNone; 15605b261ecSmrgstatic long grabWaiters[mskcnt]; 1576747b715SmrgCallbackListPtr ServerGrabCallback = NULL; 15805b261ecSmrgHWEventQueuePtr checkForInput[2]; 1596747b715Smrgint connBlockScreenStart; 16005b261ecSmrg 16105b261ecSmrgstatic void KillAllClients(void); 16205b261ecSmrg 163f7df2e56Smrgstatic int nextFreeClientID; /* always MIN free client ID */ 16405b261ecSmrg 165f7df2e56Smrgstatic int nClients; /* number of authorized clients */ 16605b261ecSmrg 1676747b715SmrgCallbackListPtr ClientStateCallback; 1685a112b11SmrgOsTimerPtr dispatchExceptionTimer; 16905b261ecSmrg 17005b261ecSmrg/* dispatchException & isItTimeToYield must be declared volatile since they 17105b261ecSmrg * are modified by signal handlers - otherwise optimizer may assume it doesn't 17205b261ecSmrg * need to actually check value in memory when used and may miss changes from 17305b261ecSmrg * signal handlers. 17405b261ecSmrg */ 1756747b715Smrgvolatile char dispatchException = 0; 1766747b715Smrgvolatile char isItTimeToYield; 17705b261ecSmrg 17805b261ecSmrg#define SAME_SCREENS(a, b) (\ 17905b261ecSmrg (a.pScreen == b.pScreen)) 18005b261ecSmrg 1815a112b11SmrgClientPtr 1825a112b11SmrgGetCurrentClient(void) 1835a112b11Smrg{ 1845a112b11Smrg if (in_input_thread()) { 1855a112b11Smrg static Bool warned; 1865a112b11Smrg 1875a112b11Smrg if (!warned) { 1885a112b11Smrg ErrorF("[dix] Error GetCurrentClient called from input-thread\n"); 1895a112b11Smrg warned = TRUE; 1905a112b11Smrg } 1915a112b11Smrg 1925a112b11Smrg return NULL; 1935a112b11Smrg } 1945a112b11Smrg 1955a112b11Smrg return currentClient; 1965a112b11Smrg} 1975a112b11Smrg 1984642e01fSmrgvoid 19905b261ecSmrgSetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) 20005b261ecSmrg{ 20105b261ecSmrg checkForInput[0] = c0; 20205b261ecSmrg checkForInput[1] = c1; 20305b261ecSmrg} 20405b261ecSmrg 2056747b715Smrgvoid 20605b261ecSmrgUpdateCurrentTime(void) 20705b261ecSmrg{ 20805b261ecSmrg TimeStamp systime; 20905b261ecSmrg 21005b261ecSmrg /* To avoid time running backwards, we must call GetTimeInMillis before 21105b261ecSmrg * calling ProcessInputEvents. 21205b261ecSmrg */ 21305b261ecSmrg systime.months = currentTime.months; 21405b261ecSmrg systime.milliseconds = GetTimeInMillis(); 21505b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 216f7df2e56Smrg systime.months++; 2177e31ba66Smrg if (InputCheckPending()) 218f7df2e56Smrg ProcessInputEvents(); 21905b261ecSmrg if (CompareTimeStamps(systime, currentTime) == LATER) 220f7df2e56Smrg currentTime = systime; 22105b261ecSmrg} 22205b261ecSmrg 22305b261ecSmrg/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ 2246747b715Smrgvoid 22505b261ecSmrgUpdateCurrentTimeIf(void) 22605b261ecSmrg{ 22705b261ecSmrg TimeStamp systime; 22805b261ecSmrg 22905b261ecSmrg systime.months = currentTime.months; 23005b261ecSmrg systime.milliseconds = GetTimeInMillis(); 23105b261ecSmrg if (systime.milliseconds < currentTime.milliseconds) 232f7df2e56Smrg systime.months++; 233f7df2e56Smrg if (CompareTimeStamps(systime, currentTime) == LATER) 234f7df2e56Smrg currentTime = systime; 23505b261ecSmrg} 23605b261ecSmrg 23705b261ecSmrg#undef SMART_DEBUG 23805b261ecSmrg 239f7df2e56Smrg/* in milliseconds */ 240f7df2e56Smrg#define SMART_SCHEDULE_DEFAULT_INTERVAL 5 241f7df2e56Smrg#define SMART_SCHEDULE_MAX_SLICE 15 24205b261ecSmrg 2437e31ba66Smrg#ifdef HAVE_SETITIMER 2447e31ba66SmrgBool SmartScheduleSignalEnable = TRUE; 245f7df2e56Smrg#endif 2467e31ba66Smrg 2476747b715Smrglong SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; 2486747b715Smrglong SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; 2496747b715Smrglong SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; 2506747b715Smrglong SmartScheduleTime; 2516747b715Smrgint SmartScheduleLatencyLimited = 0; 252f7df2e56Smrgstatic ClientPtr SmartLastClient; 253f7df2e56Smrgstatic int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1]; 25405b261ecSmrg 25505b261ecSmrg#ifdef SMART_DEBUG 256f7df2e56Smrglong SmartLastPrint; 25705b261ecSmrg#endif 25805b261ecSmrg 259f7df2e56Smrgvoid Dispatch(void); 26005b261ecSmrg 2617e31ba66Smrgstatic struct xorg_list ready_clients; 2627e31ba66Smrgstatic struct xorg_list saved_ready_clients; 2637e31ba66Smrgstruct xorg_list output_pending_clients; 2647e31ba66Smrg 2657e31ba66Smrgstatic void 2667e31ba66Smrginit_client_ready(void) 26705b261ecSmrg{ 2687e31ba66Smrg xorg_list_init(&ready_clients); 2697e31ba66Smrg xorg_list_init(&saved_ready_clients); 2707e31ba66Smrg xorg_list_init(&output_pending_clients); 2717e31ba66Smrg} 2727e31ba66Smrg 2737e31ba66SmrgBool 2747e31ba66Smrgclients_are_ready(void) 2757e31ba66Smrg{ 2767e31ba66Smrg return !xorg_list_is_empty(&ready_clients); 2777e31ba66Smrg} 2787e31ba66Smrg 2797e31ba66Smrg/* Client has requests queued or data on the network */ 2807e31ba66Smrgvoid 2817e31ba66Smrgmark_client_ready(ClientPtr client) 2827e31ba66Smrg{ 2837e31ba66Smrg if (xorg_list_is_empty(&client->ready)) 2847e31ba66Smrg xorg_list_append(&client->ready, &ready_clients); 2857e31ba66Smrg} 2867e31ba66Smrg 2877e31ba66Smrg/* 2887e31ba66Smrg * Client has requests queued or data on the network, but awaits a 2897e31ba66Smrg * server grab release 2907e31ba66Smrg */ 2917e31ba66Smrgvoid mark_client_saved_ready(ClientPtr client) 2927e31ba66Smrg{ 2937e31ba66Smrg if (xorg_list_is_empty(&client->ready)) 2947e31ba66Smrg xorg_list_append(&client->ready, &saved_ready_clients); 2957e31ba66Smrg} 2967e31ba66Smrg 2977e31ba66Smrg/* Client has no requests queued and no data on network */ 2987e31ba66Smrgvoid 2997e31ba66Smrgmark_client_not_ready(ClientPtr client) 3007e31ba66Smrg{ 3017e31ba66Smrg xorg_list_del(&client->ready); 3027e31ba66Smrg} 3037e31ba66Smrg 3047e31ba66Smrgstatic void 3057e31ba66Smrgmark_client_grab(ClientPtr grab) 3067e31ba66Smrg{ 3077e31ba66Smrg ClientPtr client, tmp; 3087e31ba66Smrg 3097e31ba66Smrg xorg_list_for_each_entry_safe(client, tmp, &ready_clients, ready) { 3107e31ba66Smrg if (client != grab) { 3117e31ba66Smrg xorg_list_del(&client->ready); 3127e31ba66Smrg xorg_list_append(&client->ready, &saved_ready_clients); 3137e31ba66Smrg } 3147e31ba66Smrg } 3157e31ba66Smrg} 3167e31ba66Smrg 3177e31ba66Smrgstatic void 3187e31ba66Smrgmark_client_ungrab(void) 3197e31ba66Smrg{ 3207e31ba66Smrg ClientPtr client, tmp; 3217e31ba66Smrg 3227e31ba66Smrg xorg_list_for_each_entry_safe(client, tmp, &saved_ready_clients, ready) { 3237e31ba66Smrg xorg_list_del(&client->ready); 3247e31ba66Smrg xorg_list_append(&client->ready, &ready_clients); 3257e31ba66Smrg } 3267e31ba66Smrg} 3277e31ba66Smrg 3287e31ba66Smrgstatic ClientPtr 3297e31ba66SmrgSmartScheduleClient(void) 3307e31ba66Smrg{ 3317e31ba66Smrg ClientPtr pClient, best = NULL; 332f7df2e56Smrg int bestRobin, robin; 333f7df2e56Smrg long now = SmartScheduleTime; 334f7df2e56Smrg long idle; 3357e31ba66Smrg int nready = 0; 33605b261ecSmrg 33705b261ecSmrg bestRobin = 0; 33805b261ecSmrg idle = 2 * SmartScheduleSlice; 3397e31ba66Smrg 3407e31ba66Smrg xorg_list_for_each_entry(pClient, &ready_clients, ready) { 3417e31ba66Smrg nready++; 3427e31ba66Smrg 343f7df2e56Smrg /* Praise clients which haven't run in a while */ 344f7df2e56Smrg if ((now - pClient->smart_stop_tick) >= idle) { 345f7df2e56Smrg if (pClient->smart_priority < 0) 346f7df2e56Smrg pClient->smart_priority++; 347f7df2e56Smrg } 348f7df2e56Smrg 349f7df2e56Smrg /* check priority to select best client */ 350f7df2e56Smrg robin = 351f7df2e56Smrg (pClient->index - 352f7df2e56Smrg SmartLastIndex[pClient->smart_priority - 353f7df2e56Smrg SMART_MIN_PRIORITY]) & 0xff; 3547e31ba66Smrg 3557e31ba66Smrg /* pick the best client */ 3567e31ba66Smrg if (!best || 3577e31ba66Smrg pClient->priority > best->priority || 3587e31ba66Smrg (pClient->priority == best->priority && 3597e31ba66Smrg (pClient->smart_priority > best->smart_priority || 3607e31ba66Smrg (pClient->smart_priority == best->smart_priority && robin > bestRobin)))) 3617e31ba66Smrg { 3627e31ba66Smrg best = pClient; 363f7df2e56Smrg bestRobin = robin; 364f7df2e56Smrg } 36505b261ecSmrg#ifdef SMART_DEBUG 366f7df2e56Smrg if ((now - SmartLastPrint) >= 5000) 3677e31ba66Smrg fprintf(stderr, " %2d: %3d", pClient->index, pClient->smart_priority); 36805b261ecSmrg#endif 36905b261ecSmrg } 37005b261ecSmrg#ifdef SMART_DEBUG 371f7df2e56Smrg if ((now - SmartLastPrint) >= 5000) { 3727e31ba66Smrg fprintf(stderr, " use %2d\n", best->index); 373f7df2e56Smrg SmartLastPrint = now; 37405b261ecSmrg } 37505b261ecSmrg#endif 3767e31ba66Smrg SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index; 37705b261ecSmrg /* 37805b261ecSmrg * Set current client pointer 37905b261ecSmrg */ 3807e31ba66Smrg if (SmartLastClient != best) { 3817e31ba66Smrg best->smart_start_tick = now; 3827e31ba66Smrg SmartLastClient = best; 38305b261ecSmrg } 38405b261ecSmrg /* 38505b261ecSmrg * Adjust slice 38605b261ecSmrg */ 387f7df2e56Smrg if (nready == 1 && SmartScheduleLatencyLimited == 0) { 388f7df2e56Smrg /* 389f7df2e56Smrg * If it's been a long time since another client 390f7df2e56Smrg * has run, bump the slice up to get maximal 391f7df2e56Smrg * performance from a single client 392f7df2e56Smrg */ 3937e31ba66Smrg if ((now - best->smart_start_tick) > 1000 && 394f7df2e56Smrg SmartScheduleSlice < SmartScheduleMaxSlice) { 395f7df2e56Smrg SmartScheduleSlice += SmartScheduleInterval; 396f7df2e56Smrg } 39705b261ecSmrg } 398f7df2e56Smrg else { 399f7df2e56Smrg SmartScheduleSlice = SmartScheduleInterval; 40005b261ecSmrg } 40105b261ecSmrg return best; 40205b261ecSmrg} 40305b261ecSmrg 4045a112b11Smrgstatic CARD32 4055a112b11SmrgDispatchExceptionCallback(OsTimerPtr timer, CARD32 time, void *arg) 4065a112b11Smrg{ 4075a112b11Smrg dispatchException |= dispatchExceptionAtReset; 4085a112b11Smrg 4095a112b11Smrg /* Don't re-arm the timer */ 4105a112b11Smrg return 0; 4115a112b11Smrg} 4125a112b11Smrg 4135a112b11Smrgstatic void 4145a112b11SmrgCancelDispatchExceptionTimer(void) 4155a112b11Smrg{ 4165a112b11Smrg TimerFree(dispatchExceptionTimer); 4175a112b11Smrg dispatchExceptionTimer = NULL; 4185a112b11Smrg} 4195a112b11Smrg 4205a112b11Smrgstatic void 4215a112b11SmrgSetDispatchExceptionTimer(void) 4225a112b11Smrg{ 4235a112b11Smrg /* The timer delay is only for terminate, not reset */ 4245a112b11Smrg if (!(dispatchExceptionAtReset & DE_TERMINATE)) { 4255a112b11Smrg dispatchException |= dispatchExceptionAtReset; 4265a112b11Smrg return; 4275a112b11Smrg } 4285a112b11Smrg 4295a112b11Smrg CancelDispatchExceptionTimer(); 4305a112b11Smrg 4315a112b11Smrg if (terminateDelay == 0) 4325a112b11Smrg dispatchException |= dispatchExceptionAtReset; 4335a112b11Smrg else 4345a112b11Smrg dispatchExceptionTimer = TimerSet(dispatchExceptionTimer, 4355a112b11Smrg 0, terminateDelay * 1000 /* msec */, 4365a112b11Smrg &DispatchExceptionCallback, 4375a112b11Smrg NULL); 4385a112b11Smrg} 4395a112b11Smrg 4405a112b11Smrgstatic Bool 4415a112b11SmrgShouldDisconnectRemainingClients(void) 4425a112b11Smrg{ 4435a112b11Smrg int i; 4445a112b11Smrg 4455a112b11Smrg for (i = 1; i < currentMaxClients; i++) { 4465a112b11Smrg if (clients[i]) { 4475a112b11Smrg if (!XFixesShouldDisconnectClient(clients[i])) 4485a112b11Smrg return FALSE; 4495a112b11Smrg } 4505a112b11Smrg } 4515a112b11Smrg 4525a112b11Smrg /* All remaining clients can be safely ignored */ 4535a112b11Smrg return TRUE; 4545a112b11Smrg} 4555a112b11Smrg 456b1d344b3Smrgvoid 457b1d344b3SmrgEnableLimitedSchedulingLatency(void) 458b1d344b3Smrg{ 459b1d344b3Smrg ++SmartScheduleLatencyLimited; 460b1d344b3Smrg SmartScheduleSlice = SmartScheduleInterval; 461b1d344b3Smrg} 462b1d344b3Smrg 463b1d344b3Smrgvoid 464b1d344b3SmrgDisableLimitedSchedulingLatency(void) 465b1d344b3Smrg{ 466b1d344b3Smrg --SmartScheduleLatencyLimited; 467b1d344b3Smrg 468b1d344b3Smrg /* protect against bugs */ 469b1d344b3Smrg if (SmartScheduleLatencyLimited < 0) 470f7df2e56Smrg SmartScheduleLatencyLimited = 0; 471b1d344b3Smrg} 472b1d344b3Smrg 47305b261ecSmrgvoid 47405b261ecSmrgDispatch(void) 47505b261ecSmrg{ 476f7df2e56Smrg int result; 477f7df2e56Smrg ClientPtr client; 478f7df2e56Smrg long start_tick; 47905b261ecSmrg 48005b261ecSmrg nextFreeClientID = 1; 48105b261ecSmrg nClients = 0; 48205b261ecSmrg 483b1d344b3Smrg SmartScheduleSlice = SmartScheduleInterval; 4847e31ba66Smrg init_client_ready(); 4857e31ba66Smrg 486f7df2e56Smrg while (!dispatchException) { 4877e31ba66Smrg if (InputCheckPending()) { 488f7df2e56Smrg ProcessInputEvents(); 489f7df2e56Smrg FlushIfCriticalOutputPending(); 490f7df2e56Smrg } 491f7df2e56Smrg 4927e31ba66Smrg if (!WaitForSomething(clients_are_ready())) 4937e31ba66Smrg continue; 494f7df2e56Smrg 495f7df2e56Smrg /***************** 496f7df2e56Smrg * Handle events in round robin fashion, doing input between 497f7df2e56Smrg * each round 49805b261ecSmrg *****************/ 49905b261ecSmrg 5007e31ba66Smrg if (!dispatchException && clients_are_ready()) { 5017e31ba66Smrg client = SmartScheduleClient(); 5027e31ba66Smrg 503f7df2e56Smrg isItTimeToYield = FALSE; 504f7df2e56Smrg 505f7df2e56Smrg start_tick = SmartScheduleTime; 506f7df2e56Smrg while (!isItTimeToYield) { 5077e31ba66Smrg if (InputCheckPending()) 508f7df2e56Smrg ProcessInputEvents(); 509f7df2e56Smrg 510f7df2e56Smrg FlushIfCriticalOutputPending(); 5117e31ba66Smrg if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice) 5127e31ba66Smrg { 513f7df2e56Smrg /* Penalize clients which consume ticks */ 514f7df2e56Smrg if (client->smart_priority > SMART_MIN_PRIORITY) 515f7df2e56Smrg client->smart_priority--; 516f7df2e56Smrg break; 517f7df2e56Smrg } 518f7df2e56Smrg 5197e31ba66Smrg /* now, finally, deal with client requests */ 520f7df2e56Smrg result = ReadRequestFromClient(client); 5212f76b07dSmrg if (result == 0) 5222f76b07dSmrg break; 5232f76b07dSmrg else if (result == -1) { 5242f76b07dSmrg CloseDownClient(client); 525f7df2e56Smrg break; 526f7df2e56Smrg } 527f7df2e56Smrg 528f7df2e56Smrg client->sequence++; 529f7df2e56Smrg client->majorOp = ((xReq *) client->requestBuffer)->reqType; 530f7df2e56Smrg client->minorOp = 0; 531f7df2e56Smrg if (client->majorOp >= EXTENSION_BASE) { 532f7df2e56Smrg ExtensionEntry *ext = GetExtensionEntry(client->majorOp); 533f7df2e56Smrg 534f7df2e56Smrg if (ext) 535f7df2e56Smrg client->minorOp = ext->MinorOpcode(client); 536f7df2e56Smrg } 53705b261ecSmrg#ifdef XSERVER_DTRACE 538f7df2e56Smrg if (XSERVER_REQUEST_START_ENABLED()) 539f7df2e56Smrg XSERVER_REQUEST_START(LookupMajorName(client->majorOp), 540f7df2e56Smrg client->majorOp, 541f7df2e56Smrg ((xReq *) client->requestBuffer)->length, 542f7df2e56Smrg client->index, 543f7df2e56Smrg client->requestBuffer); 54405b261ecSmrg#endif 5452f76b07dSmrg if (result < 0 || result > (maxBigRequestSize << 2)) 546f7df2e56Smrg result = BadLength; 547f7df2e56Smrg else { 548f7df2e56Smrg result = XaceHookDispatch(client, client->majorOp); 5495a112b11Smrg if (result == Success) { 5505a112b11Smrg currentClient = client; 551f7df2e56Smrg result = 552f7df2e56Smrg (*client->requestVector[client->majorOp]) (client); 5535a112b11Smrg currentClient = NULL; 5545a112b11Smrg } 555f7df2e56Smrg } 5567e31ba66Smrg if (!SmartScheduleSignalEnable) 5577e31ba66Smrg SmartScheduleTime = GetTimeInMillis(); 5587e31ba66Smrg 55905b261ecSmrg#ifdef XSERVER_DTRACE 560f7df2e56Smrg if (XSERVER_REQUEST_DONE_ENABLED()) 561f7df2e56Smrg XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), 562f7df2e56Smrg client->majorOp, client->sequence, 563f7df2e56Smrg client->index, result); 56405b261ecSmrg#endif 56505b261ecSmrg 566f7df2e56Smrg if (client->noClientException != Success) { 567f7df2e56Smrg CloseDownClient(client); 568f7df2e56Smrg break; 569f7df2e56Smrg } 570f7df2e56Smrg else if (result != Success) { 571f7df2e56Smrg SendErrorToClient(client, client->majorOp, 572f7df2e56Smrg client->minorOp, 573f7df2e56Smrg client->errorValue, result); 574f7df2e56Smrg break; 575f7df2e56Smrg } 576f7df2e56Smrg } 577f7df2e56Smrg FlushAllOutput(); 5787e31ba66Smrg if (client == SmartLastClient) 579f7df2e56Smrg client->smart_stop_tick = SmartScheduleTime; 580f7df2e56Smrg } 581f7df2e56Smrg dispatchException &= ~DE_PRIORITYCHANGE; 58205b261ecSmrg } 58305b261ecSmrg#if defined(DDXBEFORERESET) 584f7df2e56Smrg ddxBeforeReset(); 58505b261ecSmrg#endif 58605b261ecSmrg KillAllClients(); 58705b261ecSmrg dispatchException &= ~DE_RESET; 588b1d344b3Smrg SmartScheduleLatencyLimited = 0; 589f7df2e56Smrg ResetOsBuffers(); 59005b261ecSmrg} 59105b261ecSmrg 592f7df2e56Smrgstatic int VendorRelease = VENDOR_RELEASE; 5936747b715Smrg 5946747b715Smrgvoid 5956747b715SmrgSetVendorRelease(int release) 5966747b715Smrg{ 5976747b715Smrg VendorRelease = release; 5986747b715Smrg} 5996747b715Smrg 6006747b715SmrgBool 6016747b715SmrgCreateConnectionBlock(void) 6026747b715Smrg{ 6036747b715Smrg xConnSetup setup; 6046747b715Smrg xWindowRoot root; 605f7df2e56Smrg xDepth depth; 6066747b715Smrg xVisualType visual; 6076747b715Smrg xPixmapFormat format; 6086747b715Smrg unsigned long vid; 609f7df2e56Smrg int i, j, k, lenofblock, sizesofar = 0; 6106747b715Smrg char *pBuf; 6115a112b11Smrg const char VendorString[] = VENDOR_NAME; 6126747b715Smrg 6136747b715Smrg memset(&setup, 0, sizeof(xConnSetup)); 6146747b715Smrg /* Leave off the ridBase and ridMask, these must be sent with 6156747b715Smrg connection */ 6166747b715Smrg 6176747b715Smrg setup.release = VendorRelease; 6186747b715Smrg /* 6196747b715Smrg * per-server image and bitmap parameters are defined in Xmd.h 6206747b715Smrg */ 6216747b715Smrg setup.imageByteOrder = screenInfo.imageByteOrder; 6226747b715Smrg 6236747b715Smrg setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; 6246747b715Smrg setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; 6256747b715Smrg 6266747b715Smrg setup.bitmapBitOrder = screenInfo.bitmapBitOrder; 6276747b715Smrg setup.motionBufferSize = NumMotionEvents(); 6286747b715Smrg setup.numRoots = screenInfo.numScreens; 6296747b715Smrg setup.nbytesVendor = strlen(VendorString); 6306747b715Smrg setup.numFormats = screenInfo.numPixmapFormats; 6316747b715Smrg setup.maxRequestSize = MAX_REQUEST_SIZE; 6326747b715Smrg QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); 6336747b715Smrg 6346747b715Smrg lenofblock = sizeof(xConnSetup) + 635f7df2e56Smrg pad_to_int32(setup.nbytesVendor) + 636f7df2e56Smrg (setup.numFormats * sizeof(xPixmapFormat)) + 637f7df2e56Smrg (setup.numRoots * sizeof(xWindowRoot)); 6386747b715Smrg ConnectionInfo = malloc(lenofblock); 6396747b715Smrg if (!ConnectionInfo) 640f7df2e56Smrg return FALSE; 6416747b715Smrg 642f7df2e56Smrg memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup)); 6436747b715Smrg sizesofar = sizeof(xConnSetup); 6446747b715Smrg pBuf = ConnectionInfo + sizeof(xConnSetup); 6456747b715Smrg 646f7df2e56Smrg memmove(pBuf, VendorString, (int) setup.nbytesVendor); 6476747b715Smrg sizesofar += setup.nbytesVendor; 6486747b715Smrg pBuf += setup.nbytesVendor; 649f7df2e56Smrg i = padding_for_int32(setup.nbytesVendor); 6506747b715Smrg sizesofar += i; 6516747b715Smrg while (--i >= 0) 652f7df2e56Smrg *pBuf++ = 0; 6536747b715Smrg 6546747b715Smrg memset(&format, 0, sizeof(xPixmapFormat)); 655f7df2e56Smrg for (i = 0; i < screenInfo.numPixmapFormats; i++) { 656f7df2e56Smrg format.depth = screenInfo.formats[i].depth; 657f7df2e56Smrg format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; 658f7df2e56Smrg format.scanLinePad = screenInfo.formats[i].scanlinePad; 659f7df2e56Smrg memmove(pBuf, (char *) &format, sizeof(xPixmapFormat)); 660f7df2e56Smrg pBuf += sizeof(xPixmapFormat); 661f7df2e56Smrg sizesofar += sizeof(xPixmapFormat); 6626747b715Smrg } 6636747b715Smrg 6646747b715Smrg connBlockScreenStart = sizesofar; 6656747b715Smrg memset(&depth, 0, sizeof(xDepth)); 6666747b715Smrg memset(&visual, 0, sizeof(xVisualType)); 667f7df2e56Smrg for (i = 0; i < screenInfo.numScreens; i++) { 668f7df2e56Smrg ScreenPtr pScreen; 669f7df2e56Smrg DepthPtr pDepth; 670f7df2e56Smrg VisualPtr pVisual; 671f7df2e56Smrg 672f7df2e56Smrg pScreen = screenInfo.screens[i]; 673f7df2e56Smrg root.windowId = pScreen->root->drawable.id; 674f7df2e56Smrg root.defaultColormap = pScreen->defColormap; 675f7df2e56Smrg root.whitePixel = pScreen->whitePixel; 676f7df2e56Smrg root.blackPixel = pScreen->blackPixel; 677f7df2e56Smrg root.currentInputMask = 0; /* filled in when sent */ 678f7df2e56Smrg root.pixWidth = pScreen->width; 679f7df2e56Smrg root.pixHeight = pScreen->height; 680f7df2e56Smrg root.mmWidth = pScreen->mmWidth; 681f7df2e56Smrg root.mmHeight = pScreen->mmHeight; 682f7df2e56Smrg root.minInstalledMaps = pScreen->minInstalledCmaps; 683f7df2e56Smrg root.maxInstalledMaps = pScreen->maxInstalledCmaps; 684f7df2e56Smrg root.rootVisualID = pScreen->rootVisual; 685f7df2e56Smrg root.backingStore = pScreen->backingStoreSupport; 686f7df2e56Smrg root.saveUnders = FALSE; 687f7df2e56Smrg root.rootDepth = pScreen->rootDepth; 688f7df2e56Smrg root.nDepths = pScreen->numDepths; 689f7df2e56Smrg memmove(pBuf, (char *) &root, sizeof(xWindowRoot)); 690f7df2e56Smrg sizesofar += sizeof(xWindowRoot); 691f7df2e56Smrg pBuf += sizeof(xWindowRoot); 692f7df2e56Smrg 693f7df2e56Smrg pDepth = pScreen->allowedDepths; 694f7df2e56Smrg for (j = 0; j < pScreen->numDepths; j++, pDepth++) { 695f7df2e56Smrg lenofblock += sizeof(xDepth) + 696f7df2e56Smrg (pDepth->numVids * sizeof(xVisualType)); 697f7df2e56Smrg pBuf = (char *) realloc(ConnectionInfo, lenofblock); 698f7df2e56Smrg if (!pBuf) { 699f7df2e56Smrg free(ConnectionInfo); 700f7df2e56Smrg return FALSE; 701f7df2e56Smrg } 702f7df2e56Smrg ConnectionInfo = pBuf; 703f7df2e56Smrg pBuf += sizesofar; 704f7df2e56Smrg depth.depth = pDepth->depth; 705f7df2e56Smrg depth.nVisuals = pDepth->numVids; 706f7df2e56Smrg memmove(pBuf, (char *) &depth, sizeof(xDepth)); 707f7df2e56Smrg pBuf += sizeof(xDepth); 708f7df2e56Smrg sizesofar += sizeof(xDepth); 709f7df2e56Smrg for (k = 0; k < pDepth->numVids; k++) { 710f7df2e56Smrg vid = pDepth->vids[k]; 711f7df2e56Smrg for (pVisual = pScreen->visuals; 712f7df2e56Smrg pVisual->vid != vid; pVisual++); 713f7df2e56Smrg visual.visualID = vid; 714f7df2e56Smrg visual.class = pVisual->class; 715f7df2e56Smrg visual.bitsPerRGB = pVisual->bitsPerRGBValue; 716f7df2e56Smrg visual.colormapEntries = pVisual->ColormapEntries; 717f7df2e56Smrg visual.redMask = pVisual->redMask; 718f7df2e56Smrg visual.greenMask = pVisual->greenMask; 719f7df2e56Smrg visual.blueMask = pVisual->blueMask; 720f7df2e56Smrg memmove(pBuf, (char *) &visual, sizeof(xVisualType)); 721f7df2e56Smrg pBuf += sizeof(xVisualType); 722f7df2e56Smrg sizesofar += sizeof(xVisualType); 723f7df2e56Smrg } 724f7df2e56Smrg } 7256747b715Smrg } 7266747b715Smrg connSetupPrefix.success = xTrue; 727f7df2e56Smrg connSetupPrefix.length = lenofblock / 4; 7286747b715Smrg connSetupPrefix.majorVersion = X_PROTOCOL; 7296747b715Smrg connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; 7306747b715Smrg return TRUE; 7316747b715Smrg} 7326747b715Smrg 7336747b715Smrgint 73405b261ecSmrgProcBadRequest(ClientPtr client) 73505b261ecSmrg{ 7366747b715Smrg return BadRequest; 73705b261ecSmrg} 73805b261ecSmrg 73905b261ecSmrgint 74005b261ecSmrgProcCreateWindow(ClientPtr client) 74105b261ecSmrg{ 74205b261ecSmrg WindowPtr pParent, pWin; 743f7df2e56Smrg 74405b261ecSmrg REQUEST(xCreateWindowReq); 7454642e01fSmrg int len, rc; 74605b261ecSmrg 74705b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateWindowReq); 748f7df2e56Smrg 74905b261ecSmrg LEGAL_NEW_RESOURCE(stuff->wid, client); 7504642e01fSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 75105b261ecSmrg if (rc != Success) 75205b261ecSmrg return rc; 7536747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); 75405b261ecSmrg if (Ones(stuff->mask) != len) 75505b261ecSmrg return BadLength; 756f7df2e56Smrg if (!stuff->width || !stuff->height) { 757f7df2e56Smrg client->errorValue = 0; 75805b261ecSmrg return BadValue; 75905b261ecSmrg } 76005b261ecSmrg pWin = CreateWindow(stuff->wid, pParent, stuff->x, 761f7df2e56Smrg stuff->y, stuff->width, stuff->height, 762f7df2e56Smrg stuff->borderWidth, stuff->class, 763f7df2e56Smrg stuff->mask, (XID *) &stuff[1], 764f7df2e56Smrg (int) stuff->depth, client, stuff->visual, &rc); 765f7df2e56Smrg if (pWin) { 766f7df2e56Smrg Mask mask = pWin->eventMask; 767f7df2e56Smrg 768f7df2e56Smrg pWin->eventMask = 0; /* subterfuge in case AddResource fails */ 769f7df2e56Smrg if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin)) 770f7df2e56Smrg return BadAlloc; 771f7df2e56Smrg pWin->eventMask = mask; 77205b261ecSmrg } 7736747b715Smrg return rc; 77405b261ecSmrg} 77505b261ecSmrg 77605b261ecSmrgint 77705b261ecSmrgProcChangeWindowAttributes(ClientPtr client) 77805b261ecSmrg{ 77905b261ecSmrg WindowPtr pWin; 780f7df2e56Smrg 78105b261ecSmrg REQUEST(xChangeWindowAttributesReq); 7826747b715Smrg int len, rc; 7834642e01fSmrg Mask access_mode = 0; 78405b261ecSmrg 78505b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); 7864642e01fSmrg access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; 7874642e01fSmrg access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; 7884642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); 78905b261ecSmrg if (rc != Success) 79005b261ecSmrg return rc; 7916747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); 79205b261ecSmrg if (len != Ones(stuff->valueMask)) 79305b261ecSmrg return BadLength; 7946747b715Smrg return ChangeWindowAttributes(pWin, 795f7df2e56Smrg stuff->valueMask, (XID *) &stuff[1], client); 79605b261ecSmrg} 79705b261ecSmrg 79805b261ecSmrgint 79905b261ecSmrgProcGetWindowAttributes(ClientPtr client) 80005b261ecSmrg{ 80105b261ecSmrg WindowPtr pWin; 802f7df2e56Smrg 80305b261ecSmrg REQUEST(xResourceReq); 80405b261ecSmrg xGetWindowAttributesReply wa; 80505b261ecSmrg int rc; 80605b261ecSmrg 80705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8084642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 80905b261ecSmrg if (rc != Success) 810f7df2e56Smrg return rc; 8116747b715Smrg memset(&wa, 0, sizeof(xGetWindowAttributesReply)); 81205b261ecSmrg GetWindowAttributes(pWin, client, &wa); 81305b261ecSmrg WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); 8146747b715Smrg return Success; 81505b261ecSmrg} 81605b261ecSmrg 81705b261ecSmrgint 81805b261ecSmrgProcDestroyWindow(ClientPtr client) 81905b261ecSmrg{ 82005b261ecSmrg WindowPtr pWin; 821f7df2e56Smrg 82205b261ecSmrg REQUEST(xResourceReq); 82305b261ecSmrg int rc; 82405b261ecSmrg 82505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 82605b261ecSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 82705b261ecSmrg if (rc != Success) 828f7df2e56Smrg return rc; 8294642e01fSmrg if (pWin->parent) { 830f7df2e56Smrg rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, 831f7df2e56Smrg DixRemoveAccess); 832f7df2e56Smrg if (rc != Success) 833f7df2e56Smrg return rc; 834f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 8354642e01fSmrg } 8366747b715Smrg return Success; 83705b261ecSmrg} 83805b261ecSmrg 83905b261ecSmrgint 84005b261ecSmrgProcDestroySubwindows(ClientPtr client) 84105b261ecSmrg{ 84205b261ecSmrg WindowPtr pWin; 843f7df2e56Smrg 84405b261ecSmrg REQUEST(xResourceReq); 84505b261ecSmrg int rc; 84605b261ecSmrg 84705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 8484642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); 84905b261ecSmrg if (rc != Success) 850f7df2e56Smrg return rc; 85105b261ecSmrg DestroySubwindows(pWin, client); 8526747b715Smrg return Success; 85305b261ecSmrg} 85405b261ecSmrg 85505b261ecSmrgint 85605b261ecSmrgProcChangeSaveSet(ClientPtr client) 85705b261ecSmrg{ 85805b261ecSmrg WindowPtr pWin; 859f7df2e56Smrg 86005b261ecSmrg REQUEST(xChangeSaveSetReq); 8616747b715Smrg int rc; 862f7df2e56Smrg 86305b261ecSmrg REQUEST_SIZE_MATCH(xChangeSaveSetReq); 8644642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 86505b261ecSmrg if (rc != Success) 86605b261ecSmrg return rc; 86705b261ecSmrg if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) 86805b261ecSmrg return BadMatch; 86905b261ecSmrg if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) 8706747b715Smrg return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); 8716747b715Smrg client->errorValue = stuff->mode; 8726747b715Smrg return BadValue; 87305b261ecSmrg} 87405b261ecSmrg 87505b261ecSmrgint 87605b261ecSmrgProcReparentWindow(ClientPtr client) 87705b261ecSmrg{ 87805b261ecSmrg WindowPtr pWin, pParent; 879f7df2e56Smrg 88005b261ecSmrg REQUEST(xReparentWindowReq); 8816747b715Smrg int rc; 88205b261ecSmrg 88305b261ecSmrg REQUEST_SIZE_MATCH(xReparentWindowReq); 8844642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 88505b261ecSmrg if (rc != Success) 88605b261ecSmrg return rc; 8874642e01fSmrg rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 88805b261ecSmrg if (rc != Success) 88905b261ecSmrg return rc; 8906747b715Smrg if (!SAME_SCREENS(pWin->drawable, pParent->drawable)) 891f7df2e56Smrg return BadMatch; 8926747b715Smrg if ((pWin->backgroundState == ParentRelative) && 893f7df2e56Smrg (pParent->drawable.depth != pWin->drawable.depth)) 894f7df2e56Smrg return BadMatch; 8956747b715Smrg if ((pWin->drawable.class != InputOnly) && 896f7df2e56Smrg (pParent->drawable.class == InputOnly)) 897f7df2e56Smrg return BadMatch; 8986747b715Smrg return ReparentWindow(pWin, pParent, 899f7df2e56Smrg (short) stuff->x, (short) stuff->y, client); 90005b261ecSmrg} 90105b261ecSmrg 90205b261ecSmrgint 90305b261ecSmrgProcMapWindow(ClientPtr client) 90405b261ecSmrg{ 90505b261ecSmrg WindowPtr pWin; 906f7df2e56Smrg 90705b261ecSmrg REQUEST(xResourceReq); 90805b261ecSmrg int rc; 90905b261ecSmrg 91005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 9114642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); 91205b261ecSmrg if (rc != Success) 91305b261ecSmrg return rc; 91405b261ecSmrg MapWindow(pWin, client); 915f7df2e56Smrg /* update cache to say it is mapped */ 9166747b715Smrg return Success; 91705b261ecSmrg} 91805b261ecSmrg 91905b261ecSmrgint 92005b261ecSmrgProcMapSubwindows(ClientPtr client) 92105b261ecSmrg{ 92205b261ecSmrg WindowPtr pWin; 923f7df2e56Smrg 92405b261ecSmrg REQUEST(xResourceReq); 92505b261ecSmrg int rc; 92605b261ecSmrg 92705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 9284642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 92905b261ecSmrg if (rc != Success) 93005b261ecSmrg return rc; 93105b261ecSmrg MapSubwindows(pWin, client); 932f7df2e56Smrg /* update cache to say it is mapped */ 9336747b715Smrg return Success; 93405b261ecSmrg} 93505b261ecSmrg 93605b261ecSmrgint 93705b261ecSmrgProcUnmapWindow(ClientPtr client) 93805b261ecSmrg{ 93905b261ecSmrg WindowPtr pWin; 940f7df2e56Smrg 94105b261ecSmrg REQUEST(xResourceReq); 94205b261ecSmrg int rc; 94305b261ecSmrg 94405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 9454642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); 94605b261ecSmrg if (rc != Success) 94705b261ecSmrg return rc; 94805b261ecSmrg UnmapWindow(pWin, FALSE); 949f7df2e56Smrg /* update cache to say it is mapped */ 9506747b715Smrg return Success; 95105b261ecSmrg} 95205b261ecSmrg 95305b261ecSmrgint 95405b261ecSmrgProcUnmapSubwindows(ClientPtr client) 95505b261ecSmrg{ 95605b261ecSmrg WindowPtr pWin; 957f7df2e56Smrg 95805b261ecSmrg REQUEST(xResourceReq); 95905b261ecSmrg int rc; 96005b261ecSmrg 96105b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 9624642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 96305b261ecSmrg if (rc != Success) 96405b261ecSmrg return rc; 96505b261ecSmrg UnmapSubwindows(pWin); 9666747b715Smrg return Success; 96705b261ecSmrg} 96805b261ecSmrg 96905b261ecSmrgint 97005b261ecSmrgProcConfigureWindow(ClientPtr client) 97105b261ecSmrg{ 97205b261ecSmrg WindowPtr pWin; 973f7df2e56Smrg 97405b261ecSmrg REQUEST(xConfigureWindowReq); 97505b261ecSmrg int len, rc; 97605b261ecSmrg 97705b261ecSmrg REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); 9784642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, 979f7df2e56Smrg DixManageAccess | DixSetAttrAccess); 98005b261ecSmrg if (rc != Success) 98105b261ecSmrg return rc; 9826747b715Smrg len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); 983f7df2e56Smrg if (Ones((Mask) stuff->mask) != len) 98405b261ecSmrg return BadLength; 985f7df2e56Smrg return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client); 98605b261ecSmrg} 98705b261ecSmrg 98805b261ecSmrgint 98905b261ecSmrgProcCirculateWindow(ClientPtr client) 99005b261ecSmrg{ 99105b261ecSmrg WindowPtr pWin; 992f7df2e56Smrg 99305b261ecSmrg REQUEST(xCirculateWindowReq); 99405b261ecSmrg int rc; 99505b261ecSmrg 99605b261ecSmrg REQUEST_SIZE_MATCH(xCirculateWindowReq); 997f7df2e56Smrg if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) { 998f7df2e56Smrg client->errorValue = stuff->direction; 99905b261ecSmrg return BadValue; 100005b261ecSmrg } 10014642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 100205b261ecSmrg if (rc != Success) 100305b261ecSmrg return rc; 1004f7df2e56Smrg CirculateWindow(pWin, (int) stuff->direction, client); 10056747b715Smrg return Success; 100605b261ecSmrg} 100705b261ecSmrg 100805b261ecSmrgstatic int 1009f7df2e56SmrgGetGeometry(ClientPtr client, xGetGeometryReply * rep) 101005b261ecSmrg{ 101105b261ecSmrg DrawablePtr pDraw; 101205b261ecSmrg int rc; 1013f7df2e56Smrg 101405b261ecSmrg REQUEST(xResourceReq); 101505b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 101605b261ecSmrg 10174642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); 101805b261ecSmrg if (rc != Success) 1019f7df2e56Smrg return rc; 102005b261ecSmrg 102105b261ecSmrg rep->type = X_Reply; 102205b261ecSmrg rep->length = 0; 102305b261ecSmrg rep->sequenceNumber = client->sequence; 10246747b715Smrg rep->root = pDraw->pScreen->root->drawable.id; 102505b261ecSmrg rep->depth = pDraw->depth; 102605b261ecSmrg rep->width = pDraw->width; 102705b261ecSmrg rep->height = pDraw->height; 102805b261ecSmrg 1029f7df2e56Smrg if (WindowDrawable(pDraw->type)) { 1030f7df2e56Smrg WindowPtr pWin = (WindowPtr) pDraw; 1031f7df2e56Smrg 1032f7df2e56Smrg rep->x = pWin->origin.x - wBorderWidth(pWin); 1033f7df2e56Smrg rep->y = pWin->origin.y - wBorderWidth(pWin); 1034f7df2e56Smrg rep->borderWidth = pWin->borderWidth; 103505b261ecSmrg } 1036f7df2e56Smrg else { /* DRAWABLE_PIXMAP */ 1037f7df2e56Smrg 1038f7df2e56Smrg rep->x = rep->y = rep->borderWidth = 0; 103905b261ecSmrg } 104005b261ecSmrg 104105b261ecSmrg return Success; 104205b261ecSmrg} 104305b261ecSmrg 104405b261ecSmrgint 104505b261ecSmrgProcGetGeometry(ClientPtr client) 104605b261ecSmrg{ 1047f7df2e56Smrg xGetGeometryReply rep = { .type = X_Reply }; 104805b261ecSmrg int status; 104905b261ecSmrg 105005b261ecSmrg if ((status = GetGeometry(client, &rep)) != Success) 1051f7df2e56Smrg return status; 105205b261ecSmrg 105305b261ecSmrg WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); 10546747b715Smrg return Success; 105505b261ecSmrg} 105605b261ecSmrg 105705b261ecSmrgint 105805b261ecSmrgProcQueryTree(ClientPtr client) 105905b261ecSmrg{ 106005b261ecSmrg xQueryTreeReply reply; 106105b261ecSmrg int rc, numChildren = 0; 106205b261ecSmrg WindowPtr pChild, pWin, pHead; 1063f7df2e56Smrg Window *childIDs = (Window *) NULL; 1064f7df2e56Smrg 106505b261ecSmrg REQUEST(xResourceReq); 106605b261ecSmrg 106705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 10684642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 106905b261ecSmrg if (rc != Success) 107005b261ecSmrg return rc; 1071f7df2e56Smrg 1072f7df2e56Smrg reply = (xQueryTreeReply) { 1073f7df2e56Smrg .type = X_Reply, 1074f7df2e56Smrg .sequenceNumber = client->sequence, 1075f7df2e56Smrg .root = pWin->drawable.pScreen->root->drawable.id, 1076f7df2e56Smrg .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None 1077f7df2e56Smrg }; 107805b261ecSmrg pHead = RealChildHead(pWin); 107905b261ecSmrg for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 1080f7df2e56Smrg numChildren++; 1081f7df2e56Smrg if (numChildren) { 1082f7df2e56Smrg int curChild = 0; 108305b261ecSmrg 1084f7df2e56Smrg childIDs = xallocarray(numChildren, sizeof(Window)); 1085f7df2e56Smrg if (!childIDs) 1086f7df2e56Smrg return BadAlloc; 1087f7df2e56Smrg for (pChild = pWin->lastChild; pChild != pHead; 1088f7df2e56Smrg pChild = pChild->prevSib) 1089f7df2e56Smrg childIDs[curChild++] = pChild->drawable.id; 109005b261ecSmrg } 1091f7df2e56Smrg 109205b261ecSmrg reply.nChildren = numChildren; 10936747b715Smrg reply.length = bytes_to_int32(numChildren * sizeof(Window)); 1094f7df2e56Smrg 109505b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); 1096f7df2e56Smrg if (numChildren) { 1097f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 1098f7df2e56Smrg WriteSwappedDataToClient(client, numChildren * sizeof(Window), 1099f7df2e56Smrg childIDs); 1100f7df2e56Smrg free(childIDs); 110105b261ecSmrg } 110205b261ecSmrg 11036747b715Smrg return Success; 110405b261ecSmrg} 110505b261ecSmrg 110605b261ecSmrgint 110705b261ecSmrgProcInternAtom(ClientPtr client) 110805b261ecSmrg{ 110905b261ecSmrg Atom atom; 111005b261ecSmrg char *tchar; 1111f7df2e56Smrg 111205b261ecSmrg REQUEST(xInternAtomReq); 111305b261ecSmrg 111405b261ecSmrg REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); 1115f7df2e56Smrg if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) { 1116f7df2e56Smrg client->errorValue = stuff->onlyIfExists; 11176747b715Smrg return BadValue; 111805b261ecSmrg } 111905b261ecSmrg tchar = (char *) &stuff[1]; 112005b261ecSmrg atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); 1121f7df2e56Smrg if (atom != BAD_RESOURCE) { 1122f7df2e56Smrg xInternAtomReply reply = { 1123f7df2e56Smrg .type = X_Reply, 1124f7df2e56Smrg .sequenceNumber = client->sequence, 1125f7df2e56Smrg .length = 0, 1126f7df2e56Smrg .atom = atom 1127f7df2e56Smrg }; 1128f7df2e56Smrg WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); 1129f7df2e56Smrg return Success; 113005b261ecSmrg } 113105b261ecSmrg else 1132f7df2e56Smrg return BadAlloc; 113305b261ecSmrg} 113405b261ecSmrg 113505b261ecSmrgint 113605b261ecSmrgProcGetAtomName(ClientPtr client) 113705b261ecSmrg{ 11386747b715Smrg const char *str; 1139f7df2e56Smrg 114005b261ecSmrg REQUEST(xResourceReq); 114105b261ecSmrg 114205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 1143f7df2e56Smrg if ((str = NameForAtom(stuff->id))) { 1144f7df2e56Smrg int len = strlen(str); 1145f7df2e56Smrg xGetAtomNameReply reply = { 1146f7df2e56Smrg .type = X_Reply, 1147f7df2e56Smrg .sequenceNumber = client->sequence, 1148f7df2e56Smrg .length = bytes_to_int32(len), 1149f7df2e56Smrg .nameLength = len 1150f7df2e56Smrg }; 1151f7df2e56Smrg 1152f7df2e56Smrg WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); 1153f7df2e56Smrg WriteToClient(client, len, str); 1154f7df2e56Smrg return Success; 115505b261ecSmrg } 1156f7df2e56Smrg else { 1157f7df2e56Smrg client->errorValue = stuff->id; 1158f7df2e56Smrg return BadAtom; 115905b261ecSmrg } 116005b261ecSmrg} 116105b261ecSmrg 116205b261ecSmrgint 116305b261ecSmrgProcGrabServer(ClientPtr client) 116405b261ecSmrg{ 11654642e01fSmrg int rc; 1166f7df2e56Smrg 116705b261ecSmrg REQUEST_SIZE_MATCH(xReq); 1168f7df2e56Smrg if (grabState != GrabNone && client != grabClient) { 1169f7df2e56Smrg ResetCurrentRequest(client); 1170f7df2e56Smrg client->sequence--; 1171f7df2e56Smrg BITSET(grabWaiters, client->index); 1172f7df2e56Smrg IgnoreClient(client); 1173f7df2e56Smrg return Success; 117405b261ecSmrg } 11754642e01fSmrg rc = OnlyListenToOneClient(client); 11764642e01fSmrg if (rc != Success) 1177f7df2e56Smrg return rc; 11787e31ba66Smrg grabState = GrabActive; 117905b261ecSmrg grabClient = client; 11807e31ba66Smrg mark_client_grab(client); 118105b261ecSmrg 1182f7df2e56Smrg if (ServerGrabCallback) { 1183f7df2e56Smrg ServerGrabInfoRec grabinfo; 1184f7df2e56Smrg 1185f7df2e56Smrg grabinfo.client = client; 1186f7df2e56Smrg grabinfo.grabstate = SERVER_GRABBED; 1187f7df2e56Smrg CallCallbacks(&ServerGrabCallback, (void *) &grabinfo); 118805b261ecSmrg } 118905b261ecSmrg 11906747b715Smrg return Success; 119105b261ecSmrg} 119205b261ecSmrg 119305b261ecSmrgstatic void 119405b261ecSmrgUngrabServer(ClientPtr client) 119505b261ecSmrg{ 119605b261ecSmrg int i; 119705b261ecSmrg 119805b261ecSmrg grabState = GrabNone; 119905b261ecSmrg ListenToAllClients(); 12007e31ba66Smrg mark_client_ungrab(); 1201f7df2e56Smrg for (i = mskcnt; --i >= 0 && !grabWaiters[i];); 1202f7df2e56Smrg if (i >= 0) { 1203f7df2e56Smrg i <<= 5; 1204f7df2e56Smrg while (!GETBIT(grabWaiters, i)) 1205f7df2e56Smrg i++; 1206f7df2e56Smrg BITCLEAR(grabWaiters, i); 1207f7df2e56Smrg AttendClient(clients[i]); 120805b261ecSmrg } 120905b261ecSmrg 1210f7df2e56Smrg if (ServerGrabCallback) { 1211f7df2e56Smrg ServerGrabInfoRec grabinfo; 1212f7df2e56Smrg 1213f7df2e56Smrg grabinfo.client = client; 1214f7df2e56Smrg grabinfo.grabstate = SERVER_UNGRABBED; 1215f7df2e56Smrg CallCallbacks(&ServerGrabCallback, (void *) &grabinfo); 121605b261ecSmrg } 121705b261ecSmrg} 121805b261ecSmrg 121905b261ecSmrgint 122005b261ecSmrgProcUngrabServer(ClientPtr client) 122105b261ecSmrg{ 122205b261ecSmrg REQUEST_SIZE_MATCH(xReq); 122305b261ecSmrg UngrabServer(client); 12246747b715Smrg return Success; 122505b261ecSmrg} 122605b261ecSmrg 122705b261ecSmrgint 122805b261ecSmrgProcTranslateCoords(ClientPtr client) 122905b261ecSmrg{ 123005b261ecSmrg REQUEST(xTranslateCoordsReq); 123105b261ecSmrg 123205b261ecSmrg WindowPtr pWin, pDst; 123305b261ecSmrg xTranslateCoordsReply rep; 123405b261ecSmrg int rc; 123505b261ecSmrg 123605b261ecSmrg REQUEST_SIZE_MATCH(xTranslateCoordsReq); 12374642e01fSmrg rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); 123805b261ecSmrg if (rc != Success) 123905b261ecSmrg return rc; 12404642e01fSmrg rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); 124105b261ecSmrg if (rc != Success) 124205b261ecSmrg return rc; 1243f7df2e56Smrg 1244f7df2e56Smrg rep = (xTranslateCoordsReply) { 1245f7df2e56Smrg .type = X_Reply, 1246f7df2e56Smrg .sequenceNumber = client->sequence, 1247f7df2e56Smrg .length = 0 1248f7df2e56Smrg }; 1249f7df2e56Smrg if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) { 1250f7df2e56Smrg rep.sameScreen = xFalse; 125105b261ecSmrg rep.child = None; 1252f7df2e56Smrg rep.dstX = rep.dstY = 0; 125305b261ecSmrg } 1254f7df2e56Smrg else { 1255f7df2e56Smrg INT16 x, y; 1256f7df2e56Smrg 1257f7df2e56Smrg rep.sameScreen = xTrue; 1258f7df2e56Smrg rep.child = None; 1259f7df2e56Smrg /* computing absolute coordinates -- adjust to destination later */ 1260f7df2e56Smrg x = pWin->drawable.x + stuff->srcX; 1261f7df2e56Smrg y = pWin->drawable.y + stuff->srcY; 1262f7df2e56Smrg pWin = pDst->firstChild; 1263f7df2e56Smrg while (pWin) { 1264f7df2e56Smrg BoxRec box; 1265f7df2e56Smrg 1266f7df2e56Smrg if ((pWin->mapped) && 1267f7df2e56Smrg (x >= pWin->drawable.x - wBorderWidth(pWin)) && 1268f7df2e56Smrg (x < pWin->drawable.x + (int) pWin->drawable.width + 1269f7df2e56Smrg wBorderWidth(pWin)) && 1270f7df2e56Smrg (y >= pWin->drawable.y - wBorderWidth(pWin)) && 1271f7df2e56Smrg (y < pWin->drawable.y + (int) pWin->drawable.height + 1272f7df2e56Smrg wBorderWidth(pWin)) 1273f7df2e56Smrg /* When a window is shaped, a further check 1274f7df2e56Smrg * is made to see if the point is inside 1275f7df2e56Smrg * borderSize 1276f7df2e56Smrg */ 1277f7df2e56Smrg && (!wBoundingShape(pWin) || 1278f7df2e56Smrg RegionContainsPoint(&pWin->borderSize, x, y, &box)) 1279f7df2e56Smrg 1280f7df2e56Smrg && (!wInputShape(pWin) || 1281f7df2e56Smrg RegionContainsPoint(wInputShape(pWin), 1282f7df2e56Smrg x - pWin->drawable.x, 1283f7df2e56Smrg y - pWin->drawable.y, &box)) 1284f7df2e56Smrg ) { 1285f7df2e56Smrg rep.child = pWin->drawable.id; 1286f7df2e56Smrg pWin = (WindowPtr) NULL; 1287f7df2e56Smrg } 1288f7df2e56Smrg else 1289f7df2e56Smrg pWin = pWin->nextSib; 1290f7df2e56Smrg } 1291f7df2e56Smrg /* adjust to destination coordinates */ 1292f7df2e56Smrg rep.dstX = x - pDst->drawable.x; 1293f7df2e56Smrg rep.dstY = y - pDst->drawable.y; 129405b261ecSmrg } 129505b261ecSmrg WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); 12966747b715Smrg return Success; 129705b261ecSmrg} 129805b261ecSmrg 129905b261ecSmrgint 130005b261ecSmrgProcOpenFont(ClientPtr client) 130105b261ecSmrg{ 1302f7df2e56Smrg int err; 1303f7df2e56Smrg 130405b261ecSmrg REQUEST(xOpenFontReq); 130505b261ecSmrg 130605b261ecSmrg REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); 130705b261ecSmrg client->errorValue = stuff->fid; 130805b261ecSmrg LEGAL_NEW_RESOURCE(stuff->fid, client); 130905b261ecSmrg err = OpenFont(client, stuff->fid, (Mask) 0, 1310f7df2e56Smrg stuff->nbytes, (char *) &stuff[1]); 1311f7df2e56Smrg if (err == Success) { 1312f7df2e56Smrg return Success; 131305b261ecSmrg } 131405b261ecSmrg else 1315f7df2e56Smrg return err; 131605b261ecSmrg} 131705b261ecSmrg 131805b261ecSmrgint 131905b261ecSmrgProcCloseFont(ClientPtr client) 132005b261ecSmrg{ 132105b261ecSmrg FontPtr pFont; 13226747b715Smrg int rc; 1323f7df2e56Smrg 132405b261ecSmrg REQUEST(xResourceReq); 132505b261ecSmrg 132605b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 1327f7df2e56Smrg rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT, 1328f7df2e56Smrg client, DixDestroyAccess); 1329f7df2e56Smrg if (rc == Success) { 133005b261ecSmrg FreeResource(stuff->id, RT_NONE); 1331f7df2e56Smrg return Success; 133205b261ecSmrg } 1333f7df2e56Smrg else { 1334f7df2e56Smrg client->errorValue = stuff->id; 13356747b715Smrg return rc; 133605b261ecSmrg } 133705b261ecSmrg} 133805b261ecSmrg 133905b261ecSmrgint 134005b261ecSmrgProcQueryFont(ClientPtr client) 134105b261ecSmrg{ 1342f7df2e56Smrg xQueryFontReply *reply; 134305b261ecSmrg FontPtr pFont; 13444642e01fSmrg int rc; 1345f7df2e56Smrg 134605b261ecSmrg REQUEST(xResourceReq); 134705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 13484642e01fSmrg 13496747b715Smrg rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess); 13504642e01fSmrg if (rc != Success) 1351f7df2e56Smrg return rc; 135205b261ecSmrg 135305b261ecSmrg { 1354f7df2e56Smrg xCharInfo *pmax = FONTINKMAX(pFont); 1355f7df2e56Smrg xCharInfo *pmin = FONTINKMIN(pFont); 1356f7df2e56Smrg int nprotoxcistructs; 1357f7df2e56Smrg int rlength; 1358f7df2e56Smrg 1359f7df2e56Smrg nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing && 1360f7df2e56Smrg pmax->leftSideBearing == pmin->leftSideBearing && 1361f7df2e56Smrg pmax->descent == pmin->descent && 1362f7df2e56Smrg pmax->ascent == pmin->ascent && 1363f7df2e56Smrg pmax->characterWidth == pmin->characterWidth) ? 1364f7df2e56Smrg 0 : N2dChars(pFont); 1365f7df2e56Smrg 1366f7df2e56Smrg rlength = sizeof(xQueryFontReply) + 1367f7df2e56Smrg FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + 1368f7df2e56Smrg nprotoxcistructs * sizeof(xCharInfo); 1369f7df2e56Smrg reply = calloc(1, rlength); 1370f7df2e56Smrg if (!reply) { 1371f7df2e56Smrg return BadAlloc; 1372f7df2e56Smrg } 1373f7df2e56Smrg 1374f7df2e56Smrg reply->type = X_Reply; 1375f7df2e56Smrg reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); 1376f7df2e56Smrg reply->sequenceNumber = client->sequence; 1377f7df2e56Smrg QueryFont(pFont, reply, nprotoxcistructs); 137805b261ecSmrg 137905b261ecSmrg WriteReplyToClient(client, rlength, reply); 1380f7df2e56Smrg free(reply); 1381f7df2e56Smrg return Success; 138205b261ecSmrg } 138305b261ecSmrg} 138405b261ecSmrg 138505b261ecSmrgint 138605b261ecSmrgProcQueryTextExtents(ClientPtr client) 138705b261ecSmrg{ 138805b261ecSmrg xQueryTextExtentsReply reply; 138905b261ecSmrg FontPtr pFont; 139005b261ecSmrg ExtentInfoRec info; 139105b261ecSmrg unsigned long length; 13924642e01fSmrg int rc; 1393f7df2e56Smrg 13944642e01fSmrg REQUEST(xQueryTextExtentsReq); 139505b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); 1396f7df2e56Smrg 13976747b715Smrg rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess); 13984642e01fSmrg if (rc != Success) 1399f7df2e56Smrg return rc; 14004642e01fSmrg 14016747b715Smrg length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); 140205b261ecSmrg length = length << 1; 1403f7df2e56Smrg if (stuff->oddLength) { 1404f7df2e56Smrg if (length == 0) 1405f7df2e56Smrg return BadLength; 140605b261ecSmrg length--; 140705b261ecSmrg } 14087e31ba66Smrg if (!xfont2_query_text_extents(pFont, length, (unsigned char *) &stuff[1], &info)) 1409f7df2e56Smrg return BadAlloc; 1410f7df2e56Smrg reply = (xQueryTextExtentsReply) { 1411f7df2e56Smrg .type = X_Reply, 1412f7df2e56Smrg .drawDirection = info.drawDirection, 1413f7df2e56Smrg .sequenceNumber = client->sequence, 1414f7df2e56Smrg .length = 0, 1415f7df2e56Smrg .fontAscent = info.fontAscent, 1416f7df2e56Smrg .fontDescent = info.fontDescent, 1417f7df2e56Smrg .overallAscent = info.overallAscent, 1418f7df2e56Smrg .overallDescent = info.overallDescent, 1419f7df2e56Smrg .overallWidth = info.overallWidth, 1420f7df2e56Smrg .overallLeft = info.overallLeft, 1421f7df2e56Smrg .overallRight = info.overallRight 1422f7df2e56Smrg }; 142305b261ecSmrg WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); 14246747b715Smrg return Success; 142505b261ecSmrg} 142605b261ecSmrg 142705b261ecSmrgint 142805b261ecSmrgProcListFonts(ClientPtr client) 142905b261ecSmrg{ 143005b261ecSmrg REQUEST(xListFontsReq); 143105b261ecSmrg 143205b261ecSmrg REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); 143305b261ecSmrg 1434f7df2e56Smrg return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 1435f7df2e56Smrg stuff->maxNames); 143605b261ecSmrg} 143705b261ecSmrg 143805b261ecSmrgint 143905b261ecSmrgProcListFontsWithInfo(ClientPtr client) 144005b261ecSmrg{ 144105b261ecSmrg REQUEST(xListFontsWithInfoReq); 144205b261ecSmrg 144305b261ecSmrg REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); 144405b261ecSmrg 144505b261ecSmrg return StartListFontsWithInfo(client, stuff->nbytes, 1446f7df2e56Smrg (unsigned char *) &stuff[1], stuff->maxNames); 144705b261ecSmrg} 144805b261ecSmrg 144905b261ecSmrg/** 145005b261ecSmrg * 145105b261ecSmrg * \param value must conform to DeleteType 145205b261ecSmrg */ 145305b261ecSmrgint 1454f7df2e56SmrgdixDestroyPixmap(void *value, XID pid) 145505b261ecSmrg{ 1456f7df2e56Smrg PixmapPtr pPixmap = (PixmapPtr) value; 1457f7df2e56Smrg 1458f7df2e56Smrg return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); 145905b261ecSmrg} 146005b261ecSmrg 146105b261ecSmrgint 146205b261ecSmrgProcCreatePixmap(ClientPtr client) 146305b261ecSmrg{ 146405b261ecSmrg PixmapPtr pMap; 146505b261ecSmrg DrawablePtr pDraw; 1466f7df2e56Smrg 146705b261ecSmrg REQUEST(xCreatePixmapReq); 146805b261ecSmrg DepthPtr pDepth; 146905b261ecSmrg int i, rc; 147005b261ecSmrg 147105b261ecSmrg REQUEST_SIZE_MATCH(xCreatePixmapReq); 147205b261ecSmrg client->errorValue = stuff->pid; 147305b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 1474f7df2e56Smrg 147505b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 1476f7df2e56Smrg DixGetAttrAccess); 147705b261ecSmrg if (rc != Success) 1478f7df2e56Smrg return rc; 147905b261ecSmrg 1480f7df2e56Smrg if (!stuff->width || !stuff->height) { 1481f7df2e56Smrg client->errorValue = 0; 148205b261ecSmrg return BadValue; 148305b261ecSmrg } 1484f7df2e56Smrg if (stuff->width > 32767 || stuff->height > 32767) { 1485f7df2e56Smrg /* It is allowed to try and allocate a pixmap which is larger than 1486f7df2e56Smrg * 32767 in either dimension. However, all of the framebuffer code 1487f7df2e56Smrg * is buggy and does not reliably draw to such big pixmaps, basically 1488f7df2e56Smrg * because the Region data structure operates with signed shorts 1489f7df2e56Smrg * for the rectangles in it. 1490f7df2e56Smrg * 1491f7df2e56Smrg * Furthermore, several places in the X server computes the 1492f7df2e56Smrg * size in bytes of the pixmap and tries to store it in an 1493f7df2e56Smrg * integer. This integer can overflow and cause the allocated size 1494f7df2e56Smrg * to be much smaller. 1495f7df2e56Smrg * 1496f7df2e56Smrg * So, such big pixmaps are rejected here with a BadAlloc 1497f7df2e56Smrg */ 1498f7df2e56Smrg return BadAlloc; 1499f7df2e56Smrg } 1500f7df2e56Smrg if (stuff->depth != 1) { 150105b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 1502f7df2e56Smrg for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++) 1503f7df2e56Smrg if (pDepth->depth == stuff->depth) 1504f7df2e56Smrg goto CreatePmap; 1505f7df2e56Smrg client->errorValue = stuff->depth; 150605b261ecSmrg return BadValue; 150705b261ecSmrg } 1508f7df2e56Smrg CreatePmap: 1509f7df2e56Smrg pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap) 1510f7df2e56Smrg (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0); 1511f7df2e56Smrg if (pMap) { 1512f7df2e56Smrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 1513f7df2e56Smrg pMap->drawable.id = stuff->pid; 1514f7df2e56Smrg /* security creation/labeling check */ 1515f7df2e56Smrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 1516f7df2e56Smrg pMap, RT_NONE, NULL, DixCreateAccess); 1517f7df2e56Smrg if (rc != Success) { 1518f7df2e56Smrg (*pDraw->pScreen->DestroyPixmap) (pMap); 1519f7df2e56Smrg return rc; 1520f7df2e56Smrg } 1521f7df2e56Smrg if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap)) 1522f7df2e56Smrg return Success; 152305b261ecSmrg } 15246747b715Smrg return BadAlloc; 152505b261ecSmrg} 152605b261ecSmrg 152705b261ecSmrgint 152805b261ecSmrgProcFreePixmap(ClientPtr client) 152905b261ecSmrg{ 153005b261ecSmrg PixmapPtr pMap; 15314642e01fSmrg int rc; 1532f7df2e56Smrg 153305b261ecSmrg REQUEST(xResourceReq); 153405b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 15354642e01fSmrg 1536f7df2e56Smrg rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP, 1537f7df2e56Smrg client, DixDestroyAccess); 1538f7df2e56Smrg if (rc == Success) { 1539f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 1540f7df2e56Smrg return Success; 154105b261ecSmrg } 1542f7df2e56Smrg else { 1543f7df2e56Smrg client->errorValue = stuff->id; 1544f7df2e56Smrg return rc; 154505b261ecSmrg } 154605b261ecSmrg} 154705b261ecSmrg 154805b261ecSmrgint 154905b261ecSmrgProcCreateGC(ClientPtr client) 155005b261ecSmrg{ 155105b261ecSmrg int error, rc; 155205b261ecSmrg GC *pGC; 155305b261ecSmrg DrawablePtr pDraw; 155405b261ecSmrg unsigned len; 1555f7df2e56Smrg 155605b261ecSmrg REQUEST(xCreateGCReq); 155705b261ecSmrg 155805b261ecSmrg REQUEST_AT_LEAST_SIZE(xCreateGCReq); 155905b261ecSmrg client->errorValue = stuff->gc; 156005b261ecSmrg LEGAL_NEW_RESOURCE(stuff->gc, client); 15614642e01fSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 1562f7df2e56Smrg DixGetAttrAccess); 156305b261ecSmrg if (rc != Success) 1564f7df2e56Smrg return rc; 156505b261ecSmrg 1566f7df2e56Smrg len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); 156705b261ecSmrg if (len != Ones(stuff->mask)) 156805b261ecSmrg return BadLength; 1569f7df2e56Smrg pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, 1570f7df2e56Smrg stuff->gc, client); 157105b261ecSmrg if (error != Success) 157205b261ecSmrg return error; 1573f7df2e56Smrg if (!AddResource(stuff->gc, RT_GC, (void *) pGC)) 1574f7df2e56Smrg return BadAlloc; 15756747b715Smrg return Success; 157605b261ecSmrg} 157705b261ecSmrg 157805b261ecSmrgint 157905b261ecSmrgProcChangeGC(ClientPtr client) 158005b261ecSmrg{ 158105b261ecSmrg GC *pGC; 158205b261ecSmrg int result; 158305b261ecSmrg unsigned len; 1584f7df2e56Smrg 158505b261ecSmrg REQUEST(xChangeGCReq); 158605b261ecSmrg REQUEST_AT_LEAST_SIZE(xChangeGCReq); 158705b261ecSmrg 15884642e01fSmrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 158905b261ecSmrg if (result != Success) 1590f7df2e56Smrg return result; 159105b261ecSmrg 1592f7df2e56Smrg len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); 159305b261ecSmrg if (len != Ones(stuff->mask)) 159405b261ecSmrg return BadLength; 159505b261ecSmrg 15966747b715Smrg return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]); 159705b261ecSmrg} 159805b261ecSmrg 159905b261ecSmrgint 160005b261ecSmrgProcCopyGC(ClientPtr client) 160105b261ecSmrg{ 160205b261ecSmrg GC *dstGC; 160305b261ecSmrg GC *pGC; 160405b261ecSmrg int result; 1605f7df2e56Smrg 160605b261ecSmrg REQUEST(xCopyGCReq); 160705b261ecSmrg REQUEST_SIZE_MATCH(xCopyGCReq); 160805b261ecSmrg 16094642e01fSmrg result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); 161005b261ecSmrg if (result != Success) 1611f7df2e56Smrg return result; 16124642e01fSmrg result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); 161305b261ecSmrg if (result != Success) 1614f7df2e56Smrg return result; 161505b261ecSmrg if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 16166747b715Smrg return BadMatch; 1617f7df2e56Smrg if (stuff->mask & ~GCAllBits) { 1618f7df2e56Smrg client->errorValue = stuff->mask; 1619f7df2e56Smrg return BadValue; 162005b261ecSmrg } 16216747b715Smrg return CopyGC(pGC, dstGC, stuff->mask); 162205b261ecSmrg} 162305b261ecSmrg 162405b261ecSmrgint 162505b261ecSmrgProcSetDashes(ClientPtr client) 162605b261ecSmrg{ 162705b261ecSmrg GC *pGC; 162805b261ecSmrg int result; 1629f7df2e56Smrg 163005b261ecSmrg REQUEST(xSetDashesReq); 163105b261ecSmrg 163205b261ecSmrg REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 1633f7df2e56Smrg if (stuff->nDashes == 0) { 1634f7df2e56Smrg client->errorValue = 0; 1635f7df2e56Smrg return BadValue; 163605b261ecSmrg } 163705b261ecSmrg 1638f7df2e56Smrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 163905b261ecSmrg if (result != Success) 1640f7df2e56Smrg return result; 164105b261ecSmrg 16426747b715Smrg /* If there's an error, either there's no sensible errorValue, 16436747b715Smrg * or there was a dash segment of 0. */ 16446747b715Smrg client->errorValue = 0; 16456747b715Smrg return SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 1646f7df2e56Smrg (unsigned char *) &stuff[1]); 164705b261ecSmrg} 164805b261ecSmrg 164905b261ecSmrgint 165005b261ecSmrgProcSetClipRectangles(ClientPtr client) 165105b261ecSmrg{ 1652f7df2e56Smrg int nr, result; 165305b261ecSmrg GC *pGC; 1654f7df2e56Smrg 165505b261ecSmrg REQUEST(xSetClipRectanglesReq); 165605b261ecSmrg 165705b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 165805b261ecSmrg if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 1659f7df2e56Smrg (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) { 1660f7df2e56Smrg client->errorValue = stuff->ordering; 166105b261ecSmrg return BadValue; 166205b261ecSmrg } 1663f7df2e56Smrg result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 166405b261ecSmrg if (result != Success) 1665f7df2e56Smrg return result; 1666f7df2e56Smrg 166705b261ecSmrg nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 166805b261ecSmrg if (nr & 4) 1669f7df2e56Smrg return BadLength; 167005b261ecSmrg nr >>= 3; 16716747b715Smrg return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 1672f7df2e56Smrg nr, (xRectangle *) &stuff[1], (int) stuff->ordering); 167305b261ecSmrg} 167405b261ecSmrg 167505b261ecSmrgint 167605b261ecSmrgProcFreeGC(ClientPtr client) 167705b261ecSmrg{ 167805b261ecSmrg GC *pGC; 167905b261ecSmrg int rc; 1680f7df2e56Smrg 168105b261ecSmrg REQUEST(xResourceReq); 168205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 168305b261ecSmrg 168405b261ecSmrg rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 168505b261ecSmrg if (rc != Success) 1686f7df2e56Smrg return rc; 168705b261ecSmrg 168805b261ecSmrg FreeResource(stuff->id, RT_NONE); 16896747b715Smrg return Success; 169005b261ecSmrg} 169105b261ecSmrg 169205b261ecSmrgint 169305b261ecSmrgProcClearToBackground(ClientPtr client) 169405b261ecSmrg{ 169505b261ecSmrg REQUEST(xClearAreaReq); 169605b261ecSmrg WindowPtr pWin; 169705b261ecSmrg int rc; 169805b261ecSmrg 169905b261ecSmrg REQUEST_SIZE_MATCH(xClearAreaReq); 170005b261ecSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 170105b261ecSmrg if (rc != Success) 170205b261ecSmrg return rc; 1703f7df2e56Smrg if (pWin->drawable.class == InputOnly) { 1704f7df2e56Smrg client->errorValue = stuff->window; 1705f7df2e56Smrg return BadMatch; 1706f7df2e56Smrg } 1707f7df2e56Smrg if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) { 1708f7df2e56Smrg client->errorValue = stuff->exposures; 17096747b715Smrg return BadValue; 171005b261ecSmrg } 1711f7df2e56Smrg (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y, 1712f7df2e56Smrg stuff->width, stuff->height, 1713f7df2e56Smrg (Bool) stuff->exposures); 17146747b715Smrg return Success; 171505b261ecSmrg} 171605b261ecSmrg 1717f7df2e56Smrg/* send GraphicsExpose events, or a NoExpose event, based on the region */ 1718f7df2e56Smrgvoid 1719f7df2e56SmrgSendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable, 1720f7df2e56Smrg int major, int minor) 1721f7df2e56Smrg{ 1722f7df2e56Smrg if (pRgn && !RegionNil(pRgn)) { 1723f7df2e56Smrg xEvent *pEvent; 1724f7df2e56Smrg xEvent *pe; 1725f7df2e56Smrg BoxPtr pBox; 1726f7df2e56Smrg int i; 1727f7df2e56Smrg int numRects; 1728f7df2e56Smrg 1729f7df2e56Smrg numRects = RegionNumRects(pRgn); 1730f7df2e56Smrg pBox = RegionRects(pRgn); 1731f7df2e56Smrg if (!(pEvent = calloc(numRects, sizeof(xEvent)))) 1732f7df2e56Smrg return; 1733f7df2e56Smrg pe = pEvent; 1734f7df2e56Smrg 1735f7df2e56Smrg for (i = 1; i <= numRects; i++, pe++, pBox++) { 1736f7df2e56Smrg pe->u.u.type = GraphicsExpose; 1737f7df2e56Smrg pe->u.graphicsExposure.drawable = drawable; 1738f7df2e56Smrg pe->u.graphicsExposure.x = pBox->x1; 1739f7df2e56Smrg pe->u.graphicsExposure.y = pBox->y1; 1740f7df2e56Smrg pe->u.graphicsExposure.width = pBox->x2 - pBox->x1; 1741f7df2e56Smrg pe->u.graphicsExposure.height = pBox->y2 - pBox->y1; 1742f7df2e56Smrg pe->u.graphicsExposure.count = numRects - i; 1743f7df2e56Smrg pe->u.graphicsExposure.majorEvent = major; 1744f7df2e56Smrg pe->u.graphicsExposure.minorEvent = minor; 1745f7df2e56Smrg } 1746f7df2e56Smrg /* GraphicsExpose is a "critical event", which TryClientEvents 1747f7df2e56Smrg * handles specially. */ 1748f7df2e56Smrg TryClientEvents(client, NULL, pEvent, numRects, 1749f7df2e56Smrg (Mask) 0, NoEventMask, NullGrab); 1750f7df2e56Smrg free(pEvent); 1751f7df2e56Smrg } 1752f7df2e56Smrg else { 1753f7df2e56Smrg xEvent event = { 1754f7df2e56Smrg .u.noExposure.drawable = drawable, 1755f7df2e56Smrg .u.noExposure.majorEvent = major, 1756f7df2e56Smrg .u.noExposure.minorEvent = minor 1757f7df2e56Smrg }; 1758f7df2e56Smrg event.u.u.type = NoExpose; 1759f7df2e56Smrg WriteEventsToClient(client, 1, &event); 1760f7df2e56Smrg } 1761f7df2e56Smrg} 1762f7df2e56Smrg 176305b261ecSmrgint 176405b261ecSmrgProcCopyArea(ClientPtr client) 176505b261ecSmrg{ 176605b261ecSmrg DrawablePtr pDst; 176705b261ecSmrg DrawablePtr pSrc; 176805b261ecSmrg GC *pGC; 1769f7df2e56Smrg 177005b261ecSmrg REQUEST(xCopyAreaReq); 177105b261ecSmrg RegionPtr pRgn; 177205b261ecSmrg int rc; 177305b261ecSmrg 177405b261ecSmrg REQUEST_SIZE_MATCH(xCopyAreaReq); 177505b261ecSmrg 1776f7df2e56Smrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 1777f7df2e56Smrg if (stuff->dstDrawable != stuff->srcDrawable) { 1778f7df2e56Smrg rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 1779f7df2e56Smrg DixReadAccess); 1780f7df2e56Smrg if (rc != Success) 1781f7df2e56Smrg return rc; 1782f7df2e56Smrg if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) { 1783f7df2e56Smrg client->errorValue = stuff->dstDrawable; 1784f7df2e56Smrg return BadMatch; 1785f7df2e56Smrg } 178605b261ecSmrg } 178705b261ecSmrg else 178805b261ecSmrg pSrc = pDst; 178905b261ecSmrg 1790f7df2e56Smrg pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 1791f7df2e56Smrg stuff->width, stuff->height, 1792f7df2e56Smrg stuff->dstX, stuff->dstY); 1793f7df2e56Smrg if (pGC->graphicsExposures) { 1794f7df2e56Smrg SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 1795f7df2e56Smrg if (pRgn) 1796f7df2e56Smrg RegionDestroy(pRgn); 179705b261ecSmrg } 179805b261ecSmrg 17996747b715Smrg return Success; 180005b261ecSmrg} 180105b261ecSmrg 180205b261ecSmrgint 180305b261ecSmrgProcCopyPlane(ClientPtr client) 180405b261ecSmrg{ 180505b261ecSmrg DrawablePtr psrcDraw, pdstDraw; 180605b261ecSmrg GC *pGC; 1807f7df2e56Smrg 180805b261ecSmrg REQUEST(xCopyPlaneReq); 180905b261ecSmrg RegionPtr pRgn; 181005b261ecSmrg int rc; 181105b261ecSmrg 181205b261ecSmrg REQUEST_SIZE_MATCH(xCopyPlaneReq); 181305b261ecSmrg 18144642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); 1815f7df2e56Smrg if (stuff->dstDrawable != stuff->srcDrawable) { 1816f7df2e56Smrg rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 1817f7df2e56Smrg DixReadAccess); 1818f7df2e56Smrg if (rc != Success) 1819f7df2e56Smrg return rc; 1820f7df2e56Smrg 1821f7df2e56Smrg if (pdstDraw->pScreen != psrcDraw->pScreen) { 1822f7df2e56Smrg client->errorValue = stuff->dstDrawable; 1823f7df2e56Smrg return BadMatch; 1824f7df2e56Smrg } 182505b261ecSmrg } 182605b261ecSmrg else 182705b261ecSmrg psrcDraw = pdstDraw; 182805b261ecSmrg 182905b261ecSmrg /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 1830f7df2e56Smrg if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 1831f7df2e56Smrg (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) { 1832f7df2e56Smrg client->errorValue = stuff->bitPlane; 1833f7df2e56Smrg return BadValue; 183405b261ecSmrg } 183505b261ecSmrg 1836f7df2e56Smrg pRgn = 1837f7df2e56Smrg (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX, 1838f7df2e56Smrg stuff->srcY, stuff->width, stuff->height, 1839f7df2e56Smrg stuff->dstX, stuff->dstY, stuff->bitPlane); 1840f7df2e56Smrg if (pGC->graphicsExposures) { 1841f7df2e56Smrg SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 1842f7df2e56Smrg if (pRgn) 1843f7df2e56Smrg RegionDestroy(pRgn); 184405b261ecSmrg } 18456747b715Smrg return Success; 184605b261ecSmrg} 184705b261ecSmrg 184805b261ecSmrgint 184905b261ecSmrgProcPolyPoint(ClientPtr client) 185005b261ecSmrg{ 185105b261ecSmrg int npoint; 185205b261ecSmrg GC *pGC; 185305b261ecSmrg DrawablePtr pDraw; 1854f7df2e56Smrg 185505b261ecSmrg REQUEST(xPolyPointReq); 185605b261ecSmrg 185705b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyPointReq); 1858f7df2e56Smrg if ((stuff->coordMode != CoordModeOrigin) && 1859f7df2e56Smrg (stuff->coordMode != CoordModePrevious)) { 1860f7df2e56Smrg client->errorValue = stuff->coordMode; 186105b261ecSmrg return BadValue; 186205b261ecSmrg } 1863f7df2e56Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 18646747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); 186505b261ecSmrg if (npoint) 1866f7df2e56Smrg (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint, 1867f7df2e56Smrg (xPoint *) &stuff[1]); 18686747b715Smrg return Success; 186905b261ecSmrg} 187005b261ecSmrg 187105b261ecSmrgint 187205b261ecSmrgProcPolyLine(ClientPtr client) 187305b261ecSmrg{ 187405b261ecSmrg int npoint; 187505b261ecSmrg GC *pGC; 187605b261ecSmrg DrawablePtr pDraw; 1877f7df2e56Smrg 187805b261ecSmrg REQUEST(xPolyLineReq); 187905b261ecSmrg 188005b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyLineReq); 1881f7df2e56Smrg if ((stuff->coordMode != CoordModeOrigin) && 1882f7df2e56Smrg (stuff->coordMode != CoordModePrevious)) { 1883f7df2e56Smrg client->errorValue = stuff->coordMode; 188405b261ecSmrg return BadValue; 188505b261ecSmrg } 18864642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 18876747b715Smrg npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); 188805b261ecSmrg if (npoint > 1) 1889f7df2e56Smrg (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint, 1890f7df2e56Smrg (DDXPointPtr) &stuff[1]); 18916747b715Smrg return Success; 189205b261ecSmrg} 189305b261ecSmrg 189405b261ecSmrgint 189505b261ecSmrgProcPolySegment(ClientPtr client) 189605b261ecSmrg{ 189705b261ecSmrg int nsegs; 189805b261ecSmrg GC *pGC; 189905b261ecSmrg DrawablePtr pDraw; 1900f7df2e56Smrg 190105b261ecSmrg REQUEST(xPolySegmentReq); 190205b261ecSmrg 190305b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 19044642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 190505b261ecSmrg nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 190605b261ecSmrg if (nsegs & 4) 1907f7df2e56Smrg return BadLength; 190805b261ecSmrg nsegs >>= 3; 190905b261ecSmrg if (nsegs) 1910f7df2e56Smrg (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 19116747b715Smrg return Success; 191205b261ecSmrg} 191305b261ecSmrg 191405b261ecSmrgint 1915f7df2e56SmrgProcPolyRectangle(ClientPtr client) 191605b261ecSmrg{ 191705b261ecSmrg int nrects; 191805b261ecSmrg GC *pGC; 191905b261ecSmrg DrawablePtr pDraw; 1920f7df2e56Smrg 192105b261ecSmrg REQUEST(xPolyRectangleReq); 192205b261ecSmrg 192305b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 19244642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 192505b261ecSmrg nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 192605b261ecSmrg if (nrects & 4) 1927f7df2e56Smrg return BadLength; 192805b261ecSmrg nrects >>= 3; 192905b261ecSmrg if (nrects) 1930f7df2e56Smrg (*pGC->ops->PolyRectangle) (pDraw, pGC, 1931f7df2e56Smrg nrects, (xRectangle *) &stuff[1]); 19326747b715Smrg return Success; 193305b261ecSmrg} 193405b261ecSmrg 193505b261ecSmrgint 193605b261ecSmrgProcPolyArc(ClientPtr client) 193705b261ecSmrg{ 1938f7df2e56Smrg int narcs; 193905b261ecSmrg GC *pGC; 194005b261ecSmrg DrawablePtr pDraw; 1941f7df2e56Smrg 194205b261ecSmrg REQUEST(xPolyArcReq); 194305b261ecSmrg 194405b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyArcReq); 19454642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 194605b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 194705b261ecSmrg if (narcs % sizeof(xArc)) 1948f7df2e56Smrg return BadLength; 194905b261ecSmrg narcs /= sizeof(xArc); 195005b261ecSmrg if (narcs) 1951f7df2e56Smrg (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 19526747b715Smrg return Success; 195305b261ecSmrg} 195405b261ecSmrg 195505b261ecSmrgint 195605b261ecSmrgProcFillPoly(ClientPtr client) 195705b261ecSmrg{ 1958f7df2e56Smrg int things; 195905b261ecSmrg GC *pGC; 196005b261ecSmrg DrawablePtr pDraw; 1961f7df2e56Smrg 196205b261ecSmrg REQUEST(xFillPolyReq); 196305b261ecSmrg 196405b261ecSmrg REQUEST_AT_LEAST_SIZE(xFillPolyReq); 1965f7df2e56Smrg if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 1966f7df2e56Smrg (stuff->shape != Convex)) { 1967f7df2e56Smrg client->errorValue = stuff->shape; 196805b261ecSmrg return BadValue; 196905b261ecSmrg } 1970f7df2e56Smrg if ((stuff->coordMode != CoordModeOrigin) && 1971f7df2e56Smrg (stuff->coordMode != CoordModePrevious)) { 1972f7df2e56Smrg client->errorValue = stuff->coordMode; 197305b261ecSmrg return BadValue; 197405b261ecSmrg } 197505b261ecSmrg 19764642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 19776747b715Smrg things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); 197805b261ecSmrg if (things) 197905b261ecSmrg (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 1980f7df2e56Smrg stuff->coordMode, things, 1981f7df2e56Smrg (DDXPointPtr) &stuff[1]); 19826747b715Smrg return Success; 198305b261ecSmrg} 198405b261ecSmrg 198505b261ecSmrgint 198605b261ecSmrgProcPolyFillRectangle(ClientPtr client) 198705b261ecSmrg{ 1988f7df2e56Smrg int things; 198905b261ecSmrg GC *pGC; 199005b261ecSmrg DrawablePtr pDraw; 1991f7df2e56Smrg 199205b261ecSmrg REQUEST(xPolyFillRectangleReq); 199305b261ecSmrg 199405b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 19954642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 199605b261ecSmrg things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 199705b261ecSmrg if (things & 4) 1998f7df2e56Smrg return BadLength; 199905b261ecSmrg things >>= 3; 200005b261ecSmrg 200105b261ecSmrg if (things) 200205b261ecSmrg (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 2003f7df2e56Smrg (xRectangle *) &stuff[1]); 20046747b715Smrg return Success; 200505b261ecSmrg} 200605b261ecSmrg 200705b261ecSmrgint 200805b261ecSmrgProcPolyFillArc(ClientPtr client) 200905b261ecSmrg{ 2010f7df2e56Smrg int narcs; 201105b261ecSmrg GC *pGC; 201205b261ecSmrg DrawablePtr pDraw; 2013f7df2e56Smrg 201405b261ecSmrg REQUEST(xPolyFillArcReq); 201505b261ecSmrg 201605b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 20174642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 201805b261ecSmrg narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 201905b261ecSmrg if (narcs % sizeof(xArc)) 2020f7df2e56Smrg return BadLength; 202105b261ecSmrg narcs /= sizeof(xArc); 202205b261ecSmrg if (narcs) 202305b261ecSmrg (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 20246747b715Smrg return Success; 202505b261ecSmrg} 202605b261ecSmrg 202705b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 202805b261ecSmrg 202905b261ecSmrgint 2030f7df2e56SmrgServerOrder(void) 203105b261ecSmrg{ 2032f7df2e56Smrg int whichbyte = 1; 203305b261ecSmrg 203405b261ecSmrg if (*((char *) &whichbyte)) 2035f7df2e56Smrg return LSBFirst; 203605b261ecSmrg return MSBFirst; 203705b261ecSmrg} 203805b261ecSmrg 203905b261ecSmrg#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 204005b261ecSmrg 204105b261ecSmrgvoid 2042f7df2e56SmrgReformatImage(char *base, int nbytes, int bpp, int order) 204305b261ecSmrg{ 204405b261ecSmrg switch (bpp) { 2045f7df2e56Smrg case 1: /* yuck */ 2046f7df2e56Smrg if (BITMAP_BIT_ORDER != order) 2047f7df2e56Smrg BitOrderInvert((unsigned char *) base, nbytes); 204805b261ecSmrg#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 2049f7df2e56Smrg ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order); 205005b261ecSmrg#endif 2051f7df2e56Smrg break; 205205b261ecSmrg case 4: 2053f7df2e56Smrg break; /* yuck */ 205405b261ecSmrg case 8: 2055f7df2e56Smrg break; 205605b261ecSmrg case 16: 2057f7df2e56Smrg if (IMAGE_BYTE_ORDER != order) 2058f7df2e56Smrg TwoByteSwap((unsigned char *) base, nbytes); 2059f7df2e56Smrg break; 206005b261ecSmrg case 32: 2061f7df2e56Smrg if (IMAGE_BYTE_ORDER != order) 2062f7df2e56Smrg FourByteSwap((unsigned char *) base, nbytes); 2063f7df2e56Smrg break; 206405b261ecSmrg } 206505b261ecSmrg} 206605b261ecSmrg#else 206705b261ecSmrg#define ReformatImage(b,n,bpp,o) 206805b261ecSmrg#endif 206905b261ecSmrg 207005b261ecSmrg/* 64-bit server notes: the protocol restricts padding of images to 207105b261ecSmrg * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 207205b261ecSmrg * to use internally. Removes need for internal alignment checking. 207305b261ecSmrg * All of the PutImage functions could be changed individually, but 207405b261ecSmrg * as currently written, they call other routines which require things 207505b261ecSmrg * to be 64-bit padded on scanlines, so we changed things here. 207605b261ecSmrg * If an image would be padded differently for 64- versus 32-, then 207705b261ecSmrg * copy each scanline to a 64-bit padded scanline. 207805b261ecSmrg * Also, we need to make sure that the image is aligned on a 64-bit 207905b261ecSmrg * boundary, even if the scanlines are padded to our satisfaction. 208005b261ecSmrg */ 208105b261ecSmrgint 208205b261ecSmrgProcPutImage(ClientPtr client) 208305b261ecSmrg{ 208405b261ecSmrg GC *pGC; 208505b261ecSmrg DrawablePtr pDraw; 2086f7df2e56Smrg long length; /* length of scanline server padded */ 2087f7df2e56Smrg long lengthProto; /* length of scanline protocol padded */ 2088f7df2e56Smrg char *tmpImage; 2089f7df2e56Smrg 209005b261ecSmrg REQUEST(xPutImageReq); 209105b261ecSmrg 209205b261ecSmrg REQUEST_AT_LEAST_SIZE(xPutImageReq); 20934642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2094f7df2e56Smrg if (stuff->format == XYBitmap) { 209505b261ecSmrg if ((stuff->depth != 1) || 2096f7df2e56Smrg (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad)) 209705b261ecSmrg return BadMatch; 2098f7df2e56Smrg length = BitmapBytePad(stuff->width + stuff->leftPad); 209905b261ecSmrg } 2100f7df2e56Smrg else if (stuff->format == XYPixmap) { 2101f7df2e56Smrg if ((pDraw->depth != stuff->depth) || 2102f7df2e56Smrg (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad)) 210305b261ecSmrg return BadMatch; 2104f7df2e56Smrg length = BitmapBytePad(stuff->width + stuff->leftPad); 2105f7df2e56Smrg length *= stuff->depth; 210605b261ecSmrg } 2107f7df2e56Smrg else if (stuff->format == ZPixmap) { 210805b261ecSmrg if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 210905b261ecSmrg return BadMatch; 2110f7df2e56Smrg length = PixmapBytePad(stuff->width, stuff->depth); 211105b261ecSmrg } 2112f7df2e56Smrg else { 2113f7df2e56Smrg client->errorValue = stuff->format; 211405b261ecSmrg return BadValue; 211505b261ecSmrg } 211605b261ecSmrg 2117f7df2e56Smrg tmpImage = (char *) &stuff[1]; 211805b261ecSmrg lengthProto = length; 21190b0d8713Smrg 2120f7df2e56Smrg if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height)) 21210b0d8713Smrg return BadLength; 2122f7df2e56Smrg 21236747b715Smrg if ((bytes_to_int32(lengthProto * stuff->height) + 2124f7df2e56Smrg bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) 2125f7df2e56Smrg return BadLength; 2126f7df2e56Smrg 2127f7df2e56Smrg ReformatImage(tmpImage, lengthProto * stuff->height, 2128f7df2e56Smrg stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1, 2129f7df2e56Smrg ClientOrder(client)); 213005b261ecSmrg 213105b261ecSmrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 2132f7df2e56Smrg stuff->width, stuff->height, 2133f7df2e56Smrg stuff->leftPad, stuff->format, tmpImage); 213405b261ecSmrg 2135f7df2e56Smrg return Success; 213605b261ecSmrg} 213705b261ecSmrg 213805b261ecSmrgstatic int 2139f7df2e56SmrgDoGetImage(ClientPtr client, int format, Drawable drawable, 2140f7df2e56Smrg int x, int y, int width, int height, 2141f7df2e56Smrg Mask planemask) 214205b261ecSmrg{ 2143f7df2e56Smrg DrawablePtr pDraw, pBoundingDraw; 2144f7df2e56Smrg int nlines, linesPerBuf, rc; 2145f7df2e56Smrg int linesDone; 2146f7df2e56Smrg 21476747b715Smrg /* coordinates relative to the bounding drawable */ 2148f7df2e56Smrg int relx, rely; 2149f7df2e56Smrg long widthBytesLine, length; 2150f7df2e56Smrg Mask plane = 0; 2151f7df2e56Smrg char *pBuf; 2152f7df2e56Smrg xGetImageReply xgi; 215305b261ecSmrg RegionPtr pVisibleRegion = NULL; 215405b261ecSmrg 2155f7df2e56Smrg if ((format != XYPixmap) && (format != ZPixmap)) { 2156f7df2e56Smrg client->errorValue = format; 21576747b715Smrg return BadValue; 215805b261ecSmrg } 215905b261ecSmrg rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 216005b261ecSmrg if (rc != Success) 2161f7df2e56Smrg return rc; 216205b261ecSmrg 21636747b715Smrg memset(&xgi, 0, sizeof(xGetImageReply)); 21646747b715Smrg 21656747b715Smrg relx = x; 21666747b715Smrg rely = y; 21676747b715Smrg 2168f7df2e56Smrg if (pDraw->type == DRAWABLE_WINDOW) { 2169f7df2e56Smrg WindowPtr pWin = (WindowPtr) pDraw; 2170f7df2e56Smrg 2171f7df2e56Smrg /* "If the drawable is a window, the window must be viewable ... or a 2172f7df2e56Smrg * BadMatch error results" */ 2173f7df2e56Smrg if (!pWin->viewable) 2174f7df2e56Smrg return BadMatch; 21756747b715Smrg 2176f7df2e56Smrg /* If the drawable is a window, the rectangle must be contained within 2177f7df2e56Smrg * its bounds (including the border). */ 2178f7df2e56Smrg if (x < -wBorderWidth(pWin) || 2179f7df2e56Smrg x + width > wBorderWidth(pWin) + (int) pDraw->width || 2180f7df2e56Smrg y < -wBorderWidth(pWin) || 2181f7df2e56Smrg y + height > wBorderWidth(pWin) + (int) pDraw->height) 2182f7df2e56Smrg return BadMatch; 21836747b715Smrg 2184f7df2e56Smrg relx += pDraw->x; 2185f7df2e56Smrg rely += pDraw->y; 21866747b715Smrg 2187f7df2e56Smrg if (pDraw->pScreen->GetWindowPixmap) { 2188f7df2e56Smrg PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); 21896747b715Smrg 2190f7df2e56Smrg pBoundingDraw = &pPix->drawable; 21916747b715Smrg#ifdef COMPOSITE 2192f7df2e56Smrg relx -= pPix->screen_x; 2193f7df2e56Smrg rely -= pPix->screen_y; 21946747b715Smrg#endif 2195f7df2e56Smrg } 2196f7df2e56Smrg else { 2197f7df2e56Smrg pBoundingDraw = (DrawablePtr) pDraw->pScreen->root; 2198f7df2e56Smrg } 21996747b715Smrg 2200f7df2e56Smrg xgi.visual = wVisual(pWin); 220105b261ecSmrg } 2202f7df2e56Smrg else { 2203f7df2e56Smrg pBoundingDraw = pDraw; 2204f7df2e56Smrg xgi.visual = None; 220505b261ecSmrg } 220605b261ecSmrg 22076747b715Smrg /* "If the drawable is a pixmap, the given rectangle must be wholly 22086747b715Smrg * contained within the pixmap, or a BadMatch error results. If the 22096747b715Smrg * drawable is a window [...] it must be the case that if there were no 22106747b715Smrg * inferiors or overlapping windows, the specified rectangle of the window 22116747b715Smrg * would be fully visible on the screen and wholly contained within the 22126747b715Smrg * outside edges of the window, or a BadMatch error results." 22136747b715Smrg * 22146747b715Smrg * We relax the window case slightly to mean that the rectangle must exist 22156747b715Smrg * within the bounds of the window's backing pixmap. In particular, this 22166747b715Smrg * means that a GetImage request may succeed or fail with BadMatch depending 22176747b715Smrg * on whether any of its ancestor windows are redirected. */ 2218f7df2e56Smrg if (relx < 0 || relx + width > (int) pBoundingDraw->width || 2219f7df2e56Smrg rely < 0 || rely + height > (int) pBoundingDraw->height) 2220f7df2e56Smrg return BadMatch; 22216747b715Smrg 222205b261ecSmrg xgi.type = X_Reply; 222305b261ecSmrg xgi.sequenceNumber = client->sequence; 222405b261ecSmrg xgi.depth = pDraw->depth; 2225f7df2e56Smrg if (format == ZPixmap) { 2226f7df2e56Smrg widthBytesLine = PixmapBytePad(width, pDraw->depth); 2227f7df2e56Smrg length = widthBytesLine * height; 222805b261ecSmrg 222905b261ecSmrg } 2230f7df2e56Smrg else { 2231f7df2e56Smrg widthBytesLine = BitmapBytePad(width); 2232f7df2e56Smrg plane = ((Mask) 1) << (pDraw->depth - 1); 2233f7df2e56Smrg /* only planes asked for */ 2234f7df2e56Smrg length = widthBytesLine * height * 2235f7df2e56Smrg Ones(planemask & (plane | (plane - 1))); 223605b261ecSmrg 223705b261ecSmrg } 223805b261ecSmrg 223905b261ecSmrg xgi.length = length; 224005b261ecSmrg 2241f7df2e56Smrg xgi.length = bytes_to_int32(xgi.length); 2242f7df2e56Smrg if (widthBytesLine == 0 || height == 0) 2243f7df2e56Smrg linesPerBuf = 0; 2244f7df2e56Smrg else if (widthBytesLine >= IMAGE_BUFSIZE) 2245f7df2e56Smrg linesPerBuf = 1; 2246f7df2e56Smrg else { 2247f7df2e56Smrg linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 2248f7df2e56Smrg if (linesPerBuf > height) 2249f7df2e56Smrg linesPerBuf = height; 2250f7df2e56Smrg } 2251f7df2e56Smrg length = linesPerBuf * widthBytesLine; 2252f7df2e56Smrg if (linesPerBuf < height) { 2253f7df2e56Smrg /* we have to make sure intermediate buffers don't need padding */ 2254f7df2e56Smrg while ((linesPerBuf > 1) && 2255f7df2e56Smrg (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) { 2256f7df2e56Smrg linesPerBuf--; 2257f7df2e56Smrg length -= widthBytesLine; 2258f7df2e56Smrg } 2259f7df2e56Smrg while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) { 2260f7df2e56Smrg linesPerBuf++; 2261f7df2e56Smrg length += widthBytesLine; 2262f7df2e56Smrg } 226305b261ecSmrg } 2264f7df2e56Smrg if (!(pBuf = calloc(1, length))) 2265f7df2e56Smrg return BadAlloc; 2266f7df2e56Smrg WriteReplyToClient(client, sizeof(xGetImageReply), &xgi); 226705b261ecSmrg 22684e185dc0Smrg if (pDraw->type == DRAWABLE_WINDOW) { 22697e31ba66Smrg pVisibleRegion = &((WindowPtr) pDraw)->borderClip; 22704e185dc0Smrg pDraw->pScreen->SourceValidate(pDraw, x, y, width, height, 22714e185dc0Smrg IncludeInferiors); 22724e185dc0Smrg } 2273f7df2e56Smrg 2274f7df2e56Smrg if (linesPerBuf == 0) { 2275f7df2e56Smrg /* nothing to do */ 2276f7df2e56Smrg } 2277f7df2e56Smrg else if (format == ZPixmap) { 227805b261ecSmrg linesDone = 0; 2279f7df2e56Smrg while (height - linesDone > 0) { 2280f7df2e56Smrg nlines = min(linesPerBuf, height - linesDone); 2281f7df2e56Smrg (*pDraw->pScreen->GetImage) (pDraw, 2282f7df2e56Smrg x, 2283f7df2e56Smrg y + linesDone, 2284f7df2e56Smrg width, 2285f7df2e56Smrg nlines, 2286f7df2e56Smrg format, planemask, (void *) pBuf); 2287f7df2e56Smrg if (pVisibleRegion) 2288f7df2e56Smrg XaceCensorImage(client, pVisibleRegion, widthBytesLine, 2289f7df2e56Smrg pDraw, x, y + linesDone, width, 2290f7df2e56Smrg nlines, format, pBuf); 2291f7df2e56Smrg 2292f7df2e56Smrg /* Note that this is NOT a call to WriteSwappedDataToClient, 229305b261ecSmrg as we do NOT byte swap */ 2294f7df2e56Smrg ReformatImage(pBuf, (int) (nlines * widthBytesLine), 2295f7df2e56Smrg BitsPerPixel(pDraw->depth), ClientOrder(client)); 2296f7df2e56Smrg 2297f7df2e56Smrg WriteToClient(client, (int) (nlines * widthBytesLine), pBuf); 2298f7df2e56Smrg linesDone += nlines; 229905b261ecSmrg } 230005b261ecSmrg } 2301f7df2e56Smrg else { /* XYPixmap */ 2302f7df2e56Smrg 2303f7df2e56Smrg for (; plane; plane >>= 1) { 2304f7df2e56Smrg if (planemask & plane) { 2305f7df2e56Smrg linesDone = 0; 2306f7df2e56Smrg while (height - linesDone > 0) { 2307f7df2e56Smrg nlines = min(linesPerBuf, height - linesDone); 2308f7df2e56Smrg (*pDraw->pScreen->GetImage) (pDraw, 2309f7df2e56Smrg x, 2310f7df2e56Smrg y + linesDone, 2311f7df2e56Smrg width, 2312f7df2e56Smrg nlines, 2313f7df2e56Smrg format, plane, (void *) pBuf); 2314f7df2e56Smrg if (pVisibleRegion) 2315f7df2e56Smrg XaceCensorImage(client, pVisibleRegion, 2316f7df2e56Smrg widthBytesLine, 2317f7df2e56Smrg pDraw, x, y + linesDone, width, 2318f7df2e56Smrg nlines, format, pBuf); 2319f7df2e56Smrg 2320f7df2e56Smrg /* Note: NOT a call to WriteSwappedDataToClient, 2321f7df2e56Smrg as we do NOT byte swap */ 2322f7df2e56Smrg ReformatImage(pBuf, (int) (nlines * widthBytesLine), 2323f7df2e56Smrg 1, ClientOrder(client)); 2324f7df2e56Smrg 2325f7df2e56Smrg WriteToClient(client, (int)(nlines * widthBytesLine), pBuf); 2326f7df2e56Smrg linesDone += nlines; 2327f7df2e56Smrg } 232805b261ecSmrg } 2329f7df2e56Smrg } 233005b261ecSmrg } 2331f7df2e56Smrg free(pBuf); 23326747b715Smrg return Success; 233305b261ecSmrg} 233405b261ecSmrg 233505b261ecSmrgint 233605b261ecSmrgProcGetImage(ClientPtr client) 233705b261ecSmrg{ 233805b261ecSmrg REQUEST(xGetImageReq); 233905b261ecSmrg 234005b261ecSmrg REQUEST_SIZE_MATCH(xGetImageReq); 234105b261ecSmrg 234205b261ecSmrg return DoGetImage(client, stuff->format, stuff->drawable, 2343f7df2e56Smrg stuff->x, stuff->y, 2344f7df2e56Smrg (int) stuff->width, (int) stuff->height, 2345f7df2e56Smrg stuff->planeMask); 234605b261ecSmrg} 234705b261ecSmrg 234805b261ecSmrgint 234905b261ecSmrgProcPolyText(ClientPtr client) 235005b261ecSmrg{ 2351f7df2e56Smrg int err; 2352f7df2e56Smrg 235305b261ecSmrg REQUEST(xPolyTextReq); 235405b261ecSmrg DrawablePtr pDraw; 235505b261ecSmrg GC *pGC; 235605b261ecSmrg 235705b261ecSmrg REQUEST_AT_LEAST_SIZE(xPolyTextReq); 23584642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 235905b261ecSmrg 236005b261ecSmrg err = PolyText(client, 2361f7df2e56Smrg pDraw, 2362f7df2e56Smrg pGC, 2363f7df2e56Smrg (unsigned char *) &stuff[1], 2364f7df2e56Smrg ((unsigned char *) stuff) + (client->req_len << 2), 2365f7df2e56Smrg stuff->x, stuff->y, stuff->reqType, stuff->drawable); 2366f7df2e56Smrg 2367f7df2e56Smrg if (err == Success) { 2368f7df2e56Smrg return Success; 236905b261ecSmrg } 237005b261ecSmrg else 2371f7df2e56Smrg return err; 237205b261ecSmrg} 237305b261ecSmrg 237405b261ecSmrgint 237505b261ecSmrgProcImageText8(ClientPtr client) 237605b261ecSmrg{ 2377f7df2e56Smrg int err; 237805b261ecSmrg DrawablePtr pDraw; 237905b261ecSmrg GC *pGC; 238005b261ecSmrg 238105b261ecSmrg REQUEST(xImageTextReq); 238205b261ecSmrg 238305b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 23844642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 238505b261ecSmrg 238605b261ecSmrg err = ImageText(client, 2387f7df2e56Smrg pDraw, 2388f7df2e56Smrg pGC, 2389f7df2e56Smrg stuff->nChars, 2390f7df2e56Smrg (unsigned char *) &stuff[1], 2391f7df2e56Smrg stuff->x, stuff->y, stuff->reqType, stuff->drawable); 2392f7df2e56Smrg 2393f7df2e56Smrg if (err == Success) { 2394f7df2e56Smrg return Success; 239505b261ecSmrg } 239605b261ecSmrg else 2397f7df2e56Smrg return err; 239805b261ecSmrg} 239905b261ecSmrg 240005b261ecSmrgint 240105b261ecSmrgProcImageText16(ClientPtr client) 240205b261ecSmrg{ 2403f7df2e56Smrg int err; 240405b261ecSmrg DrawablePtr pDraw; 240505b261ecSmrg GC *pGC; 240605b261ecSmrg 240705b261ecSmrg REQUEST(xImageTextReq); 240805b261ecSmrg 240905b261ecSmrg REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 24104642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 241105b261ecSmrg 241205b261ecSmrg err = ImageText(client, 2413f7df2e56Smrg pDraw, 2414f7df2e56Smrg pGC, 2415f7df2e56Smrg stuff->nChars, 2416f7df2e56Smrg (unsigned char *) &stuff[1], 2417f7df2e56Smrg stuff->x, stuff->y, stuff->reqType, stuff->drawable); 2418f7df2e56Smrg 2419f7df2e56Smrg if (err == Success) { 2420f7df2e56Smrg return Success; 242105b261ecSmrg } 242205b261ecSmrg else 2423f7df2e56Smrg return err; 242405b261ecSmrg} 242505b261ecSmrg 242605b261ecSmrgint 242705b261ecSmrgProcCreateColormap(ClientPtr client) 242805b261ecSmrg{ 2429f7df2e56Smrg VisualPtr pVisual; 2430f7df2e56Smrg ColormapPtr pmap; 2431f7df2e56Smrg Colormap mid; 2432f7df2e56Smrg WindowPtr pWin; 243305b261ecSmrg ScreenPtr pScreen; 2434f7df2e56Smrg 243505b261ecSmrg REQUEST(xCreateColormapReq); 243605b261ecSmrg int i, result; 243705b261ecSmrg 243805b261ecSmrg REQUEST_SIZE_MATCH(xCreateColormapReq); 243905b261ecSmrg 2440f7df2e56Smrg if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) { 2441f7df2e56Smrg client->errorValue = stuff->alloc; 24426747b715Smrg return BadValue; 244305b261ecSmrg } 244405b261ecSmrg mid = stuff->mid; 244505b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 24464642e01fSmrg result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 244705b261ecSmrg if (result != Success) 244805b261ecSmrg return result; 244905b261ecSmrg 245005b261ecSmrg pScreen = pWin->drawable.pScreen; 245105b261ecSmrg for (i = 0, pVisual = pScreen->visuals; 2452f7df2e56Smrg i < pScreen->numVisuals; i++, pVisual++) { 2453f7df2e56Smrg if (pVisual->vid != stuff->visual) 2454f7df2e56Smrg continue; 2455f7df2e56Smrg return CreateColormap(mid, pScreen, pVisual, &pmap, 2456f7df2e56Smrg (int) stuff->alloc, client->index); 245705b261ecSmrg } 245805b261ecSmrg client->errorValue = stuff->visual; 24596747b715Smrg return BadMatch; 246005b261ecSmrg} 246105b261ecSmrg 246205b261ecSmrgint 246305b261ecSmrgProcFreeColormap(ClientPtr client) 246405b261ecSmrg{ 246505b261ecSmrg ColormapPtr pmap; 24664642e01fSmrg int rc; 2467f7df2e56Smrg 246805b261ecSmrg REQUEST(xResourceReq); 246905b261ecSmrg 247005b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 2471f7df2e56Smrg rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP, 2472f7df2e56Smrg client, DixDestroyAccess); 2473f7df2e56Smrg if (rc == Success) { 2474f7df2e56Smrg /* Freeing a default colormap is a no-op */ 2475f7df2e56Smrg if (!(pmap->flags & IsDefault)) 2476f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 2477f7df2e56Smrg return Success; 247805b261ecSmrg } 2479f7df2e56Smrg else { 2480f7df2e56Smrg client->errorValue = stuff->id; 2481f7df2e56Smrg return rc; 248205b261ecSmrg } 248305b261ecSmrg} 248405b261ecSmrg 248505b261ecSmrgint 248605b261ecSmrgProcCopyColormapAndFree(ClientPtr client) 248705b261ecSmrg{ 2488f7df2e56Smrg Colormap mid; 2489f7df2e56Smrg ColormapPtr pSrcMap; 2490f7df2e56Smrg 249105b261ecSmrg REQUEST(xCopyColormapAndFreeReq); 24924642e01fSmrg int rc; 249305b261ecSmrg 249405b261ecSmrg REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 249505b261ecSmrg mid = stuff->mid; 249605b261ecSmrg LEGAL_NEW_RESOURCE(mid, client); 2497f7df2e56Smrg rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap, 2498f7df2e56Smrg RT_COLORMAP, client, 2499f7df2e56Smrg DixReadAccess | DixRemoveAccess); 25004642e01fSmrg if (rc == Success) 2501f7df2e56Smrg return CopyColormapAndFree(mid, pSrcMap, client->index); 25026747b715Smrg client->errorValue = stuff->srcCmap; 25036747b715Smrg return rc; 250405b261ecSmrg} 250505b261ecSmrg 250605b261ecSmrgint 250705b261ecSmrgProcInstallColormap(ClientPtr client) 250805b261ecSmrg{ 250905b261ecSmrg ColormapPtr pcmp; 25104642e01fSmrg int rc; 2511f7df2e56Smrg 251205b261ecSmrg REQUEST(xResourceReq); 251305b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 25144642e01fSmrg 2515f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, 2516f7df2e56Smrg client, DixInstallAccess); 25174642e01fSmrg if (rc != Success) 2518f7df2e56Smrg goto out; 25194642e01fSmrg 25204642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 25216747b715Smrg if (rc != Success) { 2522f7df2e56Smrg if (rc == BadValue) 2523f7df2e56Smrg rc = BadColor; 2524f7df2e56Smrg goto out; 25256747b715Smrg } 25264642e01fSmrg 25274642e01fSmrg (*(pcmp->pScreen->InstallColormap)) (pcmp); 25286747b715Smrg return Success; 25294642e01fSmrg 2530f7df2e56Smrg out: 25314642e01fSmrg client->errorValue = stuff->id; 25326747b715Smrg return rc; 253305b261ecSmrg} 253405b261ecSmrg 253505b261ecSmrgint 253605b261ecSmrgProcUninstallColormap(ClientPtr client) 253705b261ecSmrg{ 253805b261ecSmrg ColormapPtr pcmp; 25394642e01fSmrg int rc; 2540f7df2e56Smrg 254105b261ecSmrg REQUEST(xResourceReq); 254205b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 25434642e01fSmrg 2544f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, 2545f7df2e56Smrg client, DixUninstallAccess); 25464642e01fSmrg if (rc != Success) 2547f7df2e56Smrg goto out; 25484642e01fSmrg 25494642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 25506747b715Smrg if (rc != Success) { 2551f7df2e56Smrg if (rc == BadValue) 2552f7df2e56Smrg rc = BadColor; 2553f7df2e56Smrg goto out; 25546747b715Smrg } 25554642e01fSmrg 2556f7df2e56Smrg if (pcmp->mid != pcmp->pScreen->defColormap) 2557f7df2e56Smrg (*(pcmp->pScreen->UninstallColormap)) (pcmp); 25586747b715Smrg return Success; 25594642e01fSmrg 2560f7df2e56Smrg out: 25614642e01fSmrg client->errorValue = stuff->id; 25626747b715Smrg return rc; 256305b261ecSmrg} 256405b261ecSmrg 256505b261ecSmrgint 256605b261ecSmrgProcListInstalledColormaps(ClientPtr client) 256705b261ecSmrg{ 2568f7df2e56Smrg xListInstalledColormapsReply *preply; 256905b261ecSmrg int nummaps, rc; 257005b261ecSmrg WindowPtr pWin; 2571f7df2e56Smrg 257205b261ecSmrg REQUEST(xResourceReq); 257305b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 25744642e01fSmrg 25754642e01fSmrg rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 257605b261ecSmrg if (rc != Success) 2577f7df2e56Smrg return rc; 25784642e01fSmrg 25794642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 2580f7df2e56Smrg DixGetAttrAccess); 25814642e01fSmrg if (rc != Success) 2582f7df2e56Smrg return rc; 258305b261ecSmrg 25846747b715Smrg preply = malloc(sizeof(xListInstalledColormapsReply) + 2585f7df2e56Smrg pWin->drawable.pScreen->maxInstalledCmaps * 2586f7df2e56Smrg sizeof(Colormap)); 2587f7df2e56Smrg if (!preply) 25886747b715Smrg return BadAlloc; 258905b261ecSmrg 259005b261ecSmrg preply->type = X_Reply; 259105b261ecSmrg preply->sequenceNumber = client->sequence; 259205b261ecSmrg nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 2593f7df2e56Smrg (pWin->drawable.pScreen, (Colormap *) &preply[1]); 259405b261ecSmrg preply->nColormaps = nummaps; 259505b261ecSmrg preply->length = nummaps; 2596f7df2e56Smrg WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply); 259705b261ecSmrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 259805b261ecSmrg WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 25996747b715Smrg free(preply); 26006747b715Smrg return Success; 260105b261ecSmrg} 260205b261ecSmrg 260305b261ecSmrgint 2604f7df2e56SmrgProcAllocColor(ClientPtr client) 260505b261ecSmrg{ 260605b261ecSmrg ColormapPtr pmap; 26074642e01fSmrg int rc; 2608f7df2e56Smrg 260905b261ecSmrg REQUEST(xAllocColorReq); 261005b261ecSmrg 261105b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorReq); 2612f7df2e56Smrg rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP, 2613f7df2e56Smrg client, DixAddAccess); 2614f7df2e56Smrg if (rc == Success) { 2615f7df2e56Smrg xAllocColorReply acr = { 2616f7df2e56Smrg .type = X_Reply, 2617f7df2e56Smrg .sequenceNumber = client->sequence, 2618f7df2e56Smrg .length = 0, 2619f7df2e56Smrg .red = stuff->red, 2620f7df2e56Smrg .green = stuff->green, 2621f7df2e56Smrg .blue = stuff->blue, 2622f7df2e56Smrg .pixel = 0 2623f7df2e56Smrg }; 2624f7df2e56Smrg if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 2625f7df2e56Smrg &acr.pixel, client->index))) 2626f7df2e56Smrg return rc; 262705b261ecSmrg#ifdef PANORAMIX 2628f7df2e56Smrg if (noPanoramiXExtension || !pmap->pScreen->myNum) 262905b261ecSmrg#endif 2630f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 2631f7df2e56Smrg return Success; 263205b261ecSmrg 263305b261ecSmrg } 2634f7df2e56Smrg else { 263505b261ecSmrg client->errorValue = stuff->cmap; 26366747b715Smrg return rc; 263705b261ecSmrg } 263805b261ecSmrg} 263905b261ecSmrg 264005b261ecSmrgint 2641f7df2e56SmrgProcAllocNamedColor(ClientPtr client) 264205b261ecSmrg{ 264305b261ecSmrg ColormapPtr pcmp; 26444642e01fSmrg int rc; 2645f7df2e56Smrg 264605b261ecSmrg REQUEST(xAllocNamedColorReq); 264705b261ecSmrg 264805b261ecSmrg REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 2649f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2650f7df2e56Smrg client, DixAddAccess); 2651f7df2e56Smrg if (rc == Success) { 2652f7df2e56Smrg xAllocNamedColorReply ancr = { 2653f7df2e56Smrg .type = X_Reply, 2654f7df2e56Smrg .sequenceNumber = client->sequence, 2655f7df2e56Smrg .length = 0 2656f7df2e56Smrg }; 2657f7df2e56Smrg if (OsLookupColor 2658f7df2e56Smrg (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, 2659f7df2e56Smrg &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) { 2660f7df2e56Smrg ancr.screenRed = ancr.exactRed; 2661f7df2e56Smrg ancr.screenGreen = ancr.exactGreen; 2662f7df2e56Smrg ancr.screenBlue = ancr.exactBlue; 2663f7df2e56Smrg ancr.pixel = 0; 2664f7df2e56Smrg if ((rc = AllocColor(pcmp, 2665f7df2e56Smrg &ancr.screenRed, &ancr.screenGreen, 2666f7df2e56Smrg &ancr.screenBlue, &ancr.pixel, client->index))) 2667f7df2e56Smrg return rc; 266805b261ecSmrg#ifdef PANORAMIX 2669f7df2e56Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 267005b261ecSmrg#endif 2671f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocNamedColorReply), 2672f7df2e56Smrg &ancr); 2673f7df2e56Smrg return Success; 2674f7df2e56Smrg } 2675f7df2e56Smrg else 2676f7df2e56Smrg return BadName; 2677f7df2e56Smrg 267805b261ecSmrg } 2679f7df2e56Smrg else { 268005b261ecSmrg client->errorValue = stuff->cmap; 26816747b715Smrg return rc; 268205b261ecSmrg } 268305b261ecSmrg} 268405b261ecSmrg 268505b261ecSmrgint 2686f7df2e56SmrgProcAllocColorCells(ClientPtr client) 268705b261ecSmrg{ 268805b261ecSmrg ColormapPtr pcmp; 26894642e01fSmrg int rc; 2690f7df2e56Smrg 269105b261ecSmrg REQUEST(xAllocColorCellsReq); 269205b261ecSmrg 269305b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorCellsReq); 2694f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2695f7df2e56Smrg client, DixAddAccess); 2696f7df2e56Smrg if (rc == Success) { 2697f7df2e56Smrg int npixels, nmasks; 2698f7df2e56Smrg long length; 2699f7df2e56Smrg Pixel *ppixels, *pmasks; 2700f7df2e56Smrg 2701f7df2e56Smrg npixels = stuff->colors; 2702f7df2e56Smrg if (!npixels) { 2703f7df2e56Smrg client->errorValue = npixels; 2704f7df2e56Smrg return BadValue; 2705f7df2e56Smrg } 2706f7df2e56Smrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) { 2707f7df2e56Smrg client->errorValue = stuff->contiguous; 2708f7df2e56Smrg return BadValue; 2709f7df2e56Smrg } 2710f7df2e56Smrg nmasks = stuff->planes; 2711f7df2e56Smrg length = ((long) npixels + (long) nmasks) * sizeof(Pixel); 2712f7df2e56Smrg ppixels = malloc(length); 2713f7df2e56Smrg if (!ppixels) 27146747b715Smrg return BadAlloc; 2715f7df2e56Smrg pmasks = ppixels + npixels; 2716f7df2e56Smrg 2717f7df2e56Smrg if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 2718f7df2e56Smrg (Bool) stuff->contiguous, ppixels, pmasks))) { 2719f7df2e56Smrg free(ppixels); 2720f7df2e56Smrg return rc; 2721f7df2e56Smrg } 272205b261ecSmrg#ifdef PANORAMIX 2723f7df2e56Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 272405b261ecSmrg#endif 2725f7df2e56Smrg { 2726f7df2e56Smrg xAllocColorCellsReply accr = { 2727f7df2e56Smrg .type = X_Reply, 2728f7df2e56Smrg .sequenceNumber = client->sequence, 2729f7df2e56Smrg .length = bytes_to_int32(length), 2730f7df2e56Smrg .nPixels = npixels, 2731f7df2e56Smrg .nMasks = nmasks 2732f7df2e56Smrg }; 2733f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr); 2734f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2735f7df2e56Smrg WriteSwappedDataToClient(client, length, ppixels); 2736f7df2e56Smrg } 2737f7df2e56Smrg free(ppixels); 27386747b715Smrg return Success; 273905b261ecSmrg } 2740f7df2e56Smrg else { 274105b261ecSmrg client->errorValue = stuff->cmap; 27426747b715Smrg return rc; 274305b261ecSmrg } 274405b261ecSmrg} 274505b261ecSmrg 274605b261ecSmrgint 274705b261ecSmrgProcAllocColorPlanes(ClientPtr client) 274805b261ecSmrg{ 274905b261ecSmrg ColormapPtr pcmp; 27504642e01fSmrg int rc; 2751f7df2e56Smrg 275205b261ecSmrg REQUEST(xAllocColorPlanesReq); 275305b261ecSmrg 275405b261ecSmrg REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 2755f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2756f7df2e56Smrg client, DixAddAccess); 2757f7df2e56Smrg if (rc == Success) { 2758f7df2e56Smrg xAllocColorPlanesReply acpr; 2759f7df2e56Smrg int npixels; 2760f7df2e56Smrg long length; 2761f7df2e56Smrg Pixel *ppixels; 2762f7df2e56Smrg 2763f7df2e56Smrg npixels = stuff->colors; 2764f7df2e56Smrg if (!npixels) { 2765f7df2e56Smrg client->errorValue = npixels; 2766f7df2e56Smrg return BadValue; 2767f7df2e56Smrg } 2768f7df2e56Smrg if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) { 2769f7df2e56Smrg client->errorValue = stuff->contiguous; 2770f7df2e56Smrg return BadValue; 2771f7df2e56Smrg } 2772f7df2e56Smrg acpr = (xAllocColorPlanesReply) { 2773f7df2e56Smrg .type = X_Reply, 2774f7df2e56Smrg .sequenceNumber = client->sequence, 2775f7df2e56Smrg .nPixels = npixels 2776f7df2e56Smrg }; 2777f7df2e56Smrg length = (long) npixels *sizeof(Pixel); 2778f7df2e56Smrg 2779f7df2e56Smrg ppixels = malloc(length); 2780f7df2e56Smrg if (!ppixels) 27816747b715Smrg return BadAlloc; 2782f7df2e56Smrg if ((rc = AllocColorPlanes(client->index, pcmp, npixels, 2783f7df2e56Smrg (int) stuff->red, (int) stuff->green, 2784f7df2e56Smrg (int) stuff->blue, (Bool) stuff->contiguous, 2785f7df2e56Smrg ppixels, &acpr.redMask, &acpr.greenMask, 2786f7df2e56Smrg &acpr.blueMask))) { 27876747b715Smrg free(ppixels); 2788f7df2e56Smrg return rc; 2789f7df2e56Smrg } 2790f7df2e56Smrg acpr.length = bytes_to_int32(length); 279105b261ecSmrg#ifdef PANORAMIX 2792f7df2e56Smrg if (noPanoramiXExtension || !pcmp->pScreen->myNum) 279305b261ecSmrg#endif 2794f7df2e56Smrg { 2795f7df2e56Smrg WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 2796f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2797f7df2e56Smrg WriteSwappedDataToClient(client, length, ppixels); 2798f7df2e56Smrg } 2799f7df2e56Smrg free(ppixels); 28006747b715Smrg return Success; 280105b261ecSmrg } 2802f7df2e56Smrg else { 280305b261ecSmrg client->errorValue = stuff->cmap; 28046747b715Smrg return rc; 280505b261ecSmrg } 280605b261ecSmrg} 280705b261ecSmrg 280805b261ecSmrgint 280905b261ecSmrgProcFreeColors(ClientPtr client) 281005b261ecSmrg{ 281105b261ecSmrg ColormapPtr pcmp; 28124642e01fSmrg int rc; 2813f7df2e56Smrg 281405b261ecSmrg REQUEST(xFreeColorsReq); 281505b261ecSmrg 281605b261ecSmrg REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 2817f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2818f7df2e56Smrg client, DixRemoveAccess); 2819f7df2e56Smrg if (rc == Success) { 2820f7df2e56Smrg int count; 282105b261ecSmrg 2822f7df2e56Smrg if (pcmp->flags & AllAllocated) 2823f7df2e56Smrg return BadAccess; 2824f7df2e56Smrg count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); 2825f7df2e56Smrg return FreeColors(pcmp, client->index, count, 2826f7df2e56Smrg (Pixel *) &stuff[1], (Pixel) stuff->planeMask); 282705b261ecSmrg } 2828f7df2e56Smrg else { 282905b261ecSmrg client->errorValue = stuff->cmap; 28306747b715Smrg return rc; 283105b261ecSmrg } 283205b261ecSmrg} 283305b261ecSmrg 283405b261ecSmrgint 2835f7df2e56SmrgProcStoreColors(ClientPtr client) 283605b261ecSmrg{ 283705b261ecSmrg ColormapPtr pcmp; 28384642e01fSmrg int rc; 2839f7df2e56Smrg 284005b261ecSmrg REQUEST(xStoreColorsReq); 284105b261ecSmrg 284205b261ecSmrg REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 2843f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2844f7df2e56Smrg client, DixWriteAccess); 2845f7df2e56Smrg if (rc == Success) { 2846f7df2e56Smrg int count; 284705b261ecSmrg 284805b261ecSmrg count = (client->req_len << 2) - sizeof(xStoreColorsReq); 2849f7df2e56Smrg if (count % sizeof(xColorItem)) 2850f7df2e56Smrg return BadLength; 2851f7df2e56Smrg count /= sizeof(xColorItem); 2852f7df2e56Smrg return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client); 285305b261ecSmrg } 2854f7df2e56Smrg else { 285505b261ecSmrg client->errorValue = stuff->cmap; 28566747b715Smrg return rc; 285705b261ecSmrg } 285805b261ecSmrg} 285905b261ecSmrg 286005b261ecSmrgint 2861f7df2e56SmrgProcStoreNamedColor(ClientPtr client) 286205b261ecSmrg{ 286305b261ecSmrg ColormapPtr pcmp; 28644642e01fSmrg int rc; 2865f7df2e56Smrg 286605b261ecSmrg REQUEST(xStoreNamedColorReq); 286705b261ecSmrg 286805b261ecSmrg REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 2869f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2870f7df2e56Smrg client, DixWriteAccess); 2871f7df2e56Smrg if (rc == Success) { 2872f7df2e56Smrg xColorItem def; 2873f7df2e56Smrg 2874f7df2e56Smrg if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1], 2875f7df2e56Smrg stuff->nbytes, &def.red, &def.green, &def.blue)) { 2876f7df2e56Smrg def.flags = stuff->flags; 2877f7df2e56Smrg def.pixel = stuff->pixel; 2878f7df2e56Smrg return StoreColors(pcmp, 1, &def, client); 2879f7df2e56Smrg } 28806747b715Smrg return BadName; 288105b261ecSmrg } 2882f7df2e56Smrg else { 288305b261ecSmrg client->errorValue = stuff->cmap; 28846747b715Smrg return rc; 288505b261ecSmrg } 288605b261ecSmrg} 288705b261ecSmrg 288805b261ecSmrgint 288905b261ecSmrgProcQueryColors(ClientPtr client) 289005b261ecSmrg{ 289105b261ecSmrg ColormapPtr pcmp; 28924642e01fSmrg int rc; 2893f7df2e56Smrg 289405b261ecSmrg REQUEST(xQueryColorsReq); 289505b261ecSmrg 289605b261ecSmrg REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 2897f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2898f7df2e56Smrg client, DixReadAccess); 2899f7df2e56Smrg if (rc == Success) { 2900f7df2e56Smrg int count; 2901f7df2e56Smrg xrgb *prgbs; 2902f7df2e56Smrg xQueryColorsReply qcr; 2903f7df2e56Smrg 2904f7df2e56Smrg count = 2905f7df2e56Smrg bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); 2906f7df2e56Smrg prgbs = calloc(count, sizeof(xrgb)); 2907f7df2e56Smrg if (!prgbs && count) 29086747b715Smrg return BadAlloc; 2909f7df2e56Smrg if ((rc = 2910f7df2e56Smrg QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) { 2911f7df2e56Smrg free(prgbs); 2912f7df2e56Smrg return rc; 2913f7df2e56Smrg } 2914f7df2e56Smrg qcr = (xQueryColorsReply) { 2915f7df2e56Smrg .type = X_Reply, 2916f7df2e56Smrg .sequenceNumber = client->sequence, 2917f7df2e56Smrg .length = bytes_to_int32(count * sizeof(xrgb)), 2918f7df2e56Smrg .nColors = count 2919f7df2e56Smrg }; 2920f7df2e56Smrg WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 2921f7df2e56Smrg if (count) { 2922f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 2923f7df2e56Smrg WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 2924f7df2e56Smrg } 2925f7df2e56Smrg free(prgbs); 2926f7df2e56Smrg return Success; 2927f7df2e56Smrg 292805b261ecSmrg } 2929f7df2e56Smrg else { 293005b261ecSmrg client->errorValue = stuff->cmap; 29316747b715Smrg return rc; 293205b261ecSmrg } 2933f7df2e56Smrg} 293405b261ecSmrg 293505b261ecSmrgint 293605b261ecSmrgProcLookupColor(ClientPtr client) 293705b261ecSmrg{ 293805b261ecSmrg ColormapPtr pcmp; 29394642e01fSmrg int rc; 2940f7df2e56Smrg 294105b261ecSmrg REQUEST(xLookupColorReq); 294205b261ecSmrg 294305b261ecSmrg REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 2944f7df2e56Smrg rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP, 2945f7df2e56Smrg client, DixReadAccess); 2946f7df2e56Smrg if (rc == Success) { 2947f7df2e56Smrg CARD16 exactRed, exactGreen, exactBlue; 2948f7df2e56Smrg 2949f7df2e56Smrg if (OsLookupColor 2950f7df2e56Smrg (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes, 2951f7df2e56Smrg &exactRed, &exactGreen, &exactBlue)) { 2952f7df2e56Smrg xLookupColorReply lcr = { 2953f7df2e56Smrg .type = X_Reply, 2954f7df2e56Smrg .sequenceNumber = client->sequence, 2955f7df2e56Smrg .length = 0, 2956f7df2e56Smrg .exactRed = exactRed, 2957f7df2e56Smrg .exactGreen = exactGreen, 2958f7df2e56Smrg .exactBlue = exactBlue, 2959f7df2e56Smrg .screenRed = exactRed, 2960f7df2e56Smrg .screenGreen = exactGreen, 2961f7df2e56Smrg .screenBlue = exactBlue 2962f7df2e56Smrg }; 2963f7df2e56Smrg (*pcmp->pScreen->ResolveColor) (&lcr.screenRed, 2964f7df2e56Smrg &lcr.screenGreen, 2965f7df2e56Smrg &lcr.screenBlue, pcmp->pVisual); 2966f7df2e56Smrg WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 2967f7df2e56Smrg return Success; 2968f7df2e56Smrg } 29696747b715Smrg return BadName; 297005b261ecSmrg } 2971f7df2e56Smrg else { 297205b261ecSmrg client->errorValue = stuff->cmap; 29736747b715Smrg return rc; 297405b261ecSmrg } 297505b261ecSmrg} 297605b261ecSmrg 297705b261ecSmrgint 2978f7df2e56SmrgProcCreateCursor(ClientPtr client) 297905b261ecSmrg{ 2980f7df2e56Smrg CursorPtr pCursor; 2981f7df2e56Smrg PixmapPtr src; 2982f7df2e56Smrg PixmapPtr msk; 2983f7df2e56Smrg unsigned char *srcbits; 2984f7df2e56Smrg unsigned char *mskbits; 2985f7df2e56Smrg unsigned short width, height; 2986f7df2e56Smrg long n; 2987f7df2e56Smrg CursorMetricRec cm; 29884642e01fSmrg int rc; 298905b261ecSmrg 299005b261ecSmrg REQUEST(xCreateCursorReq); 299105b261ecSmrg 299205b261ecSmrg REQUEST_SIZE_MATCH(xCreateCursorReq); 299305b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 299405b261ecSmrg 2995f7df2e56Smrg rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP, 2996f7df2e56Smrg client, DixReadAccess); 29974642e01fSmrg if (rc != Success) { 2998f7df2e56Smrg client->errorValue = stuff->source; 2999f7df2e56Smrg return rc; 300005b261ecSmrg } 30014642e01fSmrg 3002f7df2e56Smrg if (src->drawable.depth != 1) 3003f7df2e56Smrg return (BadMatch); 3004f7df2e56Smrg 3005f7df2e56Smrg /* Find and validate cursor mask pixmap, if one is provided */ 3006f7df2e56Smrg if (stuff->mask != None) { 3007f7df2e56Smrg rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP, 3008f7df2e56Smrg client, DixReadAccess); 3009f7df2e56Smrg if (rc != Success) { 3010f7df2e56Smrg client->errorValue = stuff->mask; 3011f7df2e56Smrg return rc; 3012f7df2e56Smrg } 3013f7df2e56Smrg 3014f7df2e56Smrg if (src->drawable.width != msk->drawable.width 3015f7df2e56Smrg || src->drawable.height != msk->drawable.height 3016f7df2e56Smrg || src->drawable.depth != 1 || msk->drawable.depth != 1) 3017f7df2e56Smrg return BadMatch; 3018f7df2e56Smrg } 3019f7df2e56Smrg else 3020f7df2e56Smrg msk = NULL; 302105b261ecSmrg 302205b261ecSmrg width = src->drawable.width; 302305b261ecSmrg height = src->drawable.height; 302405b261ecSmrg 3025f7df2e56Smrg if (stuff->x > width || stuff->y > height) 3026f7df2e56Smrg return BadMatch; 302705b261ecSmrg 3028f7df2e56Smrg srcbits = calloc(BitmapBytePad(width), height); 302905b261ecSmrg if (!srcbits) 3030f7df2e56Smrg return BadAlloc; 3031f7df2e56Smrg n = BitmapBytePad(width) * height; 30326747b715Smrg mskbits = malloc(n); 3033f7df2e56Smrg if (!mskbits) { 3034f7df2e56Smrg free(srcbits); 3035f7df2e56Smrg return BadAlloc; 303605b261ecSmrg } 303705b261ecSmrg 3038f7df2e56Smrg (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height, 3039f7df2e56Smrg XYPixmap, 1, (void *) srcbits); 3040f7df2e56Smrg if (msk == (PixmapPtr) NULL) { 3041f7df2e56Smrg unsigned char *bits = mskbits; 3042f7df2e56Smrg 3043f7df2e56Smrg while (--n >= 0) 3044f7df2e56Smrg *bits++ = ~0; 304505b261ecSmrg } 3046f7df2e56Smrg else { 3047f7df2e56Smrg /* zeroing the (pad) bits helps some ddx cursor handling */ 3048f7df2e56Smrg memset((char *) mskbits, 0, n); 3049f7df2e56Smrg (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width, 3050f7df2e56Smrg height, XYPixmap, 1, 3051f7df2e56Smrg (void *) mskbits); 305205b261ecSmrg } 305305b261ecSmrg cm.width = width; 305405b261ecSmrg cm.height = height; 305505b261ecSmrg cm.xhot = stuff->x; 305605b261ecSmrg cm.yhot = stuff->y; 30574642e01fSmrg rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 3058f7df2e56Smrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 3059f7df2e56Smrg stuff->backRed, stuff->backGreen, stuff->backBlue, 3060f7df2e56Smrg &pCursor, client, stuff->cid); 306105b261ecSmrg 30624642e01fSmrg if (rc != Success) 3063f7df2e56Smrg goto bail; 3064f7df2e56Smrg if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) { 3065f7df2e56Smrg rc = BadAlloc; 3066f7df2e56Smrg goto bail; 3067f7df2e56Smrg } 30684642e01fSmrg 30696747b715Smrg return Success; 3070f7df2e56Smrg bail: 3071f7df2e56Smrg free(srcbits); 3072f7df2e56Smrg free(mskbits); 3073f7df2e56Smrg return rc; 307405b261ecSmrg} 307505b261ecSmrg 307605b261ecSmrgint 3077f7df2e56SmrgProcCreateGlyphCursor(ClientPtr client) 307805b261ecSmrg{ 307905b261ecSmrg CursorPtr pCursor; 308005b261ecSmrg int res; 308105b261ecSmrg 308205b261ecSmrg REQUEST(xCreateGlyphCursorReq); 308305b261ecSmrg 308405b261ecSmrg REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 308505b261ecSmrg LEGAL_NEW_RESOURCE(stuff->cid, client); 308605b261ecSmrg 308705b261ecSmrg res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 3088f7df2e56Smrg stuff->mask, stuff->maskChar, 3089f7df2e56Smrg stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 3090f7df2e56Smrg stuff->backRed, stuff->backGreen, stuff->backBlue, 3091f7df2e56Smrg &pCursor, client, stuff->cid); 309205b261ecSmrg if (res != Success) 3093f7df2e56Smrg return res; 3094f7df2e56Smrg if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) 3095f7df2e56Smrg return Success; 309605b261ecSmrg return BadAlloc; 309705b261ecSmrg} 309805b261ecSmrg 309905b261ecSmrgint 3100f7df2e56SmrgProcFreeCursor(ClientPtr client) 310105b261ecSmrg{ 310205b261ecSmrg CursorPtr pCursor; 31034642e01fSmrg int rc; 3104f7df2e56Smrg 310505b261ecSmrg REQUEST(xResourceReq); 310605b261ecSmrg 310705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 3108f7df2e56Smrg rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR, 3109f7df2e56Smrg client, DixDestroyAccess); 3110f7df2e56Smrg if (rc == Success) { 3111d566a54bSmrg if (pCursor == rootCursor) { 3112d566a54bSmrg client->errorValue = stuff->id; 3113d566a54bSmrg return BadCursor; 3114d566a54bSmrg } 3115f7df2e56Smrg FreeResource(stuff->id, RT_NONE); 3116f7df2e56Smrg return Success; 311705b261ecSmrg } 3118f7df2e56Smrg else { 3119f7df2e56Smrg client->errorValue = stuff->id; 3120f7df2e56Smrg return rc; 312105b261ecSmrg } 312205b261ecSmrg} 312305b261ecSmrg 312405b261ecSmrgint 3125f7df2e56SmrgProcQueryBestSize(ClientPtr client) 312605b261ecSmrg{ 3127f7df2e56Smrg xQueryBestSizeReply reply; 312805b261ecSmrg DrawablePtr pDraw; 312905b261ecSmrg ScreenPtr pScreen; 313005b261ecSmrg int rc; 3131f7df2e56Smrg 313205b261ecSmrg REQUEST(xQueryBestSizeReq); 313305b261ecSmrg REQUEST_SIZE_MATCH(xQueryBestSizeReq); 313405b261ecSmrg 3135f7df2e56Smrg if ((stuff->class != CursorShape) && 3136f7df2e56Smrg (stuff->class != TileShape) && (stuff->class != StippleShape)) { 3137f7df2e56Smrg client->errorValue = stuff->class; 31386747b715Smrg return BadValue; 313905b261ecSmrg } 314005b261ecSmrg 314105b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 3142f7df2e56Smrg DixGetAttrAccess); 314305b261ecSmrg if (rc != Success) 3144f7df2e56Smrg return rc; 314505b261ecSmrg if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 3146f7df2e56Smrg return BadMatch; 314705b261ecSmrg pScreen = pDraw->pScreen; 31484642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 31494642e01fSmrg if (rc != Success) 3150f7df2e56Smrg return rc; 3151f7df2e56Smrg (*pScreen->QueryBestSize) (stuff->class, &stuff->width, 3152f7df2e56Smrg &stuff->height, pScreen); 3153f7df2e56Smrg reply = (xQueryBestSizeReply) { 3154f7df2e56Smrg .type = X_Reply, 3155f7df2e56Smrg .sequenceNumber = client->sequence, 3156f7df2e56Smrg .length = 0, 3157f7df2e56Smrg .width = stuff->width, 3158f7df2e56Smrg .height = stuff->height 3159f7df2e56Smrg }; 316005b261ecSmrg WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 31616747b715Smrg return Success; 316205b261ecSmrg} 316305b261ecSmrg 316405b261ecSmrgint 3165f7df2e56SmrgProcSetScreenSaver(ClientPtr client) 316605b261ecSmrg{ 31674642e01fSmrg int rc, i, blankingOption, exposureOption; 3168f7df2e56Smrg 316905b261ecSmrg REQUEST(xSetScreenSaverReq); 317005b261ecSmrg REQUEST_SIZE_MATCH(xSetScreenSaverReq); 31714642e01fSmrg 31724642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 3173f7df2e56Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3174f7df2e56Smrg DixSetAttrAccess); 3175f7df2e56Smrg if (rc != Success) 3176f7df2e56Smrg return rc; 31774642e01fSmrg } 31784642e01fSmrg 317905b261ecSmrg blankingOption = stuff->preferBlank; 318005b261ecSmrg if ((blankingOption != DontPreferBlanking) && 318105b261ecSmrg (blankingOption != PreferBlanking) && 3182f7df2e56Smrg (blankingOption != DefaultBlanking)) { 3183f7df2e56Smrg client->errorValue = blankingOption; 318405b261ecSmrg return BadValue; 318505b261ecSmrg } 318605b261ecSmrg exposureOption = stuff->allowExpose; 318705b261ecSmrg if ((exposureOption != DontAllowExposures) && 318805b261ecSmrg (exposureOption != AllowExposures) && 3189f7df2e56Smrg (exposureOption != DefaultExposures)) { 3190f7df2e56Smrg client->errorValue = exposureOption; 319105b261ecSmrg return BadValue; 319205b261ecSmrg } 3193f7df2e56Smrg if (stuff->timeout < -1) { 3194f7df2e56Smrg client->errorValue = stuff->timeout; 319505b261ecSmrg return BadValue; 319605b261ecSmrg } 3197f7df2e56Smrg if (stuff->interval < -1) { 3198f7df2e56Smrg client->errorValue = stuff->interval; 319905b261ecSmrg return BadValue; 320005b261ecSmrg } 320105b261ecSmrg 320205b261ecSmrg if (blankingOption == DefaultBlanking) 3203f7df2e56Smrg ScreenSaverBlanking = defaultScreenSaverBlanking; 320405b261ecSmrg else 3205f7df2e56Smrg ScreenSaverBlanking = blankingOption; 320605b261ecSmrg if (exposureOption == DefaultExposures) 3207f7df2e56Smrg ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 320805b261ecSmrg else 3209f7df2e56Smrg ScreenSaverAllowExposures = exposureOption; 321005b261ecSmrg 321105b261ecSmrg if (stuff->timeout >= 0) 3212f7df2e56Smrg ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 3213f7df2e56Smrg else 3214f7df2e56Smrg ScreenSaverTime = defaultScreenSaverTime; 321505b261ecSmrg if (stuff->interval >= 0) 3216f7df2e56Smrg ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 321705b261ecSmrg else 3218f7df2e56Smrg ScreenSaverInterval = defaultScreenSaverInterval; 321905b261ecSmrg 322005b261ecSmrg SetScreenSaverTimer(); 32216747b715Smrg return Success; 322205b261ecSmrg} 322305b261ecSmrg 322405b261ecSmrgint 322505b261ecSmrgProcGetScreenSaver(ClientPtr client) 322605b261ecSmrg{ 322705b261ecSmrg xGetScreenSaverReply rep; 32284642e01fSmrg int rc, i; 3229f7df2e56Smrg 323005b261ecSmrg REQUEST_SIZE_MATCH(xReq); 32314642e01fSmrg 32324642e01fSmrg for (i = 0; i < screenInfo.numScreens; i++) { 3233f7df2e56Smrg rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3234f7df2e56Smrg DixGetAttrAccess); 3235f7df2e56Smrg if (rc != Success) 3236f7df2e56Smrg return rc; 3237f7df2e56Smrg } 3238f7df2e56Smrg 3239f7df2e56Smrg rep = (xGetScreenSaverReply) { 3240f7df2e56Smrg .type = X_Reply, 3241f7df2e56Smrg .sequenceNumber = client->sequence, 3242f7df2e56Smrg .length = 0, 3243f7df2e56Smrg .timeout = ScreenSaverTime / MILLI_PER_SECOND, 3244f7df2e56Smrg .interval = ScreenSaverInterval / MILLI_PER_SECOND, 3245f7df2e56Smrg .preferBlanking = ScreenSaverBlanking, 3246f7df2e56Smrg .allowExposures = ScreenSaverAllowExposures 3247f7df2e56Smrg }; 324805b261ecSmrg WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 32496747b715Smrg return Success; 325005b261ecSmrg} 325105b261ecSmrg 325205b261ecSmrgint 325305b261ecSmrgProcChangeHosts(ClientPtr client) 325405b261ecSmrg{ 325505b261ecSmrg REQUEST(xChangeHostsReq); 325605b261ecSmrg 325705b261ecSmrg REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 325805b261ecSmrg 3259f7df2e56Smrg if (stuff->mode == HostInsert) 3260f7df2e56Smrg return AddHost(client, (int) stuff->hostFamily, 3261f7df2e56Smrg stuff->hostLength, (void *) &stuff[1]); 32626747b715Smrg if (stuff->mode == HostDelete) 3263f7df2e56Smrg return RemoveHost(client, (int) stuff->hostFamily, 3264f7df2e56Smrg stuff->hostLength, (void *) &stuff[1]); 32656747b715Smrg client->errorValue = stuff->mode; 32666747b715Smrg return BadValue; 326705b261ecSmrg} 326805b261ecSmrg 326905b261ecSmrgint 327005b261ecSmrgProcListHosts(ClientPtr client) 327105b261ecSmrg{ 327205b261ecSmrg xListHostsReply reply; 3273f7df2e56Smrg int len, nHosts, result; 3274f7df2e56Smrg BOOL enabled; 3275f7df2e56Smrg void *pdata; 3276f7df2e56Smrg 327705b261ecSmrg /* REQUEST(xListHostsReq); */ 327805b261ecSmrg 327905b261ecSmrg REQUEST_SIZE_MATCH(xListHostsReq); 328005b261ecSmrg 328105b261ecSmrg /* untrusted clients can't list hosts */ 32824642e01fSmrg result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); 32834642e01fSmrg if (result != Success) 3284f7df2e56Smrg return result; 328505b261ecSmrg 3286f7df2e56Smrg result = GetHosts(&pdata, &nHosts, &len, &enabled); 328705b261ecSmrg if (result != Success) 3288f7df2e56Smrg return result; 3289f7df2e56Smrg 3290f7df2e56Smrg reply = (xListHostsReply) { 3291f7df2e56Smrg .type = X_Reply, 3292f7df2e56Smrg .enabled = enabled, 3293f7df2e56Smrg .sequenceNumber = client->sequence, 3294f7df2e56Smrg .length = bytes_to_int32(len), 3295f7df2e56Smrg .nHosts = nHosts 3296f7df2e56Smrg }; 329705b261ecSmrg WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 3298f7df2e56Smrg if (nHosts) { 3299f7df2e56Smrg client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 3300f7df2e56Smrg WriteSwappedDataToClient(client, len, pdata); 330105b261ecSmrg } 33026747b715Smrg free(pdata); 33036747b715Smrg return Success; 330405b261ecSmrg} 330505b261ecSmrg 330605b261ecSmrgint 330705b261ecSmrgProcChangeAccessControl(ClientPtr client) 330805b261ecSmrg{ 330905b261ecSmrg REQUEST(xSetAccessControlReq); 331005b261ecSmrg 331105b261ecSmrg REQUEST_SIZE_MATCH(xSetAccessControlReq); 3312f7df2e56Smrg if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) { 3313f7df2e56Smrg client->errorValue = stuff->mode; 331405b261ecSmrg return BadValue; 331505b261ecSmrg } 33166747b715Smrg return ChangeAccessControl(client, stuff->mode == EnableAccess); 331705b261ecSmrg} 331805b261ecSmrg 331905b261ecSmrg/********************* 332005b261ecSmrg * CloseDownRetainedResources 332105b261ecSmrg * 3322f7df2e56Smrg * Find all clients that are gone and have terminated in RetainTemporary 332305b261ecSmrg * and destroy their resources. 332405b261ecSmrg *********************/ 332505b261ecSmrg 332605b261ecSmrgstatic void 332705b261ecSmrgCloseDownRetainedResources(void) 332805b261ecSmrg{ 332905b261ecSmrg int i; 333005b261ecSmrg ClientPtr client; 333105b261ecSmrg 3332f7df2e56Smrg for (i = 1; i < currentMaxClients; i++) { 333305b261ecSmrg client = clients[i]; 333405b261ecSmrg if (client && (client->closeDownMode == RetainTemporary) 3335f7df2e56Smrg && (client->clientGone)) 3336f7df2e56Smrg CloseDownClient(client); 333705b261ecSmrg } 333805b261ecSmrg} 333905b261ecSmrg 334005b261ecSmrgint 334105b261ecSmrgProcKillClient(ClientPtr client) 334205b261ecSmrg{ 334305b261ecSmrg REQUEST(xResourceReq); 334405b261ecSmrg ClientPtr killclient; 334505b261ecSmrg int rc; 334605b261ecSmrg 334705b261ecSmrg REQUEST_SIZE_MATCH(xResourceReq); 3348f7df2e56Smrg if (stuff->id == AllTemporary) { 3349f7df2e56Smrg CloseDownRetainedResources(); 33506747b715Smrg return Success; 335105b261ecSmrg } 335205b261ecSmrg 335305b261ecSmrg rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 335405b261ecSmrg if (rc == Success) { 3355f7df2e56Smrg CloseDownClient(killclient); 3356f7df2e56Smrg if (client == killclient) { 3357f7df2e56Smrg /* force yield and return Success, so that Dispatch() 3358f7df2e56Smrg * doesn't try to touch client 3359f7df2e56Smrg */ 3360f7df2e56Smrg isItTimeToYield = TRUE; 3361f7df2e56Smrg } 3362f7df2e56Smrg return Success; 336305b261ecSmrg } 336405b261ecSmrg else 3365f7df2e56Smrg return rc; 336605b261ecSmrg} 336705b261ecSmrg 336805b261ecSmrgint 336905b261ecSmrgProcSetFontPath(ClientPtr client) 337005b261ecSmrg{ 337105b261ecSmrg unsigned char *ptr; 337205b261ecSmrg unsigned long nbytes, total; 337305b261ecSmrg long nfonts; 33746747b715Smrg int n; 3375f7df2e56Smrg 337605b261ecSmrg REQUEST(xSetFontPathReq); 3377f7df2e56Smrg 337805b261ecSmrg REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 3379f7df2e56Smrg 338005b261ecSmrg nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 338105b261ecSmrg total = nbytes; 3382f7df2e56Smrg ptr = (unsigned char *) &stuff[1]; 338305b261ecSmrg nfonts = stuff->nFonts; 3384f7df2e56Smrg while (--nfonts >= 0) { 3385f7df2e56Smrg if ((total == 0) || (total < (n = (*ptr + 1)))) 3386f7df2e56Smrg return BadLength; 3387f7df2e56Smrg total -= n; 3388f7df2e56Smrg ptr += n; 338905b261ecSmrg } 339005b261ecSmrg if (total >= 4) 3391f7df2e56Smrg return BadLength; 3392f7df2e56Smrg return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]); 339305b261ecSmrg} 339405b261ecSmrg 339505b261ecSmrgint 339605b261ecSmrgProcGetFontPath(ClientPtr client) 339705b261ecSmrg{ 339805b261ecSmrg xGetFontPathReply reply; 33994642e01fSmrg int rc, stringLens, numpaths; 340005b261ecSmrg unsigned char *bufferStart; 3401f7df2e56Smrg 340205b261ecSmrg /* REQUEST (xReq); */ 340305b261ecSmrg 340405b261ecSmrg REQUEST_SIZE_MATCH(xReq); 34054642e01fSmrg rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); 34064642e01fSmrg if (rc != Success) 3407f7df2e56Smrg return rc; 340805b261ecSmrg 3409f7df2e56Smrg reply = (xGetFontPathReply) { 3410f7df2e56Smrg .type = X_Reply, 3411f7df2e56Smrg .sequenceNumber = client->sequence, 3412f7df2e56Smrg .length = bytes_to_int32(stringLens + numpaths), 3413f7df2e56Smrg .nPaths = numpaths 3414f7df2e56Smrg }; 341505b261ecSmrg 341605b261ecSmrg WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 341705b261ecSmrg if (stringLens || numpaths) 3418f7df2e56Smrg WriteToClient(client, stringLens + numpaths, bufferStart); 34196747b715Smrg return Success; 342005b261ecSmrg} 342105b261ecSmrg 342205b261ecSmrgint 342305b261ecSmrgProcChangeCloseDownMode(ClientPtr client) 342405b261ecSmrg{ 34254642e01fSmrg int rc; 3426f7df2e56Smrg 342705b261ecSmrg REQUEST(xSetCloseDownModeReq); 342805b261ecSmrg REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 34294642e01fSmrg 34304642e01fSmrg rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); 34314642e01fSmrg if (rc != Success) 3432f7df2e56Smrg return rc; 34334642e01fSmrg 343405b261ecSmrg if ((stuff->mode == AllTemporary) || 3435f7df2e56Smrg (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) { 3436f7df2e56Smrg client->closeDownMode = stuff->mode; 3437f7df2e56Smrg return Success; 343805b261ecSmrg } 3439f7df2e56Smrg else { 3440f7df2e56Smrg client->errorValue = stuff->mode; 3441f7df2e56Smrg return BadValue; 344205b261ecSmrg } 344305b261ecSmrg} 344405b261ecSmrg 3445f7df2e56Smrgint 3446f7df2e56SmrgProcForceScreenSaver(ClientPtr client) 3447f7df2e56Smrg{ 34484642e01fSmrg int rc; 3449f7df2e56Smrg 345005b261ecSmrg REQUEST(xForceScreenSaverReq); 345105b261ecSmrg 345205b261ecSmrg REQUEST_SIZE_MATCH(xForceScreenSaverReq); 3453f7df2e56Smrg 3454f7df2e56Smrg if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) { 3455f7df2e56Smrg client->errorValue = stuff->mode; 345605b261ecSmrg return BadValue; 345705b261ecSmrg } 3458f7df2e56Smrg rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode); 34594642e01fSmrg if (rc != Success) 3460f7df2e56Smrg return rc; 34616747b715Smrg return Success; 346205b261ecSmrg} 346305b261ecSmrg 3464f7df2e56Smrgint 3465f7df2e56SmrgProcNoOperation(ClientPtr client) 346605b261ecSmrg{ 346705b261ecSmrg REQUEST_AT_LEAST_SIZE(xReq); 3468f7df2e56Smrg 346905b261ecSmrg /* noop -- don't do anything */ 34706747b715Smrg return Success; 347105b261ecSmrg} 347205b261ecSmrg 347305b261ecSmrg/********************** 347405b261ecSmrg * CloseDownClient 347505b261ecSmrg * 347605b261ecSmrg * Client can either mark his resources destroy or retain. If retained and 347705b261ecSmrg * then killed again, the client is really destroyed. 347805b261ecSmrg *********************/ 347905b261ecSmrg 348005b261ecSmrgchar dispatchExceptionAtReset = DE_RESET; 34815a112b11Smrgint terminateDelay = 0; 348205b261ecSmrg 348305b261ecSmrgvoid 348405b261ecSmrgCloseDownClient(ClientPtr client) 348505b261ecSmrg{ 348605b261ecSmrg Bool really_close_down = client->clientGone || 3487f7df2e56Smrg client->closeDownMode == DestroyAll; 348805b261ecSmrg 3489f7df2e56Smrg if (!client->clientGone) { 3490f7df2e56Smrg /* ungrab server if grabbing client dies */ 3491f7df2e56Smrg if (grabState != GrabNone && grabClient == client) { 3492f7df2e56Smrg UngrabServer(client); 3493f7df2e56Smrg } 3494f7df2e56Smrg BITCLEAR(grabWaiters, client->index); 3495f7df2e56Smrg DeleteClientFromAnySelections(client); 3496f7df2e56Smrg ReleaseActiveGrabs(client); 3497f7df2e56Smrg DeleteClientFontStuff(client); 3498f7df2e56Smrg if (!really_close_down) { 3499f7df2e56Smrg /* This frees resources that should never be retained 3500f7df2e56Smrg * no matter what the close down mode is. Actually we 3501f7df2e56Smrg * could do this unconditionally, but it's probably 3502f7df2e56Smrg * better not to traverse all the client's resources 3503f7df2e56Smrg * twice (once here, once a few lines down in 3504f7df2e56Smrg * FreeClientResources) in the common case of 3505f7df2e56Smrg * really_close_down == TRUE. 3506f7df2e56Smrg */ 3507f7df2e56Smrg FreeClientNeverRetainResources(client); 3508f7df2e56Smrg client->clientState = ClientStateRetained; 3509f7df2e56Smrg if (ClientStateCallback) { 3510f7df2e56Smrg NewClientInfoRec clientinfo; 3511f7df2e56Smrg 3512f7df2e56Smrg clientinfo.client = client; 3513f7df2e56Smrg clientinfo.prefix = (xConnSetupPrefix *) NULL; 3514f7df2e56Smrg clientinfo.setup = (xConnSetup *) NULL; 3515f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3516f7df2e56Smrg } 3517f7df2e56Smrg } 3518f7df2e56Smrg client->clientGone = TRUE; /* so events aren't sent to client */ 3519f7df2e56Smrg if (ClientIsAsleep(client)) 3520f7df2e56Smrg ClientSignal(client); 3521f7df2e56Smrg ProcessWorkQueueZombies(); 3522f7df2e56Smrg CloseDownConnection(client); 35237e31ba66Smrg output_pending_clear(client); 35247e31ba66Smrg mark_client_not_ready(client); 3525f7df2e56Smrg 3526f7df2e56Smrg /* If the client made it to the Running stage, nClients has 3527f7df2e56Smrg * been incremented on its behalf, so we need to decrement it 3528f7df2e56Smrg * now. If it hasn't gotten to Running, nClients has *not* 3529f7df2e56Smrg * been incremented, so *don't* decrement it. 3530f7df2e56Smrg */ 3531f7df2e56Smrg if (client->clientState != ClientStateInitial) { 3532f7df2e56Smrg --nClients; 3533f7df2e56Smrg } 3534f7df2e56Smrg } 3535f7df2e56Smrg 3536f7df2e56Smrg if (really_close_down) { 3537f7df2e56Smrg if (client->clientState == ClientStateRunning && nClients == 0) 35385a112b11Smrg SetDispatchExceptionTimer(); 3539f7df2e56Smrg 3540f7df2e56Smrg client->clientState = ClientStateGone; 3541f7df2e56Smrg if (ClientStateCallback) { 3542f7df2e56Smrg NewClientInfoRec clientinfo; 3543f7df2e56Smrg 3544f7df2e56Smrg clientinfo.client = client; 3545f7df2e56Smrg clientinfo.prefix = (xConnSetupPrefix *) NULL; 3546f7df2e56Smrg clientinfo.setup = (xConnSetup *) NULL; 3547f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3548f7df2e56Smrg } 3549f7df2e56Smrg TouchListenerGone(client->clientAsMask); 35505a112b11Smrg GestureListenerGone(client->clientAsMask); 3551f7df2e56Smrg FreeClientResources(client); 3552f7df2e56Smrg /* Disable client ID tracking. This must be done after 3553f7df2e56Smrg * ClientStateCallback. */ 3554f7df2e56Smrg ReleaseClientIds(client); 355505b261ecSmrg#ifdef XSERVER_DTRACE 3556f7df2e56Smrg XSERVER_CLIENT_DISCONNECT(client->index); 3557f7df2e56Smrg#endif 3558f7df2e56Smrg if (client->index < nextFreeClientID) 3559f7df2e56Smrg nextFreeClientID = client->index; 3560f7df2e56Smrg clients[client->index] = NullClient; 3561f7df2e56Smrg SmartLastClient = NullClient; 3562f7df2e56Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 356305b261ecSmrg 3564f7df2e56Smrg while (!clients[currentMaxClients - 1]) 3565f7df2e56Smrg currentMaxClients--; 356605b261ecSmrg } 35675a112b11Smrg 35685a112b11Smrg if (ShouldDisconnectRemainingClients()) 35695a112b11Smrg SetDispatchExceptionTimer(); 357005b261ecSmrg} 357105b261ecSmrg 357205b261ecSmrgstatic void 357305b261ecSmrgKillAllClients(void) 357405b261ecSmrg{ 357505b261ecSmrg int i; 3576f7df2e56Smrg 3577f7df2e56Smrg for (i = 1; i < currentMaxClients; i++) 357805b261ecSmrg if (clients[i]) { 357905b261ecSmrg /* Make sure Retained clients are released. */ 358005b261ecSmrg clients[i]->closeDownMode = DestroyAll; 3581f7df2e56Smrg CloseDownClient(clients[i]); 358205b261ecSmrg } 358305b261ecSmrg} 358405b261ecSmrg 3585f7df2e56Smrgvoid 3586f7df2e56SmrgInitClient(ClientPtr client, int i, void *ospriv) 358705b261ecSmrg{ 358805b261ecSmrg client->index = i; 35897e31ba66Smrg xorg_list_init(&client->ready); 35907e31ba66Smrg xorg_list_init(&client->output_pending); 3591f7df2e56Smrg client->clientAsMask = ((Mask) i) << CLIENTOFFSET; 35924642e01fSmrg client->closeDownMode = i ? DestroyAll : RetainPermanent; 359305b261ecSmrg client->requestVector = InitialVector; 359405b261ecSmrg client->osPrivate = ospriv; 3595f7df2e56Smrg QueryMinMaxKeyCodes(&client->minKC, &client->maxKC); 359605b261ecSmrg client->smart_start_tick = SmartScheduleTime; 359705b261ecSmrg client->smart_stop_tick = SmartScheduleTime; 3598f7df2e56Smrg client->clientIds = NULL; 359905b261ecSmrg} 360005b261ecSmrg 360105b261ecSmrg/************************ 360205b261ecSmrg * int NextAvailableClient(ospriv) 360305b261ecSmrg * 360405b261ecSmrg * OS dependent portion can't assign client id's because of CloseDownModes. 360505b261ecSmrg * Returns NULL if there are no free clients. 360605b261ecSmrg *************************/ 360705b261ecSmrg 3608f7df2e56SmrgClientPtr 3609f7df2e56SmrgNextAvailableClient(void *ospriv) 361005b261ecSmrg{ 361105b261ecSmrg int i; 361205b261ecSmrg ClientPtr client; 361305b261ecSmrg xReq data; 361405b261ecSmrg 361505b261ecSmrg i = nextFreeClientID; 3616f7df2e56Smrg if (i == LimitClients) 3617f7df2e56Smrg return (ClientPtr) NULL; 3618f7df2e56Smrg clients[i] = client = 3619f7df2e56Smrg dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT); 362005b261ecSmrg if (!client) 3621f7df2e56Smrg return (ClientPtr) NULL; 362205b261ecSmrg InitClient(client, i, ospriv); 3623f7df2e56Smrg if (!InitClientResources(client)) { 3624f7df2e56Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3625f7df2e56Smrg return (ClientPtr) NULL; 362605b261ecSmrg } 362705b261ecSmrg data.reqType = 1; 36286747b715Smrg data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); 3629f7df2e56Smrg if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) { 3630f7df2e56Smrg FreeClientResources(client); 3631f7df2e56Smrg dixFreeObjectWithPrivates(client, PRIVATE_CLIENT); 3632f7df2e56Smrg return (ClientPtr) NULL; 363305b261ecSmrg } 363405b261ecSmrg if (i == currentMaxClients) 3635f7df2e56Smrg currentMaxClients++; 3636f7df2e56Smrg while ((nextFreeClientID < LimitClients) && clients[nextFreeClientID]) 3637f7df2e56Smrg nextFreeClientID++; 3638f7df2e56Smrg 3639f7df2e56Smrg /* Enable client ID tracking. This must be done before 3640f7df2e56Smrg * ClientStateCallback. */ 3641f7df2e56Smrg ReserveClientIds(client); 3642f7df2e56Smrg 3643f7df2e56Smrg if (ClientStateCallback) { 3644f7df2e56Smrg NewClientInfoRec clientinfo; 364505b261ecSmrg 3646f7df2e56Smrg clientinfo.client = client; 3647f7df2e56Smrg clientinfo.prefix = (xConnSetupPrefix *) NULL; 364805b261ecSmrg clientinfo.setup = (xConnSetup *) NULL; 3649f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3650f7df2e56Smrg } 36516747b715Smrg return client; 365205b261ecSmrg} 365305b261ecSmrg 365405b261ecSmrgint 365505b261ecSmrgProcInitialConnection(ClientPtr client) 365605b261ecSmrg{ 365705b261ecSmrg REQUEST(xReq); 365805b261ecSmrg xConnClientPrefix *prefix; 365905b261ecSmrg int whichbyte = 1; 3660f7df2e56Smrg char order; 366105b261ecSmrg 3662f7df2e56Smrg prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq); 3663f7df2e56Smrg order = prefix->byteOrder; 3664f7df2e56Smrg if (order != 'l' && order != 'B' && order != 'r' && order != 'R') 36656747b715Smrg return client->noClientException = -1; 3666f7df2e56Smrg if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || 3667f7df2e56Smrg (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { 366805b261ecSmrg client->swapped = TRUE; 366905b261ecSmrg SwapConnClientPrefix(prefix); 367005b261ecSmrg } 367105b261ecSmrg stuff->reqType = 2; 36726747b715Smrg stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + 3673f7df2e56Smrg bytes_to_int32(prefix->nbytesAuthString); 3674f7df2e56Smrg if (client->swapped) { 3675f7df2e56Smrg swaps(&stuff->length); 3676f7df2e56Smrg } 3677f7df2e56Smrg if (order == 'r' || order == 'R') { 3678f7df2e56Smrg client->local = FALSE; 367905b261ecSmrg } 368005b261ecSmrg ResetCurrentRequest(client); 36816747b715Smrg return Success; 368205b261ecSmrg} 368305b261ecSmrg 36844642e01fSmrgstatic int 3685f7df2e56SmrgSendConnSetup(ClientPtr client, const char *reason) 368605b261ecSmrg{ 368705b261ecSmrg xWindowRoot *root; 368805b261ecSmrg int i; 368905b261ecSmrg int numScreens; 3690f7df2e56Smrg char *lConnectionInfo; 3691f7df2e56Smrg xConnSetupPrefix *lconnSetupPrefix; 369205b261ecSmrg 3693f7df2e56Smrg if (reason) { 3694f7df2e56Smrg xConnSetupPrefix csp; 3695f7df2e56Smrg 3696f7df2e56Smrg csp.success = xFalse; 3697f7df2e56Smrg csp.lengthReason = strlen(reason); 3698f7df2e56Smrg csp.length = bytes_to_int32(csp.lengthReason); 3699f7df2e56Smrg csp.majorVersion = X_PROTOCOL; 3700f7df2e56Smrg csp.minorVersion = X_PROTOCOL_REVISION; 3701f7df2e56Smrg if (client->swapped) 3702f7df2e56Smrg WriteSConnSetupPrefix(client, &csp); 3703f7df2e56Smrg else 3704f7df2e56Smrg WriteToClient(client, sz_xConnSetupPrefix, &csp); 3705f7df2e56Smrg WriteToClient(client, (int) csp.lengthReason, reason); 3706f7df2e56Smrg return client->noClientException = -1; 370705b261ecSmrg } 370805b261ecSmrg 370905b261ecSmrg numScreens = screenInfo.numScreens; 371005b261ecSmrg lConnectionInfo = ConnectionInfo; 371105b261ecSmrg lconnSetupPrefix = &connSetupPrefix; 371205b261ecSmrg 371305b261ecSmrg /* We're about to start speaking X protocol back to the client by 371405b261ecSmrg * sending the connection setup info. This means the authorization 371505b261ecSmrg * step is complete, and we can count the client as an 371605b261ecSmrg * authorized one. 371705b261ecSmrg */ 371805b261ecSmrg nClients++; 371905b261ecSmrg 372005b261ecSmrg client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 372105b261ecSmrg client->sequence = 0; 3722f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask; 3723f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 372405b261ecSmrg#ifdef MATCH_CLIENT_ENDIAN 3725f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client); 3726f7df2e56Smrg ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client); 372705b261ecSmrg#endif 372805b261ecSmrg /* fill in the "currentInputMask" */ 3729f7df2e56Smrg root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart); 373005b261ecSmrg#ifdef PANORAMIX 373105b261ecSmrg if (noPanoramiXExtension) 3732f7df2e56Smrg numScreens = screenInfo.numScreens; 3733f7df2e56Smrg else 3734f7df2e56Smrg numScreens = ((xConnSetup *) ConnectionInfo)->numRoots; 373505b261ecSmrg#endif 373605b261ecSmrg 3737f7df2e56Smrg for (i = 0; i < numScreens; i++) { 3738f7df2e56Smrg unsigned int j; 3739f7df2e56Smrg xDepth *pDepth; 3740f7df2e56Smrg WindowPtr pRoot = screenInfo.screens[i]->root; 374105b261ecSmrg 37426747b715Smrg root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot); 3743f7df2e56Smrg pDepth = (xDepth *) (root + 1); 3744f7df2e56Smrg for (j = 0; j < root->nDepths; j++) { 3745f7df2e56Smrg pDepth = (xDepth *) (((char *) (pDepth + 1)) + 3746f7df2e56Smrg pDepth->nVisuals * sizeof(xVisualType)); 3747f7df2e56Smrg } 3748f7df2e56Smrg root = (xWindowRoot *) pDepth; 374905b261ecSmrg } 375005b261ecSmrg 3751f7df2e56Smrg if (client->swapped) { 3752f7df2e56Smrg WriteSConnSetupPrefix(client, lconnSetupPrefix); 3753f7df2e56Smrg WriteSConnectionInfo(client, 3754f7df2e56Smrg (unsigned long) (lconnSetupPrefix->length << 2), 3755f7df2e56Smrg lConnectionInfo); 375605b261ecSmrg } 3757f7df2e56Smrg else { 3758f7df2e56Smrg WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix); 3759f7df2e56Smrg WriteToClient(client, (int) (lconnSetupPrefix->length << 2), 3760f7df2e56Smrg lConnectionInfo); 376105b261ecSmrg } 376205b261ecSmrg client->clientState = ClientStateRunning; 3763f7df2e56Smrg if (ClientStateCallback) { 3764f7df2e56Smrg NewClientInfoRec clientinfo; 376505b261ecSmrg 3766f7df2e56Smrg clientinfo.client = client; 3767f7df2e56Smrg clientinfo.prefix = lconnSetupPrefix; 3768f7df2e56Smrg clientinfo.setup = (xConnSetup *) lConnectionInfo; 3769f7df2e56Smrg CallCallbacks((&ClientStateCallback), (void *) &clientinfo); 3770f7df2e56Smrg } 37715a112b11Smrg CancelDispatchExceptionTimer(); 37726747b715Smrg return Success; 377305b261ecSmrg} 377405b261ecSmrg 377505b261ecSmrgint 377605b261ecSmrgProcEstablishConnection(ClientPtr client) 377705b261ecSmrg{ 3778f7df2e56Smrg const char *reason; 3779f7df2e56Smrg char *auth_proto, *auth_string; 378005b261ecSmrg xConnClientPrefix *prefix; 3781f7df2e56Smrg 378205b261ecSmrg REQUEST(xReq); 378305b261ecSmrg 3784f7df2e56Smrg prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq); 3785f7df2e56Smrg auth_proto = (char *) prefix + sz_xConnClientPrefix; 37866747b715Smrg auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); 37876e78d31fSmrg 3788875c6e4fSmrg if (client->swapped && !AllowByteSwappedClients) { 3789875c6e4fSmrg reason = "Prohibited client endianess, see the Xserver man page "; 3790875c6e4fSmrg } else if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix + 3791875c6e4fSmrg pad_to_int32(prefix->nbytesAuthProto) + 3792875c6e4fSmrg pad_to_int32(prefix->nbytesAuthString)) 37936e78d31fSmrg reason = "Bad length"; 37946e78d31fSmrg else if ((prefix->majorVersion != X_PROTOCOL) || 3795f7df2e56Smrg (prefix->minorVersion != X_PROTOCOL_REVISION)) 3796f7df2e56Smrg reason = "Protocol version mismatch"; 379705b261ecSmrg else 3798f7df2e56Smrg reason = ClientAuthorized(client, 3799f7df2e56Smrg (unsigned short) prefix->nbytesAuthProto, 3800f7df2e56Smrg auth_proto, 3801f7df2e56Smrg (unsigned short) prefix->nbytesAuthString, 3802f7df2e56Smrg auth_string); 3803f7df2e56Smrg 3804f7df2e56Smrg return (SendConnSetup(client, reason)); 380505b261ecSmrg} 380605b261ecSmrg 38076747b715Smrgvoid 3808f7df2e56SmrgSendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 380905b261ecSmrg XID resId, int errorCode) 381005b261ecSmrg{ 3811f7df2e56Smrg xError rep = { 3812f7df2e56Smrg .type = X_Error, 3813f7df2e56Smrg .errorCode = errorCode, 3814f7df2e56Smrg .resourceID = resId, 3815f7df2e56Smrg .minorCode = minorCode, 3816f7df2e56Smrg .majorCode = majorCode 3817f7df2e56Smrg }; 381805b261ecSmrg 3819f7df2e56Smrg WriteEventsToClient(client, 1, (xEvent *) &rep); 382005b261ecSmrg} 382105b261ecSmrg 382205b261ecSmrgvoid 382305b261ecSmrgMarkClientException(ClientPtr client) 382405b261ecSmrg{ 382505b261ecSmrg client->noClientException = -1; 382605b261ecSmrg} 38276747b715Smrg 38286747b715Smrg/* 38296747b715Smrg * This array encodes the answer to the question "what is the log base 2 38306747b715Smrg * of the number of pixels that fit in a scanline pad unit?" 38316747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 38326747b715Smrg */ 38336747b715Smrgstatic int answer[6][4] = { 3834f7df2e56Smrg /* pad pad pad pad */ 3835f7df2e56Smrg /* 8 16 32 64 */ 3836f7df2e56Smrg 3837f7df2e56Smrg {3, 4, 5, 6}, /* 1 bit per pixel */ 3838f7df2e56Smrg {1, 2, 3, 4}, /* 4 bits per pixel */ 3839f7df2e56Smrg {0, 1, 2, 3}, /* 8 bits per pixel */ 3840f7df2e56Smrg {~0, 0, 1, 2}, /* 16 bits per pixel */ 3841f7df2e56Smrg {~0, ~0, 0, 1}, /* 24 bits per pixel */ 3842f7df2e56Smrg {~0, ~0, 0, 1} /* 32 bits per pixel */ 38436747b715Smrg}; 38446747b715Smrg 38456747b715Smrg/* 38466747b715Smrg * This array gives the answer to the question "what is the first index for 38476747b715Smrg * the answer array above given the number of bits per pixel?" 38486747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 38496747b715Smrg */ 3850f7df2e56Smrgstatic int indexForBitsPerPixel[33] = { 3851f7df2e56Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 3852f7df2e56Smrg 1, ~0, ~0, ~0, /* 4 bits per pixel */ 3853f7df2e56Smrg 2, ~0, ~0, ~0, /* 8 bits per pixel */ 3854f7df2e56Smrg ~0, ~0, ~0, ~0, 3855f7df2e56Smrg 3, ~0, ~0, ~0, /* 16 bits per pixel */ 3856f7df2e56Smrg ~0, ~0, ~0, ~0, 3857f7df2e56Smrg 4, ~0, ~0, ~0, /* 24 bits per pixel */ 3858f7df2e56Smrg ~0, ~0, ~0, ~0, 3859f7df2e56Smrg 5 /* 32 bits per pixel */ 38606747b715Smrg}; 38616747b715Smrg 38626747b715Smrg/* 38636747b715Smrg * This array gives the bytesperPixel value for cases where the number 38646747b715Smrg * of bits per pixel is a multiple of 8 but not a power of 2. 38656747b715Smrg */ 3866f7df2e56Smrgstatic int answerBytesPerPixel[33] = { 3867f7df2e56Smrg ~0, 0, ~0, ~0, /* 1 bit per pixel */ 3868f7df2e56Smrg 0, ~0, ~0, ~0, /* 4 bits per pixel */ 3869f7df2e56Smrg 0, ~0, ~0, ~0, /* 8 bits per pixel */ 3870f7df2e56Smrg ~0, ~0, ~0, ~0, 3871f7df2e56Smrg 0, ~0, ~0, ~0, /* 16 bits per pixel */ 3872f7df2e56Smrg ~0, ~0, ~0, ~0, 3873f7df2e56Smrg 3, ~0, ~0, ~0, /* 24 bits per pixel */ 3874f7df2e56Smrg ~0, ~0, ~0, ~0, 3875f7df2e56Smrg 0 /* 32 bits per pixel */ 38766747b715Smrg}; 38776747b715Smrg 38786747b715Smrg/* 38796747b715Smrg * This array gives the answer to the question "what is the second index for 38806747b715Smrg * the answer array above given the number of bits per scanline pad unit?" 38816747b715Smrg * Note that ~0 is an invalid entry (mostly for the benefit of the reader). 38826747b715Smrg */ 3883f7df2e56Smrgstatic int indexForScanlinePad[65] = { 3884f7df2e56Smrg ~0, ~0, ~0, ~0, 3885f7df2e56Smrg ~0, ~0, ~0, ~0, 3886f7df2e56Smrg 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ 3887f7df2e56Smrg ~0, ~0, ~0, ~0, 3888f7df2e56Smrg 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ 3889f7df2e56Smrg ~0, ~0, ~0, ~0, 3890f7df2e56Smrg ~0, ~0, ~0, ~0, 3891f7df2e56Smrg ~0, ~0, ~0, ~0, 3892f7df2e56Smrg 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ 3893f7df2e56Smrg ~0, ~0, ~0, ~0, 3894f7df2e56Smrg ~0, ~0, ~0, ~0, 3895f7df2e56Smrg ~0, ~0, ~0, ~0, 3896f7df2e56Smrg ~0, ~0, ~0, ~0, 3897f7df2e56Smrg ~0, ~0, ~0, ~0, 3898f7df2e56Smrg ~0, ~0, ~0, ~0, 3899f7df2e56Smrg ~0, ~0, ~0, ~0, 3900f7df2e56Smrg 3 /* 64 bits per scanline pad unit */ 39016747b715Smrg}; 39026747b715Smrg 39036747b715Smrg/* 39046747b715Smrg grow the array of screenRecs if necessary. 39056747b715Smrg call the device-supplied initialization procedure 39066747b715Smrgwith its screen number, a pointer to its ScreenRec, argc, and argv. 39076747b715Smrg return the number of successfully installed screens. 39086747b715Smrg 39096747b715Smrg*/ 39106747b715Smrg 3911f7df2e56Smrgstatic int init_screen(ScreenPtr pScreen, int i, Bool gpu) 39126747b715Smrg{ 39136747b715Smrg int scanlinepad, format, depth, bitsPerPixel, j, k; 39146747b715Smrg 3915f7df2e56Smrg dixInitScreenSpecificPrivates(pScreen); 39166747b715Smrg 39176747b715Smrg if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) { 3918f7df2e56Smrg return -1; 39196747b715Smrg } 39206747b715Smrg pScreen->myNum = i; 3921f7df2e56Smrg if (gpu) { 3922f7df2e56Smrg pScreen->myNum += GPU_SCREEN_OFFSET; 3923f7df2e56Smrg pScreen->isGPU = TRUE; 3924f7df2e56Smrg } 3925f7df2e56Smrg pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */ 3926f7df2e56Smrg pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ 39276747b715Smrg pScreen->CreateScreenResources = 0; 39286747b715Smrg 3929f7df2e56Smrg xorg_list_init(&pScreen->pixmap_dirty_list); 39305a112b11Smrg xorg_list_init(&pScreen->secondary_list); 3931f7df2e56Smrg 39326747b715Smrg /* 39336747b715Smrg * This loop gets run once for every Screen that gets added, 39345a112b11Smrg * but that's ok. If the ddx layer initializes the formats 39356747b715Smrg * one at a time calling AddScreen() after each, then each 39366747b715Smrg * iteration will make it a little more accurate. Worst case 39376747b715Smrg * we do this loop N * numPixmapFormats where N is # of screens. 39386747b715Smrg * Anyway, this must be called after InitOutput and before the 39396747b715Smrg * screen init routine is called. 39406747b715Smrg */ 3941f7df2e56Smrg for (format = 0; format < screenInfo.numPixmapFormats; format++) { 3942f7df2e56Smrg depth = screenInfo.formats[format].depth; 3943f7df2e56Smrg bitsPerPixel = screenInfo.formats[format].bitsPerPixel; 3944f7df2e56Smrg scanlinepad = screenInfo.formats[format].scanlinePad; 3945f7df2e56Smrg j = indexForBitsPerPixel[bitsPerPixel]; 3946f7df2e56Smrg k = indexForScanlinePad[scanlinepad]; 3947f7df2e56Smrg PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k]; 3948f7df2e56Smrg PixmapWidthPaddingInfo[depth].padRoundUp = 3949f7df2e56Smrg (scanlinepad / bitsPerPixel) - 1; 3950f7df2e56Smrg j = indexForBitsPerPixel[8]; /* bits per byte */ 3951f7df2e56Smrg PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k]; 3952f7df2e56Smrg PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel; 3953f7df2e56Smrg if (answerBytesPerPixel[bitsPerPixel]) { 3954f7df2e56Smrg PixmapWidthPaddingInfo[depth].notPower2 = 1; 3955f7df2e56Smrg PixmapWidthPaddingInfo[depth].bytesPerPixel = 3956f7df2e56Smrg answerBytesPerPixel[bitsPerPixel]; 3957f7df2e56Smrg } 3958f7df2e56Smrg else { 3959f7df2e56Smrg PixmapWidthPaddingInfo[depth].notPower2 = 0; 3960f7df2e56Smrg } 39616747b715Smrg } 3962f7df2e56Smrg return 0; 3963f7df2e56Smrg} 3964f7df2e56Smrg 3965f7df2e56Smrgint 3966f7df2e56SmrgAddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , 3967f7df2e56Smrg int /*argc */ , 3968f7df2e56Smrg char ** /*argv */ 3969f7df2e56Smrg ), int argc, char **argv) 3970f7df2e56Smrg{ 3971f7df2e56Smrg 3972f7df2e56Smrg int i; 3973f7df2e56Smrg ScreenPtr pScreen; 3974f7df2e56Smrg Bool ret; 3975f7df2e56Smrg 3976f7df2e56Smrg i = screenInfo.numScreens; 3977f7df2e56Smrg if (i == MAXSCREENS) 3978f7df2e56Smrg return -1; 3979f7df2e56Smrg 3980f7df2e56Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 3981f7df2e56Smrg if (!pScreen) 3982f7df2e56Smrg return -1; 39836747b715Smrg 3984f7df2e56Smrg ret = init_screen(pScreen, i, FALSE); 3985f7df2e56Smrg if (ret != 0) { 3986f7df2e56Smrg free(pScreen); 3987f7df2e56Smrg return ret; 3988f7df2e56Smrg } 39896747b715Smrg /* This is where screen specific stuff gets initialized. Load the 39906747b715Smrg screen structure, call the hardware, whatever. 39916747b715Smrg This is also where the default colormap should be allocated and 39926747b715Smrg also pixel values for blackPixel, whitePixel, and the cursor 39936747b715Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 39946747b715Smrg any of the strings pointed to by argv. They may be passed to 39956747b715Smrg multiple screens. 3996f7df2e56Smrg */ 39976747b715Smrg screenInfo.screens[i] = pScreen; 39986747b715Smrg screenInfo.numScreens++; 3999f7df2e56Smrg if (!(*pfnInit) (pScreen, argc, argv)) { 4000f7df2e56Smrg dixFreeScreenSpecificPrivates(pScreen); 4001f7df2e56Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 4002f7df2e56Smrg free(pScreen); 4003f7df2e56Smrg screenInfo.numScreens--; 4004f7df2e56Smrg return -1; 40056747b715Smrg } 40066747b715Smrg 4007f7df2e56Smrg update_desktop_dimensions(); 4008f7df2e56Smrg 4009f7df2e56Smrg dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR, 4010f7df2e56Smrg 0); 40116747b715Smrg 40126747b715Smrg return i; 40136747b715Smrg} 4014f7df2e56Smrg 4015f7df2e56Smrgint 4016f7df2e56SmrgAddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , 4017f7df2e56Smrg int /*argc */ , 4018f7df2e56Smrg char ** /*argv */ 4019f7df2e56Smrg ), 4020f7df2e56Smrg int argc, char **argv) 4021f7df2e56Smrg{ 4022f7df2e56Smrg int i; 4023f7df2e56Smrg ScreenPtr pScreen; 4024f7df2e56Smrg Bool ret; 4025f7df2e56Smrg 4026f7df2e56Smrg i = screenInfo.numGPUScreens; 4027f7df2e56Smrg if (i == MAXGPUSCREENS) 4028f7df2e56Smrg return -1; 4029f7df2e56Smrg 4030f7df2e56Smrg pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec)); 4031f7df2e56Smrg if (!pScreen) 4032f7df2e56Smrg return -1; 4033f7df2e56Smrg 4034f7df2e56Smrg ret = init_screen(pScreen, i, TRUE); 4035f7df2e56Smrg if (ret != 0) { 4036f7df2e56Smrg free(pScreen); 4037f7df2e56Smrg return ret; 4038f7df2e56Smrg } 4039f7df2e56Smrg 4040f7df2e56Smrg /* This is where screen specific stuff gets initialized. Load the 4041f7df2e56Smrg screen structure, call the hardware, whatever. 4042f7df2e56Smrg This is also where the default colormap should be allocated and 4043f7df2e56Smrg also pixel values for blackPixel, whitePixel, and the cursor 4044f7df2e56Smrg Note that InitScreen is NOT allowed to modify argc, argv, or 4045f7df2e56Smrg any of the strings pointed to by argv. They may be passed to 4046f7df2e56Smrg multiple screens. 4047f7df2e56Smrg */ 4048f7df2e56Smrg screenInfo.gpuscreens[i] = pScreen; 4049f7df2e56Smrg screenInfo.numGPUScreens++; 4050f7df2e56Smrg if (!(*pfnInit) (pScreen, argc, argv)) { 4051f7df2e56Smrg dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); 4052f7df2e56Smrg free(pScreen); 4053f7df2e56Smrg screenInfo.numGPUScreens--; 4054f7df2e56Smrg return -1; 4055f7df2e56Smrg } 4056f7df2e56Smrg 4057f7df2e56Smrg update_desktop_dimensions(); 4058f7df2e56Smrg 40597e31ba66Smrg /* 40607e31ba66Smrg * We cannot register the Screen PRIVATE_CURSOR key if cursors are already 40617e31ba66Smrg * created, because dix/privates.c does not have relocation code for 40627e31ba66Smrg * PRIVATE_CURSOR. Once this is fixed the if() can be removed and we can 40637e31ba66Smrg * register the Screen PRIVATE_CURSOR key unconditionally. 40647e31ba66Smrg */ 40657e31ba66Smrg if (!dixPrivatesCreated(PRIVATE_CURSOR)) 40667e31ba66Smrg dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, 40677e31ba66Smrg PRIVATE_CURSOR, 0); 40687e31ba66Smrg 4069f7df2e56Smrg return i; 4070f7df2e56Smrg} 4071f7df2e56Smrg 4072f7df2e56Smrgvoid 4073f7df2e56SmrgRemoveGPUScreen(ScreenPtr pScreen) 4074f7df2e56Smrg{ 4075f7df2e56Smrg int idx, j; 4076f7df2e56Smrg if (!pScreen->isGPU) 4077f7df2e56Smrg return; 4078f7df2e56Smrg 4079f7df2e56Smrg idx = pScreen->myNum - GPU_SCREEN_OFFSET; 4080f7df2e56Smrg for (j = idx; j < screenInfo.numGPUScreens - 1; j++) { 4081f7df2e56Smrg screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1]; 4082f7df2e56Smrg screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET; 4083f7df2e56Smrg } 4084f7df2e56Smrg screenInfo.numGPUScreens--; 4085f7df2e56Smrg 4086f7df2e56Smrg /* this gets freed later in the resource list, but without 4087f7df2e56Smrg * the screen existing it causes crashes - so remove it here */ 4088f7df2e56Smrg if (pScreen->defColormap) 4089f7df2e56Smrg FreeResource(pScreen->defColormap, RT_COLORMAP); 4090f7df2e56Smrg free(pScreen); 4091f7df2e56Smrg 4092f7df2e56Smrg} 4093f7df2e56Smrg 4094f7df2e56Smrgvoid 4095f7df2e56SmrgAttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new) 4096f7df2e56Smrg{ 4097f7df2e56Smrg assert(new->isGPU); 40985a112b11Smrg assert(!new->current_primary); 40995a112b11Smrg xorg_list_add(&new->secondary_head, &pScreen->secondary_list); 41005a112b11Smrg new->current_primary = pScreen; 4101f7df2e56Smrg} 4102f7df2e56Smrg 4103f7df2e56Smrgvoid 41045a112b11SmrgDetachUnboundGPU(ScreenPtr secondary) 4105f7df2e56Smrg{ 41065a112b11Smrg assert(secondary->isGPU); 41075a112b11Smrg assert(!secondary->is_output_secondary); 41085a112b11Smrg assert(!secondary->is_offload_secondary); 41095a112b11Smrg xorg_list_del(&secondary->secondary_head); 41105a112b11Smrg secondary->current_primary = NULL; 4111f7df2e56Smrg} 4112f7df2e56Smrg 4113f7df2e56Smrgvoid 4114f7df2e56SmrgAttachOutputGPU(ScreenPtr pScreen, ScreenPtr new) 4115f7df2e56Smrg{ 4116f7df2e56Smrg assert(new->isGPU); 41175a112b11Smrg assert(!new->is_output_secondary); 41185a112b11Smrg assert(new->current_primary == pScreen); 41195a112b11Smrg new->is_output_secondary = TRUE; 41205a112b11Smrg new->current_primary->output_secondarys++; 4121f7df2e56Smrg} 4122f7df2e56Smrg 4123f7df2e56Smrgvoid 41245a112b11SmrgDetachOutputGPU(ScreenPtr secondary) 4125f7df2e56Smrg{ 41265a112b11Smrg assert(secondary->isGPU); 41275a112b11Smrg assert(secondary->is_output_secondary); 41285a112b11Smrg secondary->current_primary->output_secondarys--; 41295a112b11Smrg secondary->is_output_secondary = FALSE; 4130f7df2e56Smrg} 4131f7df2e56Smrg 4132f7df2e56Smrgvoid 4133f7df2e56SmrgAttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new) 4134f7df2e56Smrg{ 4135f7df2e56Smrg assert(new->isGPU); 41365a112b11Smrg assert(!new->is_offload_secondary); 41375a112b11Smrg assert(new->current_primary == pScreen); 41385a112b11Smrg new->is_offload_secondary = TRUE; 4139f7df2e56Smrg} 4140f7df2e56Smrg 4141f7df2e56Smrgvoid 41425a112b11SmrgDetachOffloadGPU(ScreenPtr secondary) 4143f7df2e56Smrg{ 41445a112b11Smrg assert(secondary->isGPU); 41455a112b11Smrg assert(secondary->is_offload_secondary); 41465a112b11Smrg secondary->is_offload_secondary = FALSE; 4147f7df2e56Smrg} 4148f7df2e56Smrg 4149